mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-22 22:25:57 +00:00
Invite Links Improvements
This commit is contained in:
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user