Invite Links Improvements

This commit is contained in:
Ilya Laktyushin
2021-02-10 18:21:59 +04:00
1990 changed files with 487093 additions and 5876 deletions

View File

@@ -15,8 +15,9 @@ public final class DatePickerTheme: Equatable {
public let selectionColor: UIColor
public let selectionTextColor: UIColor
public let separatorColor: UIColor
public let segmentedControlTheme: SegmentedControlTheme
public init(backgroundColor: UIColor, textColor: UIColor, secondaryTextColor: UIColor, accentColor: UIColor, disabledColor: UIColor, selectionColor: UIColor, selectionTextColor: UIColor, separatorColor: UIColor) {
public init(backgroundColor: UIColor, textColor: UIColor, secondaryTextColor: UIColor, accentColor: UIColor, disabledColor: UIColor, selectionColor: UIColor, selectionTextColor: UIColor, separatorColor: UIColor, segmentedControlTheme: SegmentedControlTheme) {
self.backgroundColor = backgroundColor
self.textColor = textColor
self.secondaryTextColor = secondaryTextColor
@@ -25,6 +26,7 @@ public final class DatePickerTheme: Equatable {
self.selectionColor = selectionColor
self.selectionTextColor = selectionTextColor
self.separatorColor = separatorColor
self.segmentedControlTheme = segmentedControlTheme
}
public static func ==(lhs: DatePickerTheme, rhs: DatePickerTheme) -> Bool {
@@ -55,7 +57,7 @@ public final class DatePickerTheme: Equatable {
public extension DatePickerTheme {
convenience init(theme: PresentationTheme) {
self.init(backgroundColor: theme.list.itemBlocksBackgroundColor, textColor: theme.list.itemPrimaryTextColor, secondaryTextColor: theme.list.itemSecondaryTextColor, accentColor: theme.list.itemAccentColor, disabledColor: theme.list.itemDisabledTextColor, selectionColor: theme.list.itemCheckColors.fillColor, selectionTextColor: theme.list.itemCheckColors.foregroundColor, separatorColor: theme.list.itemBlocksSeparatorColor)
self.init(backgroundColor: theme.list.itemBlocksBackgroundColor, textColor: theme.list.itemPrimaryTextColor, secondaryTextColor: theme.list.itemSecondaryTextColor, accentColor: theme.list.itemAccentColor, disabledColor: theme.list.itemDisabledTextColor, selectionColor: theme.list.itemCheckColors.fillColor, selectionTextColor: theme.list.itemCheckColors.foregroundColor, separatorColor: theme.list.itemBlocksSeparatorColor, segmentedControlTheme: SegmentedControlTheme(theme: theme))
}
}
@@ -278,7 +280,7 @@ public final class DatePickerNode: ASDisplayNode {
private let strings: PresentationStrings
private let timeTitleNode: ImmediateTextNode
private let timeFieldNode: ASImageNode
private let timePickerNode: TimePickerNode
private let timeSeparatorNode: ASDisplayNode
private let dayNodes: [ImmediateTextNode]
@@ -357,7 +359,7 @@ public final class DatePickerNode: ASDisplayNode {
}
}
public init(theme: DatePickerTheme, strings: PresentationStrings) {
public init(theme: DatePickerTheme, strings: PresentationStrings, dateTimeFormat: PresentationDateTimeFormat) {
self.theme = theme
self.strings = strings
self.state = State(minDate: telegramReleaseDate, maxDate: upperLimitDate, date: Date(), displayingMonthSelection: false, selectedMonth: monthForDate(Date()))
@@ -365,9 +367,7 @@ public final class DatePickerNode: ASDisplayNode {
self.timeTitleNode = ImmediateTextNode()
self.timeTitleNode.attributedText = NSAttributedString(string: "Time", font: Font.regular(17.0), textColor: theme.textColor)
self.timeFieldNode = ASImageNode()
self.timeFieldNode.displaysAsynchronously = false
self.timeFieldNode.displayWithoutProcessing = true
self.timePickerNode = TimePickerNode(theme: theme, dateTimeFormat: dateTimeFormat, date: self.state.date)
self.timeSeparatorNode = ASDisplayNode()
self.timeSeparatorNode.backgroundColor = theme.separatorColor
@@ -403,7 +403,7 @@ public final class DatePickerNode: ASDisplayNode {
self.backgroundColor = theme.backgroundColor
self.addSubnode(self.timeTitleNode)
self.addSubnode(self.timeFieldNode)
self.addSubnode(self.timePickerNode)
self.addSubnode(self.contentNode)
@@ -421,7 +421,9 @@ public final class DatePickerNode: ASDisplayNode {
self.monthArrowNode.image = generateSmallArrowImage(color: theme.accentColor)
self.previousButtonNode.setImage(generateNavigationArrowImage(color: theme.accentColor, mirror: true), for: .normal)
self.previousButtonNode.setImage(generateNavigationArrowImage(color: theme.disabledColor, mirror: true), for: .disabled)
self.nextButtonNode.setImage(generateNavigationArrowImage(color: theme.accentColor, mirror: false), for: .normal)
self.nextButtonNode.setImage(generateNavigationArrowImage(color: theme.disabledColor, mirror: false), for: .disabled)
self.setupItems()
@@ -445,6 +447,15 @@ public final class DatePickerNode: ASDisplayNode {
self.previousButtonNode.addTarget(self, action: #selector(self.previousButtonPressed), forControlEvents: .touchUpInside)
self.nextButtonNode.addTarget(self, action: #selector(self.nextButtonPressed), forControlEvents: .touchUpInside)
self.timePickerNode.valueChanged = { [weak self] date in
if let strongSelf = self {
let updatedState = State(minDate: strongSelf.state.minDate, maxDate: strongSelf.state.maxDate, date: date, displayingMonthSelection: strongSelf.state.displayingMonthSelection, selectedMonth: strongSelf.state.selectedMonth)
strongSelf.updateState(updatedState, animated: false)
strongSelf.valueUpdated?(date)
}
}
monthChangedImpl = { [weak self] date in
if let strongSelf = self {
let updatedState = State(minDate: strongSelf.state.minDate, maxDate: strongSelf.state.maxDate, date: date, displayingMonthSelection: strongSelf.state.displayingMonthSelection, selectedMonth: monthForDate(date))
@@ -523,7 +534,7 @@ public final class DatePickerNode: ASDisplayNode {
return
}
self.theme = theme
self.backgroundColor = self.theme.backgroundColor
self.monthArrowNode.image = generateSmallArrowImage(color: theme.accentColor)
self.previousButtonNode.setImage(generateNavigationArrowImage(color: theme.accentColor, mirror: true), for: .normal)
@@ -668,9 +679,12 @@ public final class DatePickerNode: ASDisplayNode {
let timeTitleSize = self.timeTitleNode.updateLayout(size)
self.timeTitleNode.frame = CGRect(origin: CGPoint(x: 16.0, y: 14.0), size: timeTitleSize)
let timePickerSize = self.timePickerNode.updateLayout(size: size)
self.timePickerNode.frame = CGRect(origin: CGPoint(x: size.width - timePickerSize.width - 16.0, y: 6.0), size: timePickerSize)
self.timeSeparatorNode.frame = CGRect(x: 16.0, y: timeHeight, width: size.width - 16.0, height: UIScreenPixel)
self.monthTextNode.attributedText = NSAttributedString(string: stringForMonth(strings: self.strings, month: components.month.flatMap { Int32($0) - 1 } ?? 0, ofYear: components.year.flatMap { Int32($0) - 1900 } ?? 100), font: controlFont, textColor: theme.textColor)
self.monthTextNode.attributedText = NSAttributedString(string: stringForMonth(strings: self.strings, month: components.month.flatMap { Int32($0) - 1 } ?? 0, ofYear: components.year.flatMap { Int32($0) - 1900 } ?? 100), font: controlFont, textColor: self.state.displayingMonthSelection ? self.theme.accentColor : self.theme.textColor)
let monthSize = self.monthTextNode.updateLayout(size)
let monthTextFrame = CGRect(x: sideInset, y: 11.0 + timeHeight, width: monthSize.width, height: monthSize.height)
@@ -684,7 +698,9 @@ public final class DatePickerNode: ASDisplayNode {
self.monthButtonNode.frame = monthTextFrame.inset(by: UIEdgeInsets(top: -6.0, left: -6.0, bottom: -6.0, right: -30.0))
self.previousButtonNode.isEnabled = self.currentIndex > 0
self.previousButtonNode.frame = CGRect(x: size.width - sideInset - 54.0, y: monthTextFrame.minY + 1.0, width: 10.0, height: 17.0)
self.nextButtonNode.isEnabled = self.currentIndex < self.months.count - 1
self.nextButtonNode.frame = CGRect(x: size.width - sideInset - 13.0, y: monthTextFrame.minY + 1.0, width: 10.0, height: 17.0)
let daysSideInset: CGFloat = 12.0
@@ -752,6 +768,9 @@ private final class MonthPickerNode: ASDisplayNode, UIPickerViewDelegate, UIPick
}
}
var minDate: Date?
var maxDate: Date?
private let valueChanged: (Date) -> Void
private let pickerView: UIPickerView
@@ -840,3 +859,85 @@ private final class MonthPickerNode: ASDisplayNode, UIPickerViewDelegate, UIPick
self.pickerView.frame = CGRect(origin: CGPoint(), size: CGSize(width: self.bounds.size.width, height: 180.0))
}
}
private final class TimePickerNode: ASDisplayNode {
private var theme: DatePickerTheme
private let dateTimeFormat: PresentationDateTimeFormat
private let backgroundNode: ASDisplayNode
private let textNode: ImmediateTextNode
private let amPMSelectorNode: SegmentedControlNode
var date: Date
var minDate: Date?
var maxDate: Date?
var valueChanged: ((Date) -> Void)?
init(theme: DatePickerTheme, dateTimeFormat: PresentationDateTimeFormat, date: Date) {
self.theme = theme
self.dateTimeFormat = dateTimeFormat
self.date = date
self.backgroundNode = ASDisplayNode()
self.backgroundNode.backgroundColor = theme.segmentedControlTheme.backgroundColor
self.backgroundNode.cornerRadius = 9.0
self.textNode = ImmediateTextNode()
let hours = calendar.component(.hour, from: date)
self.amPMSelectorNode = SegmentedControlNode(theme: theme.segmentedControlTheme, items: [SegmentedControlItem(title: "AM"), SegmentedControlItem(title: "PM")], selectedIndex: hours > 12 ? 1 : 0)
super.init()
self.addSubnode(self.backgroundNode)
self.addSubnode(self.textNode)
self.addSubnode(self.amPMSelectorNode)
self.amPMSelectorNode.selectedIndexChanged = { index in
let hours = calendar.component(.hour, from: date)
var components = calendar.dateComponents([.year, .month, .day, .hour, .minute], from: self.date)
if index == 0 && hours >= 12 {
components.hour = hours - 12
} else if index == 1 && hours < 12 {
components.hour = hours + 12
}
if let newDate = calendar.date(from: components) {
self.valueChanged?(newDate)
}
}
}
func updateTheme(_ theme: DatePickerTheme) {
self.theme = theme
self.backgroundNode.backgroundColor = theme.segmentedControlTheme.backgroundColor
}
func updateLayout(size: CGSize) -> CGSize {
self.backgroundNode.frame = CGRect(x: 0.0, y: 0.0, width: 75.0, height: 36.0)
var contentSize = CGSize()
let hours = Int32(calendar.component(.hour, from: self.date))
let minutes = Int32(calendar.component(.hour, from: self.date))
let string = stringForShortTimestamp(hours: hours, minutes: minutes, dateTimeFormat: self.dateTimeFormat).replacingOccurrences(of: " AM", with: "").replacingOccurrences(of: " PM", with: "")
self.textNode.attributedText = NSAttributedString(string: string, font: Font.with(size: 21.0, design: .monospace, weight: .regular, traits: []), textColor: self.theme.textColor)
let textSize = self.textNode.updateLayout(size)
self.textNode.frame = CGRect(origin: CGPoint(x: floorToScreenPixels((self.backgroundNode.frame.width - textSize.width) / 2.0), y: floorToScreenPixels((self.backgroundNode.frame.height - textSize.height) / 2.0)), size: textSize)
if self.dateTimeFormat.timeFormat == .military {
contentSize = self.backgroundNode.frame.size
self.amPMSelectorNode.isHidden = true
} else {
self.amPMSelectorNode.isHidden = false
let segmentedSize = self.amPMSelectorNode.updateLayout(.sizeToFit(maximumWidth: 120.0, minimumWidth: 80.0, height: 36.0), transition: .immediate)
self.amPMSelectorNode.frame = CGRect(x: 85.0, y: 0.0, width: segmentedSize.width, height: 36.0)
contentSize = CGSize(width: 85.0 + segmentedSize.width, height: 36.0)
}
return contentSize
}
}