diff --git a/submodules/DateSelectionUI/Sources/DateSelectionActionSheetController.swift b/submodules/DateSelectionUI/Sources/DateSelectionActionSheetController.swift index 81ebef320a..b11e3572ca 100644 --- a/submodules/DateSelectionUI/Sources/DateSelectionActionSheetController.swift +++ b/submodules/DateSelectionUI/Sources/DateSelectionActionSheetController.swift @@ -105,6 +105,8 @@ private final class DateSelectionActionSheetItemNode: ActionSheetItemNode { self.pickerView = UIDatePicker() self.pickerView.timeZone = TimeZone(secondsFromGMT: 0) + self.pickerView.setValue(theme.primaryTextColor, forKey: "textColor") + self.pickerView.datePickerMode = .countDownTimer self.pickerView.datePickerMode = .date self.pickerView.date = Date(timeIntervalSince1970: Double(roundDateToDays(currentValue))) self.pickerView.locale = localeWithStrings(strings) @@ -117,8 +119,6 @@ private final class DateSelectionActionSheetItemNode: ActionSheetItemNode { self.pickerView.maximumDate = Date(timeIntervalSince1970: Double(Int32.max - 1)) } - self.pickerView.setValue(theme.primaryTextColor, forKey: "textColor") - super.init(theme: theme) self.view.addSubview(self.pickerView) diff --git a/submodules/LegacyComponents/LegacyComponents/TGIconSwitchView.m b/submodules/LegacyComponents/LegacyComponents/TGIconSwitchView.m index b5617cbf67..677863d286 100644 --- a/submodules/LegacyComponents/LegacyComponents/TGIconSwitchView.m +++ b/submodules/LegacyComponents/LegacyComponents/TGIconSwitchView.m @@ -48,6 +48,11 @@ static const void *positionChangedKey = &positionChangedKey; self.backgroundColor = [UIColor redColor]; self.tintColor = [UIColor redColor]; UIView *handleView = self.subviews[0].subviews.lastObject; + if (iosMajorVersion() >= 13) { + handleView = self.subviews[0].subviews[1].subviews.lastObject; + } else { + handleView = self.subviews[0].subviews.lastObject; + } static Class subclass; static dispatch_once_t onceToken; diff --git a/submodules/PeerInfoUI/Sources/PeerBanTimeoutController.swift b/submodules/PeerInfoUI/Sources/PeerBanTimeoutController.swift index d91a961fd7..e0dfa93163 100644 --- a/submodules/PeerInfoUI/Sources/PeerBanTimeoutController.swift +++ b/submodules/PeerInfoUI/Sources/PeerBanTimeoutController.swift @@ -94,14 +94,14 @@ private final class PeerBanTimeoutActionSheetItemNode: ActionSheetItemNode { self.valueChanged = valueChanged self.pickerView = UIDatePicker() + self.pickerView.setValue(theme.primaryTextColor, forKey: "textColor") + self.pickerView.datePickerMode = .countDownTimer self.pickerView.datePickerMode = .date self.pickerView.date = Date(timeIntervalSince1970: Double(roundDateToDays(currentValue))) self.pickerView.locale = localeWithStrings(strings) self.pickerView.minimumDate = Date() self.pickerView.maximumDate = Date(timeIntervalSince1970: Double(Int32.max - 1)) - self.pickerView.setValue(theme.primaryTextColor, forKey: "textColor") - super.init(theme: theme) self.view.addSubview(self.pickerView) diff --git a/submodules/QrCode/Sources/QrCode.swift b/submodules/QrCode/Sources/QrCode.swift index 6916f5c9cf..44c53e7c60 100644 --- a/submodules/QrCode/Sources/QrCode.swift +++ b/submodules/QrCode/Sources/QrCode.swift @@ -12,7 +12,33 @@ public enum QrCodeIcon { case custom(UIImage?) } -public func qrCode(string: String, color: UIColor, backgroundColor: UIColor? = nil, icon: QrCodeIcon, ecl: String = "M") -> Signal<(TransformImageArguments) -> DrawingContext?, NoError> { +private func floorToContextPixels(_ value: CGFloat, scale: CGFloat? = UIScreenScale) -> CGFloat { + var scale = scale ?? UIScreenScale + return floor(value * scale) / scale +} + +private func roundToContextPixels(_ value: CGFloat, scale: CGFloat? = UIScreenScale) -> CGFloat { + var scale = scale ?? UIScreenScale + return round(value * scale) / scale +} + +public func qrCodeCutout(size: Int, dimensions: CGSize, scale: CGFloat?) -> (Int, CGRect, CGFloat) { + var cutoutSize = Int(round(CGFloat(size) * 0.297)) + if size == 39 { + cutoutSize = 11 + } else if cutoutSize % 2 == 0 { + cutoutSize += 1 + } + cutoutSize = min(23, cutoutSize) + + let quadSize = floorToContextPixels(dimensions.width / CGFloat(size), scale: scale) + let cutoutSide = quadSize * CGFloat(cutoutSize - 2) + let cutoutRect = CGRect(x: floorToContextPixels((dimensions.width - cutoutSide) / 2.0, scale: scale), y: floorToContextPixels((dimensions.height - cutoutSide) / 2.0, scale: scale), width: cutoutSide, height: cutoutSide) + + return (cutoutSize, cutoutRect, quadSize) +} + +public func qrCode(string: String, color: UIColor, backgroundColor: UIColor? = nil, icon: QrCodeIcon, ecl: String = "M") -> Signal<(Int, (TransformImageArguments) -> DrawingContext?), NoError> { return Signal<(Data, Int, Int), NoError> { subscriber in if let data = string.data(using: .isoLatin1, allowLossyConversion: false), let filter = CIFilter(name: "CIQRCodeGenerator") { filter.setValue(data, forKey: "inputMessage") @@ -43,29 +69,20 @@ public func qrCode(string: String, color: UIColor, backgroundColor: UIColor? = n return EmptyDisposable } |> map { data, size, bytesPerRow in - return { arguments in + return (size, { arguments in let context = DrawingContext(size: arguments.drawingSize, scale: arguments.scale ?? 0.0, clear: true) - let side = floorToScreenPixels(arguments.drawingSize.width / CGFloat(size)) - let padding: CGFloat = floor((arguments.drawingSize.width - CGFloat(side * CGFloat(size))) / 2.0) - + let drawingRect = arguments.drawingRect let fittedSize = arguments.imageSize.aspectFilled(arguments.boundingSize).fitted(arguments.imageSize) let fittedRect = CGRect(origin: CGPoint(x: drawingRect.origin.x + (drawingRect.size.width - fittedSize.width) / 2.0, y: drawingRect.origin.y + (drawingRect.size.height - fittedSize.height) / 2.0), size: fittedSize) - - let codeScale: CGFloat = 1.10256 - let clipSide = fittedRect.width * 0.23124 - let clipRect = CGRect(x: fittedRect.midX - clipSide / 2.0, y: fittedRect.midY - clipSide / 2.0, width: clipSide, height: clipSide) + + let (cutoutSize, clipRect, side) = qrCodeCutout(size: size, dimensions: fittedSize, scale: arguments.scale) + let padding: CGFloat = roundToContextPixels((arguments.drawingSize.width - CGFloat(side * CGFloat(size))) / 2.0, scale: arguments.scale) let cutout: (Int, Int)? if case .none = icon { cutout = nil } else { - var cutoutSize = Int(ceil((clipSide + side * 2.0) / side)) - if size == 39 { - cutoutSize = 11 - } else if cutoutSize % 2 == 0 { - cutoutSize += 1 - } let start = (size - cutoutSize) / 2 cutout = (start, start + cutoutSize - 1) } @@ -211,7 +228,7 @@ public func qrCode(string: String, color: UIColor, backgroundColor: UIColor? = n c.setStrokeColor(color.cgColor) c.setFillColor(color.cgColor) - let markerSide = floorToScreenPixels(CGFloat(markerSize - 1) * squareSize.width * 1.05) + let markerSide = floorToContextPixels(CGFloat(markerSize - 1) * squareSize.width * 1.05, scale: arguments.scale) func drawMarker(x: CGFloat, y: CGFloat) { var path = UIBezierPath(roundedRect: CGRect(x: x + squareSize.width / 2.0, y: y + squareSize.width / 2.0, width: markerSide, height: markerSide), cornerRadius: markerSide / 3.5) @@ -233,7 +250,7 @@ public func qrCode(string: String, color: UIColor, backgroundColor: UIColor? = n switch icon { case .proxy: - let iconScale = fittedRect.width / 420.0 * codeScale + let iconScale = clipRect.size.width * 0.01111 let iconSize = CGSize(width: 65.0 * iconScale, height: 79.0 * iconScale) let point = CGPoint(x: fittedRect.midX - iconSize.width / 2.0, y: fittedRect.midY - iconSize.height / 2.0) c.translateBy(x: point.x, y: point.y) @@ -268,6 +285,6 @@ public func qrCode(string: String, color: UIColor, backgroundColor: UIColor? = n } return context - } + }) } } diff --git a/submodules/SettingsUI/Sources/Data and Storage/ShareProxyServerActionSheetController.swift b/submodules/SettingsUI/Sources/Data and Storage/ShareProxyServerActionSheetController.swift index f5ba2a4277..e05db4b554 100644 --- a/submodules/SettingsUI/Sources/Data and Storage/ShareProxyServerActionSheetController.swift +++ b/submodules/SettingsUI/Sources/Data and Storage/ShareProxyServerActionSheetController.swift @@ -41,8 +41,8 @@ public final class ShareProxyServerActionSheetController: ActionSheetController items.append(ActionSheetButtonItem(title: strings.SocksProxySetup_ShareQRCode, action: { [weak self] in self?.dismissAnimated() let _ = (qrCode(string: link, color: .black, backgroundColor: .white, icon: .proxy) - |> map { generator -> UIImage? in - let imageSize = CGSize(width: 512.0, height: 512.0) + |> map { _, generator -> UIImage? in + let imageSize = CGSize(width: 768.0, height: 768.0) let context = generator(TransformImageArguments(corners: ImageCorners(), imageSize: imageSize, boundingSize: imageSize, intrinsicInsets: UIEdgeInsets(), scale: 1.0)) return context?.generateImage() } @@ -128,8 +128,10 @@ private final class ProxyServerQRCodeItemNode: ActionSheetItemNode { self.label.attributedText = NSAttributedString(string: strings.SocksProxySetup_ShareQRCodeInfo, font: ActionSheetTextNode.defaultFont, textColor: self.theme.secondaryTextColor, paragraphAlignment: .center) self.imageNode = TransformImageNode() - self.imageNode.setSignal(qrCode(string: link, color: .black, backgroundColor: .white, icon: .proxy), attemptSynchronously: true) - + self.imageNode.clipsToBounds = true + self.imageNode.setSignal(qrCode(string: link, color: .black, backgroundColor: .white, icon: .proxy) |> map { $0.1 }, attemptSynchronously: true) + self.imageNode.cornerRadius = 14.0 + super.init(theme: theme) self.addSubnode(self.label) diff --git a/submodules/SettingsUI/Sources/Themes/ThemeAutoNightSettingsController.swift b/submodules/SettingsUI/Sources/Themes/ThemeAutoNightSettingsController.swift index fb6f6caafc..aa52f61314 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemeAutoNightSettingsController.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemeAutoNightSettingsController.swift @@ -245,7 +245,7 @@ private enum ThemeAutoNightSettingsControllerEntry: ItemListNodeEntry { case let .themeHeader(theme, title): return ItemListSectionHeaderItem(theme: theme, text: title, sectionId: self.section) case let .themeItem(theme, strings, themes, currentTheme, themeSpecificAccentColors): - return ThemeSettingsThemeItem(context: arguments.context, theme: theme, strings: strings, sectionId: self.section, themes: themes, themeSpecificAccentColors: themeSpecificAccentColors, currentTheme: currentTheme, updatedTheme: { theme in + return ThemeSettingsThemeItem(context: arguments.context, theme: theme, strings: strings, sectionId: self.section, themes: themes, displayUnsupported: false, themeSpecificAccentColors: themeSpecificAccentColors, currentTheme: currentTheme, updatedTheme: { theme in arguments.updateTheme(theme) }, contextAction: nil) } diff --git a/submodules/SettingsUI/Sources/Themes/ThemeAutoNightTimeSelectionActionSheet.swift b/submodules/SettingsUI/Sources/Themes/ThemeAutoNightTimeSelectionActionSheet.swift index 42516f575c..0b98f3a872 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemeAutoNightTimeSelectionActionSheet.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemeAutoNightTimeSelectionActionSheet.swift @@ -99,13 +99,13 @@ private final class ThemeAutoNightTimeSelectionActionSheetItemNode: ActionSheetI self.valueChanged = valueChanged self.pickerView = UIDatePicker() + self.pickerView.setValue(theme.primaryTextColor, forKey: "textColor") + self.pickerView.datePickerMode = .countDownTimer self.pickerView.datePickerMode = .time self.pickerView.timeZone = TimeZone(secondsFromGMT: 0) self.pickerView.date = Date(timeIntervalSince1970: Double(currentValue)) self.pickerView.locale = Locale.current - self.pickerView.setValue(theme.primaryTextColor, forKey: "textColor") - super.init(theme: theme) self.view.addSubview(self.pickerView) diff --git a/submodules/SettingsUI/Sources/Themes/ThemeSettingsController.swift b/submodules/SettingsUI/Sources/Themes/ThemeSettingsController.swift index 90ecb2ab68..099ade5053 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemeSettingsController.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemeSettingsController.swift @@ -319,7 +319,7 @@ private enum ThemeSettingsControllerEntry: ItemListNodeEntry { case let .themeListHeader(theme, text): return ItemListSectionHeaderItem(theme: theme, text: text, sectionId: self.section) case let .themeItem(theme, strings, themes, currentTheme, themeSpecificAccentColors, _): - return ThemeSettingsThemeItem(context: arguments.context, theme: theme, strings: strings, sectionId: self.section, themes: themes, themeSpecificAccentColors: themeSpecificAccentColors, currentTheme: currentTheme, updatedTheme: { theme in + return ThemeSettingsThemeItem(context: arguments.context, theme: theme, strings: strings, sectionId: self.section, themes: themes, displayUnsupported: true, themeSpecificAccentColors: themeSpecificAccentColors, currentTheme: currentTheme, updatedTheme: { theme in if case let .cloud(theme) = theme, theme.theme.file == nil { if theme.theme.isCreator { arguments.editTheme(theme) diff --git a/submodules/SettingsUI/Sources/Themes/ThemeSettingsThemeItem.swift b/submodules/SettingsUI/Sources/Themes/ThemeSettingsThemeItem.swift index 6f86183c20..f6e90cc483 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemeSettingsThemeItem.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemeSettingsThemeItem.swift @@ -87,17 +87,19 @@ class ThemeSettingsThemeItem: ListViewItem, ItemListItem { let theme: PresentationTheme let strings: PresentationStrings let themes: [PresentationThemeReference] + let displayUnsupported: Bool let themeSpecificAccentColors: [Int64: PresentationThemeAccentColor] let currentTheme: PresentationThemeReference let updatedTheme: (PresentationThemeReference) -> Void let contextAction: ((PresentationThemeReference, ASDisplayNode, ContextGesture?) -> Void)? let tag: ItemListItemTag? - init(context: AccountContext, theme: PresentationTheme, strings: PresentationStrings, sectionId: ItemListSectionId, themes: [PresentationThemeReference], themeSpecificAccentColors: [Int64: PresentationThemeAccentColor], currentTheme: PresentationThemeReference, updatedTheme: @escaping (PresentationThemeReference) -> Void, contextAction: ((PresentationThemeReference, ASDisplayNode, ContextGesture?) -> Void)?, tag: ItemListItemTag? = nil) { + init(context: AccountContext, theme: PresentationTheme, strings: PresentationStrings, sectionId: ItemListSectionId, themes: [PresentationThemeReference], displayUnsupported: Bool, themeSpecificAccentColors: [Int64: PresentationThemeAccentColor], currentTheme: PresentationThemeReference, updatedTheme: @escaping (PresentationThemeReference) -> Void, contextAction: ((PresentationThemeReference, ASDisplayNode, ContextGesture?) -> Void)?, tag: ItemListItemTag? = nil) { self.context = context self.theme = theme self.strings = strings self.themes = themes + self.displayUnsupported = displayUnsupported self.themeSpecificAccentColors = themeSpecificAccentColors self.currentTheme = currentTheme self.updatedTheme = updatedTheme @@ -389,6 +391,10 @@ class ThemeSettingsThemeItemNode: ListViewItemNode, ItemListItemNode { var i = 0 for theme in item.themes { + if !item.displayUnsupported, case let .cloud(theme) = theme, theme.theme.file == nil { + continue + } + let imageNode: ThemeSettingsThemeItemIconNode if strongSelf.nodes.count > i { imageNode = strongSelf.nodes[i] diff --git a/submodules/TelegramUI/TelegramUI/ChatDateSelectionSheet.swift b/submodules/TelegramUI/TelegramUI/ChatDateSelectionSheet.swift index 46272dc641..8d2dd7a994 100644 --- a/submodules/TelegramUI/TelegramUI/ChatDateSelectionSheet.swift +++ b/submodules/TelegramUI/TelegramUI/ChatDateSelectionSheet.swift @@ -84,14 +84,14 @@ private final class ChatDateSelectorItemNode: ActionSheetItemNode { self.valueChanged = valueChanged self.pickerView = UIDatePicker() + self.pickerView.setValue(theme.primaryTextColor, forKey: "textColor") + self.pickerView.datePickerMode = .countDownTimer self.pickerView.datePickerMode = .date self.pickerView.locale = Locale(identifier: strings.baseLanguageCode) - self.pickerView.setValue(theme.primaryTextColor, forKey: "textColor") self.pickerView.minimumDate = Date(timeIntervalSince1970: 1376438400.0) self.pickerView.maximumDate = Date(timeIntervalSinceNow: 2.0) - super.init(theme: theme) self.view.addSubview(self.pickerView) diff --git a/submodules/TelegramUI/TelegramUI/ChatScheduleTimeControllerNode.swift b/submodules/TelegramUI/TelegramUI/ChatScheduleTimeControllerNode.swift index 859f4c309b..f3bc82e05a 100644 --- a/submodules/TelegramUI/TelegramUI/ChatScheduleTimeControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatScheduleTimeControllerNode.swift @@ -134,11 +134,12 @@ class ChatScheduleTimeControllerNode: ViewControllerTracingNode, UIScrollViewDel let pickerView = UIDatePicker() pickerView.timeZone = TimeZone(secondsFromGMT: 0) + pickerView.setValue(self.presentationData.theme.actionSheet.primaryTextColor, forKey: "textColor") + pickerView.datePickerMode = .countDownTimer pickerView.datePickerMode = .dateAndTime pickerView.locale = Locale.current pickerView.timeZone = TimeZone.current pickerView.minuteInterval = 1 - pickerView.setValue(self.presentationData.theme.actionSheet.primaryTextColor, forKey: "textColor") self.contentContainerNode.view.addSubview(pickerView) pickerView.addTarget(self, action: #selector(self.datePickerUpdated), for: .valueChanged) self.pickerView = pickerView @@ -315,14 +316,14 @@ class ChatScheduleTimeControllerNode: ViewControllerTracingNode, UIScrollViewDel var buttonOffset: CGFloat = 0.0 if case .scheduledMessages(true) = self.mode { - buttonOffset += 44.0 + buttonOffset += 60.0 } let bottomInset: CGFloat = 10.0 + cleanInsets.bottom let titleHeight: CGFloat = 54.0 - var contentHeight = titleHeight + bottomInset + 52.0 + 17.0 + buttonOffset - let pickerHeight: CGFloat = min(216.0, layout.size.height - contentHeight - buttonOffset) - contentHeight = titleHeight + bottomInset + 52.0 + 17.0 + pickerHeight + var contentHeight = titleHeight + bottomInset + 52.0 + 17.0 + let pickerHeight: CGFloat = min(216.0, layout.size.height - contentHeight) + contentHeight = titleHeight + bottomInset + 52.0 + 17.0 + pickerHeight + buttonOffset let width = horizontalContainerFillingSizeForLayout(layout: layout, sideInset: layout.safeInsets.left) @@ -351,7 +352,7 @@ class ChatScheduleTimeControllerNode: ViewControllerTracingNode, UIScrollViewDel transition.updateFrame(node: self.doneButton, frame: CGRect(x: buttonInset, y: contentHeight - buttonHeight - insets.bottom - 10.0 - buttonOffset, width: contentFrame.width, height: buttonHeight)) let onlineSize = self.onlineButton.measure(CGSize(width: width, height: titleHeight)) - let onlineFrame = CGRect(origin: CGPoint(x: ceil((layout.size.width - onlineSize.width) / 2.0), y: contentHeight - 36.0 - insets.bottom), size: onlineSize) + let onlineFrame = CGRect(origin: CGPoint(x: ceil((layout.size.width - onlineSize.width) / 2.0), y: contentHeight - 45.0 - insets.bottom), size: onlineSize) transition.updateFrame(node: self.onlineButton, frame: onlineFrame) self.pickerView?.frame = CGRect(origin: CGPoint(x: 0.0, y: 54.0), size: CGSize(width: contentFrame.width, height: pickerHeight)) diff --git a/submodules/TelegramUI/TelegramUI/OpenChatMessage.swift b/submodules/TelegramUI/TelegramUI/OpenChatMessage.swift index 88f4fcce5c..609b9479f3 100644 --- a/submodules/TelegramUI/TelegramUI/OpenChatMessage.swift +++ b/submodules/TelegramUI/TelegramUI/OpenChatMessage.swift @@ -504,15 +504,22 @@ func openChatTheme(context: AccountContext, message: Message, pushController: @e } else if let contentFile = content.file, contentFile.mimeType == mimeType { file = contentFile } - if case let .theme(slug) = resolvedUrl, let file = file { - if let path = context.sharedContext.accountManager.mediaBox.completedResourcePath(file.resource), let data = try? Data(contentsOf: URL(fileURLWithPath: path), options: .mappedRead), let theme = makePresentationTheme(data: data) { - let controller = ThemePreviewController(context: context, previewTheme: theme, source: .slug(slug, file)) - pushController(controller) - } - } else { + let displayUnsupportedAlert: () -> Void = { let presentationData = context.sharedContext.currentPresentationData.with { $0 } present(textAlertController(context: context, title: nil, text: presentationData.strings.Theme_Unsupported, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), nil) } + if case let .theme(slug) = resolvedUrl, let file = file { + if let path = context.sharedContext.accountManager.mediaBox.completedResourcePath(file.resource), let data = try? Data(contentsOf: URL(fileURLWithPath: path), options: .mappedRead) { + if let theme = makePresentationTheme(data: data) { + let controller = ThemePreviewController(context: context, previewTheme: theme, source: .slug(slug, file)) + pushController(controller) + } else { + displayUnsupportedAlert() + } + } + } else { + displayUnsupportedAlert() + } }) } } diff --git a/submodules/TextFormat/Sources/GenerateTextEntities.swift b/submodules/TextFormat/Sources/GenerateTextEntities.swift index e6ed9b7734..862e92c82a 100644 --- a/submodules/TextFormat/Sources/GenerateTextEntities.swift +++ b/submodules/TextFormat/Sources/GenerateTextEntities.swift @@ -22,12 +22,11 @@ private let identifierDelimiterSet: CharacterSet = { var set = CharacterSet.punctuationCharacters set.formUnion(CharacterSet.whitespacesAndNewlines) set.insert("|") + set.insert("/") return set }() private let externalIdentifierDelimiterSet: CharacterSet = { - var set = CharacterSet.punctuationCharacters - set.formUnion(CharacterSet.whitespacesAndNewlines) - set.insert("|") + var set = identifierDelimiterSet set.remove(".") return set }() @@ -196,8 +195,10 @@ public func generateTextEntities(_ text: String, enabledTypes: EnabledEntityType if let scalar = scalar { if scalar == "/" { notFound = false - if previousScalar != nil && !delimiterSet.contains(previousScalar!) { - currentEntity = nil + if let previousScalar = previousScalar, !delimiterSet.contains(previousScalar) { + if let entity = currentEntity, entity.0 == .command { + currentEntity = nil + } } else { if let (type, range) = currentEntity { commitEntity(utf16, type, range, enabledTypes, &entities) diff --git a/submodules/WalletUI/Sources/WalletReceiveScreen.swift b/submodules/WalletUI/Sources/WalletReceiveScreen.swift index 9b98be4e05..da4f2e0e4b 100644 --- a/submodules/WalletUI/Sources/WalletReceiveScreen.swift +++ b/submodules/WalletUI/Sources/WalletReceiveScreen.swift @@ -10,7 +10,7 @@ import SolidRoundedButtonNode private func shareInvoiceQrCode(context: WalletContext, invoice: String) { let _ = (qrCode(string: invoice, color: .black, backgroundColor: .white, icon: .custom(UIImage(bundleImageName: "Wallet/QrGem"))) - |> map { generator -> UIImage? in + |> map { _, generator -> UIImage? in let imageSize = CGSize(width: 768.0, height: 768.0) let context = generator(TransformImageArguments(corners: ImageCorners(), imageSize: imageSize, boundingSize: imageSize, intrinsicInsets: UIEdgeInsets(), scale: 1.0)) return context?.generateImage() @@ -151,12 +151,15 @@ private final class WalletReceiveScreenNode: ViewControllerTracingNode { private let qrButtonNode: HighlightTrackingButtonNode private let qrImageNode: TransformImageNode private let qrIconNode: AnimatedStickerNode + private var qrCodeSize: Int? private let urlTextNode: ImmediateTextNode private let buttonNode: SolidRoundedButtonNode private let secondaryButtonNode: HighlightableButtonNode + private var validLayout: (ContainerViewLayout, CGFloat)? + var openCreateInvoice: (() -> Void)? var displayCopyContextMenu: ((ASDisplayNode, CGRect, String) -> Void)? @@ -202,7 +205,15 @@ private final class WalletReceiveScreenNode: ViewControllerTracingNode { self.addSubnode(self.buttonNode) self.addSubnode(self.secondaryButtonNode) - self.qrImageNode.setSignal(qrCode(string: urlForMode(mode), color: .black, backgroundColor: .white, icon: .cutout), attemptSynchronously: true) + self.qrImageNode.setSignal(qrCode(string: urlForMode(mode), color: .black, backgroundColor: .white, icon: .cutout) |> beforeNext { [weak self] size, _ in + guard let strongSelf = self else { + return + } + strongSelf.qrCodeSize = size + if let (layout, navigationHeight) = strongSelf.validLayout { + strongSelf.containerLayoutUpdated(layout: layout, navigationHeight: navigationHeight, transition: .immediate) + } + } |> map { $0.1 }, attemptSynchronously: true) self.qrButtonNode.addTarget(self, action: #selector(self.qrPressed), forControlEvents: .touchUpInside) self.qrButtonNode.highligthedChanged = { [weak self] highlighted in @@ -275,6 +286,8 @@ private final class WalletReceiveScreenNode: ViewControllerTracingNode { } func containerLayoutUpdated(layout: ContainerViewLayout, navigationHeight: CGFloat, transition: ContainedViewLayoutTransition) { + self.validLayout = (layout, navigationHeight) + var insets = layout.insets(options: []) insets.top += navigationHeight let inset: CGFloat = 22.0 @@ -295,11 +308,12 @@ private final class WalletReceiveScreenNode: ViewControllerTracingNode { transition.updateFrame(node: self.qrImageNode, frame: imageFrame) transition.updateFrame(node: self.qrButtonNode, frame: imageFrame) - let iconSide = floor(imageSide * 0.24) - let iconSize = CGSize(width: iconSide, height: iconSide) - self.qrIconNode.updateLayout(size: iconSize) - transition.updateBounds(node: self.qrIconNode, bounds: CGRect(origin: CGPoint(), size: iconSize)) - transition.updatePosition(node: self.qrIconNode, position: imageFrame.center.offsetBy(dx: 0.0, dy: -1.0)) + if let qrCodeSize = self.qrCodeSize { + let (_, cutoutFrame, _) = qrCodeCutout(size: qrCodeSize, dimensions: imageSize, scale: nil) + self.qrIconNode.updateLayout(size: cutoutFrame.size) + transition.updateBounds(node: self.qrIconNode, bounds: CGRect(origin: CGPoint(), size: cutoutFrame.size)) + transition.updatePosition(node: self.qrIconNode, position: imageFrame.center.offsetBy(dx: 0.0, dy: -1.0)) + } if self.urlTextNode.attributedText?.string.isEmpty ?? true { var url = urlForMode(self.mode) diff --git a/submodules/WalletUI/Sources/WalletTransactionInfoScreen.swift b/submodules/WalletUI/Sources/WalletTransactionInfoScreen.swift index 70d4ba4905..661463aa3b 100644 --- a/submodules/WalletUI/Sources/WalletTransactionInfoScreen.swift +++ b/submodules/WalletUI/Sources/WalletTransactionInfoScreen.swift @@ -427,21 +427,21 @@ private final class WalletTransactionInfoScreenNode: ViewControllerTracingNode, var feesString: String = "" if case let .completed(transaction) = walletTransaction { - if transaction.storageFee != 0 { - feesString.append(formatBalanceText(transaction.storageFee, decimalSeparator: presentationData.dateTimeFormat.decimalSeparator) + " storage fee") - } if transaction.otherFee != 0 { + feesString.append(formatBalanceText(transaction.otherFee, decimalSeparator: presentationData.dateTimeFormat.decimalSeparator) + " transaction fee") + } + if transaction.storageFee != 0 { if !feesString.isEmpty { feesString.append("\n") } - feesString.append(formatBalanceText(transaction.otherFee, decimalSeparator: presentationData.dateTimeFormat.decimalSeparator) + " transaction fee") + feesString.append(formatBalanceText(transaction.storageFee, decimalSeparator: presentationData.dateTimeFormat.decimalSeparator) + " storage fee") } self.feesInfoIconNode.isHidden = feesString.isEmpty } self.feesNode.attributedText = NSAttributedString(string: feesString, font: subtitleFont, textColor: seccondaryTextColor) - self.feesButtonNode.addTarget(self, action: #selector(feesPressed), forControlEvents: .touchUpInside) + self.feesButtonNode.addTarget(self, action: #selector(self.feesPressed), forControlEvents: .touchUpInside) var commentBackgroundColor = presentationData.theme.transaction.descriptionBackgroundColor if commentBackgroundColor.distance(to: presentationData.theme.list.plainBackgroundColor) < 100 {