diff --git a/Signal/src/Loki/Components/ConversationCell.swift b/Signal/src/Loki/Components/ConversationCell.swift index cb9ce6629..f66dc38dc 100644 --- a/Signal/src/Loki/Components/ConversationCell.swift +++ b/Signal/src/Loki/Components/ConversationCell.swift @@ -42,7 +42,9 @@ final class ConversationCell : UITableViewCell { private lazy var statusIndicatorView: UIImageView = { let result = UIImageView() - result.contentMode = .center + result.contentMode = .scaleAspectFit + result.layer.cornerRadius = Values.conversationCellStatusIndicatorSize / 2 + result.layer.masksToBounds = true return result }() @@ -167,6 +169,7 @@ final class ConversationCell : UITableViewCell { typingIndicatorView.isHidden = true typingIndicatorView.stopAnimation() } + statusIndicatorView.backgroundColor = nil let lastMessage = threadViewModel.lastMessageForInbox if let lastMessage = lastMessage as? TSOutgoingMessage { let image: UIImage @@ -174,7 +177,9 @@ final class ConversationCell : UITableViewCell { switch status { case .calculatingPoW, .uploading, .sending: image = #imageLiteral(resourceName: "CircleDotDotDot") case .sent, .skipped, .delivered: image = #imageLiteral(resourceName: "CircleCheck") - case .read: image = #imageLiteral(resourceName: "FilledCircleCheck") + case .read: + statusIndicatorView.backgroundColor = .white + image = #imageLiteral(resourceName: "FilledCircleCheck") case .failed: image = #imageLiteral(resourceName: "message_status_failed").asTintedImage(color: Colors.text)! } statusIndicatorView.image = image diff --git a/Signal/src/Loki/Components/NewConversationButtonSet.swift b/Signal/src/Loki/Components/NewConversationButtonSet.swift index fc5db863a..8510a2a51 100644 --- a/Signal/src/Loki/Components/NewConversationButtonSet.swift +++ b/Signal/src/Loki/Components/NewConversationButtonSet.swift @@ -10,6 +10,7 @@ final class NewConversationButtonSet : UIView { private let spacing = Values.largeSpacing private let iconSize = CGFloat(24) private let maxDragDistance = CGFloat(56) + private let dragMargin = CGFloat(16) // MARK: Components private lazy var mainButton = NewConversationButton(isMainButton: true, icon: #imageLiteral(resourceName: "Plus").scaled(to: CGSize(width: iconSize, height: iconSize))) @@ -120,9 +121,9 @@ final class NewConversationButtonSet : UIView { let buttons = [ joinOpenGroupButton, createNewPrivateChatButton, createNewClosedGroupButton ] let buttonToExpand = buttons.first { button in var hasUserDraggedBeyondButton = false - if button == joinOpenGroupButton && touch.isLeft(of: joinOpenGroupButton) { hasUserDraggedBeyondButton = true } - if button == createNewPrivateChatButton && touch.isAbove(createNewPrivateChatButton) { hasUserDraggedBeyondButton = true } - if button == createNewClosedGroupButton && touch.isRight(of: createNewClosedGroupButton) { hasUserDraggedBeyondButton = true } + if button == joinOpenGroupButton && touch.isLeft(of: joinOpenGroupButton, with: dragMargin) { hasUserDraggedBeyondButton = true } + if button == createNewPrivateChatButton && touch.isAbove(createNewPrivateChatButton, with: dragMargin) { hasUserDraggedBeyondButton = true } + if button == createNewClosedGroupButton && touch.isRight(of: createNewClosedGroupButton, with: dragMargin) { hasUserDraggedBeyondButton = true } return button.contains(touch) || hasUserDraggedBeyondButton } if let buttonToExpand = buttonToExpand { @@ -138,9 +139,9 @@ final class NewConversationButtonSet : UIView { override func touchesEnded(_ touches: Set, with event: UIEvent?) { guard let touch = touches.first, isUserDragging else { return } - if joinOpenGroupButton.contains(touch) || touch.isLeft(of: joinOpenGroupButton) { delegate?.joinOpenGroup() } - else if createNewPrivateChatButton.contains(touch) || touch.isAbove(createNewPrivateChatButton) { delegate?.createNewPrivateChat() } - else if createNewClosedGroupButton.contains(touch) || touch.isRight(of: createNewClosedGroupButton) { delegate?.createNewClosedGroup() } + if joinOpenGroupButton.contains(touch) || touch.isLeft(of: joinOpenGroupButton, with: dragMargin) { delegate?.joinOpenGroup() } + else if createNewPrivateChatButton.contains(touch) || touch.isAbove(createNewPrivateChatButton, with: dragMargin) { delegate?.createNewPrivateChat() } + else if createNewClosedGroupButton.contains(touch) || touch.isRight(of: createNewClosedGroupButton, with: dragMargin) { delegate?.createNewClosedGroup() } reset() } @@ -266,28 +267,28 @@ private extension UIView { private extension UITouch { - func isLeft(of view: UIView) -> Bool { - return isContainedVertically(in: view) && location(in: view).x < view.bounds.minX + func isLeft(of view: UIView, with margin: CGFloat = 0) -> Bool { + return isContainedVertically(in: view, with: margin) && location(in: view).x < view.bounds.minX } - func isAbove(_ view: UIView) -> Bool { - return isContainedHorizontally(in: view) && location(in: view).y < view.bounds.minY + func isAbove(_ view: UIView, with margin: CGFloat = 0) -> Bool { + return isContainedHorizontally(in: view, with: margin) && location(in: view).y < view.bounds.minY } - func isRight(of view: UIView) -> Bool { - return isContainedVertically(in: view) && location(in: view).x > view.bounds.maxX + func isRight(of view: UIView, with margin: CGFloat = 0) -> Bool { + return isContainedVertically(in: view, with: margin) && location(in: view).x > view.bounds.maxX } - func isBelow(_ view: UIView) -> Bool { - return isContainedHorizontally(in: view) && location(in: view).y > view.bounds.maxY + func isBelow(_ view: UIView, with margin: CGFloat = 0) -> Bool { + return isContainedHorizontally(in: view, with: margin) && location(in: view).y > view.bounds.maxY } - private func isContainedHorizontally(in view: UIView) -> Bool { - return (view.bounds.minX...view.bounds.maxX) ~= location(in: view).x + private func isContainedHorizontally(in view: UIView, with margin: CGFloat = 0) -> Bool { + return ((view.bounds.minX - margin)...(view.bounds.maxX + margin)) ~= location(in: view).x } - private func isContainedVertically(in view: UIView) -> Bool { - return (view.bounds.minY...view.bounds.maxY) ~= location(in: view).y + private func isContainedVertically(in view: UIView, with margin: CGFloat = 0) -> Bool { + return ((view.bounds.minY - margin)...(view.bounds.maxY + margin)) ~= location(in: view).y } } diff --git a/Signal/src/Loki/Style Guide/Gradients.swift b/Signal/src/Loki/Style Guide/Gradients.swift index c65be7b36..0060bf9e6 100644 --- a/Signal/src/Loki/Style Guide/Gradients.swift +++ b/Signal/src/Loki/Style Guide/Gradients.swift @@ -26,5 +26,6 @@ final class Gradient : NSObject { @objc(LKGradients) final class Gradients : NSObject { - @objc static let defaultLokiBackground = Gradient(start: UIColor(hex: 0x171717), end: UIColor(hex:0x121212)) + @objc static let defaultLokiBackground = Gradient(start: UIColor(hex: 0x171717), end: UIColor(hex: 0x121212)) + @objc static let transparentToBlack75 = Gradient(start: UIColor(red: 0, green: 0, blue: 0, alpha: 0), end: UIColor(red: 0, green: 0, blue: 0, alpha: 0.75)) } diff --git a/Signal/src/Loki/View Controllers/HomeVC.swift b/Signal/src/Loki/View Controllers/HomeVC.swift index c9a40faef..22fbffedc 100644 --- a/Signal/src/Loki/View Controllers/HomeVC.swift +++ b/Signal/src/Loki/View Controllers/HomeVC.swift @@ -51,6 +51,14 @@ final class HomeVC : UIViewController, UITableViewDataSource, UITableViewDelegat return result }() + private lazy var fadeView: UIView = { + let result = UIView() + let gradient = Gradients.transparentToBlack75 + result.setGradient(gradient) + result.isUserInteractionEnabled = false + return result + }() + // MARK: Lifecycle override func viewDidLoad() { SignalApp.shared().homeViewController = self @@ -95,6 +103,8 @@ final class HomeVC : UIViewController, UITableViewDataSource, UITableViewDelegat } tableView.pin(.trailing, to: .trailing, of: view) tableView.pin(.bottom, to: .bottom, of: view) + view.addSubview(fadeView) + fadeView.pin(to: view) // Set up search bar // tableView.tableHeaderView = searchBar // searchBar.sizeToFit()