mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Merge commit '683b2988fcfb83e15a93c127c47ac7f207074d8b'
This commit is contained in:
commit
bf40f16e1f
@ -564,6 +564,8 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
|
|||||||
} else {
|
} else {
|
||||||
transition.updateFrame(node: selectionPanelNode, frame: panelFrame)
|
transition.updateFrame(node: selectionPanelNode, frame: panelFrame)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bottomIntrinsicInset = panelHeight
|
||||||
} else if let selectionPanelNode = self.selectionPanelNode {
|
} else if let selectionPanelNode = self.selectionPanelNode {
|
||||||
self.selectionPanelNode = nil
|
self.selectionPanelNode = nil
|
||||||
transition.updateFrame(node: selectionPanelNode, frame: CGRect(origin: CGPoint(x: 0.0, y: layout.size.height), size: selectionPanelNode.bounds.size), completion: { [weak selectionPanelNode] _ in
|
transition.updateFrame(node: selectionPanelNode, frame: CGRect(origin: CGPoint(x: 0.0, y: layout.size.height), size: selectionPanelNode.bounds.size), completion: { [weak selectionPanelNode] _ in
|
||||||
@ -576,6 +578,8 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
|
|||||||
var bottomInset = layout.intrinsicInsets.bottom
|
var bottomInset = layout.intrinsicInsets.bottom
|
||||||
if let inputHeight = layout.inputHeight {
|
if let inputHeight = layout.inputHeight {
|
||||||
bottomInset = inputHeight
|
bottomInset = inputHeight
|
||||||
|
} else if let _ = self.selectionPanelNode {
|
||||||
|
bottomInset = bottomIntrinsicInset
|
||||||
} else if case .root = self.groupId {
|
} else if case .root = self.groupId {
|
||||||
bottomInset -= bottomIntrinsicInset
|
bottomInset -= bottomIntrinsicInset
|
||||||
}
|
}
|
||||||
|
@ -106,11 +106,13 @@ func suggestDates(for string: String, strings: PresentationStrings, dateTimeForm
|
|||||||
if stringComponents.count < 3 {
|
if stringComponents.count < 3 {
|
||||||
for i in 0..<5 {
|
for i in 0..<5 {
|
||||||
if let date = calendar.date(byAdding: .year, value: -i, to: resultDate), date < now {
|
if let date = calendar.date(byAdding: .year, value: -i, to: resultDate), date < now {
|
||||||
result.append((nil, date, nil))
|
let lowerDate = getLowerDate(for: resultDate)
|
||||||
|
result.append((lowerDate, date, nil))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if resultDate < now {
|
} else if resultDate < now {
|
||||||
result.append((nil, resultDate, nil))
|
let lowerDate = getLowerDate(for: resultDate)
|
||||||
|
result.append((lowerDate, resultDate, nil))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let dd = try NSDataDetector(types: NSTextCheckingResult.CheckingType.date.rawValue)
|
let dd = try NSDataDetector(types: NSTextCheckingResult.CheckingType.date.rawValue)
|
||||||
|
@ -17,7 +17,7 @@ private let timezoneOffset: Int32 = {
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
public func listMessageDateHeaderId(timestamp: Int32) -> Int64 {
|
public func listMessageDateHeaderId(timestamp: Int32) -> Int64 {
|
||||||
let unclippedValue: Int64 = min(Int64(Int32.max), Int64(timestamp) + Int64(timezoneOffset))
|
let unclippedValue: Int64 = min(Int64(Int32.max), Int64(timestamp))
|
||||||
|
|
||||||
var time: time_t = time_t(Int32(clamping: unclippedValue))
|
var time: time_t = time_t(Int32(clamping: unclippedValue))
|
||||||
var timeinfo: tm = tm()
|
var timeinfo: tm = tm()
|
||||||
@ -29,7 +29,7 @@ public func listMessageDateHeaderId(timestamp: Int32) -> Int64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public func listMessageDateHeaderInfo(timestamp: Int32) -> (year: Int32, month: Int32) {
|
public func listMessageDateHeaderInfo(timestamp: Int32) -> (year: Int32, month: Int32) {
|
||||||
var time: time_t = time_t(timestamp + timezoneOffset)
|
var time: time_t = time_t(timestamp)
|
||||||
var timeinfo: tm = tm()
|
var timeinfo: tm = tm()
|
||||||
localtime_r(&time, &timeinfo)
|
localtime_r(&time, &timeinfo)
|
||||||
|
|
||||||
@ -53,7 +53,7 @@ final class ListMessageDateHeader: ListViewItemHeader {
|
|||||||
self.strings = strings
|
self.strings = strings
|
||||||
self.fontSize = fontSize
|
self.fontSize = fontSize
|
||||||
|
|
||||||
var time: time_t = time_t(timestamp + timezoneOffset)
|
var time: time_t = time_t(timestamp)
|
||||||
var timeinfo: tm = tm()
|
var timeinfo: tm = tm()
|
||||||
localtime_r(&time, &timeinfo)
|
localtime_r(&time, &timeinfo)
|
||||||
|
|
||||||
|
@ -251,13 +251,16 @@ private class SearchBarTextField: UITextField, UIScrollViewDelegate {
|
|||||||
self.tokenNodes[token.id] = tokenNode
|
self.tokenNodes[token.id] = tokenNode
|
||||||
}
|
}
|
||||||
tokenNode.tapped = { [weak self] in
|
tokenNode.tapped = { [weak self] in
|
||||||
self?.selectedTokenIndex = i
|
|
||||||
self?.becomeFirstResponder()
|
|
||||||
if let strongSelf = self {
|
if let strongSelf = self {
|
||||||
|
strongSelf.selectedTokenIndex = i
|
||||||
|
if !strongSelf.isFirstResponder {
|
||||||
|
let _ = strongSelf.becomeFirstResponder()
|
||||||
|
} else {
|
||||||
let newPosition = strongSelf.beginningOfDocument
|
let newPosition = strongSelf.beginningOfDocument
|
||||||
strongSelf.selectedTextRange = strongSelf.textRange(from: newPosition, to: newPosition)
|
strongSelf.selectedTextRange = strongSelf.textRange(from: newPosition, to: newPosition)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
let isSelected = i == self.selectedTokenIndex
|
let isSelected = i == self.selectedTokenIndex
|
||||||
if i < self.tokens.count - 1 && isSelected {
|
if i < self.tokens.count - 1 && isSelected {
|
||||||
hasSelected = true
|
hasSelected = true
|
||||||
@ -356,7 +359,9 @@ private class SearchBarTextField: UITextField, UIScrollViewDelegate {
|
|||||||
self.tokenContainerNode.frame = CGRect(origin: self.tokenContainerNode.frame.origin, size: CGSize(width: self.tokensWidth, height: self.bounds.height))
|
self.tokenContainerNode.frame = CGRect(origin: self.tokenContainerNode.frame.origin, size: CGSize(width: self.tokensWidth, height: self.bounds.height))
|
||||||
|
|
||||||
if let scrollView = self.scrollView {
|
if let scrollView = self.scrollView {
|
||||||
|
if scrollView.contentInset.left != leftOffset {
|
||||||
scrollView.contentInset = UIEdgeInsets(top: 0.0, left: leftOffset, bottom: 0.0, right: 0.0)
|
scrollView.contentInset = UIEdgeInsets(top: 0.0, left: leftOffset, bottom: 0.0, right: 0.0)
|
||||||
|
}
|
||||||
if leftOffset.isZero {
|
if leftOffset.isZero {
|
||||||
scrollView.contentOffset = CGPoint()
|
scrollView.contentOffset = CGPoint()
|
||||||
} else if self.tokensWidth != previousTokensWidth {
|
} else if self.tokensWidth != previousTokensWidth {
|
||||||
@ -439,9 +444,26 @@ private class SearchBarTextField: UITextField, UIScrollViewDelegate {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var fixAutoScroll: CGPoint?
|
||||||
func scrollViewDidScroll(_ scrollView: UIScrollView) {
|
func scrollViewDidScroll(_ scrollView: UIScrollView) {
|
||||||
|
if let fixAutoScroll = self.fixAutoScroll {
|
||||||
|
self.scrollView?.setContentOffset(fixAutoScroll, animated: true)
|
||||||
|
self.scrollView?.setContentOffset(fixAutoScroll, animated: false)
|
||||||
|
self.fixAutoScroll = nil
|
||||||
|
} else {
|
||||||
self.updateTokenContainerPosition()
|
self.updateTokenContainerPosition()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override func becomeFirstResponder() -> Bool {
|
||||||
|
if let contentOffset = self.scrollView?.contentOffset {
|
||||||
|
self.fixAutoScroll = contentOffset
|
||||||
|
Queue.mainQueue().after(0.1) {
|
||||||
|
self.fixAutoScroll = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return super.becomeFirstResponder()
|
||||||
|
}
|
||||||
|
|
||||||
private func updateTokenContainerPosition(transition: ContainedViewLayoutTransition = .immediate) {
|
private func updateTokenContainerPosition(transition: ContainedViewLayoutTransition = .immediate) {
|
||||||
if let scrollView = self.scrollView {
|
if let scrollView = self.scrollView {
|
||||||
@ -460,7 +482,7 @@ private class SearchBarTextField: UITextField, UIScrollViewDelegate {
|
|||||||
}
|
}
|
||||||
super.keyboardAppearance = newValue
|
super.keyboardAppearance = newValue
|
||||||
if resigning {
|
if resigning {
|
||||||
self.becomeFirstResponder()
|
let _ = self.becomeFirstResponder()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -553,7 +575,6 @@ private class SearchBarTextField: UITextField, UIScrollViewDelegate {
|
|||||||
|
|
||||||
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
|
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
|
||||||
if let _ = self.selectedTokenIndex {
|
if let _ = self.selectedTokenIndex {
|
||||||
self.selectedTokenIndex = nil
|
|
||||||
if let touch = touches.first, let gestureRecognizers = touch.gestureRecognizers {
|
if let touch = touches.first, let gestureRecognizers = touch.gestureRecognizers {
|
||||||
let point = touch.location(in: self.tokenContainerNode.view)
|
let point = touch.location(in: self.tokenContainerNode.view)
|
||||||
for (_, tokenNode) in self.tokenNodes {
|
for (_, tokenNode) in self.tokenNodes {
|
||||||
@ -562,6 +583,7 @@ private class SearchBarTextField: UITextField, UIScrollViewDelegate {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
self.selectedTokenIndex = nil
|
||||||
for gesture in gestureRecognizers {
|
for gesture in gestureRecognizers {
|
||||||
if gesture is UITapGestureRecognizer, gesture.isEnabled {
|
if gesture is UITapGestureRecognizer, gesture.isEnabled {
|
||||||
gesture.isEnabled = false
|
gesture.isEnabled = false
|
||||||
@ -931,7 +953,9 @@ public class SearchBarNode: ASDisplayNode, UITextFieldDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public func activate() {
|
public func activate() {
|
||||||
self.textField.becomeFirstResponder()
|
if !self.textField.isFirstResponder {
|
||||||
|
let _ = self.textField.becomeFirstResponder()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func animateIn(from node: SearchBarPlaceholderNode, duration: Double, timingFunction: String) {
|
public func animateIn(from node: SearchBarPlaceholderNode, duration: Double, timingFunction: String) {
|
||||||
@ -1102,14 +1126,18 @@ public class SearchBarNode: ASDisplayNode, UITextFieldDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public func selectAll() {
|
public func selectAll() {
|
||||||
self.textField.becomeFirstResponder()
|
if !self.textField.isFirstResponder {
|
||||||
|
let _ = self.textField.becomeFirstResponder()
|
||||||
|
}
|
||||||
self.textField.selectAll(nil)
|
self.textField.selectAll(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func selectLastToken() {
|
public func selectLastToken() {
|
||||||
if !self.textField.tokens.isEmpty {
|
if !self.textField.tokens.isEmpty {
|
||||||
self.textField.selectedTokenIndex = self.textField.tokens.count - 1
|
self.textField.selectedTokenIndex = self.textField.tokens.count - 1
|
||||||
self.textField.becomeFirstResponder()
|
if !self.textField.isFirstResponder {
|
||||||
|
let _ = self.textField.becomeFirstResponder()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,6 +223,10 @@ public func channelAdminLogEvents(postbox: Postbox, network: Network, peerId: Pe
|
|||||||
|
|
||||||
return postbox.transaction { transaction -> AdminLogEventsResult in
|
return postbox.transaction { transaction -> AdminLogEventsResult in
|
||||||
updatePeers(transaction: transaction, peers: peers.map { $0.1 }, update: { return $1 })
|
updatePeers(transaction: transaction, peers: peers.map { $0.1 }, update: { return $1 })
|
||||||
|
var peers = peers
|
||||||
|
if peers[peerId] == nil, let peer = transaction.getPeer(peerId) {
|
||||||
|
peers[peer.id] = peer
|
||||||
|
}
|
||||||
return AdminLogEventsResult(peerId: peerId, peers: peers, events: events)
|
return AdminLogEventsResult(peerId: peerId, peers: peers, events: events)
|
||||||
} |> castError(MTRpcError.self)
|
} |> castError(MTRpcError.self)
|
||||||
}
|
}
|
||||||
|
@ -649,7 +649,8 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
|||||||
let currentViewVersion = Atomic<Int?>(value: nil)
|
let currentViewVersion = Atomic<Int?>(value: nil)
|
||||||
|
|
||||||
let historyViewUpdate: Signal<(ChatHistoryViewUpdate, Int), NoError>
|
let historyViewUpdate: Signal<(ChatHistoryViewUpdate, Int), NoError>
|
||||||
if case let .custom(messages, _, loadMore) = source {
|
var isFirstTime = true
|
||||||
|
if case let .custom(messages, at, _) = source {
|
||||||
historyViewUpdate = messages
|
historyViewUpdate = messages
|
||||||
|> map { messages, _, hasMore in
|
|> map { messages, _, hasMore in
|
||||||
let version = currentViewVersion.modify({ value in
|
let version = currentViewVersion.modify({ value in
|
||||||
@ -659,7 +660,16 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
})!
|
})!
|
||||||
return (ChatHistoryViewUpdate.HistoryView(view: MessageHistoryView(tagMask: nil, namespaces: .all, entries: messages.reversed().map { MessageHistoryEntry(message: $0, isRead: false, location: nil, monthLocation: nil, attributes: MutableMessageHistoryEntryAttributes(authorIsContact: false)) }, holeEarlier: hasMore), type: .Generic(type: ViewUpdateType.Initial), scrollPosition: nil, flashIndicators: false, originalScrollPosition: nil, initialData: ChatHistoryCombinedInitialData(initialData: nil, buttonKeyboardMessage: nil, cachedData: nil, cachedDataMessages: nil, readStateData: nil), id: 0), version)
|
|
||||||
|
let scrollPosition: ChatHistoryViewScrollPosition?
|
||||||
|
if isFirstTime, let messageIndex = messages.first(where: { $0.id == at })?.index {
|
||||||
|
scrollPosition = .index(index: .message(messageIndex), position: .center(.bottom), directionHint: .Down, animated: false, highlight: false)
|
||||||
|
isFirstTime = false
|
||||||
|
} else {
|
||||||
|
scrollPosition = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return (ChatHistoryViewUpdate.HistoryView(view: MessageHistoryView(tagMask: nil, namespaces: .all, entries: messages.reversed().map { MessageHistoryEntry(message: $0, isRead: false, location: nil, monthLocation: nil, attributes: MutableMessageHistoryEntryAttributes(authorIsContact: false)) }, holeEarlier: hasMore), type: .Generic(type: ViewUpdateType.Initial), scrollPosition: scrollPosition, flashIndicators: false, originalScrollPosition: nil, initialData: ChatHistoryCombinedInitialData(initialData: nil, buttonKeyboardMessage: nil, cachedData: nil, cachedDataMessages: nil, readStateData: nil), id: 0), version)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
historyViewUpdate = self.chatHistoryLocationPromise.get()
|
historyViewUpdate = self.chatHistoryLocationPromise.get()
|
||||||
|
@ -253,7 +253,11 @@ final class OverlayAudioPlayerControllerNode: ViewControllerTracingNode, UIGestu
|
|||||||
|
|
||||||
openMessageImpl = { [weak self] id in
|
openMessageImpl = { [weak self] id in
|
||||||
if let strongSelf = self, strongSelf.isNodeLoaded, let message = strongSelf.historyNode.messageInCurrentHistoryView(id) {
|
if let strongSelf = self, strongSelf.isNodeLoaded, let message = strongSelf.historyNode.messageInCurrentHistoryView(id) {
|
||||||
return strongSelf.context.sharedContext.openChatMessage(OpenChatMessageParams(context: strongSelf.context, chatLocation: nil, chatLocationContextHolder: nil, message: message, standalone: false, reverseMessageGalleryOrder: false, navigationController: nil, dismissInput: { }, present: { _, _ in }, transitionNode: { _, _ in return nil }, addToTransitionSurface: { _ in }, openUrl: { _ in }, openPeer: { _, _ in }, callPeer: { _, _ in }, enqueueMessage: { _ in }, sendSticker: nil, setupTemporaryHiddenMedia: { _, _, _ in }, chatAvatarHiddenMedia: { _, _ in }))
|
var playlistLocation: PeerMessagesPlaylistLocation?
|
||||||
|
if let location = strongSelf.playlistLocation as? PeerMessagesPlaylistLocation, case let .custom(messages, _, loadMore) = location {
|
||||||
|
playlistLocation = .custom(messages: messages, at: id, loadMore: loadMore)
|
||||||
|
}
|
||||||
|
return strongSelf.context.sharedContext.openChatMessage(OpenChatMessageParams(context: strongSelf.context, chatLocation: nil, chatLocationContextHolder: nil, message: message, standalone: false, reverseMessageGalleryOrder: false, navigationController: nil, dismissInput: { }, present: { _, _ in }, transitionNode: { _, _ in return nil }, addToTransitionSurface: { _ in }, openUrl: { _ in }, openPeer: { _, _ in }, callPeer: { _, _ in }, enqueueMessage: { _ in }, sendSticker: nil, setupTemporaryHiddenMedia: { _, _, _ in }, chatAvatarHiddenMedia: { _, _ in }, playlistLocation: playlistLocation))
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user