From 47d41ea64deec070ddb2235d84dda502af3b278b Mon Sep 17 00:00:00 2001 From: ryanzhao Date: Wed, 28 Sep 2022 11:32:45 +1000 Subject: [PATCH 01/33] support landscape and autorotate for iPad --- Session.xcodeproj/project.pbxproj | 2 -- Session/Meta/AppDelegate.swift | 4 ++++ Session/Meta/Session-Info.plist | 7 +++++++ .../Shared View Controllers/OWSNavigationController.m | 7 +------ 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/Session.xcodeproj/project.pbxproj b/Session.xcodeproj/project.pbxproj index 95be399f6..a3827e5b6 100644 --- a/Session.xcodeproj/project.pbxproj +++ b/Session.xcodeproj/project.pbxproj @@ -169,7 +169,6 @@ 7BAF54D827ACD0E3003D12F8 /* ReusableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BAF54D527ACD0E2003D12F8 /* ReusableView.swift */; }; 7BAF54DC27ACD12B003D12F8 /* UIColor+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BAF54DB27ACD12B003D12F8 /* UIColor+Extensions.swift */; }; 7BB92B3F28C825FD0082762F /* NewConversationViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BB92B3E28C825FD0082762F /* NewConversationViewModel.swift */; }; - 7BBBDC462875600700747E59 /* DocumentTitleViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BBBDC452875600700747E59 /* DocumentTitleViewController.swift */; }; 7BBBDC44286EAD2D00747E59 /* TappableLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BBBDC43286EAD2D00747E59 /* TappableLabel.swift */; }; 7BBBDC462875600700747E59 /* DocumentTitleViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BBBDC452875600700747E59 /* DocumentTitleViewController.swift */; }; 7BC01A3E241F40AB00BC7C55 /* NotificationServiceExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BC01A3D241F40AB00BC7C55 /* NotificationServiceExtension.swift */; }; @@ -1217,7 +1216,6 @@ 7BAF54D527ACD0E2003D12F8 /* ReusableView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReusableView.swift; sourceTree = ""; }; 7BAF54DB27ACD12B003D12F8 /* UIColor+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIColor+Extensions.swift"; sourceTree = ""; }; 7BB92B3E28C825FD0082762F /* NewConversationViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewConversationViewModel.swift; sourceTree = ""; }; - 7BBBDC452875600700747E59 /* DocumentTitleViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DocumentTitleViewController.swift; sourceTree = ""; }; 7BBBDC43286EAD2D00747E59 /* TappableLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TappableLabel.swift; sourceTree = ""; }; 7BBBDC452875600700747E59 /* DocumentTitleViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DocumentTitleViewController.swift; sourceTree = ""; }; 7BC01A3B241F40AB00BC7C55 /* SessionNotificationServiceExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = SessionNotificationServiceExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; }; diff --git a/Session/Meta/AppDelegate.swift b/Session/Meta/AppDelegate.swift index 92e0295c0..0db20fced 100644 --- a/Session/Meta/AppDelegate.swift +++ b/Session/Meta/AppDelegate.swift @@ -193,6 +193,10 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD // MARK: - Orientation func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask { + if UIDevice.current.isIPad { + return .all + } + return .portrait } diff --git a/Session/Meta/Session-Info.plist b/Session/Meta/Session-Info.plist index 54e23fb8d..1c8e77c13 100644 --- a/Session/Meta/Session-Info.plist +++ b/Session/Meta/Session-Info.plist @@ -144,6 +144,13 @@ UIInterfaceOrientationPortrait + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIViewControllerBasedStatusBarAppearance diff --git a/SignalUtilitiesKit/Shared View Controllers/OWSNavigationController.m b/SignalUtilitiesKit/Shared View Controllers/OWSNavigationController.m index 3fa1aa29a..945403c46 100644 --- a/SignalUtilitiesKit/Shared View Controllers/OWSNavigationController.m +++ b/SignalUtilitiesKit/Shared View Controllers/OWSNavigationController.m @@ -178,12 +178,7 @@ NS_ASSUME_NONNULL_BEGIN - (BOOL)shouldAutorotate { - return NO; -} - -- (UIInterfaceOrientationMask)supportedInterfaceOrientations -{ - return UIInterfaceOrientationMaskPortrait; + return YES; } @end From bd1e1b266b7f69672d8e65ea9caa62db9ea6bc68 Mon Sep 17 00:00:00 2001 From: ryanzhao Date: Wed, 28 Sep 2022 14:26:07 +1000 Subject: [PATCH 02/33] fix gradient background --- Session/Onboarding/FakeChatView.swift | 2 +- Session/Shared/BaseVC.swift | 11 +++++++++-- SessionUIKit/Style Guide/Gradients.swift | 4 ++-- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/Session/Onboarding/FakeChatView.swift b/Session/Onboarding/FakeChatView.swift index 8fcf6bbfa..c55096971 100644 --- a/Session/Onboarding/FakeChatView.swift +++ b/Session/Onboarding/FakeChatView.swift @@ -46,12 +46,12 @@ final class FakeChatView : UIView { stackView.axis = .vertical stackView.spacing = spacing stackView.alignment = .fill - stackView.set(.width, to: UIScreen.main.bounds.width) let vInset = Values.smallSpacing stackView.layoutMargins = UIEdgeInsets(top: vInset, leading: Values.veryLargeSpacing, bottom: vInset, trailing: Values.veryLargeSpacing) stackView.isLayoutMarginsRelativeArrangement = true scrollView.addSubview(stackView) stackView.pin(to: scrollView) + stackView.set(.width, to: .width, of: scrollView) addSubview(scrollView) scrollView.pin(to: self) let height = chatBubbles.reduce(0) { $0 + $1.systemLayoutSizeFitting(UIView.layoutFittingExpandedSize).height } + CGFloat(chatBubbles.count - 1) * spacing + 2 * vInset diff --git a/Session/Shared/BaseVC.swift b/Session/Shared/BaseVC.swift index f84514f4d..1c0659f39 100644 --- a/Session/Shared/BaseVC.swift +++ b/Session/Shared/BaseVC.swift @@ -28,6 +28,13 @@ class BaseVC : UIViewController { NotificationCenter.default.addObserver(self, selector: #selector(appDidBecomeActive(_:)), name: .OWSApplicationDidBecomeActive, object: nil) } + override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { + if hasGradient { + let frame = CGRect(x: 0, y: 0, width: size.width, height: size.height) + setUpGradientBackground(frame: frame) + } + } + internal func ensureWindowBackground() { let appMode = AppModeManager.shared.currentAppMode switch appMode { @@ -38,11 +45,11 @@ class BaseVC : UIViewController { } } - internal func setUpGradientBackground() { + internal func setUpGradientBackground(frame: CGRect = UIScreen.main.bounds) { hasGradient = true view.backgroundColor = .clear let gradient = Gradients.defaultBackground - view.setGradient(gradient) + view.setGradient(gradient, frame: frame) } internal func setUpNavBarStyle() { diff --git a/SessionUIKit/Style Guide/Gradients.swift b/SessionUIKit/Style Guide/Gradients.swift index 1970ecc42..a08c24bdb 100644 --- a/SessionUIKit/Style Guide/Gradients.swift +++ b/SessionUIKit/Style Guide/Gradients.swift @@ -16,9 +16,9 @@ public final class Gradient : NSObject { @objc public extension UIView { - @objc func setGradient(_ gradient: Gradient) { + @objc func setGradient(_ gradient: Gradient, frame: CGRect = UIScreen.main.bounds) { let layer = CAGradientLayer() - layer.frame = UIScreen.main.bounds + layer.frame = frame layer.colors = [ gradient.start.cgColor, gradient.end.cgColor ] if let existingSublayer = self.layer.sublayers?[0], existingSublayer is CAGradientLayer { self.layer.replaceSublayer(existingSublayer, with: layer) From cc3591a207f97737ca94a1c8f2300a6bca9d3596 Mon Sep 17 00:00:00 2001 From: ryanzhao Date: Wed, 28 Sep 2022 15:58:53 +1000 Subject: [PATCH 03/33] minor tweak on the width of fake chat bubble --- Session/Onboarding/FakeChatView.swift | 4 ++-- SessionUIKit/Utilities/UIView+Constraints.swift | 13 +++++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/Session/Onboarding/FakeChatView.swift b/Session/Onboarding/FakeChatView.swift index c55096971..92180b771 100644 --- a/Session/Onboarding/FakeChatView.swift +++ b/Session/Onboarding/FakeChatView.swift @@ -22,7 +22,7 @@ final class FakeChatView : UIView { return result }() - private static let bubbleWidth = CGFloat(224) + private static let bubbleWidth = UIDevice.current.isIPad ? CGFloat(468) : CGFloat(224) private static let bubbleCornerRadius = CGFloat(10) private static let startDelay: TimeInterval = 1 private static let animationDuration: TimeInterval = 0.4 @@ -61,7 +61,7 @@ final class FakeChatView : UIView { private func getChatBubble(withText text: String, wasSentByCurrentUser: Bool) -> UIView { let result = UIView() let bubbleView = UIView() - bubbleView.set(.width, to: FakeChatView.bubbleWidth) + bubbleView.set(.width, lessThanOrEqualTo: FakeChatView.bubbleWidth) bubbleView.layer.cornerRadius = FakeChatView.bubbleCornerRadius bubbleView.layer.shadowColor = UIColor.black.cgColor bubbleView.layer.shadowRadius = isLightMode ? 4 : 8 diff --git a/SessionUIKit/Utilities/UIView+Constraints.swift b/SessionUIKit/Utilities/UIView+Constraints.swift index f9b237c64..b00e02872 100644 --- a/SessionUIKit/Utilities/UIView+Constraints.swift +++ b/SessionUIKit/Utilities/UIView+Constraints.swift @@ -127,4 +127,17 @@ public extension UIView { constraint.isActive = true return constraint } + + @discardableResult + func set(_ dimension: Dimension, lessThanOrEqualTo size: CGFloat) -> NSLayoutConstraint { + translatesAutoresizingMaskIntoConstraints = false + let constraint: NSLayoutConstraint = { + switch dimension { + case .width: return widthAnchor.constraint(lessThanOrEqualToConstant: size) + case .height: return heightAnchor.constraint(lessThanOrEqualToConstant: size) + } + }() + constraint.isActive = true + return constraint + } } From b20e123bfd8515b58d500927d1a2b4ee93f94e10 Mon Sep 17 00:00:00 2001 From: ryanzhao Date: Wed, 28 Sep 2022 16:57:13 +1000 Subject: [PATCH 04/33] WIP: fix message bubble UI in conversation view when rotating the device --- Session/Conversations/ConversationVC.swift | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Session/Conversations/ConversationVC.swift b/Session/Conversations/ConversationVC.swift index 8142600ea..de52e02a5 100644 --- a/Session/Conversations/ConversationVC.swift +++ b/Session/Conversations/ConversationVC.swift @@ -476,6 +476,11 @@ final class ConversationVC: BaseVC, OWSConversationSettingsViewDelegate, Convers stopObservingChanges() } + override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { + super.viewWillTransition(to: size, with: coordinator) + tableView.reloadData() + } + // MARK: - Updating private func startObservingChanges(didReturnFromBackground: Bool = false) { From ce73cc7e986033c94735bc146f26f1ef5373ee15 Mon Sep 17 00:00:00 2001 From: ryanzhao Date: Thu, 29 Sep 2022 14:50:44 +1000 Subject: [PATCH 05/33] fix home screen conversation cell UI --- Session/Meta/AppDelegate.swift | 2 +- Session/Meta/Session-Info.plist | 1 - Session/Shared/FullConversationCell.swift | 14 ++++---------- 3 files changed, 5 insertions(+), 12 deletions(-) diff --git a/Session/Meta/AppDelegate.swift b/Session/Meta/AppDelegate.swift index 0db20fced..e4523d53a 100644 --- a/Session/Meta/AppDelegate.swift +++ b/Session/Meta/AppDelegate.swift @@ -194,7 +194,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask { if UIDevice.current.isIPad { - return .all + return .allButUpsideDown } return .portrait diff --git a/Session/Meta/Session-Info.plist b/Session/Meta/Session-Info.plist index 1c8e77c13..e186b98c9 100644 --- a/Session/Meta/Session-Info.plist +++ b/Session/Meta/Session-Info.plist @@ -149,7 +149,6 @@ UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown UIViewControllerBasedStatusBarAppearance diff --git a/Session/Shared/FullConversationCell.swift b/Session/Shared/FullConversationCell.swift index 8739de5c5..f98a612be 100644 --- a/Session/Shared/FullConversationCell.swift +++ b/Session/Shared/FullConversationCell.swift @@ -191,7 +191,7 @@ public final class FullConversationCell: UITableViewCell { let labelContainerView = UIStackView(arrangedSubviews: [ topLabelStackView, bottomLabelStackView ]) labelContainerView.axis = .vertical - labelContainerView.alignment = .leading + labelContainerView.alignment = .fill labelContainerView.spacing = 6 labelContainerView.isUserInteractionEnabled = false @@ -207,12 +207,10 @@ public final class FullConversationCell: UITableViewCell { accentLineView.pin(.bottom, to: .bottom, of: contentView) timestampLabel.setContentCompressionResistancePriority(.required, for: NSLayoutConstraint.Axis.horizontal) - // HACK: The six lines below are part of a workaround for a weird layout bug - topLabelStackView.set(.width, to: UIScreen.main.bounds.width - Values.accentLineThickness - profilePictureViewSize - 3 * Values.mediumSpacing) + // HACK: The 4 lines below are part of a workaround for a weird layout bug topLabelStackView.set(.height, to: 20) topLabelSpacer.set(.height, to: 20) - bottomLabelStackView.set(.width, to: UIScreen.main.bounds.width - Values.accentLineThickness - profilePictureViewSize - 3 * Values.mediumSpacing) bottomLabelStackView.set(.height, to: 18) bottomLabelSpacer.set(.height, to: 18) @@ -224,12 +222,8 @@ public final class FullConversationCell: UITableViewCell { typingIndicatorView.pin(.leading, to: .leading, of: snippetLabelContainer) typingIndicatorView.centerYAnchor.constraint(equalTo: snippetLabel.centerYAnchor).isActive = true - stackView.pin(.leading, to: .leading, of: contentView) - stackView.pin(.top, to: .top, of: contentView) - - // HACK: The two lines below are part of a workaround for a weird layout bug - stackView.set(.width, to: UIScreen.main.bounds.width - Values.mediumSpacing) - stackView.set(.height, to: cellHeight) + stackView.pin([ UIView.VerticalEdge.bottom, UIView.VerticalEdge.top, UIView.HorizontalEdge.leading ], to: contentView) + stackView.pin(.trailing, to: .trailing, of: contentView, withInset: -Values.mediumSpacing) } // MARK: - Content From 361c6c729c4420403d271271ca6bd78d9273beba Mon Sep 17 00:00:00 2001 From: ryanzhao Date: Thu, 29 Sep 2022 15:08:11 +1000 Subject: [PATCH 06/33] extent message bubble width for iPad --- Session/Conversations/Message Cells/VisibleMessageCell.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Session/Conversations/Message Cells/VisibleMessageCell.swift b/Session/Conversations/Message Cells/VisibleMessageCell.swift index a56bf9119..6dfc88fff 100644 --- a/Session/Conversations/Message Cells/VisibleMessageCell.swift +++ b/Session/Conversations/Message Cells/VisibleMessageCell.swift @@ -147,7 +147,7 @@ final class VisibleMessageCell: MessageCell, TappableLabelDelegate { var result = groupThreadHSpacing + profilePictureSize + groupThreadHSpacing if UIDevice.current.isIPad { - result += CGFloat(UIScreen.main.bounds.width / 2 - 88) + result += 168 } return result From c82e4ab11f9b098c967be8c33331a61f677e7de9 Mon Sep 17 00:00:00 2001 From: ryanzhao Date: Thu, 29 Sep 2022 15:14:19 +1000 Subject: [PATCH 07/33] fix a localised string --- .../Message Cells/Content Views/ReactionContainerView.swift | 2 +- Session/Meta/Translations/de.lproj/Localizable.strings | 1 + Session/Meta/Translations/en.lproj/Localizable.strings | 1 + Session/Meta/Translations/es.lproj/Localizable.strings | 1 + Session/Meta/Translations/fa.lproj/Localizable.strings | 1 + Session/Meta/Translations/fi.lproj/Localizable.strings | 1 + Session/Meta/Translations/fr.lproj/Localizable.strings | 1 + Session/Meta/Translations/hi.lproj/Localizable.strings | 1 + Session/Meta/Translations/hr.lproj/Localizable.strings | 1 + Session/Meta/Translations/id-ID.lproj/Localizable.strings | 1 + Session/Meta/Translations/it.lproj/Localizable.strings | 1 + Session/Meta/Translations/ja.lproj/Localizable.strings | 1 + Session/Meta/Translations/nl.lproj/Localizable.strings | 1 + Session/Meta/Translations/pl.lproj/Localizable.strings | 1 + Session/Meta/Translations/pt_BR.lproj/Localizable.strings | 1 + Session/Meta/Translations/ru.lproj/Localizable.strings | 1 + Session/Meta/Translations/si.lproj/Localizable.strings | 1 + Session/Meta/Translations/sk.lproj/Localizable.strings | 1 + Session/Meta/Translations/sv.lproj/Localizable.strings | 1 + Session/Meta/Translations/th.lproj/Localizable.strings | 1 + Session/Meta/Translations/vi-VN.lproj/Localizable.strings | 1 + Session/Meta/Translations/zh-Hant.lproj/Localizable.strings | 1 + Session/Meta/Translations/zh_CN.lproj/Localizable.strings | 1 + 23 files changed, 23 insertions(+), 1 deletion(-) diff --git a/Session/Conversations/Message Cells/Content Views/ReactionContainerView.swift b/Session/Conversations/Message Cells/Content Views/ReactionContainerView.swift index 982195f50..dc5fb0c2e 100644 --- a/Session/Conversations/Message Cells/Content Views/ReactionContainerView.swift +++ b/Session/Conversations/Message Cells/Content Views/ReactionContainerView.swift @@ -36,7 +36,7 @@ final class ReactionContainerView: UIView { arrow.tintColor = Colors.text let textLabel = UILabel() - textLabel.text = "Show less" + textLabel.text = "EMOJI_REACTS_SHOW_LESS".localized() textLabel.font = .systemFont(ofSize: Values.verySmallFontSize) textLabel.textColor = Colors.text diff --git a/Session/Meta/Translations/de.lproj/Localizable.strings b/Session/Meta/Translations/de.lproj/Localizable.strings index 0f3da385f..ddbe30436 100644 --- a/Session/Meta/Translations/de.lproj/Localizable.strings +++ b/Session/Meta/Translations/de.lproj/Localizable.strings @@ -711,6 +711,7 @@ "EMOJI_REACTS_NOTIFICATION" = "%@ reacts to a message with %@."; "EMOJI_REACTS_MORE_REACTORS_ONE" = "And 1 other has reacted %@ to this message."; "EMOJI_REACTS_MORE_REACTORS_MUTIPLE" = "And %@ others have reacted %@ to this message."; +"EMOJI_REACTS_SHOW_LESS" = "Show less"; /* New conversation screen*/ "vc_new_conversation_title" = "New Conversation"; "CREATE_GROUP_BUTTON_TITLE" = "Create"; diff --git a/Session/Meta/Translations/en.lproj/Localizable.strings b/Session/Meta/Translations/en.lproj/Localizable.strings index cc1c26a72..a0ccdb557 100644 --- a/Session/Meta/Translations/en.lproj/Localizable.strings +++ b/Session/Meta/Translations/en.lproj/Localizable.strings @@ -711,6 +711,7 @@ "EMOJI_REACTS_NOTIFICATION" = "%@ reacts to a message with %@."; "EMOJI_REACTS_MORE_REACTORS_ONE" = "And 1 other has reacted %@ to this message."; "EMOJI_REACTS_MORE_REACTORS_MUTIPLE" = "And %@ others have reacted %@ to this message."; +"EMOJI_REACTS_SHOW_LESS" = "Show less"; /* New conversation screen*/ "vc_new_conversation_title" = "New Conversation"; "CREATE_GROUP_BUTTON_TITLE" = "Create"; diff --git a/Session/Meta/Translations/es.lproj/Localizable.strings b/Session/Meta/Translations/es.lproj/Localizable.strings index e447a29e6..b1a1905b7 100644 --- a/Session/Meta/Translations/es.lproj/Localizable.strings +++ b/Session/Meta/Translations/es.lproj/Localizable.strings @@ -711,6 +711,7 @@ "EMOJI_REACTS_NOTIFICATION" = "%@ reacts to a message with %@."; "EMOJI_REACTS_MORE_REACTORS_ONE" = "And 1 other has reacted %@ to this message."; "EMOJI_REACTS_MORE_REACTORS_MUTIPLE" = "And %@ others have reacted %@ to this message."; +"EMOJI_REACTS_SHOW_LESS" = "Show less"; /* New conversation screen*/ "vc_new_conversation_title" = "New Conversation"; "CREATE_GROUP_BUTTON_TITLE" = "Create"; diff --git a/Session/Meta/Translations/fa.lproj/Localizable.strings b/Session/Meta/Translations/fa.lproj/Localizable.strings index 82423e38e..97a7d53af 100644 --- a/Session/Meta/Translations/fa.lproj/Localizable.strings +++ b/Session/Meta/Translations/fa.lproj/Localizable.strings @@ -711,6 +711,7 @@ "EMOJI_REACTS_NOTIFICATION" = "%@ reacts to a message with %@."; "EMOJI_REACTS_MORE_REACTORS_ONE" = "And 1 other has reacted %@ to this message."; "EMOJI_REACTS_MORE_REACTORS_MUTIPLE" = "And %@ others have reacted %@ to this message."; +"EMOJI_REACTS_SHOW_LESS" = "Show less"; /* New conversation screen*/ "vc_new_conversation_title" = "New Conversation"; "CREATE_GROUP_BUTTON_TITLE" = "Create"; diff --git a/Session/Meta/Translations/fi.lproj/Localizable.strings b/Session/Meta/Translations/fi.lproj/Localizable.strings index 7989da67f..fcc54e445 100644 --- a/Session/Meta/Translations/fi.lproj/Localizable.strings +++ b/Session/Meta/Translations/fi.lproj/Localizable.strings @@ -711,6 +711,7 @@ "EMOJI_REACTS_NOTIFICATION" = "%@ reacts to a message with %@."; "EMOJI_REACTS_MORE_REACTORS_ONE" = "And 1 other has reacted %@ to this message."; "EMOJI_REACTS_MORE_REACTORS_MUTIPLE" = "And %@ others have reacted %@ to this message."; +"EMOJI_REACTS_SHOW_LESS" = "Show less"; /* New conversation screen*/ "vc_new_conversation_title" = "New Conversation"; "CREATE_GROUP_BUTTON_TITLE" = "Create"; diff --git a/Session/Meta/Translations/fr.lproj/Localizable.strings b/Session/Meta/Translations/fr.lproj/Localizable.strings index 54da86768..476a9fb88 100644 --- a/Session/Meta/Translations/fr.lproj/Localizable.strings +++ b/Session/Meta/Translations/fr.lproj/Localizable.strings @@ -711,6 +711,7 @@ "EMOJI_REACTS_NOTIFICATION" = "%@ reacts to a message with %@."; "EMOJI_REACTS_MORE_REACTORS_ONE" = "And 1 other has reacted %@ to this message."; "EMOJI_REACTS_MORE_REACTORS_MUTIPLE" = "And %@ others have reacted %@ to this message."; +"EMOJI_REACTS_SHOW_LESS" = "Show less"; /* New conversation screen*/ "vc_new_conversation_title" = "New Conversation"; "CREATE_GROUP_BUTTON_TITLE" = "Create"; diff --git a/Session/Meta/Translations/hi.lproj/Localizable.strings b/Session/Meta/Translations/hi.lproj/Localizable.strings index d79703f35..fa86873a1 100644 --- a/Session/Meta/Translations/hi.lproj/Localizable.strings +++ b/Session/Meta/Translations/hi.lproj/Localizable.strings @@ -711,6 +711,7 @@ "EMOJI_REACTS_NOTIFICATION" = "%@ reacts to a message with %@."; "EMOJI_REACTS_MORE_REACTORS_ONE" = "And 1 other has reacted %@ to this message."; "EMOJI_REACTS_MORE_REACTORS_MUTIPLE" = "And %@ others have reacted %@ to this message."; +"EMOJI_REACTS_SHOW_LESS" = "Show less"; /* New conversation screen*/ "vc_new_conversation_title" = "New Conversation"; "CREATE_GROUP_BUTTON_TITLE" = "Create"; diff --git a/Session/Meta/Translations/hr.lproj/Localizable.strings b/Session/Meta/Translations/hr.lproj/Localizable.strings index 17fa91859..81f632d73 100644 --- a/Session/Meta/Translations/hr.lproj/Localizable.strings +++ b/Session/Meta/Translations/hr.lproj/Localizable.strings @@ -711,6 +711,7 @@ "EMOJI_REACTS_NOTIFICATION" = "%@ reacts to a message with %@."; "EMOJI_REACTS_MORE_REACTORS_ONE" = "And 1 other has reacted %@ to this message."; "EMOJI_REACTS_MORE_REACTORS_MUTIPLE" = "And %@ others have reacted %@ to this message."; +"EMOJI_REACTS_SHOW_LESS" = "Show less"; /* New conversation screen*/ "vc_new_conversation_title" = "New Conversation"; "CREATE_GROUP_BUTTON_TITLE" = "Create"; diff --git a/Session/Meta/Translations/id-ID.lproj/Localizable.strings b/Session/Meta/Translations/id-ID.lproj/Localizable.strings index d50e08397..4ca937a6a 100644 --- a/Session/Meta/Translations/id-ID.lproj/Localizable.strings +++ b/Session/Meta/Translations/id-ID.lproj/Localizable.strings @@ -711,6 +711,7 @@ "EMOJI_REACTS_NOTIFICATION" = "%@ reacts to a message with %@."; "EMOJI_REACTS_MORE_REACTORS_ONE" = "And 1 other has reacted %@ to this message."; "EMOJI_REACTS_MORE_REACTORS_MUTIPLE" = "And %@ others have reacted %@ to this message."; +"EMOJI_REACTS_SHOW_LESS" = "Show less"; /* New conversation screen*/ "vc_new_conversation_title" = "New Conversation"; "CREATE_GROUP_BUTTON_TITLE" = "Create"; diff --git a/Session/Meta/Translations/it.lproj/Localizable.strings b/Session/Meta/Translations/it.lproj/Localizable.strings index 8f20f588d..963e7ef75 100644 --- a/Session/Meta/Translations/it.lproj/Localizable.strings +++ b/Session/Meta/Translations/it.lproj/Localizable.strings @@ -711,6 +711,7 @@ "EMOJI_REACTS_NOTIFICATION" = "%@ reacts to a message with %@."; "EMOJI_REACTS_MORE_REACTORS_ONE" = "And 1 other has reacted %@ to this message."; "EMOJI_REACTS_MORE_REACTORS_MUTIPLE" = "And %@ others have reacted %@ to this message."; +"EMOJI_REACTS_SHOW_LESS" = "Show less"; /* New conversation screen*/ "vc_new_conversation_title" = "New Conversation"; "CREATE_GROUP_BUTTON_TITLE" = "Create"; diff --git a/Session/Meta/Translations/ja.lproj/Localizable.strings b/Session/Meta/Translations/ja.lproj/Localizable.strings index 6185b3ad5..0904264ed 100644 --- a/Session/Meta/Translations/ja.lproj/Localizable.strings +++ b/Session/Meta/Translations/ja.lproj/Localizable.strings @@ -711,6 +711,7 @@ "EMOJI_REACTS_NOTIFICATION" = "%@ reacts to a message with %@."; "EMOJI_REACTS_MORE_REACTORS_ONE" = "And 1 other has reacted %@ to this message."; "EMOJI_REACTS_MORE_REACTORS_MUTIPLE" = "And %@ others have reacted %@ to this message."; +"EMOJI_REACTS_SHOW_LESS" = "Show less"; /* New conversation screen*/ "vc_new_conversation_title" = "New Conversation"; "CREATE_GROUP_BUTTON_TITLE" = "Create"; diff --git a/Session/Meta/Translations/nl.lproj/Localizable.strings b/Session/Meta/Translations/nl.lproj/Localizable.strings index ada8b4092..82039b3d9 100644 --- a/Session/Meta/Translations/nl.lproj/Localizable.strings +++ b/Session/Meta/Translations/nl.lproj/Localizable.strings @@ -711,6 +711,7 @@ "EMOJI_REACTS_NOTIFICATION" = "%@ reacts to a message with %@."; "EMOJI_REACTS_MORE_REACTORS_ONE" = "And 1 other has reacted %@ to this message."; "EMOJI_REACTS_MORE_REACTORS_MUTIPLE" = "And %@ others have reacted %@ to this message."; +"EMOJI_REACTS_SHOW_LESS" = "Show less"; /* New conversation screen*/ "vc_new_conversation_title" = "New Conversation"; "CREATE_GROUP_BUTTON_TITLE" = "Create"; diff --git a/Session/Meta/Translations/pl.lproj/Localizable.strings b/Session/Meta/Translations/pl.lproj/Localizable.strings index ad77428b6..433df8a79 100644 --- a/Session/Meta/Translations/pl.lproj/Localizable.strings +++ b/Session/Meta/Translations/pl.lproj/Localizable.strings @@ -711,6 +711,7 @@ "EMOJI_REACTS_NOTIFICATION" = "%@ reacts to a message with %@."; "EMOJI_REACTS_MORE_REACTORS_ONE" = "And 1 other has reacted %@ to this message."; "EMOJI_REACTS_MORE_REACTORS_MUTIPLE" = "And %@ others have reacted %@ to this message."; +"EMOJI_REACTS_SHOW_LESS" = "Show less"; /* New conversation screen*/ "vc_new_conversation_title" = "New Conversation"; "CREATE_GROUP_BUTTON_TITLE" = "Create"; diff --git a/Session/Meta/Translations/pt_BR.lproj/Localizable.strings b/Session/Meta/Translations/pt_BR.lproj/Localizable.strings index a13ec240b..50246ecdb 100644 --- a/Session/Meta/Translations/pt_BR.lproj/Localizable.strings +++ b/Session/Meta/Translations/pt_BR.lproj/Localizable.strings @@ -711,6 +711,7 @@ "EMOJI_REACTS_NOTIFICATION" = "%@ reacts to a message with %@."; "EMOJI_REACTS_MORE_REACTORS_ONE" = "And 1 other has reacted %@ to this message."; "EMOJI_REACTS_MORE_REACTORS_MUTIPLE" = "And %@ others have reacted %@ to this message."; +"EMOJI_REACTS_SHOW_LESS" = "Show less"; /* New conversation screen*/ "vc_new_conversation_title" = "New Conversation"; "CREATE_GROUP_BUTTON_TITLE" = "Create"; diff --git a/Session/Meta/Translations/ru.lproj/Localizable.strings b/Session/Meta/Translations/ru.lproj/Localizable.strings index 28eb7d371..70e67700b 100644 --- a/Session/Meta/Translations/ru.lproj/Localizable.strings +++ b/Session/Meta/Translations/ru.lproj/Localizable.strings @@ -711,6 +711,7 @@ "EMOJI_REACTS_NOTIFICATION" = "%@ reacts to a message with %@."; "EMOJI_REACTS_MORE_REACTORS_ONE" = "And 1 other has reacted %@ to this message."; "EMOJI_REACTS_MORE_REACTORS_MUTIPLE" = "And %@ others have reacted %@ to this message."; +"EMOJI_REACTS_SHOW_LESS" = "Show less"; /* New conversation screen*/ "vc_new_conversation_title" = "New Conversation"; "CREATE_GROUP_BUTTON_TITLE" = "Create"; diff --git a/Session/Meta/Translations/si.lproj/Localizable.strings b/Session/Meta/Translations/si.lproj/Localizable.strings index 2bc02f293..794e8e676 100644 --- a/Session/Meta/Translations/si.lproj/Localizable.strings +++ b/Session/Meta/Translations/si.lproj/Localizable.strings @@ -711,6 +711,7 @@ "EMOJI_REACTS_NOTIFICATION" = "%@ reacts to a message with %@."; "EMOJI_REACTS_MORE_REACTORS_ONE" = "And 1 other has reacted %@ to this message."; "EMOJI_REACTS_MORE_REACTORS_MUTIPLE" = "And %@ others have reacted %@ to this message."; +"EMOJI_REACTS_SHOW_LESS" = "Show less"; /* New conversation screen*/ "vc_new_conversation_title" = "New Conversation"; "CREATE_GROUP_BUTTON_TITLE" = "Create"; diff --git a/Session/Meta/Translations/sk.lproj/Localizable.strings b/Session/Meta/Translations/sk.lproj/Localizable.strings index 90da4af9e..2d7efef0c 100644 --- a/Session/Meta/Translations/sk.lproj/Localizable.strings +++ b/Session/Meta/Translations/sk.lproj/Localizable.strings @@ -711,6 +711,7 @@ "EMOJI_REACTS_NOTIFICATION" = "%@ reacts to a message with %@."; "EMOJI_REACTS_MORE_REACTORS_ONE" = "And 1 other has reacted %@ to this message."; "EMOJI_REACTS_MORE_REACTORS_MUTIPLE" = "And %@ others have reacted %@ to this message."; +"EMOJI_REACTS_SHOW_LESS" = "Show less"; /* New conversation screen*/ "vc_new_conversation_title" = "New Conversation"; "CREATE_GROUP_BUTTON_TITLE" = "Create"; diff --git a/Session/Meta/Translations/sv.lproj/Localizable.strings b/Session/Meta/Translations/sv.lproj/Localizable.strings index 12cf7b6f1..d44de70e2 100644 --- a/Session/Meta/Translations/sv.lproj/Localizable.strings +++ b/Session/Meta/Translations/sv.lproj/Localizable.strings @@ -711,6 +711,7 @@ "EMOJI_REACTS_NOTIFICATION" = "%@ reacts to a message with %@."; "EMOJI_REACTS_MORE_REACTORS_ONE" = "And 1 other has reacted %@ to this message."; "EMOJI_REACTS_MORE_REACTORS_MUTIPLE" = "And %@ others have reacted %@ to this message."; +"EMOJI_REACTS_SHOW_LESS" = "Show less"; /* New conversation screen*/ "vc_new_conversation_title" = "New Conversation"; "CREATE_GROUP_BUTTON_TITLE" = "Create"; diff --git a/Session/Meta/Translations/th.lproj/Localizable.strings b/Session/Meta/Translations/th.lproj/Localizable.strings index aa3d751f0..17fc5c318 100644 --- a/Session/Meta/Translations/th.lproj/Localizable.strings +++ b/Session/Meta/Translations/th.lproj/Localizable.strings @@ -711,6 +711,7 @@ "EMOJI_REACTS_NOTIFICATION" = "%@ reacts to a message with %@."; "EMOJI_REACTS_MORE_REACTORS_ONE" = "And 1 other has reacted %@ to this message."; "EMOJI_REACTS_MORE_REACTORS_MUTIPLE" = "And %@ others have reacted %@ to this message."; +"EMOJI_REACTS_SHOW_LESS" = "Show less"; /* New conversation screen*/ "vc_new_conversation_title" = "New Conversation"; "CREATE_GROUP_BUTTON_TITLE" = "Create"; diff --git a/Session/Meta/Translations/vi-VN.lproj/Localizable.strings b/Session/Meta/Translations/vi-VN.lproj/Localizable.strings index f1a783851..526941fb8 100644 --- a/Session/Meta/Translations/vi-VN.lproj/Localizable.strings +++ b/Session/Meta/Translations/vi-VN.lproj/Localizable.strings @@ -711,6 +711,7 @@ "EMOJI_REACTS_NOTIFICATION" = "%@ reacts to a message with %@."; "EMOJI_REACTS_MORE_REACTORS_ONE" = "And 1 other has reacted %@ to this message."; "EMOJI_REACTS_MORE_REACTORS_MUTIPLE" = "And %@ others have reacted %@ to this message."; +"EMOJI_REACTS_SHOW_LESS" = "Show less"; /* New conversation screen*/ "vc_new_conversation_title" = "New Conversation"; "CREATE_GROUP_BUTTON_TITLE" = "Create"; diff --git a/Session/Meta/Translations/zh-Hant.lproj/Localizable.strings b/Session/Meta/Translations/zh-Hant.lproj/Localizable.strings index 61045a1fa..a5426caa5 100644 --- a/Session/Meta/Translations/zh-Hant.lproj/Localizable.strings +++ b/Session/Meta/Translations/zh-Hant.lproj/Localizable.strings @@ -711,6 +711,7 @@ "EMOJI_REACTS_NOTIFICATION" = "%@ reacts to a message with %@."; "EMOJI_REACTS_MORE_REACTORS_ONE" = "And 1 other has reacted %@ to this message."; "EMOJI_REACTS_MORE_REACTORS_MUTIPLE" = "And %@ others have reacted %@ to this message."; +"EMOJI_REACTS_SHOW_LESS" = "Show less"; /* New conversation screen*/ "vc_new_conversation_title" = "New Conversation"; "CREATE_GROUP_BUTTON_TITLE" = "Create"; diff --git a/Session/Meta/Translations/zh_CN.lproj/Localizable.strings b/Session/Meta/Translations/zh_CN.lproj/Localizable.strings index f833919df..2d6327e45 100644 --- a/Session/Meta/Translations/zh_CN.lproj/Localizable.strings +++ b/Session/Meta/Translations/zh_CN.lproj/Localizable.strings @@ -711,6 +711,7 @@ "EMOJI_REACTS_NOTIFICATION" = "%@ reacts to a message with %@."; "EMOJI_REACTS_MORE_REACTORS_ONE" = "And 1 other has reacted %@ to this message."; "EMOJI_REACTS_MORE_REACTORS_MUTIPLE" = "And %@ others have reacted %@ to this message."; +"EMOJI_REACTS_SHOW_LESS" = "Show less"; /* New conversation screen*/ "vc_new_conversation_title" = "New Conversation"; "CREATE_GROUP_BUTTON_TITLE" = "Create"; From 2c14073b04fb28185cb96c5eba51dae3b7f2842b Mon Sep 17 00:00:00 2001 From: ryanzhao Date: Thu, 29 Sep 2022 17:00:23 +1000 Subject: [PATCH 08/33] fix global search search bar width --- .../Home/GlobalSearch/GlobalSearchViewController.swift | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Session/Home/GlobalSearch/GlobalSearchViewController.swift b/Session/Home/GlobalSearch/GlobalSearchViewController.swift index c88b527be..ebbb24927 100644 --- a/Session/Home/GlobalSearch/GlobalSearchViewController.swift +++ b/Session/Home/GlobalSearch/GlobalSearchViewController.swift @@ -55,6 +55,8 @@ class GlobalSearchViewController: BaseVC, UITableViewDelegate, UITableViewDataSo result.showsCancelButton = true return result }() + + private var searchBarWidth: NSLayoutConstraint? internal lazy var tableView: UITableView = { let result: UITableView = UITableView(frame: .zero, style: .grouped) @@ -97,6 +99,11 @@ class GlobalSearchViewController: BaseVC, UITableViewDelegate, UITableViewDataSo super.viewWillDisappear(animated) searchBar.resignFirstResponder() } + + override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { + super.viewWillTransition(to: size, with: coordinator) + searchBarWidth?.constant = size.width - 32 + } private func setupNavigationBar() { // This is a workaround for a UI issue that the navigation bar can be a bit higher if @@ -107,7 +114,7 @@ class GlobalSearchViewController: BaseVC, UITableViewDelegate, UITableViewDataSo searchBar.sizeToFit() searchBar.layoutMargins = UIEdgeInsets.zero searchBarContainer.set(.height, to: 44) - searchBarContainer.set(.width, to: UIScreen.main.bounds.width - 32) + searchBarWidth = searchBarContainer.set(.width, to: UIScreen.main.bounds.width - 32) searchBarContainer.addSubview(searchBar) navigationItem.titleView = searchBarContainer From c5c2d7e8a1d078a22d652c47d2902abbee9c445e Mon Sep 17 00:00:00 2001 From: ryanzhao Date: Thu, 29 Sep 2022 17:21:40 +1000 Subject: [PATCH 09/33] fix conversation search bar width when rotating --- Session/Conversations/ConversationVC.swift | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Session/Conversations/ConversationVC.swift b/Session/Conversations/ConversationVC.swift index de52e02a5..f0a45d9c6 100644 --- a/Session/Conversations/ConversationVC.swift +++ b/Session/Conversations/ConversationVC.swift @@ -39,6 +39,8 @@ final class ConversationVC: BaseVC, OWSConversationSettingsViewDelegate, Convers var audioRecorder: AVAudioRecorder? var audioTimer: Timer? + private var searchBarWidth: NSLayoutConstraint? + // Context menu var contextMenuWindow: ContextMenuWindow? var contextMenuVC: ContextMenuVC? @@ -478,6 +480,7 @@ final class ConversationVC: BaseVC, OWSConversationSettingsViewDelegate, Convers override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { super.viewWillTransition(to: size, with: coordinator) + searchBarWidth?.constant = size.width - 32 tableView.reloadData() } @@ -1398,7 +1401,7 @@ final class ConversationVC: BaseVC, OWSConversationSettingsViewDelegate, Convers searchBar.sizeToFit() searchBar.layoutMargins = UIEdgeInsets.zero searchBarContainer.set(.height, to: 44) - searchBarContainer.set(.width, to: UIScreen.main.bounds.width - 32) + searchBarWidth = searchBarContainer.set(.width, to: UIScreen.main.bounds.width - 32) searchBarContainer.addSubview(searchBar) navigationItem.titleView = searchBarContainer From 4c2b01ca424a7f23729f4bbfbc134d7f8e4cf5dd Mon Sep 17 00:00:00 2001 From: ryanzhao Date: Fri, 30 Sep 2022 10:54:40 +1000 Subject: [PATCH 10/33] fix create closed group screen --- Session/Closed Groups/NewClosedGroupVC.swift | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/Session/Closed Groups/NewClosedGroupVC.swift b/Session/Closed Groups/NewClosedGroupVC.swift index b468a56ee..2120ed2f3 100644 --- a/Session/Closed Groups/NewClosedGroupVC.swift +++ b/Session/Closed Groups/NewClosedGroupVC.swift @@ -27,6 +27,10 @@ final class NewClosedGroupVC: BaseVC, UITableViewDataSource, UITableViewDelegate private var selectedContacts: Set = [] private var searchText: String = "" + // MARK: - Layout + + private var tableViewWidth: NSLayoutConstraint? + // MARK: - Components private lazy var nameTextField: TextField = { @@ -105,6 +109,11 @@ final class NewClosedGroupVC: BaseVC, UITableViewDataSource, UITableViewDelegate // Set up content setUpViewHierarchy() } + + override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { + super.viewWillTransition(to: size, with: coordinator) + tableViewWidth?.constant = size.width + } private func setUpViewHierarchy() { guard !contactProfiles.isEmpty else { @@ -158,15 +167,13 @@ final class NewClosedGroupVC: BaseVC, UITableViewDataSource, UITableViewDelegate mainStackView.addArrangedSubview(separator) tableView.set(.height, to: CGFloat(contactProfiles.count * 65 + 100)) // A cell is exactly 65 points high - tableView.set(.width, to: UIScreen.main.bounds.width) + tableViewWidth = tableView.set(.width, to: UIScreen.main.bounds.width) mainStackView.addArrangedSubview(tableView) let scrollView: UIScrollView = UIScrollView(wrapping: mainStackView, withInsets: UIEdgeInsets.zero) scrollView.showsVerticalScrollIndicator = false scrollView.delegate = self view.addSubview(scrollView) - - scrollView.set(.width, to: UIScreen.main.bounds.width) scrollView.pin(to: view) view.addSubview(fadeView) From 420af95f6802cc3ed47eea17799615d8fce824c1 Mon Sep 17 00:00:00 2001 From: ryanzhao Date: Fri, 30 Sep 2022 11:31:06 +1000 Subject: [PATCH 11/33] fix new dm screen --- Session/Home/New Conversation/NewDMVC.swift | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/Session/Home/New Conversation/NewDMVC.swift b/Session/Home/New Conversation/NewDMVC.swift index 47fd20390..cf04c4cff 100644 --- a/Session/Home/New Conversation/NewDMVC.swift +++ b/Session/Home/New Conversation/NewDMVC.swift @@ -102,6 +102,12 @@ final class NewDMVC : BaseVC, UIPageViewControllerDataSource, UIPageViewControll scanQRCodePlaceholderVC.constrainHeight(to: height) } + override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { + super.viewWillTransition(to: size, with: coordinator) + enterPublicKeyVC.viewWidth?.constant = size.width + scanQRCodePlaceholderVC.viewWidth?.constant = size.width + } + // MARK: General func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? { guard let index = pages.firstIndex(of: viewController), index != 0 else { return nil } @@ -269,6 +275,8 @@ private final class EnterPublicKeyVC : UIViewController { return result }() + var viewWidth: NSLayoutConstraint? + // MARK: Lifecycle override func viewDidLoad() { // Remove background color @@ -329,12 +337,10 @@ private final class EnterPublicKeyVC : UIViewController { mainStackView.layoutMargins = UIEdgeInsets(top: Values.largeSpacing, left: Values.largeSpacing, bottom: Values.largeSpacing, right: Values.largeSpacing) mainStackView.isLayoutMarginsRelativeArrangement = true view.addSubview(mainStackView) - mainStackView.pin(.leading, to: .leading, of: view) - mainStackView.pin(.top, to: .top, of: view) - view.pin(.trailing, to: .trailing, of: mainStackView) + mainStackView.pin([ UIView.HorizontalEdge.leading, UIView.HorizontalEdge.trailing, UIView.VerticalEdge.top ], to: view) bottomConstraint = view.pin(.bottom, to: .bottom, of: mainStackView, withInset: bottomMargin) // Width constraint - view.set(.width, to: UIScreen.main.bounds.width) + viewWidth = view.set(.width, to: UIScreen.main.bounds.width) // Dismiss keyboard on tap let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(dismissKeyboard)) view.addGestureRecognizer(tapGestureRecognizer) @@ -430,6 +436,8 @@ private final class EnterPublicKeyVC : UIViewController { private final class ScanQRCodePlaceholderVC : UIViewController { weak var NewDMVC: NewDMVC! + var viewWidth: NSLayoutConstraint? + override func viewDidLoad() { // Remove background color view.backgroundColor = .clear @@ -453,7 +461,7 @@ private final class ScanQRCodePlaceholderVC : UIViewController { stackView.spacing = Values.mediumSpacing stackView.alignment = .center // Set up constraints - view.set(.width, to: UIScreen.main.bounds.width) + viewWidth = view.set(.width, to: UIScreen.main.bounds.width) view.addSubview(stackView) stackView.pin(.leading, to: .leading, of: view, withInset: Values.massiveSpacing) view.pin(.trailing, to: .trailing, of: stackView, withInset: Values.massiveSpacing) From dafd63db5ffd3cfcc87fbfbc0718ad1ea2325cfd Mon Sep 17 00:00:00 2001 From: ryanzhao Date: Fri, 30 Sep 2022 13:54:29 +1000 Subject: [PATCH 12/33] fix join open group screen --- Session/Open Groups/JoinOpenGroupVC.swift | 17 ++++++++++++++--- .../Open Groups/OpenGroupSuggestionGrid.swift | 7 ++++++- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/Session/Open Groups/JoinOpenGroupVC.swift b/Session/Open Groups/JoinOpenGroupVC.swift index c6fb9c912..29fd90510 100644 --- a/Session/Open Groups/JoinOpenGroupVC.swift +++ b/Session/Open Groups/JoinOpenGroupVC.swift @@ -88,6 +88,13 @@ final class JoinOpenGroupVC: BaseVC, UIPageViewControllerDataSource, UIPageViewC enterURLVC.constrainHeight(to: height) scanQRCodePlaceholderVC.constrainHeight(to: height) } + + override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { + super.viewWillTransition(to: size, with: coordinator) + enterURLVC.viewWidth?.constant = size.width + enterURLVC.suggestionGrid.refreshLayout(with: size.width - 2 * Values.largeSpacing) + scanQRCodePlaceholderVC.viewWidth?.constant = size.width + } // MARK: - General @@ -230,13 +237,15 @@ private final class EnterURLVC: UIViewController, UIGestureRecognizerDelegate, O return result }() - private lazy var suggestionGrid: OpenGroupSuggestionGrid = { + lazy var suggestionGrid: OpenGroupSuggestionGrid = { let maxWidth: CGFloat = (UIScreen.main.bounds.width - Values.largeSpacing * 2) let result: OpenGroupSuggestionGrid = OpenGroupSuggestionGrid(maxWidth: maxWidth) result.delegate = self return result }() + + var viewWidth: NSLayoutConstraint? // MARK: - Lifecycle @@ -270,7 +279,7 @@ private final class EnterURLVC: UIViewController, UIGestureRecognizerDelegate, O bottomConstraint = view.pin(.bottom, to: .bottom, of: stackView, withInset: bottomMargin) // Constraints - view.set(.width, to: UIScreen.main.bounds.width) + viewWidth = view.set(.width, to: UIScreen.main.bounds.width) // Dismiss keyboard on tap let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(dismissKeyboard)) @@ -374,6 +383,8 @@ private final class EnterURLVC: UIViewController, UIGestureRecognizerDelegate, O private final class ScanQRCodePlaceholderVC: UIViewController { weak var joinOpenGroupVC: JoinOpenGroupVC? + var viewWidth: NSLayoutConstraint? + // MARK: - Lifecycle override func viewDidLoad() { @@ -403,7 +414,7 @@ private final class ScanQRCodePlaceholderVC: UIViewController { stackView.alignment = .center // Constraints - view.set(.width, to: UIScreen.main.bounds.width) + viewWidth = view.set(.width, to: UIScreen.main.bounds.width) view.addSubview(stackView) stackView.pin(.leading, to: .leading, of: view, withInset: Values.massiveSpacing) view.pin(.trailing, to: .trailing, of: stackView, withInset: Values.massiveSpacing) diff --git a/Session/Open Groups/OpenGroupSuggestionGrid.swift b/Session/Open Groups/OpenGroupSuggestionGrid.swift index 7ab0611f6..c6563d82e 100644 --- a/Session/Open Groups/OpenGroupSuggestionGrid.swift +++ b/Session/Open Groups/OpenGroupSuggestionGrid.swift @@ -5,7 +5,7 @@ import SessionUIKit final class OpenGroupSuggestionGrid: UIView, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout { private let itemsPerSection: Int = (UIDevice.current.isIPad ? 4 : 2) - private let maxWidth: CGFloat + private var maxWidth: CGFloat private var rooms: [OpenGroupAPI.Room] = [] { didSet { update() } } private var heightConstraint: NSLayoutConstraint! var delegate: OpenGroupSuggestionGridDelegate? @@ -142,6 +142,11 @@ final class OpenGroupSuggestionGrid: UIView, UICollectionViewDataSource, UIColle errorView.isHidden = (roomCount > 0) } + public func refreshLayout(with maxWidth: CGFloat) { + self.maxWidth = maxWidth + collectionView.collectionViewLayout.invalidateLayout() + } + // MARK: - Layout func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { From a45ed574807c5d44224c25091faab5c7b2ff72c7 Mon Sep 17 00:00:00 2001 From: ryanzhao Date: Fri, 30 Sep 2022 14:29:40 +1000 Subject: [PATCH 13/33] fix settings screen --- Session/Settings/SettingsVC.swift | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Session/Settings/SettingsVC.swift b/Session/Settings/SettingsVC.swift index aa8e84e21..9b4c4177c 100644 --- a/Session/Settings/SettingsVC.swift +++ b/Session/Settings/SettingsVC.swift @@ -10,6 +10,8 @@ final class SettingsVC: BaseVC, AvatarViewHelperDelegate { private var displayNameToBeUploaded: String? private var isEditingDisplayName = false { didSet { handleIsEditingDisplayNameChanged() } } + private var viewWidth: NSLayoutConstraint? + // MARK: - Components private lazy var profilePictureView: ProfilePictureView = { @@ -246,7 +248,7 @@ final class SettingsVC: BaseVC, AvatarViewHelperDelegate { stackView.alignment = .fill stackView.layoutMargins = UIEdgeInsets(top: Values.mediumSpacing, left: 0, bottom: Values.mediumSpacing, right: 0) stackView.isLayoutMarginsRelativeArrangement = true - stackView.set(.width, to: UIScreen.main.bounds.width) + viewWidth = stackView.set(.width, to: UIScreen.main.bounds.width) // Scroll view let scrollView = UIScrollView() @@ -257,6 +259,11 @@ final class SettingsVC: BaseVC, AvatarViewHelperDelegate { scrollView.pin(to: view) } + override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { + super.viewWillTransition(to: size, with: coordinator) + viewWidth?.constant = size.width + } + private func getSettingButtons() -> [UIView] { func getSeparator() -> UIView { let result = UIView() From 2968a3cf066906f62e5ec8e5113bc66286a5201d Mon Sep 17 00:00:00 2001 From: ryanzhao Date: Fri, 30 Sep 2022 15:42:03 +1000 Subject: [PATCH 14/33] fix mini call screen size --- Session/Calls/Views & Modals/CallVideoView.swift | 4 ++-- Session/Calls/Views & Modals/MiniCallView.swift | 10 +++++++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/Session/Calls/Views & Modals/CallVideoView.swift b/Session/Calls/Views & Modals/CallVideoView.swift index 7bf90dcf1..1f10930f3 100644 --- a/Session/Calls/Views & Modals/CallVideoView.swift +++ b/Session/Calls/Views & Modals/CallVideoView.swift @@ -78,8 +78,8 @@ class RemoteVideoView: TargetView { class LocalVideoView: TargetView { - static let width: CGFloat = 80 - static let height: CGFloat = 173 + static let width: CGFloat = UIDevice.current.isIPad ? 160 : 80 + static let height: CGFloat = UIDevice.current.isIPad ? 346: 173 override func renderFrame(_ frame: RTCVideoFrame?) { super.renderFrame(frame) diff --git a/Session/Calls/Views & Modals/MiniCallView.swift b/Session/Calls/Views & Modals/MiniCallView.swift index 86d17e508..3d3455df2 100644 --- a/Session/Calls/Views & Modals/MiniCallView.swift +++ b/Session/Calls/Views & Modals/MiniCallView.swift @@ -5,7 +5,8 @@ final class MiniCallView: UIView, RTCVideoViewDelegate { var callVC: CallVC // MARK: UI - private static let defaultSize: CGFloat = 100 + private static let defaultSize: CGFloat = UIDevice.current.isIPad ? 200 : 100 + private static let defaultVideoSize: CGFloat = UIDevice.current.isIPad ? 320 : 160 private let topMargin = UIApplication.shared.keyWindow!.safeAreaInsets.top + Values.veryLargeSpacing private let bottomMargin = UIApplication.shared.keyWindow!.safeAreaInsets.bottom @@ -70,7 +71,7 @@ final class MiniCallView: UIView, RTCVideoViewDelegate { private func setUpViewHierarchy() { self.width = self.set(.width, to: MiniCallView.defaultSize) self.height = self.set(.height, to: MiniCallView.defaultSize) - self.layer.cornerRadius = 10 + self.layer.cornerRadius = UIDevice.current.isIPad ? 20 : 10 self.layer.masksToBounds = true // Background let background = getBackgroudView() @@ -139,7 +140,10 @@ final class MiniCallView: UIView, RTCVideoViewDelegate { // MARK: RTCVideoViewDelegate func videoView(_ videoView: RTCVideoRenderer, didChangeVideoSize size: CGSize) { - let newSize = CGSize(width: min(160.0, 160.0 * size.width / size.height), height: min(160.0, 160.0 * size.height / size.width)) + let newSize = CGSize( + width: min(Self.defaultVideoSize, Self.defaultVideoSize * size.width / size.height), + height: min(Self.defaultVideoSize, Self.defaultVideoSize * size.height / size.width) + ) persistCurrentPosition(newSize: newSize) self.width?.constant = newSize.width self.height?.constant = newSize.height From fbcdd1358c420a11a389d1a0a732b13002835d67 Mon Sep 17 00:00:00 2001 From: ryanzhao Date: Fri, 30 Sep 2022 16:44:48 +1000 Subject: [PATCH 15/33] WIP: fix video call view --- Session/Calls/CallVC.swift | 15 ++++++++++++++- Session/Calls/Views & Modals/CallVideoView.swift | 10 ++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/Session/Calls/CallVC.swift b/Session/Calls/CallVC.swift index 704df50d8..8ccef1ea1 100644 --- a/Session/Calls/CallVC.swift +++ b/Session/Calls/CallVC.swift @@ -23,7 +23,7 @@ final class CallVC: UIViewController, VideoPreviewDelegate { private lazy var localVideoView: LocalVideoView = { let result = LocalVideoView() result.isHidden = !call.isVideoEnabled - result.layer.cornerRadius = 10 + result.layer.cornerRadius = UIDevice.current.isIPad ? 20 : 10 result.layer.masksToBounds = true result.set(.width, to: LocalVideoView.width) result.set(.height, to: LocalVideoView.height) @@ -284,6 +284,18 @@ final class CallVC: UIViewController, VideoPreviewDelegate { NotificationCenter.default.addObserver(self, selector: #selector(audioRouteDidChange), name: AVAudioSession.routeChangeNotification, object: nil) } + override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { + super.viewWillTransition(to: size, with: coordinator) + let layer = CAGradientLayer() + layer.frame = CGRect(x: 0, y: 0, width: size.width, height: 64) + layer.colors = [ UIColor(hex: 0x000000).withAlphaComponent(0.4).cgColor, UIColor(hex: 0x000000).withAlphaComponent(0).cgColor ] + if let existingSublayer = fadeView.layer.sublayers?[0], existingSublayer is CAGradientLayer { + fadeView.layer.replaceSublayer(existingSublayer, with: layer) + } else { + fadeView.layer.insertSublayer(layer, at: 0) + } + } + deinit { UIDevice.current.endGeneratingDeviceOrientationNotifications() NotificationCenter.default.removeObserver(self) @@ -373,6 +385,7 @@ final class CallVC: UIViewController, VideoPreviewDelegate { } @objc func didChangeDeviceOrientation(notification: Notification) { + if UIDevice.current.isIPad { return } func rotateAllButtons(rotationAngle: CGFloat) { let transform = CGAffineTransform(rotationAngle: rotationAngle) diff --git a/Session/Calls/Views & Modals/CallVideoView.swift b/Session/Calls/Views & Modals/CallVideoView.swift index 1f10930f3..899732f66 100644 --- a/Session/Calls/Views & Modals/CallVideoView.swift +++ b/Session/Calls/Views & Modals/CallVideoView.swift @@ -16,6 +16,16 @@ class RemoteVideoView: TargetView { override func renderFrame(_ frame: RTCVideoFrame?) { super.renderFrame(frame) guard let frame = frame else { return } + if UIDevice.current.isIPad { + DispatchMainThreadSafe { +#if targetEnvironment(simulator) + self.contentMode = .scaleAspectFit +#else + self.videoContentMode = .scaleAspectFit +#endif + } + return + } DispatchMainThreadSafe { let frameRatio = Double(frame.height) / Double(frame.width) From 15694aeeb0367c0768294493539da8c5aa301d35 Mon Sep 17 00:00:00 2001 From: ryanzhao Date: Tue, 4 Oct 2022 17:13:05 +1100 Subject: [PATCH 16/33] minor fix to adapt to theming --- Session/Calls/CallVC.swift | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/Session/Calls/CallVC.swift b/Session/Calls/CallVC.swift index 49bb6a1e0..3ff0a65f9 100644 --- a/Session/Calls/CallVC.swift +++ b/Session/Calls/CallVC.swift @@ -374,13 +374,12 @@ final class CallVC: UIViewController, VideoPreviewDelegate { override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { super.viewWillTransition(to: size, with: coordinator) - let layer = CAGradientLayer() - layer.frame = CGRect(x: 0, y: 0, width: size.width, height: 64) - layer.colors = [ UIColor(hex: 0x000000).withAlphaComponent(0.4).cgColor, UIColor(hex: 0x000000).withAlphaComponent(0).cgColor ] - if let existingSublayer = fadeView.layer.sublayers?[0], existingSublayer is CAGradientLayer { + + if let existingSublayer = fadeView.layer.sublayers?[0] as? CAGradientLayer { + let layer = CAGradientLayer() + layer.frame = CGRect(x: 0, y: 0, width: size.width, height: 64) + layer.colors = existingSublayer.colors fadeView.layer.replaceSublayer(existingSublayer, with: layer) - } else { - fadeView.layer.insertSublayer(layer, at: 0) } } From ccc517746d409d39ee7716fcadba3551a783aeb4 Mon Sep 17 00:00:00 2001 From: ryanzhao Date: Wed, 5 Oct 2022 11:58:58 +1100 Subject: [PATCH 17/33] fix settings screen --- Session/Shared/Views/SessionAvatarCell.swift | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/Session/Shared/Views/SessionAvatarCell.swift b/Session/Shared/Views/SessionAvatarCell.swift index 8016641bb..3ccea1689 100644 --- a/Session/Shared/Views/SessionAvatarCell.swift +++ b/Session/Shared/Views/SessionAvatarCell.swift @@ -114,17 +114,7 @@ class SessionAvatarCell: UITableViewCell { stackView.alignment = .center stackView.distribution = .fillEqually stackView.spacing = (UIDevice.current.isIPad ? Values.iPadButtonSpacing : Values.mediumSpacing) - - if (UIDevice.current.isIPad) { - stackView.layoutMargins = UIEdgeInsets( - top: 0, - left: Values.iPadButtonContainerMargin, - bottom: 0, - right: Values.iPadButtonContainerMargin - ) - stackView.isLayoutMarginsRelativeArrangement = true - } - + return stackView }() @@ -242,6 +232,10 @@ class SessionAvatarCell: UITableViewCell { descriptionSeparator.update(title: style.separatorTitle) descriptionSeparator.isHidden = (style.separatorTitle == nil) + if (UIDevice.current.isIPad) { + descriptionActionStackView.addArrangedSubview(UIView.hStretchingSpacer()) + } + style.descriptionActions.forEach { action in let result: SessionButton = SessionButton(style: .bordered, size: .medium) result.setTitle(action.title, for: UIControl.State.normal) @@ -252,6 +246,10 @@ class SessionAvatarCell: UITableViewCell { descriptionActionStackView.addArrangedSubview(result) } + + if (UIDevice.current.isIPad) { + descriptionActionStackView.addArrangedSubview(UIView.hStretchingSpacer()) + } descriptionActionStackView.isHidden = style.descriptionActions.isEmpty } From 202a2de1b5b4a8e9bc1f72eb1cbc315049ea06fa Mon Sep 17 00:00:00 2001 From: ryanzhao Date: Wed, 5 Oct 2022 13:35:05 +1100 Subject: [PATCH 18/33] dismiss context menu view when the screen rotates --- Session/Conversations/Context Menu/ContextMenuVC.swift | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Session/Conversations/Context Menu/ContextMenuVC.swift b/Session/Conversations/Context Menu/ContextMenuVC.swift index 3f3146df2..2e12cd093 100644 --- a/Session/Conversations/Context Menu/ContextMenuVC.swift +++ b/Session/Conversations/Context Menu/ContextMenuVC.swift @@ -283,6 +283,11 @@ final class ContextMenuVC: UIViewController { } } + override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { + super.viewWillTransition(to: size, with: coordinator) + snDismiss() + } + func calculateFrame(menuHeight: CGFloat, spacing: CGFloat) -> CGRect { var finalFrame: CGRect = frame let ratio: CGFloat = (frame.width / frame.height) From 2638fe4025e3ad1db61cca01ba641a4e72158f90 Mon Sep 17 00:00:00 2001 From: ryanzhao Date: Wed, 5 Oct 2022 14:19:01 +1100 Subject: [PATCH 19/33] fix share button in my qr code view --- Session/Settings/QRCodeVC.swift | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Session/Settings/QRCodeVC.swift b/Session/Settings/QRCodeVC.swift index c1b34d08e..d4e622337 100644 --- a/Session/Settings/QRCodeVC.swift +++ b/Session/Settings/QRCodeVC.swift @@ -234,9 +234,14 @@ private final class ViewMyQRCodeVC : UIViewController { let shareButtonContainer = UIView() shareButtonContainer.addSubview(shareButton) shareButton.pin(.top, to: .top, of: shareButtonContainer) - shareButton.pin(.leading, to: .leading, of: shareButtonContainer, withInset: 80) - shareButton.pin(.trailing, to: .trailing, of: shareButtonContainer, withInset: -80) shareButton.pin(.bottom, to: .bottom, of: shareButtonContainer) + if UIDevice.current.isIPad { + shareButton.center(in: shareButtonContainer) + shareButton.set(.width, to: Values.iPadButtonWidth) + } else { + shareButton.pin(.leading, to: .leading, of: shareButtonContainer, withInset: 80) + shareButton.pin(.trailing, to: .trailing, of: shareButtonContainer, withInset: -80) + } // Set up stack view let spacing = (isIPhone5OrSmaller ? Values.mediumSpacing : Values.largeSpacing) From 1bee35b139e33bfb90f298d9dd7d3924ef7f29df Mon Sep 17 00:00:00 2001 From: ryanzhao Date: Wed, 5 Oct 2022 15:24:43 +1100 Subject: [PATCH 20/33] fix scan qr code screen --- Session/Shared/ScanQRCodeWrapperVC.swift | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/Session/Shared/ScanQRCodeWrapperVC.swift b/Session/Shared/ScanQRCodeWrapperVC.swift index 60fe2a29f..a80b2305c 100644 --- a/Session/Shared/ScanQRCodeWrapperVC.swift +++ b/Session/Shared/ScanQRCodeWrapperVC.swift @@ -10,8 +10,6 @@ final class ScanQRCodeWrapperVC: BaseVC { private let message: String? private let scanQRCodeVC = QRCodeScanningViewController() - override var supportedInterfaceOrientations: UIInterfaceOrientationMask { return .portrait } - // MARK: - Lifecycle init(message: String?) { @@ -47,7 +45,7 @@ final class ScanQRCodeWrapperVC: BaseVC { scanQRCodeVCView.autoPinEdge(.top, to: .top, of: view) if let message = message { - scanQRCodeVCView.autoPinToSquareAspectRatio() + scanQRCodeVCView.set(.height, lessThanOrEqualTo: UIScreen.main.bounds.width) // Set up bottom view let bottomView = UIView() @@ -78,8 +76,6 @@ final class ScanQRCodeWrapperVC: BaseVC { override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) - UIDevice.current.ows_setOrientation(.portrait) - self.scanQRCodeVC.startCapture() } From 46b156b2c4380485e6f95e702d222cdf995c5134 Mon Sep 17 00:00:00 2001 From: ryanzhao Date: Wed, 5 Oct 2022 16:44:14 +1100 Subject: [PATCH 21/33] increase max emojis per line for iPad --- .../Message Cells/Content Views/ReactionContainerView.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Session/Conversations/Message Cells/Content Views/ReactionContainerView.swift b/Session/Conversations/Message Cells/Content Views/ReactionContainerView.swift index 622a23900..564f2c1ad 100644 --- a/Session/Conversations/Message Cells/Content Views/ReactionContainerView.swift +++ b/Session/Conversations/Message Cells/Content Views/ReactionContainerView.swift @@ -7,7 +7,7 @@ import SignalUtilitiesKit final class ReactionContainerView: UIView { var showingAllReactions = false private var showNumbers = true - private var maxEmojisPerLine = isIPhone6OrSmaller ? 5 : 6 + private var maxEmojisPerLine = UIDevice.current.isIPad ? 10 : (isIPhone6OrSmaller ? 5 : 6) private var oldSize: CGSize = .zero var reactions: [ReactionViewModel] = [] From 3563d7d469ecacb93f4fa50d8534a4649c2d096d Mon Sep 17 00:00:00 2001 From: Ryan Zhao Date: Thu, 6 Oct 2022 13:11:17 +1100 Subject: [PATCH 22/33] clean --- .../Content Views/ReactionContainerView.swift | 3 +- .../Message Cells/VisibleMessageCell.swift | 2 +- Session/Settings/SettingsVC.swift | 681 ------------------ .../OWSNavigationController.m | 186 ----- 4 files changed, 2 insertions(+), 870 deletions(-) delete mode 100644 Session/Settings/SettingsVC.swift delete mode 100644 SignalUtilitiesKit/Shared View Controllers/OWSNavigationController.m diff --git a/Session/Conversations/Message Cells/Content Views/ReactionContainerView.swift b/Session/Conversations/Message Cells/Content Views/ReactionContainerView.swift index febc2ee61..583142633 100644 --- a/Session/Conversations/Message Cells/Content Views/ReactionContainerView.swift +++ b/Session/Conversations/Message Cells/Content Views/ReactionContainerView.swift @@ -13,7 +13,6 @@ final class ReactionContainerView: UIView { private var collapsedCount: Int = 0 private var showingAllReactions: Bool = false private var showNumbers: Bool = true - private var maxEmojisPerLine = UIDevice.current.isIPad ? 10 : (isIPhone6OrSmaller ? 5 : 6) private var oldSize: CGSize = .zero var reactions: [ReactionViewModel] = [] @@ -114,7 +113,7 @@ final class ReactionContainerView: UIView { // button appear horizontally centered (if we don't do this it gets offset to one side) guard frame != CGRect.zero, frame.size != oldSize else { return } - var targetSuperview: UIView? = { + let targetSuperview: UIView? = { var result: UIView? = self.superview while result != nil, result?.isKind(of: UITableViewCell.self) != true { diff --git a/Session/Conversations/Message Cells/VisibleMessageCell.swift b/Session/Conversations/Message Cells/VisibleMessageCell.swift index d70a5f3d3..5c0641334 100644 --- a/Session/Conversations/Message Cells/VisibleMessageCell.swift +++ b/Session/Conversations/Message Cells/VisibleMessageCell.swift @@ -372,7 +372,7 @@ final class VisibleMessageCell: MessageCell, TappableLabelDelegate { for: cellViewModel, maxWidth: VisibleMessageCell.getMaxWidth( for: cellViewModel, - includingOppositeGutter: false + includingOppositeGutter: UIDevice.current.isIPad ), showExpandedReactions: showExpandedReactions ) diff --git a/Session/Settings/SettingsVC.swift b/Session/Settings/SettingsVC.swift deleted file mode 100644 index 9b4c4177c..000000000 --- a/Session/Settings/SettingsVC.swift +++ /dev/null @@ -1,681 +0,0 @@ -// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved. - -import UIKit -import SessionUIKit -import SessionUtilitiesKit -import SessionMessagingKit -import SignalUtilitiesKit - -final class SettingsVC: BaseVC, AvatarViewHelperDelegate { - private var displayNameToBeUploaded: String? - private var isEditingDisplayName = false { didSet { handleIsEditingDisplayNameChanged() } } - - private var viewWidth: NSLayoutConstraint? - - // MARK: - Components - - private lazy var profilePictureView: ProfilePictureView = { - let result = ProfilePictureView() - let size = Values.largeProfilePictureSize - result.size = size - result.set(.width, to: size) - result.set(.height, to: size) - result.accessibilityLabel = "Edit profile picture button" - result.isAccessibilityElement = true - - return result - }() - - private lazy var profilePictureUtilities: AvatarViewHelper = { - let result = AvatarViewHelper() - result.delegate = self - - return result - }() - - private lazy var displayNameLabel: UILabel = { - let result = UILabel() - result.textColor = Colors.text - result.font = .boldSystemFont(ofSize: Values.veryLargeFontSize) - result.lineBreakMode = .byTruncatingTail - result.textAlignment = .center - - return result - }() - - private lazy var displayNameTextField: TextField = { - let result = TextField(placeholder: NSLocalizedString("vc_settings_display_name_text_field_hint", comment: ""), usesDefaultHeight: false) - result.textAlignment = .center - result.accessibilityLabel = "Edit display name text field" - - return result - }() - - private lazy var publicKeyLabel: UILabel = { - let result = UILabel() - result.textColor = Colors.text - result.font = Fonts.spaceMono(ofSize: isIPhone5OrSmaller ? Values.mediumFontSize : Values.largeFontSize) - result.numberOfLines = 0 - result.textAlignment = .center - result.lineBreakMode = .byCharWrapping - result.text = getUserHexEncodedPublicKey() - - return result - }() - - private lazy var copyButton: Button = { - let result = Button(style: .prominentOutline, size: .medium) - result.setTitle(NSLocalizedString("copy", comment: ""), for: UIControl.State.normal) - result.addTarget(self, action: #selector(copyPublicKey), for: UIControl.Event.touchUpInside) - - return result - }() - - private lazy var settingButtonsStackView: UIStackView = { - let result = UIStackView() - result.axis = .vertical - result.alignment = .fill - - return result - }() - - private lazy var inviteButton: UIButton = { - let result = UIButton() - result.setTitle(NSLocalizedString("vc_settings_invite_a_friend_button_title", comment: ""), for: UIControl.State.normal) - result.setTitleColor(Colors.text, for: UIControl.State.normal) - result.titleLabel!.font = .boldSystemFont(ofSize: Values.smallFontSize) - result.addTarget(self, action: #selector(sendInvitation), for: UIControl.Event.touchUpInside) - - return result - }() - - private lazy var faqButton: UIButton = { - let result = UIButton() - result.setTitle(NSLocalizedString("vc_settings_faq_button_title", comment: ""), for: UIControl.State.normal) - result.setTitleColor(Colors.text, for: UIControl.State.normal) - result.titleLabel!.font = .boldSystemFont(ofSize: Values.smallFontSize) - result.addTarget(self, action: #selector(openFAQ), for: UIControl.Event.touchUpInside) - - return result - }() - - private lazy var surveyButton: UIButton = { - let result = UIButton() - result.setTitle(NSLocalizedString("vc_settings_survey_button_title", comment: ""), for: UIControl.State.normal) - result.setTitleColor(Colors.text, for: UIControl.State.normal) - result.titleLabel?.font = .boldSystemFont(ofSize: Values.smallFontSize) - result.addTarget(self, action: #selector(openSurvey), for: UIControl.Event.touchUpInside) - - return result - }() - - private lazy var supportButton: UIButton = { - let result = UIButton() - result.setTitle(NSLocalizedString("vc_settings_support_button_title", comment: ""), for: UIControl.State.normal) - result.setTitleColor(Colors.text, for: UIControl.State.normal) - result.titleLabel!.font = .boldSystemFont(ofSize: Values.smallFontSize) - result.addTarget(self, action: #selector(shareLogs), for: UIControl.Event.touchUpInside) - - return result - }() - - private lazy var helpTranslateButton: UIButton = { - let result = UIButton() - result.setTitle(NSLocalizedString("vc_settings_help_us_translate_button_title", comment: ""), for: UIControl.State.normal) - result.setTitleColor(Colors.text, for: UIControl.State.normal) - result.titleLabel!.font = .boldSystemFont(ofSize: Values.smallFontSize) - result.addTarget(self, action: #selector(helpTranslate), for: UIControl.Event.touchUpInside) - - return result - }() - - private lazy var logoImageView: UIImageView = { - let result = UIImageView() - result.set(.height, to: 24) - result.contentMode = .scaleAspectFit - - return result - }() - - private lazy var versionLabel: UILabel = { - let result = UILabel() - result.textColor = Colors.text.withAlphaComponent(Values.mediumOpacity) - result.font = .systemFont(ofSize: Values.verySmallFontSize) - result.numberOfLines = 0 - result.textAlignment = .center - result.lineBreakMode = .byCharWrapping - let version = Bundle.main.infoDictionary!["CFBundleShortVersionString"]! - let buildNumber = Bundle.main.infoDictionary!["CFBundleVersion"]! - result.text = "Version \(version) (\(buildNumber))" - - return result - }() - - // MARK: - Settings - - private static let buttonHeight = isIPhone5OrSmaller ? CGFloat(52) : CGFloat(75) - - // MARK: - Lifecycle - - override func viewDidLoad() { - super.viewDidLoad() - - setUpGradientBackground() - setUpNavBarStyle() - setNavBarTitle(NSLocalizedString("vc_settings_title", comment: "")) - - // Navigation bar buttons - updateNavigationBarButtons() - - // Profile picture view - let profile: Profile = Profile.fetchOrCreateCurrentUser() - let profilePictureTapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(showEditProfilePictureUI)) - profilePictureView.addGestureRecognizer(profilePictureTapGestureRecognizer) - profilePictureView - .update( - publicKey: profile.id, - profile: profile, - threadVariant: .contact - ) - // Display name label - displayNameLabel.text = profile.name - - // Display name container - let displayNameContainer = UIView() - displayNameContainer.accessibilityLabel = "Edit display name text field" - displayNameContainer.isAccessibilityElement = true - displayNameContainer.addSubview(displayNameLabel) - displayNameLabel.pin(to: displayNameContainer) - displayNameContainer.addSubview(displayNameTextField) - displayNameTextField.pin(to: displayNameContainer) - displayNameContainer.set(.height, to: 40) - displayNameTextField.alpha = 0 - let displayNameContainerTapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(showEditDisplayNameUI)) - displayNameContainer.addGestureRecognizer(displayNameContainerTapGestureRecognizer) - - // Header view - let headerStackView = UIStackView(arrangedSubviews: [ profilePictureView, displayNameContainer ]) - headerStackView.axis = .vertical - headerStackView.spacing = Values.smallSpacing - headerStackView.alignment = .center - - // Separator - let separator = Separator(title: NSLocalizedString("your_session_id", comment: "")) - - // Share button - let shareButton = Button(style: .regular, size: .medium) - shareButton.setTitle(NSLocalizedString("share", comment: ""), for: UIControl.State.normal) - shareButton.addTarget(self, action: #selector(sharePublicKey), for: UIControl.Event.touchUpInside) - - // Button container - let buttonContainer = UIStackView(arrangedSubviews: [ copyButton, shareButton ]) - buttonContainer.axis = .horizontal - buttonContainer.spacing = UIDevice.current.isIPad ? Values.iPadButtonSpacing : Values.mediumSpacing - buttonContainer.distribution = .fillEqually - - if (UIDevice.current.isIPad) { - buttonContainer.layoutMargins = UIEdgeInsets(top: 0, left: Values.iPadButtonContainerMargin, bottom: 0, right: Values.iPadButtonContainerMargin) - buttonContainer.isLayoutMarginsRelativeArrangement = true - } - // User session id container - let userPublicKeyContainer = UIView(wrapping: publicKeyLabel, withInsets: .zero, shouldAdaptForIPadWithWidth: Values.iPadUserSessionIdContainerWidth) - - // Top stack view - let topStackView = UIStackView(arrangedSubviews: [ headerStackView, separator, userPublicKeyContainer, buttonContainer ]) - topStackView.axis = .vertical - topStackView.spacing = Values.largeSpacing - topStackView.alignment = .fill - topStackView.layoutMargins = UIEdgeInsets(top: 0, left: Values.largeSpacing, bottom: 0, right: Values.largeSpacing) - topStackView.isLayoutMarginsRelativeArrangement = true - - // Setting buttons stack view - getSettingButtons().forEach { settingButtonOrSeparator in - settingButtonsStackView.addArrangedSubview(settingButtonOrSeparator) - } - - // Oxen logo - updateLogo() - let logoContainer = UIView() - logoContainer.addSubview(logoImageView) - logoImageView.pin(.top, to: .top, of: logoContainer) - logoContainer.pin(.bottom, to: .bottom, of: logoImageView) - logoImageView.centerXAnchor.constraint(equalTo: logoContainer.centerXAnchor, constant: -2).isActive = true - - // Main stack view - let stackView = UIStackView(arrangedSubviews: [ topStackView, settingButtonsStackView, inviteButton, faqButton, surveyButton, supportButton, helpTranslateButton, logoContainer, versionLabel ]) - stackView.axis = .vertical - stackView.spacing = Values.largeSpacing - stackView.alignment = .fill - stackView.layoutMargins = UIEdgeInsets(top: Values.mediumSpacing, left: 0, bottom: Values.mediumSpacing, right: 0) - stackView.isLayoutMarginsRelativeArrangement = true - viewWidth = stackView.set(.width, to: UIScreen.main.bounds.width) - - // Scroll view - let scrollView = UIScrollView() - scrollView.showsVerticalScrollIndicator = false - scrollView.addSubview(stackView) - stackView.pin(to: scrollView) - view.addSubview(scrollView) - scrollView.pin(to: view) - } - - override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { - super.viewWillTransition(to: size, with: coordinator) - viewWidth?.constant = size.width - } - - private func getSettingButtons() -> [UIView] { - func getSeparator() -> UIView { - let result = UIView() - result.backgroundColor = Colors.separator - result.set(.height, to: Values.separatorThickness) - - return result - } - - func getSettingButton(withTitle title: String, color: UIColor, action selector: Selector) -> UIButton { - let button = UIButton() - button.setTitle(title, for: UIControl.State.normal) - button.setTitleColor(color, for: UIControl.State.normal) - button.titleLabel!.font = .boldSystemFont(ofSize: Values.mediumFontSize) - button.titleLabel!.textAlignment = .center - - func getImage(withColor color: UIColor) -> UIImage { - let rect = CGRect(origin: CGPoint.zero, size: CGSize(width: 1, height: 1)) - UIGraphicsBeginImageContext(rect.size) - - let context = UIGraphicsGetCurrentContext()! - context.setFillColor(color.cgColor) - context.fill(rect) - - let image = UIGraphicsGetImageFromCurrentImageContext() - UIGraphicsEndImageContext() - - return image! - } - - let backgroundColor = isLightMode ? UIColor(hex: 0xF9F9F9) : UIColor(hex: 0x1B1B1B) - button.setBackgroundImage(getImage(withColor: backgroundColor), for: UIControl.State.normal) - - let selectedColor = isLightMode ? UIColor(hex: 0xDFDFDF) : UIColor(hex: 0x0C0C0C) - button.setBackgroundImage(getImage(withColor: selectedColor), for: UIControl.State.highlighted) - button.addTarget(self, action: selector, for: UIControl.Event.touchUpInside) - button.set(.height, to: SettingsVC.buttonHeight) - - return button - } - - let pathButton = getSettingButton(withTitle: NSLocalizedString("vc_path_title", comment: ""), color: Colors.text, action: #selector(showPath)) - let pathStatusView = PathStatusView() - pathStatusView.set(.width, to: PathStatusView.size) - pathStatusView.set(.height, to: PathStatusView.size) - - pathButton.addSubview(pathStatusView) - pathStatusView.pin(.leading, to: .trailing, of: pathButton.titleLabel!, withInset: Values.smallSpacing) - pathStatusView.autoVCenterInSuperview() - - return [ - getSeparator(), - pathButton, - getSeparator(), - getSettingButton(withTitle: NSLocalizedString("vc_settings_privacy_button_title", comment: ""), color: Colors.text, action: #selector(showPrivacySettings)), - getSeparator(), - getSettingButton(withTitle: NSLocalizedString("vc_settings_notifications_button_title", comment: ""), color: Colors.text, action: #selector(showNotificationSettings)), - getSeparator(), - getSettingButton(withTitle: NSLocalizedString("MESSAGE_REQUESTS_TITLE", comment: ""), color: Colors.text, action: #selector(showMessageRequests)), - getSeparator(), - getSettingButton(withTitle: NSLocalizedString("CHATS_TITLE", comment: ""), color: Colors.text, action: #selector(showChatSettings)), - getSeparator(), - getSettingButton(withTitle: NSLocalizedString("vc_settings_recovery_phrase_button_title", comment: ""), color: Colors.text, action: #selector(showSeed)), - getSeparator(), - getSettingButton(withTitle: NSLocalizedString("vc_settings_clear_all_data_button_title", comment: ""), color: Colors.destructive, action: #selector(clearAllData)), - getSeparator() - ] - } - - // MARK: - General - - @objc private func enableCopyButton() { - copyButton.isUserInteractionEnabled = true - - UIView.transition( - with: copyButton, - duration: 0.25, - options: .transitionCrossDissolve, - animations: { - self.copyButton.setTitle("copy".localized(), for: .normal) - }, - completion: nil - ) - } - - func avatarActionSheetTitle() -> String? { return "Update Profile Picture" } - func fromViewController() -> UIViewController { return self } - func hasClearAvatarAction() -> Bool { return false } - func clearAvatarActionLabel() -> String { return "Clear" } - - // MARK: - Updating - - private func handleIsEditingDisplayNameChanged() { - updateNavigationBarButtons() - - UIView.animate(withDuration: 0.25) { - self.displayNameLabel.alpha = self.isEditingDisplayName ? 0 : 1 - self.displayNameTextField.alpha = self.isEditingDisplayName ? 1 : 0 - } - - if isEditingDisplayName { - displayNameTextField.becomeFirstResponder() - } - else { - displayNameTextField.resignFirstResponder() - } - } - - private func updateNavigationBarButtons() { - if isEditingDisplayName { - let cancelButton = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(handleCancelDisplayNameEditingButtonTapped)) - cancelButton.tintColor = Colors.text - cancelButton.accessibilityLabel = "Cancel button" - cancelButton.isAccessibilityElement = true - navigationItem.leftBarButtonItem = cancelButton - - let doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(handleSaveDisplayNameButtonTapped)) - doneButton.tintColor = Colors.text - doneButton.accessibilityLabel = "Done button" - doneButton.isAccessibilityElement = true - navigationItem.rightBarButtonItem = doneButton - } - else { - let closeButton = UIBarButtonItem(image: #imageLiteral(resourceName: "X"), style: .plain, target: self, action: #selector(close)) - closeButton.tintColor = Colors.text - closeButton.accessibilityLabel = "Close button" - closeButton.isAccessibilityElement = true - navigationItem.leftBarButtonItem = closeButton - - let appModeIcon: UIImage - if isSystemDefault { - appModeIcon = isDarkMode ? #imageLiteral(resourceName: "ic_theme_auto").withTintColor(.white) : #imageLiteral(resourceName: "ic_theme_auto").withTintColor(.black) - } - else { - appModeIcon = isDarkMode ? #imageLiteral(resourceName: "ic_dark_theme_on").withTintColor(.white) : #imageLiteral(resourceName: "ic_dark_theme_off").withTintColor(.black) - } - - let appModeButton = UIButton() - appModeButton.setImage(appModeIcon, for: UIControl.State.normal) - appModeButton.tintColor = Colors.text - appModeButton.addTarget(self, action: #selector(switchAppMode), for: UIControl.Event.touchUpInside) - appModeButton.accessibilityLabel = "Switch app mode button" - - let qrCodeIcon = isDarkMode ? #imageLiteral(resourceName: "QRCode").withTintColor(.white) : #imageLiteral(resourceName: "QRCode").withTintColor(.black) - let qrCodeButton = UIButton() - qrCodeButton.setImage(qrCodeIcon, for: UIControl.State.normal) - qrCodeButton.tintColor = Colors.text - qrCodeButton.addTarget(self, action: #selector(showQRCode), for: UIControl.Event.touchUpInside) - qrCodeButton.accessibilityLabel = "Show QR code button" - - let stackView = UIStackView(arrangedSubviews: [ appModeButton, qrCodeButton ]) - stackView.axis = .horizontal - stackView.spacing = Values.mediumSpacing - navigationItem.rightBarButtonItem = UIBarButtonItem(customView: stackView) - } - } - - func avatarDidChange(_ image: UIImage?, filePath: String?) { - updateProfile( - profilePicture: image, - profilePictureFilePath: filePath, - isUpdatingDisplayName: false, - isUpdatingProfilePicture: true - ) - } - - func clearAvatar() { - updateProfile( - profilePicture: nil, - profilePictureFilePath: nil, - isUpdatingDisplayName: false, - isUpdatingProfilePicture: true - ) - } - - private func updateProfile( - profilePicture: UIImage?, - profilePictureFilePath: String?, - isUpdatingDisplayName: Bool, - isUpdatingProfilePicture: Bool - ) { - let userDefaults = UserDefaults.standard - let name: String? = (displayNameToBeUploaded ?? Profile.fetchOrCreateCurrentUser().name) - let imageFilePath: String? = (profilePictureFilePath ?? ProfileManager.profileAvatarFilepath(id: getUserHexEncodedPublicKey())) - - ModalActivityIndicatorViewController.present(fromViewController: navigationController!, canCancel: false) { [weak self, displayNameToBeUploaded] modalActivityIndicator in - ProfileManager.updateLocal( - queue: DispatchQueue.global(qos: .default), - profileName: (name ?? ""), - image: profilePicture, - imageFilePath: imageFilePath, - requiredSync: true, - success: { db, updatedProfile in - if displayNameToBeUploaded != nil { - userDefaults[.lastDisplayNameUpdate] = Date() - } - - if isUpdatingProfilePicture { - userDefaults[.lastProfilePictureUpdate] = Date() - } - - try MessageSender.syncConfiguration(db, forceSyncNow: true).retainUntilComplete() - - // Wait for the database transaction to complete before updating the UI - db.afterNextTransactionCommit { _ in - DispatchQueue.main.async { - modalActivityIndicator.dismiss { - self?.profilePictureView.update( - publicKey: updatedProfile.id, - profile: updatedProfile, - threadVariant: .contact - ) - self?.displayNameLabel.text = name - self?.displayNameToBeUploaded = nil - } - } - } - }, - failure: { error in - DispatchQueue.main.async { - modalActivityIndicator.dismiss { - let isMaxFileSizeExceeded = (error == .avatarUploadMaxFileSizeExceeded) - let title = isMaxFileSizeExceeded ? "Maximum File Size Exceeded" : "Couldn't Update Profile" - let message = isMaxFileSizeExceeded ? "Please select a smaller photo and try again" : "Please check your internet connection and try again" - let alert = UIAlertController(title: title, message: message, preferredStyle: .alert) - alert.addAction(UIAlertAction(title: "BUTTON_OK".localized(), style: .default, handler: nil)) - self?.present(alert, animated: true, completion: nil) - } - } - } - ) - } - } - - @objc override internal func handleAppModeChangedNotification(_ notification: Notification) { - super.handleAppModeChangedNotification(notification) - - updateNavigationBarButtons() - settingButtonsStackView.arrangedSubviews.forEach { settingButton in - settingButtonsStackView.removeArrangedSubview(settingButton) - settingButton.removeFromSuperview() - } - getSettingButtons().forEach { settingButtonOrSeparator in - settingButtonsStackView.addArrangedSubview(settingButtonOrSeparator) // Re-do the setting buttons - } - updateLogo() - } - - private func updateLogo() { - let logoName = isLightMode ? "OxenLightMode" : "OxenDarkMode" - logoImageView.image = UIImage(named: logoName)! - } - - // MARK: - Interaction - - @objc private func close() { - dismiss(animated: true, completion: nil) - } - - @objc private func switchAppMode() { - let alertVC = UIAlertController.init(title: nil, message: nil, preferredStyle: .actionSheet) - let systemModeAction = UIAlertAction.init(title: NSLocalizedString("system_mode_theme", comment: ""), style: .default) { _ in - AppModeManager.shared.setAppModeToSystemDefault() - } - alertVC.addAction(systemModeAction) - - let darkModeAction = UIAlertAction.init(title: NSLocalizedString("dark_mode_theme", comment: ""), style: .default) { _ in - AppModeManager.shared.setCurrentAppMode(to: .dark) - } - alertVC.addAction(darkModeAction) - - let lightModeAction = UIAlertAction.init(title: NSLocalizedString("light_mode_theme", comment: ""), style: .default) { _ in - AppModeManager.shared.setCurrentAppMode(to: .light) - } - alertVC.addAction(lightModeAction) - - let cancelAction = UIAlertAction.init(title: NSLocalizedString("TXT_CANCEL_TITLE", comment: ""), style: .cancel) {_ in } - alertVC.addAction(cancelAction) - - self.presentAlert(alertVC) - } - - @objc private func showQRCode() { - let qrCodeVC = QRCodeVC() - navigationController!.pushViewController(qrCodeVC, animated: true) - } - - @objc private func handleCancelDisplayNameEditingButtonTapped() { - isEditingDisplayName = false - } - - @objc private func handleSaveDisplayNameButtonTapped() { - func showError(title: String, message: String = "") { - let alert = UIAlertController(title: title, message: message, preferredStyle: .alert) - alert.addAction(UIAlertAction(title: NSLocalizedString("BUTTON_OK", comment: ""), style: .default, handler: nil)) - presentAlert(alert) - } - let displayName = displayNameTextField.text!.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines) - guard !displayName.isEmpty else { - return showError(title: NSLocalizedString("vc_settings_display_name_missing_error", comment: "")) - } - guard !ProfileManager.isToLong(profileName: displayName) else { - return showError(title: NSLocalizedString("vc_settings_display_name_too_long_error", comment: "")) - } - isEditingDisplayName = false - displayNameToBeUploaded = displayName - updateProfile( - profilePicture: nil, - profilePictureFilePath: nil, - isUpdatingDisplayName: true, - isUpdatingProfilePicture: false - ) - } - - @objc private func showEditProfilePictureUI() { - profilePictureUtilities.showChangeAvatarUI() - } - - @objc private func showEditDisplayNameUI() { - isEditingDisplayName = true - } - - @objc private func copyPublicKey() { - UIPasteboard.general.string = getUserHexEncodedPublicKey() - copyButton.isUserInteractionEnabled = false - UIView.transition(with: copyButton, duration: 0.25, options: .transitionCrossDissolve, animations: { - self.copyButton.setTitle(NSLocalizedString("copied", comment: ""), for: UIControl.State.normal) - }, completion: nil) - Timer.scheduledTimer(timeInterval: 4, target: self, selector: #selector(enableCopyButton), userInfo: nil, repeats: false) - } - - @objc private func sharePublicKey() { - let shareVC = UIActivityViewController(activityItems: [ getUserHexEncodedPublicKey() ], applicationActivities: nil) - if UIDevice.current.isIPad { - shareVC.excludedActivityTypes = [] - shareVC.popoverPresentationController?.permittedArrowDirections = [] - shareVC.popoverPresentationController?.sourceView = self.view - shareVC.popoverPresentationController?.sourceRect = self.view.bounds - } - navigationController!.present(shareVC, animated: true, completion: nil) - } - - @objc private func showPath() { - let pathVC = PathVC() - navigationController!.pushViewController(pathVC, animated: true) - } - - @objc private func showPrivacySettings() { - let privacySettingsVC = PrivacySettingsTableViewController() - navigationController!.pushViewController(privacySettingsVC, animated: true) - } - - @objc private func showNotificationSettings() { - let notificationSettingsVC = NotificationSettingsViewController() - navigationController!.pushViewController(notificationSettingsVC, animated: true) - } - - @objc private func showMessageRequests() { - let viewController: MessageRequestsViewController = MessageRequestsViewController() - self.navigationController?.pushViewController(viewController, animated: true) - } - - @objc private func showChatSettings() { - let chatSettingsVC = ChatSettingsViewController() - navigationController!.pushViewController(chatSettingsVC, animated: true) - } - - @objc private func showSeed() { - let seedModal = SeedModal() - seedModal.modalPresentationStyle = .overFullScreen - seedModal.modalTransitionStyle = .crossDissolve - present(seedModal, animated: true, completion: nil) - } - - @objc private func clearAllData() { - let nukeDataModal = NukeDataModal() - nukeDataModal.modalPresentationStyle = .overFullScreen - nukeDataModal.modalTransitionStyle = .crossDissolve - present(nukeDataModal, animated: true, completion: nil) - } - - @objc private func sendInvitation() { - let invitation = "Hey, I've been using Session to chat with complete privacy and security. Come join me! Download it at https://getsession.org/. My Session ID is \(getUserHexEncodedPublicKey()) !" - let shareVC = UIActivityViewController(activityItems: [ invitation ], applicationActivities: nil) - if UIDevice.current.isIPad { - shareVC.excludedActivityTypes = [] - shareVC.popoverPresentationController?.permittedArrowDirections = [] - shareVC.popoverPresentationController?.sourceView = self.view - shareVC.popoverPresentationController?.sourceRect = self.view.bounds - } - navigationController!.present(shareVC, animated: true, completion: nil) - } - - @objc private func openFAQ() { - let url = URL(string: "https://getsession.org/faq")! - UIApplication.shared.open(url) - } - - @objc private func openSurvey() { - let url = URL(string: "https://getsession.org/survey")! - UIApplication.shared.open(url) - } - - @objc private func shareLogs() { - let shareLogsModal = ShareLogsModal() - shareLogsModal.modalPresentationStyle = .overFullScreen - shareLogsModal.modalTransitionStyle = .crossDissolve - present(shareLogsModal, animated: true, completion: nil) - } - - @objc private func helpTranslate() { - let url = URL(string: "https://crowdin.com/project/session-ios")! - UIApplication.shared.open(url) - } -} diff --git a/SignalUtilitiesKit/Shared View Controllers/OWSNavigationController.m b/SignalUtilitiesKit/Shared View Controllers/OWSNavigationController.m deleted file mode 100644 index 945403c46..000000000 --- a/SignalUtilitiesKit/Shared View Controllers/OWSNavigationController.m +++ /dev/null @@ -1,186 +0,0 @@ -// -// Copyright (c) 2019 Open Whisper Systems. All rights reserved. -// - -#import "AppContext.h" -#import "OWSNavigationController.h" -#import -#import - -NS_ASSUME_NONNULL_BEGIN - -@interface UINavigationController (OWSNavigationController) - -@end - -#pragma mark - - -// Expose that UINavigationController already secretly implements UIGestureRecognizerDelegate -// so we can call [super navigationBar:shouldPopItem] in our own implementation to take advantage -// of the important side effects of that method. -@interface OWSNavigationController () - -@end - -#pragma mark - - -@implementation OWSNavigationController - -- (instancetype)init -{ - self = [super initWithNavigationBarClass:[OWSNavigationBar class] toolbarClass:nil]; - if (!self) { - return self; - } - [self setupNavbar]; - - return self; -} - -- (instancetype)initWithRootViewController:(UIViewController *)rootViewController -{ - self = [self init]; - if (!self) { - return self; - } - [self pushViewController:rootViewController animated:NO]; - - return self; -} - -- (void)dealloc -{ - [[NSNotificationCenter defaultCenter] removeObserver:self]; -} - -#pragma mark - - -- (void)viewDidLoad -{ - [super viewDidLoad]; - - self.interactivePopGestureRecognizer.delegate = self; -} - -- (BOOL)prefersStatusBarHidden -{ - if (self.ows_prefersStatusBarHidden) { - return self.ows_prefersStatusBarHidden.boolValue; - } - return [super prefersStatusBarHidden]; -} - -#pragma mark - UINavigationBarDelegate - -- (void)setupNavbar -{ - if (![self.navigationBar isKindOfClass:[OWSNavigationBar class]]) { - OWSFailDebug(@"navigationBar was unexpected class: %@", self.navigationBar); - return; - } - OWSNavigationBar *navbar = (OWSNavigationBar *)self.navigationBar; - navbar.navBarLayoutDelegate = self; - [self updateLayoutForNavbar:navbar]; -} - -// All OWSNavigationController serve as the UINavigationBarDelegate for their navbar. -// We override shouldPopItem: in order to cancel some back button presses - for example, -// if a view has unsaved changes. -- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item -{ - OWSAssertDebug(self.interactivePopGestureRecognizer.delegate == self); - UIViewController *topViewController = self.topViewController; - - // wasBackButtonClicked is YES if the back button was pressed but not - // if a back gesture was performed or if the view is popped programmatically. - BOOL wasBackButtonClicked = topViewController.navigationItem == item; - BOOL result = YES; - if (wasBackButtonClicked) { - if ([topViewController conformsToProtocol:@protocol(OWSNavigationView)]) { - id navigationView = (id)topViewController; - result = ![navigationView shouldCancelNavigationBack]; - } - } - - // If we're not going to cancel the pop/back, we need to call the super - // implementation since it has important side effects. - if (result) { - // NOTE: result might end up NO if the super implementation cancels the - // the pop/back. - [super navigationBar:navigationBar shouldPopItem:item]; - result = YES; - } - return result; -} - -#pragma mark - UIGestureRecognizerDelegate - -// We serve as the UIGestureRecognizerDelegate of the interactivePopGestureRecognizer -// in order to cancel some "back" gestures - for example, -// if a view has unsaved changes. -- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer -{ - OWSAssertDebug(gestureRecognizer == self.interactivePopGestureRecognizer); - - UIViewController *topViewController = self.topViewController; - if ([topViewController conformsToProtocol:@protocol(OWSNavigationView)]) { - id navigationView = (id)topViewController; - return ![navigationView shouldCancelNavigationBack]; - } else { - UIViewController *rootViewController = self.viewControllers.firstObject; - if (topViewController == rootViewController) { - return NO; - } else { - return YES; - } - } -} - -#pragma mark - NavBarLayoutDelegate - -- (void)navBarCallLayoutDidChangeWithNavbar:(OWSNavigationBar *)navbar -{ - [self updateLayoutForNavbar:navbar]; - [self setNeedsStatusBarAppearanceUpdate]; -} - -- (UIStatusBarStyle)preferredStatusBarStyle -{ - if (!CurrentAppContext().isMainApp) { - return super.preferredStatusBarStyle; - } else if (OWSWindowManager.sharedManager.hasCall) { - // Status bar is overlaying the green "call banner" - return UIStatusBarStyleLightContent; - } else { - return LKAppModeUtilities.isLightMode ? UIStatusBarStyleDefault : UIStatusBarStyleLightContent; - } -} - -- (void)updateLayoutForNavbar:(OWSNavigationBar *)navbar -{ - OWSLogDebug(@""); - - [UIView setAnimationsEnabled:NO]; - - if (!CurrentAppContext().isMainApp) { - self.additionalSafeAreaInsets = UIEdgeInsetsZero; - } else if (OWSWindowManager.sharedManager.hasCall) { - self.additionalSafeAreaInsets = UIEdgeInsetsMake(20, 0, 0, 0); - } else { - self.additionalSafeAreaInsets = UIEdgeInsetsZero; - } - - [navbar layoutSubviews]; - [UIView setAnimationsEnabled:YES]; -} - -#pragma mark - Orientation - -- (BOOL)shouldAutorotate -{ - return YES; -} - -@end - -NS_ASSUME_NONNULL_END From 080f147a33ea5dea9bdb40c08598e90fe9117183 Mon Sep 17 00:00:00 2001 From: Ryan Zhao Date: Thu, 6 Oct 2022 13:54:04 +1100 Subject: [PATCH 23/33] clean --- .../Message Cells/Content Views/ReactionContainerView.swift | 1 + Session/Conversations/Message Cells/VisibleMessageCell.swift | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Session/Conversations/Message Cells/Content Views/ReactionContainerView.swift b/Session/Conversations/Message Cells/Content Views/ReactionContainerView.swift index 583142633..78410b688 100644 --- a/Session/Conversations/Message Cells/Content Views/ReactionContainerView.swift +++ b/Session/Conversations/Message Cells/Content Views/ReactionContainerView.swift @@ -75,6 +75,7 @@ final class ReactionContainerView: UIView { arrow.pin(.top, to: .top, of: result) arrow.pin(.leading, to: .leading, of: result) arrow.pin(.bottom, to: .bottom, of: result) +// arrow.set(.width, to: Self.arrowSize.width) textLabel.pin(.top, to: .top, of: result) textLabel.pin(.leading, to: .trailing, of: arrow, withInset: ReactionContainerView.arrowSpacing) diff --git a/Session/Conversations/Message Cells/VisibleMessageCell.swift b/Session/Conversations/Message Cells/VisibleMessageCell.swift index 5c0641334..d70a5f3d3 100644 --- a/Session/Conversations/Message Cells/VisibleMessageCell.swift +++ b/Session/Conversations/Message Cells/VisibleMessageCell.swift @@ -372,7 +372,7 @@ final class VisibleMessageCell: MessageCell, TappableLabelDelegate { for: cellViewModel, maxWidth: VisibleMessageCell.getMaxWidth( for: cellViewModel, - includingOppositeGutter: UIDevice.current.isIPad + includingOppositeGutter: false ), showExpandedReactions: showExpandedReactions ) From 00fb27b59ad430d9b35d31592966e768e040562b Mon Sep 17 00:00:00 2001 From: Ryan Zhao Date: Thu, 6 Oct 2022 14:03:12 +1100 Subject: [PATCH 24/33] clean --- .../Message Cells/Content Views/ReactionContainerView.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/Session/Conversations/Message Cells/Content Views/ReactionContainerView.swift b/Session/Conversations/Message Cells/Content Views/ReactionContainerView.swift index 78410b688..583142633 100644 --- a/Session/Conversations/Message Cells/Content Views/ReactionContainerView.swift +++ b/Session/Conversations/Message Cells/Content Views/ReactionContainerView.swift @@ -75,7 +75,6 @@ final class ReactionContainerView: UIView { arrow.pin(.top, to: .top, of: result) arrow.pin(.leading, to: .leading, of: result) arrow.pin(.bottom, to: .bottom, of: result) -// arrow.set(.width, to: Self.arrowSize.width) textLabel.pin(.top, to: .top, of: result) textLabel.pin(.leading, to: .trailing, of: arrow, withInset: ReactionContainerView.arrowSpacing) From 27214e8478448287499cfa42615097aafc5fcc62 Mon Sep 17 00:00:00 2001 From: Ryan Zhao Date: Tue, 11 Oct 2022 14:34:49 +1100 Subject: [PATCH 25/33] fix NewDMVC --- Session/Home/New Conversation/NewDMVC.swift | 93 ++++++++++++++------- Session/Open Groups/JoinOpenGroupVC.swift | 50 ++++++++--- 2 files changed, 102 insertions(+), 41 deletions(-) diff --git a/Session/Home/New Conversation/NewDMVC.swift b/Session/Home/New Conversation/NewDMVC.swift index 2f1dfce6e..f9a48812e 100644 --- a/Session/Home/New Conversation/NewDMVC.swift +++ b/Session/Home/New Conversation/NewDMVC.swift @@ -92,36 +92,41 @@ final class NewDMVC: BaseVC, UIPageViewControllerDataSource, UIPageViewControlle navigationItem.leftBarButtonItem = closeButton } - // Set up tab bar - view.addSubview(tabBar) - tabBar.pin(.top, to: .top, of: view) - tabBar.pin(.leading, to: .leading, of: view) - tabBar.pin(.trailing, to: .trailing, of: view) - - // Set up page VC - let containerView: UIView = UIView() - view.addSubview(containerView) - containerView.pin(.top, to: .bottom, of: tabBar) - containerView.pin(.leading, to: .leading, of: view) - containerView.pin(.trailing, to: .trailing, of: view) - containerView.pin(.bottom, to: .bottom, of: view) - + // Page VC let hasCameraAccess = (AVCaptureDevice.authorizationStatus(for: .video) == .authorized) pages = [ enterPublicKeyVC, (hasCameraAccess ? scanQRCodeWrapperVC : scanQRCodePlaceholderVC) ] pageVC.dataSource = self pageVC.delegate = self pageVC.setViewControllers([ enterPublicKeyVC ], direction: .forward, animated: false, completion: nil) - addChild(pageVC) - containerView.addSubview(pageVC.view) - pageVC.view.pin(to: containerView) - pageVC.didMove(toParent: self) + // Tab bar + view.addSubview(tabBar) + tabBar.pin(.top, to: .top, of: view) + tabBar.pin(.leading, to: .leading, of: view) + tabBar.pin(.trailing, to: .trailing, of: view) + + // Page VC constraints + let pageVCView = pageVC.view! + view.addSubview(pageVCView) + pageVCView.pin(.leading, to: .leading, of: view) + pageVCView.pin(.top, to: .bottom, of: tabBar) + pageVCView.pin(.trailing, to: .trailing, of: view) + pageVCView.pin(.bottom, to: .bottom, of: view) + + let navBarHeight: CGFloat = (navigationController?.navigationBar.frame.size.height ?? 0) + let statusBarHeight: CGFloat = UIApplication.shared.statusBarFrame.size.height + let height: CGFloat = ((navigationController?.view.bounds.height ?? 0) - navBarHeight - TabBar.snHeight - statusBarHeight) + let size: CGSize = CGSize(width: UIScreen.main.bounds.width, height: height) + enterPublicKeyVC.constrainSize(to: size) + scanQRCodePlaceholderVC.constrainSize(to: size) } override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { super.viewWillTransition(to: size, with: coordinator) - enterPublicKeyVC.viewWidth?.constant = size.width - scanQRCodePlaceholderVC.viewWidth?.constant = size.width + let height: CGFloat = (size.height - TabBar.snHeight) + let size: CGSize = CGSize(width: size.width, height: height) + enterPublicKeyVC.constrainSize(to: size) + scanQRCodePlaceholderVC.constrainSize(to: size) } // MARK: - General @@ -400,7 +405,8 @@ private final class EnterPublicKeyVC: UIViewController { return result }() - var viewWidth: NSLayoutConstraint? + private var viewWidth: NSLayoutConstraint? + private var viewHeight: NSLayoutConstraint? // MARK: - Lifecycle @@ -436,9 +442,7 @@ private final class EnterPublicKeyVC: UIViewController { view.addSubview(mainStackView) mainStackView.pin([ UIView.HorizontalEdge.leading, UIView.HorizontalEdge.trailing, UIView.VerticalEdge.top ], to: view) - bottomConstraint = view.pin(.bottom, to: .bottom, of: mainStackView, withInset: bottomMargin) - // Width constraint - viewWidth = view.set(.width, to: UIScreen.main.bounds.width) + bottomConstraint = mainStackView.pin(.bottom, to: .bottom, of: view, withInset: bottomMargin) // Dismiss keyboard on tap let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(dismissKeyboard)) @@ -456,6 +460,21 @@ private final class EnterPublicKeyVC: UIViewController { // MARK: - General + func constrainSize(to size: CGSize) { + if viewWidth == nil { + viewWidth = view.set(.width, to: size.width) + } else { + viewWidth?.constant = size.width + } + + if viewHeight == nil { + viewHeight = view.set(.height, to: size.height) + } else { + viewHeight?.constant = size.height + } + } + + func setSessionId(to sessionId: String) { publicKeyTextView.insertText(sessionId) } @@ -615,7 +634,8 @@ private final class EnterPublicKeyVC: UIViewController { private final class ScanQRCodePlaceholderVC: UIViewController { weak var newDMVC: NewDMVC! - var viewWidth: NSLayoutConstraint? + private var viewWidth: NSLayoutConstraint? + private var viewHeight: NSLayoutConstraint? override func viewDidLoad() { // Remove background color @@ -644,14 +664,29 @@ private final class ScanQRCodePlaceholderVC: UIViewController { stackView.alignment = .center // Set up constraints - viewWidth = view.set(.width, to: UIScreen.main.bounds.width) - view.addSubview(stackView) stackView.pin(.leading, to: .leading, of: view, withInset: Values.massiveSpacing) - stackView.pin(.trailing, to: .trailing, of: view, withInset: -Values.massiveSpacing) - stackView.center(.vertical, in: view, withInset: -16) // Makes things appear centered visually + view.pin(.trailing, to: .trailing, of: stackView, withInset: Values.massiveSpacing) + + let verticalCenteringConstraint = stackView.center(.vertical, in: view) + verticalCenteringConstraint.constant = -16 // Makes things appear centered visually } + func constrainSize(to size: CGSize) { + if viewWidth == nil { + viewWidth = view.set(.width, to: size.width) + } else { + viewWidth?.constant = size.width + } + + if viewHeight == nil { + viewHeight = view.set(.height, to: size.height) + } else { + viewHeight?.constant = size.height + } + } + + @objc private func requestCameraAccess() { Permissions.requestCameraPermissionIfNeeded { [weak self] in self?.newDMVC.handleCameraAccessGranted() diff --git a/Session/Open Groups/JoinOpenGroupVC.swift b/Session/Open Groups/JoinOpenGroupVC.swift index 1842b6ed0..79885ae45 100644 --- a/Session/Open Groups/JoinOpenGroupVC.swift +++ b/Session/Open Groups/JoinOpenGroupVC.swift @@ -84,17 +84,22 @@ final class JoinOpenGroupVC: BaseVC, UIPageViewControllerDataSource, UIPageViewC pageVCView.pin(.top, to: .bottom, of: tabBar) pageVCView.pin(.trailing, to: .trailing, of: view) pageVCView.pin(.bottom, to: .bottom, of: view) + let navBarHeight: CGFloat = (navigationController?.navigationBar.frame.size.height ?? 0) - let height: CGFloat = ((navigationController?.view.bounds.height ?? 0) - navBarHeight - TabBar.snHeight) - enterURLVC.constrainHeight(to: height) - scanQRCodePlaceholderVC.constrainHeight(to: height) + let statusBarHeight: CGFloat = UIApplication.shared.statusBarFrame.size.height + let height: CGFloat = ((navigationController?.view.bounds.height ?? 0) - navBarHeight - TabBar.snHeight - statusBarHeight) + let size: CGSize = CGSize(width: UIScreen.main.bounds.width, height: height) + enterURLVC.constrainSize(to: size) + scanQRCodePlaceholderVC.constrainSize(to: size) } override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { super.viewWillTransition(to: size, with: coordinator) - enterURLVC.viewWidth?.constant = size.width + let height: CGFloat = (size.height - TabBar.snHeight) + let size: CGSize = CGSize(width: size.width, height: height) + enterURLVC.constrainSize(to: size) + scanQRCodePlaceholderVC.constrainSize(to: size) enterURLVC.suggestionGrid.refreshLayout(with: size.width - 2 * Values.largeSpacing) - scanQRCodePlaceholderVC.viewWidth?.constant = size.width } // MARK: - General @@ -256,7 +261,8 @@ private final class EnterURLVC: UIViewController, UIGestureRecognizerDelegate, O return result }() - var viewWidth: NSLayoutConstraint? + private var viewWidth: NSLayoutConstraint? + private var viewHeight: NSLayoutConstraint? // MARK: - Lifecycle @@ -332,8 +338,18 @@ private final class EnterURLVC: UIViewController, UIGestureRecognizerDelegate, O // MARK: - General - func constrainHeight(to height: CGFloat) { - view.set(.height, to: height) + func constrainSize(to size: CGSize) { + if viewWidth == nil { + viewWidth = view.set(.width, to: size.width) + } else { + viewWidth?.constant = size.width + } + + if viewHeight == nil { + viewHeight = view.set(.height, to: size.height) + } else { + viewHeight?.constant = size.height + } } @objc private func dismissKeyboard() { @@ -445,7 +461,8 @@ private final class EnterURLVC: UIViewController, UIGestureRecognizerDelegate, O private final class ScanQRCodePlaceholderVC: UIViewController { weak var joinOpenGroupVC: JoinOpenGroupVC? - var viewWidth: NSLayoutConstraint? + private var viewWidth: NSLayoutConstraint? + private var viewHeight: NSLayoutConstraint? // MARK: - Lifecycle @@ -476,7 +493,6 @@ private final class ScanQRCodePlaceholderVC: UIViewController { stackView.alignment = .center // Constraints - viewWidth = view.set(.width, to: UIScreen.main.bounds.width) view.addSubview(stackView) stackView.pin(.leading, to: .leading, of: view, withInset: Values.massiveSpacing) view.pin(.trailing, to: .trailing, of: stackView, withInset: Values.massiveSpacing) @@ -485,8 +501,18 @@ private final class ScanQRCodePlaceholderVC: UIViewController { verticalCenteringConstraint.constant = -16 // Makes things appear centered visually } - func constrainHeight(to height: CGFloat) { - view.set(.height, to: height) + func constrainSize(to size: CGSize) { + if viewWidth == nil { + viewWidth = view.set(.width, to: size.width) + } else { + viewWidth?.constant = size.width + } + + if viewHeight == nil { + viewHeight = view.set(.height, to: size.height) + } else { + viewHeight?.constant = size.height + } } @objc private func requestCameraAccess() { From 5d36f81a8cb345d9e99a95c91fb741058280622f Mon Sep 17 00:00:00 2001 From: Ryan Zhao Date: Tue, 11 Oct 2022 14:38:46 +1100 Subject: [PATCH 26/33] clean --- SessionUIKit/Style Guide/Gradients.swift | 65 ------------------------ 1 file changed, 65 deletions(-) delete mode 100644 SessionUIKit/Style Guide/Gradients.swift diff --git a/SessionUIKit/Style Guide/Gradients.swift b/SessionUIKit/Style Guide/Gradients.swift deleted file mode 100644 index a08c24bdb..000000000 --- a/SessionUIKit/Style Guide/Gradients.swift +++ /dev/null @@ -1,65 +0,0 @@ -import UIKit - -@objc(LKGradient) -public final class Gradient : NSObject { - public let start: UIColor - public let end: UIColor - - private override init() { preconditionFailure("Use init(start:end:) instead.") } - - @objc public init(start: UIColor, end: UIColor) { - self.start = start - self.end = end - super.init() - } -} - -@objc public extension UIView { - - @objc func setGradient(_ gradient: Gradient, frame: CGRect = UIScreen.main.bounds) { - let layer = CAGradientLayer() - layer.frame = frame - layer.colors = [ gradient.start.cgColor, gradient.end.cgColor ] - if let existingSublayer = self.layer.sublayers?[0], existingSublayer is CAGradientLayer { - self.layer.replaceSublayer(existingSublayer, with: layer) - } else { - self.layer.insertSublayer(layer, at: 0) - } - } - - func setHalfWayGradient(_ gradient: Gradient, frame: CGRect = UIScreen.main.bounds) { - let layer = CAGradientLayer() - layer.frame = frame - layer.colors = [ gradient.start.cgColor, gradient.end.cgColor, gradient.end.cgColor ] - if let existingSublayer = self.layer.sublayers?[0], existingSublayer is CAGradientLayer { - self.layer.replaceSublayer(existingSublayer, with: layer) - } else { - self.layer.insertSublayer(layer, at: 0) - } - } -} - -@objc(LKGradients) -final public class Gradients : NSObject { - - @objc public static var defaultBackground: Gradient { - switch AppModeManager.shared.currentAppMode { - case .light: return Gradient(start: UIColor(hex: 0xF9F9F9), end: UIColor(hex: 0xFFFFFF)) - case .dark: return Gradient(start: UIColor(hex: 0x171717), end: UIColor(hex: 0x121212)) - } - } - - @objc public static var homeVCFade: Gradient { - switch AppModeManager.shared.currentAppMode { - case .light: return Gradient(start: UIColor(hex: 0xFFFFFF).withAlphaComponent(0), end: UIColor(hex: 0xFFFFFF)) - case .dark: return Gradient(start: UIColor(hex: 0x000000).withAlphaComponent(0), end: UIColor(hex: 0x000000)) - } - } - - @objc public static var newClosedGroupVCFade: Gradient { - switch AppModeManager.shared.currentAppMode { - case .light: return Gradient(start: UIColor(hex: 0xF9F9F9).withAlphaComponent(0), end: UIColor(hex: 0xF9F9F9)) - case .dark: return Gradient(start: UIColor(hex: 0x1B1B1B).withAlphaComponent(0), end: UIColor(hex: 0x1B1B1B)) - } - } -} From b7616dea0bd1919bd9836065c4f8e795b529a84f Mon Sep 17 00:00:00 2001 From: Ryan Zhao Date: Tue, 11 Oct 2022 14:42:37 +1100 Subject: [PATCH 27/33] clean --- Session/Closed Groups/NewClosedGroupVC.swift | 5 ----- 1 file changed, 5 deletions(-) diff --git a/Session/Closed Groups/NewClosedGroupVC.swift b/Session/Closed Groups/NewClosedGroupVC.swift index 674a28f90..b57b93ec1 100644 --- a/Session/Closed Groups/NewClosedGroupVC.swift +++ b/Session/Closed Groups/NewClosedGroupVC.swift @@ -159,11 +159,6 @@ final class NewClosedGroupVC: BaseVC, UITableViewDataSource, UITableViewDelegate // Set up content setUpViewHierarchy() } - - override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { - super.viewWillTransition(to: size, with: coordinator) - tableViewWidth?.constant = size.width - } private func setUpViewHierarchy() { guard !contactProfiles.isEmpty else { From be670a5516002167a5a3e129b347a00e735b7455 Mon Sep 17 00:00:00 2001 From: Ryan Zhao Date: Tue, 11 Oct 2022 14:43:09 +1100 Subject: [PATCH 28/33] clean --- Session/Closed Groups/NewClosedGroupVC.swift | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/Session/Closed Groups/NewClosedGroupVC.swift b/Session/Closed Groups/NewClosedGroupVC.swift index b57b93ec1..efadfcde6 100644 --- a/Session/Closed Groups/NewClosedGroupVC.swift +++ b/Session/Closed Groups/NewClosedGroupVC.swift @@ -32,11 +32,7 @@ final class NewClosedGroupVC: BaseVC, UITableViewDataSource, UITableViewDelegate ] private var selectedContacts: Set = [] private var searchText: String = "" - - // MARK: - Layout - - private var tableViewWidth: NSLayoutConstraint? - + // MARK: - Components private static let textFieldHeight: CGFloat = 50 From d9ea06008bdfbd4d5223ec430d0ac4e8a808b4e6 Mon Sep 17 00:00:00 2001 From: Ryan Zhao Date: Tue, 11 Oct 2022 14:54:53 +1100 Subject: [PATCH 29/33] clean --- Session/Calls/CallVC.swift | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Session/Calls/CallVC.swift b/Session/Calls/CallVC.swift index 7b128fb04..6cbb255eb 100644 --- a/Session/Calls/CallVC.swift +++ b/Session/Calls/CallVC.swift @@ -363,16 +363,16 @@ final class CallVC: UIViewController, VideoPreviewDelegate { NotificationCenter.default.addObserver(self, selector: #selector(audioRouteDidChange), name: AVAudioSession.routeChangeNotification, object: nil) } - override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { - super.viewWillTransition(to: size, with: coordinator) - - if let existingSublayer = fadeView.layer.sublayers?[0] as? CAGradientLayer { - let layer = CAGradientLayer() - layer.frame = CGRect(x: 0, y: 0, width: size.width, height: 64) - layer.colors = existingSublayer.colors - fadeView.layer.replaceSublayer(existingSublayer, with: layer) - } - } +// override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { +// super.viewWillTransition(to: size, with: coordinator) +// +// if let existingSublayer = fadeView.layer.sublayers?[0] as? CAGradientLayer { +// let layer = CAGradientLayer() +// layer.frame = CGRect(x: 0, y: 0, width: size.width, height: 64) +// layer.colors = existingSublayer.colors +// fadeView.layer.replaceSublayer(existingSublayer, with: layer) +// } +// } deinit { UIDevice.current.endGeneratingDeviceOrientationNotifications() From e16180c007350123eb16e793849b7f71402b9f75 Mon Sep 17 00:00:00 2001 From: Morgan Pretty Date: Wed, 12 Oct 2022 09:05:21 +1100 Subject: [PATCH 30/33] Removed commented code and fixed a minor layout issue on SE devices --- Session/Calls/CallVC.swift | 11 ----------- SessionUIKit/Components/Separator.swift | 1 + 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/Session/Calls/CallVC.swift b/Session/Calls/CallVC.swift index 6cbb255eb..adb72deb1 100644 --- a/Session/Calls/CallVC.swift +++ b/Session/Calls/CallVC.swift @@ -363,17 +363,6 @@ final class CallVC: UIViewController, VideoPreviewDelegate { NotificationCenter.default.addObserver(self, selector: #selector(audioRouteDidChange), name: AVAudioSession.routeChangeNotification, object: nil) } -// override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { -// super.viewWillTransition(to: size, with: coordinator) -// -// if let existingSublayer = fadeView.layer.sublayers?[0] as? CAGradientLayer { -// let layer = CAGradientLayer() -// layer.frame = CGRect(x: 0, y: 0, width: size.width, height: 64) -// layer.colors = existingSublayer.colors -// fadeView.layer.replaceSublayer(existingSublayer, with: layer) -// } -// } - deinit { UIDevice.current.endGeneratingDeviceOrientationNotifications() NotificationCenter.default.removeObserver(self) diff --git a/SessionUIKit/Components/Separator.swift b/SessionUIKit/Components/Separator.swift index f4d8957c3..178c27748 100644 --- a/SessionUIKit/Components/Separator.swift +++ b/SessionUIKit/Components/Separator.swift @@ -25,6 +25,7 @@ public final class Separator: UIView { private lazy var titleLabel: UILabel = { let result = UILabel() + result.setContentCompressionResistancePriority(.required, for: .vertical) result.font = .systemFont(ofSize: Values.smallFontSize) result.themeTextColor = .textSecondary result.textAlignment = .center From 02400012013d4ff53a4ae85b21ef5d3e639de6a8 Mon Sep 17 00:00:00 2001 From: ryanzhao Date: Wed, 16 Nov 2022 10:28:07 +1100 Subject: [PATCH 31/33] fix copy and share buttons are getting squashed when switching from landscape to portrait in new DM VC --- Session/Home/New Conversation/NewDMVC.swift | 11 ++++++----- SessionUIKit/Style Guide/Values.swift | 1 - 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Session/Home/New Conversation/NewDMVC.swift b/Session/Home/New Conversation/NewDMVC.swift index 3c2e22eba..54ae31d23 100644 --- a/Session/Home/New Conversation/NewDMVC.swift +++ b/Session/Home/New Conversation/NewDMVC.swift @@ -362,11 +362,6 @@ private final class EnterPublicKeyVC: UIViewController { result.spacing = UIDevice.current.isIPad ? Values.iPadButtonSpacing : Values.mediumSpacing result.distribution = .fillEqually - if (UIDevice.current.isIPad) { - result.layoutMargins = UIEdgeInsets(top: 0, left: Values.iPadButtonContainerMargin, bottom: 0, right: Values.iPadButtonContainerMargin) - result.isLayoutMarginsRelativeArrangement = true - } - return result }() @@ -474,6 +469,12 @@ private final class EnterPublicKeyVC: UIViewController { } else { viewHeight?.constant = size.height } + + if (UIDevice.current.isIPad) { + let iPadButtonContainerMargin: CGFloat = (size.width - Values.iPadButtonSpacing) / 2 - Values.iPadButtonWidth - Values.largeSpacing + buttonContainer.layoutMargins = UIEdgeInsets(top: 0, left: iPadButtonContainerMargin, bottom: 0, right: iPadButtonContainerMargin) + buttonContainer.isLayoutMarginsRelativeArrangement = true + } } diff --git a/SessionUIKit/Style Guide/Values.swift b/SessionUIKit/Style Guide/Values.swift index fd03c9dcb..fd12c70c9 100644 --- a/SessionUIKit/Style Guide/Values.swift +++ b/SessionUIKit/Style Guide/Values.swift @@ -57,5 +57,4 @@ public final class Values : NSObject { @objc public static let iPadButtonWidth = CGFloat(196) @objc public static let iPadButtonSpacing = CGFloat(32) @objc public static let iPadUserSessionIdContainerWidth = iPadButtonWidth * 2 + iPadButtonSpacing - @objc public static let iPadButtonContainerMargin = (UIScreen.main.bounds.width - iPadButtonSpacing) / 2 - iPadButtonWidth - largeSpacing } From d827bb2770a50e545f5b67d2b67c279c97d2ca02 Mon Sep 17 00:00:00 2001 From: ryanzhao Date: Wed, 16 Nov 2022 13:13:25 +1100 Subject: [PATCH 32/33] fix message request empty state --- .../Home/Message Requests/MessageRequestsViewController.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Session/Home/Message Requests/MessageRequestsViewController.swift b/Session/Home/Message Requests/MessageRequestsViewController.swift index b64ccfdc7..3e332ec9f 100644 --- a/Session/Home/Message Requests/MessageRequestsViewController.swift +++ b/Session/Home/Message Requests/MessageRequestsViewController.swift @@ -235,8 +235,8 @@ class MessageRequestsViewController: BaseVC, UITableViewDelegate, UITableViewDat loadingConversationsLabel.isHidden = true // Show the empty state if there is no data - clearAllButton.isHidden = updatedData.isEmpty - emptyStateLabel.isHidden = !updatedData.isEmpty + clearAllButton.isHidden = !(updatedData.first?.elements.isEmpty == false) + emptyStateLabel.isHidden = !clearAllButton.isHidden CATransaction.begin() CATransaction.setCompletionBlock { [weak self] in From 47523054b2f67c5689582040055752846556463b Mon Sep 17 00:00:00 2001 From: ryanzhao Date: Wed, 16 Nov 2022 15:40:49 +1100 Subject: [PATCH 33/33] slightly reduce max width of media message on iPad --- Session/Conversations/Message Cells/VisibleMessageCell.swift | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Session/Conversations/Message Cells/VisibleMessageCell.swift b/Session/Conversations/Message Cells/VisibleMessageCell.swift index 567abe565..2c47807d8 100644 --- a/Session/Conversations/Message Cells/VisibleMessageCell.swift +++ b/Session/Conversations/Message Cells/VisibleMessageCell.swift @@ -1025,11 +1025,12 @@ final class VisibleMessageCell: MessageCell, TappableLabelDelegate { static func getMaxWidth(for cellViewModel: MessageViewModel, includingOppositeGutter: Bool = true) -> CGFloat { let screen: CGRect = UIScreen.main.bounds + let width: CGFloat = UIDevice.current.isIPad ? screen.width * 0.75 : screen.width let oppositeEdgePadding: CGFloat = (includingOppositeGutter ? gutterSize : contactThreadHSpacing) switch cellViewModel.variant { case .standardOutgoing: - return (screen.width - contactThreadHSpacing - oppositeEdgePadding) + return (width - contactThreadHSpacing - oppositeEdgePadding) case .standardIncoming, .standardIncomingDeleted: let isGroupThread = ( @@ -1038,7 +1039,7 @@ final class VisibleMessageCell: MessageCell, TappableLabelDelegate { ) let leftGutterSize = (isGroupThread ? leftGutterSize : contactThreadHSpacing) - return (screen.width - leftGutterSize - oppositeEdgePadding) + return (width - leftGutterSize - oppositeEdgePadding) default: preconditionFailure() }