Merge commit 'dafbfe44d14038100f0b1ecb81289770bbe07f97'

This commit is contained in:
Ali 2021-02-18 17:11:05 +04:00
commit e5a467fbf6
9 changed files with 193 additions and 90 deletions

View File

@ -209,6 +209,9 @@ public final class DatePickerNode: ASDisplayNode {
started = true
}
weekday += 1
if weekday > 7 {
weekday = 1
}
let textNode = self.dateNodes[i]
if started && !ended {
@ -322,6 +325,7 @@ public final class DatePickerNode: ASDisplayNode {
self.updateState(updatedState, animated: false)
self.pickerNode.minimumDate = newValue
self.timePickerNode.minimumDate = newValue
if let size = self.validLayout {
let _ = self.updateLayout(size: size, transition: .immediate)
@ -342,6 +346,7 @@ public final class DatePickerNode: ASDisplayNode {
self.updateState(updatedState, animated: false)
self.pickerNode.maximumDate = newValue
self.timePickerNode.maximumDate = newValue
if let size = self.validLayout {
let _ = self.updateLayout(size: size, transition: .immediate)
@ -396,6 +401,9 @@ public final class DatePickerNode: ASDisplayNode {
self.pickerNode.minimumDate = self.state.minDate
self.pickerNode.maximumDate = self.state.maxDate
self.timePickerNode.minimumDate = self.state.minDate
self.timePickerNode.maximumDate = self.state.maxDate
self.monthButtonNode = HighlightTrackingButtonNode()
self.monthTextNode = ImmediateTextNode()
self.monthArrowNode = ASImageNode()
@ -921,9 +929,7 @@ private class TimeInputView: UIView, UIKeyInput {
var textUpdated: ((String) -> Void)?
override func becomeFirstResponder() -> Bool {
if self.isFirstResponder {
self.didReset = false
}
let result = super.becomeFirstResponder()
self.focusUpdated?(true)
return result
@ -937,7 +943,7 @@ private class TimeInputView: UIView, UIKeyInput {
var length: Int = 4
private var didReset = false
var didReset = false
private let nonDigits = CharacterSet.decimalDigits.inverted
func insertText(_ text: String) {
if text.rangeOfCharacter(from: nonDigits) != nil {
@ -1024,6 +1030,12 @@ private class TimeInputNode: ASDisplayNode {
view.textUpdated = self.textUpdated
}
}
func reset() {
if let view = self.view as? TimeInputView {
view.didReset = false
}
}
}
private final class TimePickerNode: ASDisplayNode {
@ -1064,8 +1076,9 @@ private final class TimePickerNode: ASDisplayNode {
}
}
}
var minDate: Date?
var maxDate: Date?
var minimumDate: Date?
var maximumDate: Date?
var valueChanged: ((Date) -> Void)?
@ -1205,23 +1218,7 @@ private final class TimePickerNode: ASDisplayNode {
}
}
self.hoursNode.selected = { [weak self] index in
guard let strongSelf = self else {
return
}
switch dateTimeFormat.timeFormat {
case .military:
let hour = index
if let date = strongSelf.date {
var components = calendar.dateComponents([.year, .month, .day, .hour, .minute], from: date)
components.hour = hour
if let newDate = calendar.date(from: components) {
strongSelf.date = newDate
strongSelf.valueChanged?(newDate)
}
}
case .regular:
break
}
self?.updateTime()
}
self.minutesNode.count = {
@ -1248,29 +1245,59 @@ private final class TimePickerNode: ASDisplayNode {
}
}
}
self.minutesNode.selected = { [weak self] index in
guard let strongSelf = self else {
return
}
switch dateTimeFormat.timeFormat {
case .military:
let minute = index
if let date = strongSelf.date {
var components = calendar.dateComponents([.year, .month, .day, .hour, .minute], from: date)
components.minute = minute
if let newDate = calendar.date(from: components) {
strongSelf.date = newDate
strongSelf.valueChanged?(newDate)
}
}
case .regular:
break
}
self.minutesNode.selected = { [weak self] _ in
self?.updateTime()
}
self.update()
}
private func updateTime() {
switch self.dateTimeFormat.timeFormat {
case .military:
let hour = self.hoursNode.currentSelectedIndex
let minute = self.minutesNode.currentSelectedIndex
let date = self.date ?? Date()
var components = calendar.dateComponents([.year, .month, .day, .hour, .minute], from: date)
components.hour = hour
components.minute = minute
if var newDate = calendar.date(from: components) {
if let minDate = self.minimumDate, newDate <= minDate {
if let nextDate = calendar.date(byAdding: .day, value: 1, to: newDate) {
newDate = nextDate
}
}
self.date = newDate
self.valueChanged?(newDate)
}
case .regular:
let hour = self.hoursNode.currentSelectedIndex
let minute = self.minutesNode.currentSelectedIndex
let date = self.date ?? Date()
var components = calendar.dateComponents([.year, .month, .day, .hour, .minute], from: date)
if self.amPMSelectorNode.selectedIndex == 0 {
components.hour = hour >= 12 ? hour - 12 : hour
} else if self.amPMSelectorNode.selectedIndex == 1 {
components.hour = hour < 12 ? hour + 12 : hour
}
components.minute = minute
if var newDate = calendar.date(from: components) {
if let minDate = self.minimumDate, newDate <= minDate {
if let nextDate = calendar.date(byAdding: .day, value: 1, to: newDate) {
newDate = nextDate
}
}
self.date = newDate
self.valueChanged?(newDate)
}
}
}
override func didLoad() {
super.didLoad()
@ -1355,6 +1382,23 @@ private final class TimePickerNode: ASDisplayNode {
private var selection: Selection {
didSet {
self.typing = false
self.inputNode.reset()
switch self.selection {
case .none:
break
case .hours:
self.inputNode.text = self.hoursNode.titleAt?(self.hoursNode.currentSelectedIndex) ?? ""
self.inputNode.length = 2
case .minutes:
self.inputNode.text = self.minutesNode.titleAt?(self.minutesNode.currentSelectedIndex) ?? ""
self.inputNode.length = 2
case .all:
let hours = self.minutesNode.titleAt?(self.hoursNode.currentSelectedIndex) ?? ""
let minutes = self.minutesNode.titleAt?(self.minutesNode.currentSelectedIndex) ?? ""
self.inputNode.text = "\(hours)\(minutes)"
self.inputNode.length = 4
}
self.update()
}
}
@ -1417,8 +1461,6 @@ private final class TimePickerNode: ASDisplayNode {
self.hoursNode.isHidden = false
self.minutesNode.isHidden = false
}
self.inputNode.length = 2
case .minutes:
colonColor = self.theme.textColor
self.colonNode.alpha = 0.35
@ -1446,8 +1488,6 @@ private final class TimePickerNode: ASDisplayNode {
self.hoursNode.isHidden = false
self.minutesNode.isHidden = false
}
self.inputNode.length = 2
case .all:
colonColor = self.theme.accentColor
self.colonNode.alpha = 1.0
@ -1475,8 +1515,6 @@ private final class TimePickerNode: ASDisplayNode {
self.hoursNode.isHidden = false
self.minutesNode.isHidden = false
}
self.inputNode.length = 4
}
if let size = self.validLayout {

View File

@ -63,7 +63,9 @@ open class TapeNode: ASDisplayNode {
return UITableView()
}()
private var infinityRowsMultiplier: Int = 1
private var infinityRowsMultiplier: Int {
return generateInfinityRowsMultiplier()
}
var currentSelectedRow: Int?
var currentSelectedIndex: Int {
@ -86,8 +88,6 @@ open class TapeNode: ASDisplayNode {
}
fileprivate func setup() {
self.infinityRowsMultiplier = self.generateInfinityRowsMultiplier()
if #available(iOS 11.0, *) {
self.tableView.contentInsetAdjustmentBehavior = .never
}
@ -162,23 +162,41 @@ open class TapeNode: ASDisplayNode {
if self.currentSelectedIndex == self.indexForRow(row) {
return
}
var finalRow = row
var finalRow = row
if row <= self.numberOfRows {
let middleMultiplier = (self.infinityRowsMultiplier / 2)
let middleMultiplier = self.infinityRowsMultiplier / 2
let middleIndex = self.numberOfRows * middleMultiplier
finalRow = middleIndex - (self.numberOfRows - finalRow)
}
self.currentSelectedRow = finalRow
if let currentSelectedRow = self.currentSelectedRow {
self.tableView.setContentOffset(CGPoint(x: 0.0, y: CGFloat(currentSelectedRow) * self.rowHeight), animated: animated)
}
}
func selectMiddleRow() {
var finalRow = self.currentSelectedIndex
let middleMultiplier = self.infinityRowsMultiplier / 2
let middleIndex = self.numberOfRows * middleMultiplier
finalRow = middleIndex - (self.numberOfRows - finalRow)
self.currentSelectedRow = finalRow
if let currentSelectedRow = self.currentSelectedRow {
self.tableView.setContentOffset(CGPoint(x: 0.0, y: CGFloat(currentSelectedRow) * self.rowHeight), animated: false)
}
}
open func reloadPickerView() {
self.tableView.reloadData()
}
private func hapticTap() {
self.hapticFeedback.impact(.light)
AudioServicesPlaySystemSound(1157)
}
}
extension TapeNode: UITableViewDataSource {
@ -248,14 +266,17 @@ extension TapeNode: UIScrollViewDelegate {
if !decelerate {
self.isScrolling = false
self.isScrollingUpdated?(false)
self.selectMiddleRow()
}
}
public func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
self.isScrolling = false
self.isScrollingUpdated?(false)
}
self.selectMiddleRow()
}
public func scrollViewDidScroll(_ scrollView: UIScrollView) {
let partialRow = Float(scrollView.contentOffset.y / self.rowHeight)
@ -264,8 +285,7 @@ extension TapeNode: UIScrollViewDelegate {
if self.previousRoundedRow != roundedRow && self.isScrolling {
self.previousRoundedRow = roundedRow
self.hapticFeedback.impact()
AudioServicesPlaySystemSound(1157)
self.hapticTap()
}
}
}

View File

@ -11,7 +11,7 @@ import AccountContext
import SolidRoundedButtonNode
import AnimatedStickerNode
private func shareQrCode(context: AccountContext, link: String) {
private func shareQrCode(context: AccountContext, link: String, view: UIView) {
let _ = (qrCode(string: link, color: .black, backgroundColor: .white, icon: .custom(UIImage(bundleImageName: "Chat/Links/QrLogo")))
|> map { _, generator -> UIImage? in
let imageSize = CGSize(width: 768.0, height: 768.0)
@ -24,6 +24,11 @@ private func shareQrCode(context: AccountContext, link: String) {
}
let activityController = UIActivityViewController(activityItems: [image], applicationActivities: nil)
if let window = view.window, let rootViewController = window.rootViewController {
activityController.popoverPresentationController?.sourceView = window
activityController.popoverPresentationController?.sourceRect = CGRect(origin: CGPoint(x: window.bounds.width / 2.0, y: window.bounds.size.height - 1.0), size: CGSize(width: 1.0, height: 1.0))
rootViewController.present(activityController, animated: true, completion: nil)
}
context.sharedContext.applicationBindings.presentNativeController(activityController)
})
}
@ -253,7 +258,7 @@ public final class InviteLinkQRCodeController: ViewController {
self.cancelButton.addTarget(self, action: #selector(self.cancelButtonPressed), forControlEvents: .touchUpInside)
self.buttonNode.pressed = { [weak self] in
if let strongSelf = self{
shareQrCode(context: strongSelf.context, link: strongSelf.invite.link)
shareQrCode(context: strongSelf.context, link: strongSelf.invite.link, view: strongSelf.view)
}
}
@ -285,7 +290,7 @@ public final class InviteLinkQRCodeController: ViewController {
}
@objc private func qrPressed() {
shareQrCode(context: self.context, link: self.invite.link)
shareQrCode(context: self.context, link: self.invite.link, view: self.view)
}
func updatePresentationData(_ presentationData: PresentationData) {

View File

@ -230,7 +230,7 @@ static void setViewFrame(UIView *view, CGRect frame)
if (_inputField.internalTextView.isFirstResponder)
[TGHacks applyCurrentKeyboardAutocorrectionVariant];
NSMutableAttributedString *text = [[NSMutableAttributedString alloc] initWithAttributedString:_inputField.text == nil ? [[NSAttributedString alloc] initWithString:@""] : _inputField.attributedText]; //[[NSMutableAttributedString alloc] initWithString:_inputField.text == nil ? @"" : _inputField.text];
NSMutableAttributedString *text = [[NSMutableAttributedString alloc] initWithAttributedString:_inputField.text == nil ? [[NSAttributedString alloc] initWithString:@""] : _inputField.attributedText];
NSMutableString *usualString = [text.string mutableCopy];
int textLength = (int)text.length;
for (int i = 0; i < textLength; i++)
@ -248,20 +248,6 @@ static void setViewFrame(UIView *view, CGRect frame)
break;
}
for (int i = textLength - 1; i >= 0; i--)
{
unichar c = [usualString characterAtIndex:i];
if (c == ' ' || c == '\t' || c == '\n')
{
[text deleteCharactersInRange:NSMakeRange(i, 1)];
[usualString deleteCharactersInRange:NSMakeRange(i, 1)];
textLength--;
}
else
break;
}
_inputField.internalTextView.attributedText = text;
__autoreleasing NSArray *entities = nil;

View File

@ -3,6 +3,6 @@
@interface TGPhotoEditorHUDView : UIView
- (void)setText:(NSString *)text;
- (void)setAttributedText:(NSAttributedString *)text;
- (void)setTitle:(NSString *)title value:(NSString *)value;
@end

View File

@ -9,6 +9,7 @@
{
UIImageView *_backgroundView;
UILabel *_label;
UILabel *_valueLabel;
}
@end
@ -41,12 +42,37 @@
_backgroundView.image = background;
[self addSubview:_backgroundView];
UIFont *font;
if (iosMajorVersion() >= 13) {
UIFontDescriptor *fontDescriptor = [UIFont systemFontOfSize:14.0f weight:UIFontWeightMedium].fontDescriptor;
NSArray *monospacedSetting = @[@{UIFontFeatureTypeIdentifierKey: @(kNumberSpacingType),
UIFontFeatureSelectorIdentifierKey: @(kMonospacedNumbersSelector)}];
UIFontDescriptor *updatedDescriptor = [fontDescriptor fontDescriptorByAddingAttributes:@{
UIFontDescriptorFeatureSettingsAttribute: monospacedSetting
}];
if (updatedDescriptor != nil) {
font = [UIFont fontWithDescriptor:updatedDescriptor size:14.0];
} else {
font = [UIFont systemFontOfSize:14];
}
} else {
font = [UIFont systemFontOfSize:14];
}
_label = [[UILabel alloc] initWithFrame:CGRectZero];
_label.backgroundColor = [UIColor clearColor];
_label.font = TGSystemFontOfSize(14);
_label.textAlignment = NSTextAlignmentCenter;
_label.font = [UIFont systemFontOfSize:14];
_label.textAlignment = NSTextAlignmentLeft;
_label.textColor = [UIColor whiteColor];
[_backgroundView addSubview:_label];
_valueLabel = [[UILabel alloc] initWithFrame:CGRectZero];
_valueLabel.backgroundColor = [UIColor clearColor];
_valueLabel.font = font;
_valueLabel.textAlignment = NSTextAlignmentRight;
_valueLabel.textColor = [TGPhotoEditorInterfaceAssets accentColor];
[_backgroundView addSubview:_valueLabel];
}
return self;
}
@ -62,22 +88,27 @@
_label.text = text;
[_label sizeToFit];
_valueLabel.hidden = true;
[self setNeedsLayout];
[self setHidden:false animated:true];
}
- (void)setAttributedText:(NSAttributedString *)text
- (void)setTitle:(NSString *)title value:(NSString *)value
{
if (text.length == 0)
if (title.length == 0)
{
[self setHidden:true animated:true];
return;
}
_label.attributedText = text;
_label.text = title;
[_label sizeToFit];
_valueLabel.text = value;
[_valueLabel sizeToFit];
[self setNeedsLayout];
[self setHidden:false animated:true];
@ -104,7 +135,15 @@
_label.frame = CGRectMake(padding, 6.0f, CGCeil(_label.frame.size.width), CGCeil(_label.frame.size.height));
CGFloat width = _label.frame.size.width + 2.0f * padding;
CGFloat width;
if (_valueLabel.isHidden) {
width = _label.frame.size.width + 2.0f * padding;
} else {
width = 2.0f * padding + _label.frame.size.width + 50.0f + 3.0f;
}
_valueLabel.frame = CGRectMake(width - padding - 50.0f, 6.0f, 50.0f, CGCeil(_valueLabel.frame.size.height));
_backgroundView.frame = CGRectMake((self.frame.size.width - width) / 2, 15, width, 30);
}

View File

@ -336,9 +336,7 @@ const CGFloat TGPhotoEditorToolsLandscapePanelSize = TGPhotoEditorToolsPanelSize
return;
}
NSMutableAttributedString *text = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"%@ %@", tool.title, [tool stringValue:true]] attributes:@{NSFontAttributeName: TGMediumSystemFontOfSize(14.0f), NSForegroundColorAttributeName: [TGPhotoEditorInterfaceAssets accentColor]}];
[text addAttributes:@{NSFontAttributeName: TGSystemFontOfSize(14.0f), NSForegroundColorAttributeName: [UIColor whiteColor]} range:NSMakeRange(0, tool.title.length)];
[_hudView setAttributedText:text];
[_hudView setTitle:tool.title value:[tool stringValue:true]];
}
#pragma mark - Transition

View File

@ -78,7 +78,7 @@ final class RecentSessionsEmptyStateItemNode: ItemListControllerEmptyStateItemNo
override func updateLayout(layout: ContainerViewLayout, navigationBarHeight: CGFloat, transition: ContainedViewLayoutTransition) {
self.validLayout = (layout, navigationBarHeight)
var insets = layout.insets(options: [])
insets.top += navigationBarHeight + 128.0
insets.top += navigationBarHeight + 200.0
let imageSpacing: CGFloat = 8.0
let textSpacing: CGFloat = 8.0
@ -86,15 +86,32 @@ final class RecentSessionsEmptyStateItemNode: ItemListControllerEmptyStateItemNo
let imageSize = self.imageNode.image?.size ?? CGSize()
let imageHeight = layout.size.width < layout.size.height ? imageSize.height + imageSpacing : 0.0
var textVisible = true
if layout.size.width == 320 {
textVisible = false
}
self.backgroundColor = .red
let titleSize = self.titleNode.measure(CGSize(width: layout.size.width - layout.safeInsets.left - layout.safeInsets.right - layout.intrinsicInsets.left - layout.intrinsicInsets.right - 50.0, height: max(1.0, layout.size.height - insets.top - insets.bottom)))
let textSize = self.textNode.measure(CGSize(width: layout.size.width - layout.safeInsets.left - layout.safeInsets.right - layout.intrinsicInsets.left - layout.intrinsicInsets.right - 50.0, height: max(1.0, layout.size.height - insets.top - insets.bottom)))
let totalHeight = imageHeight + titleSize.height + textSpacing + textSize.height
var totalHeight = imageHeight + titleSize.height
if textVisible {
totalHeight += textSpacing + textSize.height
}
let topOffset = insets.top + floor((layout.size.height - insets.top - insets.bottom - totalHeight) / 2.0)
transition.updateAlpha(node: self.imageNode, alpha: imageHeight > 0.0 ? 1.0 : 0.0)
var visible = true
if case .compact = layout.metrics.widthClass, layout.size.width > layout.size.height {
visible = false
}
transition.updateAlpha(node: self.imageNode, alpha: visible ? 1.0 : 0.0)
transition.updateAlpha(node: self.titleNode, alpha: visible ? 1.0 : 0.0)
transition.updateAlpha(node: self.textNode, alpha: visible && textVisible ? 1.0 : 0.0)
transition.updateFrame(node: self.imageNode, frame: CGRect(origin: CGPoint(x: floor((layout.size.width - imageSize.width) / 2.0), y: topOffset), size: imageSize))
transition.updateFrame(node: self.titleNode, frame: CGRect(origin: CGPoint(x: floor((layout.size.width - titleSize.width - layout.safeInsets.left - layout.safeInsets.right - layout.intrinsicInsets.left - layout.intrinsicInsets.right) / 2.0), y: topOffset + imageHeight), size: titleSize))
transition.updateFrame(node: self.textNode, frame: CGRect(origin: CGPoint(x: floor((layout.size.width - textSize.width - layout.safeInsets.left - layout.safeInsets.right - layout.intrinsicInsets.left - layout.intrinsicInsets.right) / 2.0), y: self.titleNode.frame.maxY + textSpacing), size: textSize))
transition.updateFrame(node: self.titleNode, frame: CGRect(origin: CGPoint(x: floor((layout.size.width - titleSize.width) / 2.0), y: topOffset + imageHeight), size: titleSize))
transition.updateFrame(node: self.textNode, frame: CGRect(origin: CGPoint(x: floor((layout.size.width - textSize.width) / 2.0), y: self.titleNode.frame.maxY + textSpacing), size: textSize))
}
}

View File

@ -1337,7 +1337,7 @@ private func editingItems(data: PeerInfoScreenData?, context: AccountContext, pr
}))
}
if (isCreator || (channel.adminRights != nil && channel.hasPermission(.pinMessages))) && cachedData.peerGeoLocation != nil {
if (isCreator || (channel.adminRights != nil && channel.hasPermission(.pinMessages))) && cachedData.peerGeoLocation == nil {
if cachedData.flags.contains(.canChangeUsername) {
if let linkedDiscussionPeer = data.linkedDiscussionPeer {
let peerTitle: String