Merge branch 'mkirk/disappearing-status'
@ -1,23 +0,0 @@
|
|||||||
{
|
|
||||||
"images" : [
|
|
||||||
{
|
|
||||||
"idiom" : "universal",
|
|
||||||
"filename" : "button_timer_white@1x.png",
|
|
||||||
"scale" : "1x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"idiom" : "universal",
|
|
||||||
"filename" : "button_timer_white@2x.png",
|
|
||||||
"scale" : "2x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"idiom" : "universal",
|
|
||||||
"filename" : "button_timer_white@3x.png",
|
|
||||||
"scale" : "3x"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"info" : {
|
|
||||||
"version" : 1,
|
|
||||||
"author" : "xcode"
|
|
||||||
}
|
|
||||||
}
|
|
Before Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 778 B |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 2.4 KiB |
@ -1,23 +0,0 @@
|
|||||||
{
|
|
||||||
"images" : [
|
|
||||||
{
|
|
||||||
"idiom" : "universal",
|
|
||||||
"filename" : "system_message_timer@1x.png",
|
|
||||||
"scale" : "1x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"idiom" : "universal",
|
|
||||||
"filename" : "system_message_timer@2x.png",
|
|
||||||
"scale" : "2x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"idiom" : "universal",
|
|
||||||
"filename" : "system_message_timer@3x.png",
|
|
||||||
"scale" : "3x"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"info" : {
|
|
||||||
"version" : 1,
|
|
||||||
"author" : "xcode"
|
|
||||||
}
|
|
||||||
}
|
|
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 2.7 KiB |
@ -1,26 +0,0 @@
|
|||||||
{
|
|
||||||
"images" : [
|
|
||||||
{
|
|
||||||
"idiom" : "universal",
|
|
||||||
"filename" : "table_ic_hourglass_empty@1x.png",
|
|
||||||
"scale" : "1x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"idiom" : "universal",
|
|
||||||
"filename" : "table_ic_hourglass_empty@2x.png",
|
|
||||||
"scale" : "2x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"idiom" : "universal",
|
|
||||||
"filename" : "table_ic_hourglass_empty@3x.png",
|
|
||||||
"scale" : "3x"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"info" : {
|
|
||||||
"version" : 1,
|
|
||||||
"author" : "xcode"
|
|
||||||
},
|
|
||||||
"properties" : {
|
|
||||||
"template-rendering-intent" : "template"
|
|
||||||
}
|
|
||||||
}
|
|
Before Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 2.2 KiB |
@ -1,26 +0,0 @@
|
|||||||
{
|
|
||||||
"images" : [
|
|
||||||
{
|
|
||||||
"idiom" : "universal",
|
|
||||||
"filename" : "table_ic_hourglass_full.png",
|
|
||||||
"scale" : "1x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"idiom" : "universal",
|
|
||||||
"filename" : "table_ic_hourglass_full@2x.png",
|
|
||||||
"scale" : "2x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"idiom" : "universal",
|
|
||||||
"filename" : "table_ic_hourglass_full@3x.png",
|
|
||||||
"scale" : "3x"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"info" : {
|
|
||||||
"version" : 1,
|
|
||||||
"author" : "xcode"
|
|
||||||
},
|
|
||||||
"properties" : {
|
|
||||||
"template-rendering-intent" : "template"
|
|
||||||
}
|
|
||||||
}
|
|
Before Width: | Height: | Size: 209 B |
Before Width: | Height: | Size: 302 B |
Before Width: | Height: | Size: 424 B |
@ -0,0 +1,134 @@
|
|||||||
|
//
|
||||||
|
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
@objc
|
||||||
|
public protocol DisappearingTimerConfigurationViewDelegate: class {
|
||||||
|
func disappearingTimerConfigurationViewWasTapped(_ disappearingTimerView: DisappearingTimerConfigurationView)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DisappearingTimerConfigurationView shows a timer icon and a short label showing the duration
|
||||||
|
// of disappearing messages for a thread.
|
||||||
|
//
|
||||||
|
// If you assign a delegate, it behaves like a button.
|
||||||
|
@objc
|
||||||
|
public class DisappearingTimerConfigurationView: UIView {
|
||||||
|
|
||||||
|
public weak var delegate: DisappearingTimerConfigurationViewDelegate? {
|
||||||
|
didSet {
|
||||||
|
// gesture recognizer is only enabled when a delegate is assigned.
|
||||||
|
// This lets us use this view as either an interactive button
|
||||||
|
// or as a non-interactive status indicator
|
||||||
|
pressGesture.isEnabled = delegate != nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override public var frame: CGRect {
|
||||||
|
didSet {
|
||||||
|
Logger.verbose("\(logTag) in \(#function): \(oldValue) -> \(frame)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override public var bounds: CGRect {
|
||||||
|
didSet {
|
||||||
|
Logger.verbose("\(logTag) in \(#function): \(oldValue) -> \(bounds)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override public func layoutSubviews() {
|
||||||
|
let oldFrame = self.frame
|
||||||
|
super.layoutSubviews()
|
||||||
|
Logger.verbose("\(logTag) in \(#function). Frame: \(oldFrame) -> \(self.frame)")
|
||||||
|
}
|
||||||
|
|
||||||
|
private let imageView: UIImageView
|
||||||
|
private let label: UILabel
|
||||||
|
private var pressGesture: UILongPressGestureRecognizer!
|
||||||
|
|
||||||
|
public required init?(coder aDecoder: NSCoder) {
|
||||||
|
fatalError("init(coder:) has not been implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc
|
||||||
|
public init(durationSeconds: UInt32) {
|
||||||
|
self.imageView = UIImageView(image: #imageLiteral(resourceName: "ic_timer"))
|
||||||
|
imageView.contentMode = .scaleAspectFit
|
||||||
|
|
||||||
|
self.label = UILabel()
|
||||||
|
label.text = OWSDisappearingMessagesConfiguration.string(forDurationSeconds: durationSeconds, useShortFormat: true)
|
||||||
|
label.font = UIFont.systemFont(ofSize: 10)
|
||||||
|
label.textColor = UIColor.white
|
||||||
|
label.textAlignment = .center
|
||||||
|
label.minimumScaleFactor = 0.5
|
||||||
|
|
||||||
|
super.init(frame: CGRect.zero)
|
||||||
|
|
||||||
|
applyTintColor(self.tintColor)
|
||||||
|
|
||||||
|
// Gesture, simulating button touch up inside
|
||||||
|
let gesture = UILongPressGestureRecognizer(target: self, action: #selector(pressHandler))
|
||||||
|
gesture.minimumPressDuration = 0
|
||||||
|
self.pressGesture = gesture
|
||||||
|
self.addGestureRecognizer(pressGesture)
|
||||||
|
|
||||||
|
// disable gesture recognizer until a delegate is assigned
|
||||||
|
// this lets us use the UI as either an interactive button
|
||||||
|
// or as a non-interactive status indicator
|
||||||
|
pressGesture.isEnabled = false
|
||||||
|
|
||||||
|
// Accessability
|
||||||
|
self.accessibilityLabel = NSLocalizedString("DISAPPEARING_MESSAGES_LABEL", comment: "Accessibility label for disappearing messages")
|
||||||
|
let hintFormatString = NSLocalizedString("DISAPPEARING_MESSAGES_HINT", comment: "Accessibility hint that contains current timeout information")
|
||||||
|
let durationString = OWSDisappearingMessagesConfiguration.string(forDurationSeconds: durationSeconds, useShortFormat: false)
|
||||||
|
self.accessibilityHint = String(format: hintFormatString, durationString)
|
||||||
|
|
||||||
|
// Layout
|
||||||
|
self.addSubview(imageView)
|
||||||
|
self.addSubview(label)
|
||||||
|
|
||||||
|
let kHorizontalPadding: CGFloat = 4
|
||||||
|
let kVerticalPadding: CGFloat = 6
|
||||||
|
imageView.autoPinEdgesToSuperviewEdges(with: UIEdgeInsets(top: kVerticalPadding, left: kHorizontalPadding, bottom: 0, right: kHorizontalPadding), excludingEdge: .bottom)
|
||||||
|
label.autoPinEdgesToSuperviewEdges(with: UIEdgeInsets(top: 0, left: kHorizontalPadding, bottom: kVerticalPadding, right: kHorizontalPadding), excludingEdge: .top)
|
||||||
|
label.autoPinEdge(.top, to: .bottom, of: imageView)
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc
|
||||||
|
func pressHandler(_ gestureRecognizer: UILongPressGestureRecognizer) {
|
||||||
|
Logger.verbose("\(self.logTag) in \(#function)")
|
||||||
|
|
||||||
|
// handle touch down and touch up events separately
|
||||||
|
if gestureRecognizer.state == .began {
|
||||||
|
applyTintColor(UIColor.gray)
|
||||||
|
} else if gestureRecognizer.state == .ended {
|
||||||
|
applyTintColor(self.tintColor)
|
||||||
|
|
||||||
|
let location = gestureRecognizer.location(in: self)
|
||||||
|
let isTouchUpInside = self.bounds.contains(location)
|
||||||
|
|
||||||
|
if (isTouchUpInside) {
|
||||||
|
// Similar to a UIButton's touch-up-inside
|
||||||
|
self.delegate?.disappearingTimerConfigurationViewWasTapped(self)
|
||||||
|
} else {
|
||||||
|
// Similar to a UIButton's touch-up-outside
|
||||||
|
|
||||||
|
// cancel gesture
|
||||||
|
gestureRecognizer.isEnabled = false
|
||||||
|
gestureRecognizer.isEnabled = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override public var tintColor: UIColor! {
|
||||||
|
didSet {
|
||||||
|
applyTintColor(tintColor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func applyTintColor(_ color: UIColor) {
|
||||||
|
imageView.tintColor = color
|
||||||
|
label.textColor = color
|
||||||
|
}
|
||||||
|
}
|