mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Various improvements
This commit is contained in:
parent
d253ac736d
commit
8b569209c8
@ -5898,3 +5898,5 @@ Sorry for the inconvenience.";
|
||||
"Conversation.ReplacePhoto" = "Replace Photo";
|
||||
"Conversation.ReplaceFile" = "Replace File";
|
||||
"Conversation.SendAsNewPhoto" = "Send as New Photo";
|
||||
|
||||
"Conversation.TextCopied" = "Text copied to clipboard";
|
||||
|
@ -331,13 +331,14 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
|
||||
}
|
||||
}
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
|
||||
var existingPeerIds = Set<PeerId>()
|
||||
var peers = peers
|
||||
if let accountPeer = accountPeer, let lowercasedQuery = searchQuery?.lowercased(), lowercasedQuery.count > 1 && (presentationData.strings.DialogList_SavedMessages.lowercased().hasPrefix(lowercasedQuery) || "saved messages".hasPrefix(lowercasedQuery)) {
|
||||
peers.insert(accountPeer, at: 0)
|
||||
}
|
||||
|
||||
if !peers.isEmpty && selectedFilter != .filter(ChatListSearchFilter.chats.id) {
|
||||
var existingPeerIds = Set<PeerId>()
|
||||
var peers = peers
|
||||
if let accountPeer = accountPeer, let lowercasedQuery = searchQuery?.lowercased(), lowercasedQuery.count > 1 && (presentationData.strings.DialogList_SavedMessages.lowercased().hasPrefix(lowercasedQuery) || "saved messages".hasPrefix(lowercasedQuery)) {
|
||||
peers.insert(accountPeer, at: 0)
|
||||
}
|
||||
|
||||
for peer in peers {
|
||||
if existingPeerIds.contains(peer.id) {
|
||||
continue
|
||||
|
@ -517,7 +517,7 @@ public final class GalleryPagerNode: ASDisplayNode, UIScrollViewDelegate, UIGest
|
||||
}
|
||||
if self.itemNodes.isEmpty {
|
||||
let node = self.makeNodeForItem(at: self.centralItemIndex ?? 0, synchronous: synchronous)
|
||||
node.frame = CGRect(origin: CGPoint(), size: scrollView.bounds.size)
|
||||
node.frame = CGRect(origin: CGPoint(), size: self.scrollView.bounds.size)
|
||||
if let containerLayout = self.containerLayout {
|
||||
node.containerLayoutUpdated(containerLayout.0, navigationBarHeight: containerLayout.1, transition: .immediate)
|
||||
}
|
||||
|
@ -449,8 +449,13 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode {
|
||||
if let (previousLayout, _) = self.validLayout, self.dismissOnOrientationChange, previousLayout.size.width > previousLayout.size.height && previousLayout.size.height == layout.size.width {
|
||||
dismiss = true
|
||||
}
|
||||
let hadLayout = self.validLayout != nil
|
||||
self.validLayout = (layout, navigationBarHeight)
|
||||
|
||||
if !hadLayout {
|
||||
self.zoomableContent = zoomableContent
|
||||
}
|
||||
|
||||
let statusDiameter: CGFloat = 50.0
|
||||
let statusFrame = CGRect(origin: CGPoint(x: floor((layout.size.width - statusDiameter) / 2.0), y: floor((layout.size.height - statusDiameter) / 2.0)), size: CGSize(width: statusDiameter, height: statusDiameter))
|
||||
transition.updateFrame(node: self.statusButtonNode, frame: statusFrame)
|
||||
|
@ -59,7 +59,7 @@ NSString *const TGMentionPanelCellKind = @"TGMentionPanelCell";
|
||||
self.selectedBackgroundView.backgroundColor = selectionColor;
|
||||
|
||||
_avatarView = [[TGLetteredAvatarView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 32.0f, 32.0f)];
|
||||
[_avatarView setSingleFontSize:18.0f doubleFontSize:18.0f useBoldFont:false];
|
||||
[_avatarView setSingleFontSize:16.0f doubleFontSize:16.0f useBoldFont:false];
|
||||
_avatarView.fadeTransition = true;
|
||||
[self.contentView addSubview:_avatarView];
|
||||
|
||||
|
@ -17,8 +17,8 @@ public func legacySuggestionContext(context: AccountContext, peerId: PeerId, cha
|
||||
let disposable = searchPeerMembers(context: context, peerId: peerId, chatLocation: chatLocation, query: query, scope: .mention).start(next: { peers in
|
||||
let users = NSMutableArray()
|
||||
for peer in peers {
|
||||
let user = TGUser()
|
||||
if let peer = peer as? TelegramUser {
|
||||
let user = TGUser()
|
||||
user.uid = peer.id.id
|
||||
user.firstName = peer.firstName
|
||||
user.lastName = peer.lastName
|
||||
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@ -119,7 +119,7 @@ final class ChatBotInfoItemNode: ListViewItemNode {
|
||||
break
|
||||
case .ignore:
|
||||
return .fail
|
||||
case .url, .peerMention, .textMention, .botCommand, .hashtag, .instantPage, .wallpaper, .theme, .call, .openMessage, .timecode, .bankCard, .tooltip, .openPollResults:
|
||||
case .url, .peerMention, .textMention, .botCommand, .hashtag, .instantPage, .wallpaper, .theme, .call, .openMessage, .timecode, .bankCard, .tooltip, .openPollResults, .copy:
|
||||
return .waitForSingleTap
|
||||
}
|
||||
}
|
||||
|
@ -2345,6 +2345,15 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
self?.editMessageMediaWithLegacySignals(signals)
|
||||
})
|
||||
}
|
||||
}, copyText: { [weak self] text in
|
||||
if let strongSelf = self {
|
||||
storeMessageTextInPasteboard(text, entities: nil)
|
||||
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
strongSelf.present(UndoOverlayController(presentationData: presentationData, content: .succeed(text: presentationData.strings.Conversation_TextCopied), elevatedLayout: false, animateInAsReplacement: false, action: { _ in
|
||||
return true
|
||||
}), in: .current)
|
||||
}
|
||||
}, requestMessageUpdate: { [weak self] id in
|
||||
if let strongSelf = self {
|
||||
strongSelf.chatDisplayNode.historyNode.requestMessageUpdate(id)
|
||||
@ -4396,7 +4405,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
break
|
||||
}
|
||||
}
|
||||
var inputTextMaxLength: Int32?
|
||||
var inputTextMaxLength: Int32 = 4096
|
||||
for media in message.media {
|
||||
if media is TelegramMediaImage || media is TelegramMediaFile {
|
||||
inputTextMaxLength = strongSelf.context.currentLimitsConfiguration.with { $0 }.maxMediaCaptionLength
|
||||
|
@ -117,6 +117,7 @@ public final class ChatControllerInteraction {
|
||||
let openReplyThreadOriginalMessage: (Message) -> Void
|
||||
let openMessageStats: (MessageId) -> Void
|
||||
let editMessageMedia: (MessageId, Bool) -> Void
|
||||
let copyText: (String) -> Void
|
||||
|
||||
let requestMessageUpdate: (MessageId) -> Void
|
||||
let cancelInteractiveKeyboardGestures: () -> Void
|
||||
@ -205,6 +206,7 @@ public final class ChatControllerInteraction {
|
||||
openReplyThreadOriginalMessage: @escaping (Message) -> Void,
|
||||
openMessageStats: @escaping (MessageId) -> Void,
|
||||
editMessageMedia: @escaping (MessageId, Bool) -> Void,
|
||||
copyText: @escaping (String) -> Void,
|
||||
requestMessageUpdate: @escaping (MessageId) -> Void,
|
||||
cancelInteractiveKeyboardGestures: @escaping () -> Void,
|
||||
automaticMediaDownloadSettings: MediaAutoDownloadSettings,
|
||||
@ -280,6 +282,7 @@ public final class ChatControllerInteraction {
|
||||
self.openReplyThreadOriginalMessage = openReplyThreadOriginalMessage
|
||||
self.openMessageStats = openMessageStats
|
||||
self.editMessageMedia = editMessageMedia
|
||||
self.copyText = copyText
|
||||
|
||||
self.requestMessageUpdate = requestMessageUpdate
|
||||
self.cancelInteractiveKeyboardGestures = cancelInteractiveKeyboardGestures
|
||||
@ -332,6 +335,7 @@ public final class ChatControllerInteraction {
|
||||
}, openReplyThreadOriginalMessage: { _ in
|
||||
}, openMessageStats: { _ in
|
||||
}, editMessageMedia: { _, _ in
|
||||
}, copyText: { _ in
|
||||
}, requestMessageUpdate: { _ in
|
||||
}, cancelInteractiveKeyboardGestures: {
|
||||
}, automaticMediaDownloadSettings: MediaAutoDownloadSettings.defaultSettings,
|
||||
|
@ -493,7 +493,7 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
self.inputPanelBackgroundSeparatorNode.backgroundColor = self.chatPresentationInterfaceState.theme.chat.inputPanel.panelSeparatorColor
|
||||
self.inputPanelBackgroundSeparatorNode.isLayerBacked = true
|
||||
|
||||
self.navigateButtons = ChatHistoryNavigationButtons(theme: self.chatPresentationInterfaceState.theme)
|
||||
self.navigateButtons = ChatHistoryNavigationButtons(theme: self.chatPresentationInterfaceState.theme, dateTimeFormat: self.chatPresentationInterfaceState.dateTimeFormat)
|
||||
self.navigateButtons.accessibilityElementsHidden = true
|
||||
|
||||
self.navigationBarBackroundNode = ASDisplayNode()
|
||||
@ -1919,7 +1919,7 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
let updateInputTextState = self.chatPresentationInterfaceState.interfaceState.effectiveInputState != chatPresentationInterfaceState.interfaceState.effectiveInputState
|
||||
self.chatPresentationInterfaceState = chatPresentationInterfaceState
|
||||
|
||||
self.navigateButtons.updateTheme(theme: chatPresentationInterfaceState.theme)
|
||||
self.navigateButtons.update(theme: chatPresentationInterfaceState.theme, dateTimeFormat: chatPresentationInterfaceState.dateTimeFormat)
|
||||
|
||||
if themeUpdated {
|
||||
if case let .color(color) = self.chatPresentationInterfaceState.chatWallpaper, UIColor(rgb: color).isEqual(self.chatPresentationInterfaceState.theme.chat.inputPanel.panelBackgroundColorNoWallpaper) {
|
||||
|
@ -6,6 +6,7 @@ import TelegramPresentationData
|
||||
|
||||
final class ChatHistoryNavigationButtons: ASDisplayNode {
|
||||
private var theme: PresentationTheme
|
||||
private var dateTimeFormat: PresentationDateTimeFormat
|
||||
|
||||
private let mentionsButton: ChatHistoryNavigationButtonNode
|
||||
private let mentionsButtonTapNode: ASDisplayNode
|
||||
@ -31,7 +32,7 @@ final class ChatHistoryNavigationButtons: ASDisplayNode {
|
||||
var unreadCount: Int32 = 0 {
|
||||
didSet {
|
||||
if self.unreadCount != 0 {
|
||||
self.downButton.badge = "\(self.unreadCount)"
|
||||
self.downButton.badge = compactNumericCountString(Int(self.unreadCount), decimalSeparator: self.dateTimeFormat.decimalSeparator)
|
||||
} else {
|
||||
self.downButton.badge = ""
|
||||
}
|
||||
@ -41,7 +42,7 @@ final class ChatHistoryNavigationButtons: ASDisplayNode {
|
||||
var mentionCount: Int32 = 0 {
|
||||
didSet {
|
||||
if self.mentionCount != 0 {
|
||||
self.mentionsButton.badge = "\(self.mentionCount)"
|
||||
self.mentionsButton.badge = compactNumericCountString(Int(self.mentionCount), decimalSeparator: self.dateTimeFormat.decimalSeparator)
|
||||
} else {
|
||||
self.mentionsButton.badge = ""
|
||||
}
|
||||
@ -52,8 +53,9 @@ final class ChatHistoryNavigationButtons: ASDisplayNode {
|
||||
}
|
||||
}
|
||||
|
||||
init(theme: PresentationTheme) {
|
||||
init(theme: PresentationTheme, dateTimeFormat: PresentationDateTimeFormat) {
|
||||
self.theme = theme
|
||||
self.dateTimeFormat = dateTimeFormat
|
||||
|
||||
self.mentionsButton = ChatHistoryNavigationButtonNode(theme: theme, type: .mentions)
|
||||
self.mentionsButton.alpha = 0.0
|
||||
@ -81,9 +83,10 @@ final class ChatHistoryNavigationButtons: ASDisplayNode {
|
||||
self.mentionsButtonTapNode.view.addGestureRecognizer(tapRecognizer)
|
||||
}
|
||||
|
||||
func updateTheme(theme: PresentationTheme) {
|
||||
if self.theme !== theme {
|
||||
func update(theme: PresentationTheme, dateTimeFormat: PresentationDateTimeFormat) {
|
||||
if self.theme !== theme || self.dateTimeFormat != dateTimeFormat {
|
||||
self.theme = theme
|
||||
self.dateTimeFormat = dateTimeFormat
|
||||
|
||||
self.mentionsButton.updateTheme(theme: theme)
|
||||
self.downButton.updateTheme(theme: theme)
|
||||
|
@ -146,19 +146,7 @@ func preparedChatMediaInputGridEntryTransition(account: Account, view: ItemColle
|
||||
firstIndexInSectionOffset = Int(index.itemIndex.index)
|
||||
}
|
||||
}
|
||||
|
||||
if case .initial = update {
|
||||
switch toEntries[0].index {
|
||||
case .search:
|
||||
if toEntries.count > 1 {
|
||||
//scrollToItem = GridNodeScrollToItem(index: 1, position: .top, transition: .immediate, directionHint: .up, adjustForSection: true)
|
||||
}
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
let opaqueState = ChatMediaInputStickerPaneOpaqueState(hasLower: view.lower != nil)
|
||||
|
||||
return ChatMediaInputGridTransition(deletions: deletions, insertions: insertions, updates: updates, updateFirstIndexInSectionOffset: firstIndexInSectionOffset, stationaryItems: stationaryItems, scrollToItem: scrollToItem, updateOpaqueState: opaqueState, animated: animated)
|
||||
|
@ -218,7 +218,7 @@ final class ChatMediaInputStickerGridItemNode: GridItemNode {
|
||||
return
|
||||
}
|
||||
if image != nil {
|
||||
strongSelf.removePlaceholder(animated: !firstTime)
|
||||
// strongSelf.removePlaceholder(animated: !firstTime)
|
||||
}
|
||||
firstTime = false
|
||||
}
|
||||
|
@ -97,6 +97,7 @@ enum ChatMessageBubbleContentTapAction {
|
||||
case bankCard(String)
|
||||
case ignore
|
||||
case openPollResults(Data)
|
||||
case copy(String)
|
||||
}
|
||||
|
||||
final class ChatMessageBubbleContentItem {
|
||||
|
@ -643,7 +643,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
|
||||
break
|
||||
case .ignore:
|
||||
return .fail
|
||||
case .url, .peerMention, .textMention, .botCommand, .hashtag, .instantPage, .wallpaper, .theme, .call, .openMessage, .timecode, .bankCard, .tooltip, .openPollResults:
|
||||
case .url, .peerMention, .textMention, .botCommand, .hashtag, .instantPage, .wallpaper, .theme, .call, .openMessage, .timecode, .bankCard, .tooltip, .openPollResults, .copy:
|
||||
return .waitForSingleTap
|
||||
}
|
||||
}
|
||||
@ -3122,6 +3122,12 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
|
||||
item.controllerInteraction.openMessagePollResults(item.message.id, option)
|
||||
})
|
||||
}
|
||||
case let .copy(text):
|
||||
if let item = self.item {
|
||||
return .optionalAction({
|
||||
item.controllerInteraction.copyText(text)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
@ -3198,6 +3204,8 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
|
||||
break
|
||||
case .openPollResults:
|
||||
break
|
||||
case .copy:
|
||||
break
|
||||
}
|
||||
}
|
||||
if let tapMessage = tapMessage {
|
||||
|
@ -450,6 +450,8 @@ class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode {
|
||||
return .timecode(timecode.time, timecode.text)
|
||||
} else if let bankCard = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.BankCard)] as? String {
|
||||
return .bankCard(bankCard)
|
||||
} else if let pre = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.Pre)] as? String {
|
||||
return .copy(pre)
|
||||
} else {
|
||||
return .none
|
||||
}
|
||||
|
@ -456,6 +456,7 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
|
||||
}, openReplyThreadOriginalMessage: { _ in
|
||||
}, openMessageStats: { _ in
|
||||
}, editMessageMedia: { _, _ in
|
||||
}, copyText: { _ in
|
||||
}, requestMessageUpdate: { _ in
|
||||
}, cancelInteractiveKeyboardGestures: {
|
||||
}, automaticMediaDownloadSettings: self.automaticMediaDownloadSettings,
|
||||
|
@ -31,8 +31,6 @@ final class ChatTextInputActionButtonsNode: ASDisplayNode {
|
||||
|
||||
self.micButton = ChatTextInputMediaRecordingButton(theme: theme, strings: strings, presentController: presentController)
|
||||
self.sendButton = HighlightTrackingButtonNode(pointerStyle: .lift)
|
||||
//self.sendButton.adjustsImageWhenHighlighted = false
|
||||
//self.sendButton.adjustsImageWhenDisabled = false
|
||||
|
||||
self.expandMediaInputButton = HighlightableButtonNode(pointerStyle: .default)
|
||||
|
||||
|
@ -204,6 +204,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
let textInputBackgroundNode: ASImageNode
|
||||
let actionButtons: ChatTextInputActionButtonsNode
|
||||
var mediaRecordingAccessibilityArea: AccessibilityAreaNode?
|
||||
private let counterTextNode: ImmediateTextNode
|
||||
|
||||
let attachmentButton: HighlightableButtonNode
|
||||
let attachmentButtonDisabledNode: HighlightableButtonNode
|
||||
@ -244,6 +245,8 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
private var theme: PresentationTheme?
|
||||
private var strings: PresentationStrings?
|
||||
|
||||
private let hapticFeedback = HapticFeedback()
|
||||
|
||||
var inputTextState: ChatTextInputState {
|
||||
if let textInputNode = self.textInputNode {
|
||||
let selectionRange: Range<Int> = textInputNode.selectedRange.location ..< (textInputNode.selectedRange.location + textInputNode.selectedRange.length)
|
||||
@ -403,6 +406,8 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
self.searchLayoutClearButton.addSubnode(self.searchLayoutClearImageNode)
|
||||
|
||||
self.actionButtons = ChatTextInputActionButtonsNode(theme: presentationInterfaceState.theme, strings: presentationInterfaceState.strings, presentController: presentController)
|
||||
self.counterTextNode = ImmediateTextNode()
|
||||
self.counterTextNode.textAlignment = .center
|
||||
|
||||
super.init()
|
||||
|
||||
@ -491,6 +496,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
self.addSubnode(self.attachmentButtonDisabledNode)
|
||||
|
||||
self.addSubnode(self.actionButtons)
|
||||
self.addSubnode(self.counterTextNode)
|
||||
|
||||
self.view.addSubview(self.searchLayoutClearButton)
|
||||
|
||||
@ -1183,6 +1189,22 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
textInputBackgroundWidthOffset = 36.0
|
||||
}
|
||||
|
||||
if let textInputNode = self.textInputNode, let presentationInterfaceState = self.presentationInterfaceState, let editMessage = presentationInterfaceState.interfaceState.editMessage, let inputTextMaxLength = editMessage.inputTextMaxLength {
|
||||
let textCount = Int32(textInputNode.textView.text.count)
|
||||
let counterColor: UIColor = textCount > inputTextMaxLength ? presentationInterfaceState.theme.chat.inputPanel.panelControlDestructiveColor : presentationInterfaceState.theme.chat.inputPanel.panelControlColor
|
||||
|
||||
let remainingCount = inputTextMaxLength - textCount
|
||||
let counterText = remainingCount >= 5 ? "" : "\(inputTextMaxLength - textCount)"
|
||||
self.counterTextNode.attributedText = NSAttributedString(string: counterText, font: Font.regular(14.0), textColor: counterColor)
|
||||
} else {
|
||||
self.counterTextNode.attributedText = NSAttributedString(string: "", font: Font.regular(14.0), textColor: .black)
|
||||
}
|
||||
|
||||
let counterSize = self.counterTextNode.updateLayout(CGSize(width: 44.0, height: 44.0))
|
||||
let actionButtonsOriginX = width - rightInset - 43.0 - UIScreenPixel + composeButtonsOffset
|
||||
let counterFrame = CGRect(origin: CGPoint(x: actionButtonsOriginX, y: panelHeight - minimalHeight - counterSize.height + 3.0), size: CGSize(width: width - actionButtonsOriginX - rightInset, height: counterSize.height))
|
||||
transition.updateFrame(node: self.counterTextNode, frame: counterFrame)
|
||||
|
||||
let actionButtonsFrame = CGRect(origin: CGPoint(x: width - rightInset - 43.0 - UIScreenPixel + composeButtonsOffset, y: panelHeight - minimalHeight), size: CGSize(width: 44.0, height: minimalHeight))
|
||||
transition.updateFrame(node: self.actionButtons, frame: actionButtonsFrame)
|
||||
|
||||
@ -1454,6 +1476,21 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
self.interfaceInteraction?.updateTextInputStateAndMode({ _, inputMode in return (inputTextState, inputMode) })
|
||||
self.interfaceInteraction?.updateInputLanguage({ _ in return textInputNode.textInputMode.primaryLanguage })
|
||||
self.updateTextNodeText(animated: true)
|
||||
|
||||
if let editMessage = presentationInterfaceState.interfaceState.editMessage, let inputTextMaxLength = editMessage.inputTextMaxLength {
|
||||
let textCount = Int32(textInputNode.textView.text.count)
|
||||
let counterColor: UIColor = textCount > inputTextMaxLength ? presentationInterfaceState.theme.chat.inputPanel.panelControlDestructiveColor : presentationInterfaceState.theme.chat.inputPanel.panelControlColor
|
||||
|
||||
let remainingCount = inputTextMaxLength - textCount
|
||||
let counterText = remainingCount >= 5 ? "" : "\(inputTextMaxLength - textCount)"
|
||||
self.counterTextNode.attributedText = NSAttributedString(string: counterText, font: Font.regular(14.0), textColor: counterColor)
|
||||
} else {
|
||||
self.counterTextNode.attributedText = NSAttributedString(string: "", font: Font.regular(14.0), textColor: .black)
|
||||
}
|
||||
|
||||
if let (width, leftInset, rightInset, maxHeight, metrics, isSecondary) = self.validLayout {
|
||||
let _ = self.updateLayout(width: width, leftInset: leftInset, rightInset: rightInset, maxHeight: maxHeight, isSecondary: isSecondary, transition: .immediate, interfaceState: presentationInterfaceState, metrics: metrics)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1793,14 +1830,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let newText = (editableTextNode.textView.text as NSString).replacingCharacters(in: range, with: cleanText)
|
||||
if let interfaceState = self.presentationInterfaceState, let editMessage = interfaceState.interfaceState.editMessage, let inputTextMaxLength = editMessage.inputTextMaxLength {
|
||||
if newText.count > inputTextMaxLength {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if cleanText != text {
|
||||
let string = NSMutableAttributedString(attributedString: editableTextNode.attributedText ?? NSAttributedString())
|
||||
var textColor: UIColor = .black
|
||||
@ -1898,6 +1928,17 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
}
|
||||
|
||||
@objc func sendButtonPressed() {
|
||||
if let textInputNode = self.textInputNode, let presentationInterfaceState = self.presentationInterfaceState, let editMessage = presentationInterfaceState.interfaceState.editMessage, let inputTextMaxLength = editMessage.inputTextMaxLength {
|
||||
let textCount = Int32(textInputNode.textView.text.count)
|
||||
let remainingCount = inputTextMaxLength - textCount
|
||||
|
||||
if remainingCount < 0 {
|
||||
textInputNode.layer.addShakeAnimation()
|
||||
self.hapticFeedback.error()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
self.sendMessage()
|
||||
}
|
||||
|
||||
|
@ -149,6 +149,7 @@ private final class DrawingStickersScreenNode: ViewControllerTracingNode {
|
||||
}, openReplyThreadOriginalMessage: { _ in
|
||||
}, openMessageStats: { _ in
|
||||
}, editMessageMedia: { _, _ in
|
||||
}, copyText: { _ in
|
||||
}, requestMessageUpdate: { _ in
|
||||
}, cancelInteractiveKeyboardGestures: {
|
||||
}, automaticMediaDownloadSettings: MediaAutoDownloadSettings.defaultSettings,
|
||||
|
@ -139,6 +139,7 @@ final class OverlayAudioPlayerControllerNode: ViewControllerTracingNode, UIGestu
|
||||
}, openReplyThreadOriginalMessage: { _ in
|
||||
}, openMessageStats: { _ in
|
||||
}, editMessageMedia: { _, _ in
|
||||
}, copyText: { _ in
|
||||
}, requestMessageUpdate: { _ in
|
||||
}, cancelInteractiveKeyboardGestures: {
|
||||
}, automaticMediaDownloadSettings: MediaAutoDownloadSettings.defaultSettings, pollActionState: ChatInterfacePollActionState(), stickerSettings: ChatInterfaceStickerSettings(loopAnimatedStickers: false))
|
||||
|
@ -1970,6 +1970,7 @@ private final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewD
|
||||
}, openReplyThreadOriginalMessage: { _ in
|
||||
}, openMessageStats: { _ in
|
||||
}, editMessageMedia: { _, _ in
|
||||
}, copyText: { _ in
|
||||
}, requestMessageUpdate: { _ in
|
||||
}, cancelInteractiveKeyboardGestures: {
|
||||
}, automaticMediaDownloadSettings: MediaAutoDownloadSettings.defaultSettings,
|
||||
|
@ -1239,6 +1239,7 @@ public final class SharedAccountContextImpl: SharedAccountContext {
|
||||
}, openReplyThreadOriginalMessage: { _ in
|
||||
}, openMessageStats: { _ in
|
||||
}, editMessageMedia: { _, _ in
|
||||
}, copyText: { _ in
|
||||
}, requestMessageUpdate: { _ in
|
||||
}, cancelInteractiveKeyboardGestures: {
|
||||
}, automaticMediaDownloadSettings: MediaAutoDownloadSettings.defaultSettings,
|
||||
|
@ -160,15 +160,17 @@ public func stringWithAppliedEntities(_ text: String, entities: [MessageTextEnti
|
||||
if case .Mention = entities[i + 1].type {
|
||||
let nextRange = NSRange(location: entities[i + 1].range.lowerBound, length: entities[i + 1].range.upperBound - entities[i + 1].range.lowerBound)
|
||||
if nextRange.location == range.location + range.length + 1 && nsString!.character(at: range.location + range.length) == 43 {
|
||||
let peerName: String = nsString!.substring(with: NSRange(location: nextRange.location + 1, length: nextRange.length - 1))
|
||||
|
||||
skipEntity = true
|
||||
let combinedRange = NSRange(location: range.location, length: nextRange.location + nextRange.length - range.location)
|
||||
string.addAttribute(NSAttributedString.Key.foregroundColor, value: linkColor, range: combinedRange)
|
||||
if linkColor.isEqual(baseColor) {
|
||||
string.addAttribute(NSAttributedString.Key.underlineStyle, value: NSUnderlineStyle.single.rawValue as NSNumber, range: combinedRange)
|
||||
if nextRange.length > 0 {
|
||||
let peerName: String = nsString!.substring(with: NSRange(location: nextRange.location + 1, length: nextRange.length - 1))
|
||||
|
||||
let combinedRange = NSRange(location: range.location, length: nextRange.location + nextRange.length - range.location)
|
||||
string.addAttribute(NSAttributedString.Key.foregroundColor, value: linkColor, range: combinedRange)
|
||||
if linkColor.isEqual(baseColor) {
|
||||
string.addAttribute(NSAttributedString.Key.underlineStyle, value: NSUnderlineStyle.single.rawValue as NSNumber, range: combinedRange)
|
||||
}
|
||||
string.addAttribute(NSAttributedString.Key(rawValue: TelegramTextAttributes.Hashtag), value: TelegramHashtag(peerName: peerName, hashtag: hashtag), range: combinedRange)
|
||||
}
|
||||
string.addAttribute(NSAttributedString.Key(rawValue: TelegramTextAttributes.Hashtag), value: TelegramHashtag(peerName: peerName, hashtag: hashtag), range: combinedRange)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -190,6 +192,10 @@ public func stringWithAppliedEntities(_ text: String, entities: [MessageTextEnti
|
||||
string.addAttribute(NSAttributedString.Key(rawValue: TelegramTextAttributes.BotCommand), value: nsString!.substring(with: range), range: range)
|
||||
case .Code, .Pre:
|
||||
string.addAttribute(NSAttributedString.Key.font, value: fixedFont, range: range)
|
||||
if nsString == nil {
|
||||
nsString = text as NSString
|
||||
}
|
||||
string.addAttribute(NSAttributedString.Key(rawValue: TelegramTextAttributes.Pre), value: nsString!.substring(with: range), range: range)
|
||||
case .BlockQuote:
|
||||
if let fontAttribute = fontAttributes[range] {
|
||||
fontAttributes[range] = fontAttribute.union(.blockQuote)
|
||||
|
@ -40,4 +40,5 @@ public struct TelegramTextAttributes {
|
||||
public static let BankCard = "TelegramBankCard"
|
||||
public static let Timecode = "TelegramTimecode"
|
||||
public static let BlockQuote = "TelegramBlockQuote"
|
||||
public static let Pre = "TelegramPre"
|
||||
}
|
||||
|
@ -142,7 +142,7 @@ final class UndoOverlayControllerNode: ViewControllerTracingNode {
|
||||
self.textNode.attributedText = attributedText
|
||||
self.textNode.maximumNumberOfLines = 2
|
||||
displayUndo = false
|
||||
self.originalRemainingSeconds = 5
|
||||
self.originalRemainingSeconds = 3
|
||||
case let .info(text):
|
||||
self.iconNode = nil
|
||||
self.iconCheckNode = nil
|
||||
|
Loading…
x
Reference in New Issue
Block a user