mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Local scrolling
This commit is contained in:
parent
ed5e3b3c5a
commit
920e16a17f
@ -284,6 +284,7 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture
|
||||
public private(set) var isTracking = false
|
||||
public private(set) var trackingOffset: CGFloat = 0.0
|
||||
public private(set) var beganTrackingAtTopOrigin = false
|
||||
public private(set) var isDragging = false
|
||||
public private(set) var isDeceleratingAfterTracking = false
|
||||
|
||||
private final var transactionQueue: ListViewTransactionQueue
|
||||
@ -770,6 +771,8 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture
|
||||
self.snapToBottomInsetUntilFirstInteraction = false
|
||||
}
|
||||
self.scrolledToItem = nil
|
||||
|
||||
self.isDragging = true
|
||||
|
||||
self.beganInteractiveDragging(self.touchesPosition)
|
||||
|
||||
@ -781,6 +784,7 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture
|
||||
}
|
||||
|
||||
public func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
|
||||
self.isDragging = false
|
||||
if decelerate {
|
||||
self.lastContentOffsetTimestamp = CACurrentMediaTime()
|
||||
self.isDeceleratingAfterTracking = true
|
||||
|
@ -2691,6 +2691,20 @@ final class MessageHistoryTable: Table {
|
||||
}
|
||||
return closestIndex
|
||||
}
|
||||
|
||||
func findMessageAtAbsoluteIndex(peerId: PeerId, namespace: MessageId.Namespace, index: Int) -> MessageIndex? {
|
||||
var count = 0
|
||||
var result: MessageIndex?
|
||||
self.valueBox.range(self.table, start: self.upperBound(peerId: peerId, namespace: namespace), end: self.lowerBound(peerId: peerId, namespace: namespace), keys: { key in
|
||||
if count == index {
|
||||
result = extractKey(key)
|
||||
return false
|
||||
}
|
||||
count += 1
|
||||
return true
|
||||
}, limit: 10000)
|
||||
return result
|
||||
}
|
||||
|
||||
func findRandomMessage(peerId: PeerId, namespace: MessageId.Namespace, tag: MessageTags, ignoreIds: ([MessageId], Set<MessageId>)) -> MessageIndex? {
|
||||
if let index = self.tagsTable.findRandomIndex(peerId: peerId, namespace: namespace, tag: tag, ignoreIds: ignoreIds, isMessage: { index in
|
||||
@ -2811,8 +2825,22 @@ final class MessageHistoryTable: Table {
|
||||
return indices
|
||||
}
|
||||
|
||||
func getMessageCountInRange(peerId: PeerId, namespace: MessageId.Namespace, tag: MessageTags, lowerBound: MessageIndex, upperBound: MessageIndex) -> Int {
|
||||
return self.tagsTable.getMessageCountInRange(tag: tag, peerId: peerId, namespace: namespace, lowerBound: lowerBound, upperBound: upperBound)
|
||||
func getMessageCountInRange(peerId: PeerId, namespace: MessageId.Namespace, tag: MessageTags?, lowerBound: MessageIndex, upperBound: MessageIndex) -> Int {
|
||||
if let tag = tag {
|
||||
return self.tagsTable.getMessageCountInRange(tag: tag, peerId: peerId, namespace: namespace, lowerBound: lowerBound, upperBound: upperBound)
|
||||
} else {
|
||||
precondition(lowerBound.id.namespace == namespace)
|
||||
precondition(upperBound.id.namespace == namespace)
|
||||
var lowerBoundKey = self.key(lowerBound)
|
||||
if lowerBound.timestamp > 1 {
|
||||
lowerBoundKey = lowerBoundKey.predecessor
|
||||
}
|
||||
var upperBoundKey = self.key(upperBound)
|
||||
if upperBound.timestamp < Int32.max - 1 {
|
||||
upperBoundKey = upperBoundKey.successor
|
||||
}
|
||||
return Int(self.valueBox.count(self.table, start: lowerBoundKey, end: upperBoundKey))
|
||||
}
|
||||
}
|
||||
|
||||
func setPendingMessageAction(id: MessageId, type: PendingMessageActionType, action: PendingMessageActionData?, pendingActionsOperations: inout [PendingMessageActionsOperation], updatedMessageActionsSummaries: inout [PendingMessageActionsSummaryKey: Int32]) {
|
||||
|
@ -245,7 +245,6 @@ public struct MessageHistoryViewOrderStatistics: OptionSet {
|
||||
}
|
||||
|
||||
public static let combinedLocation = MessageHistoryViewOrderStatistics(rawValue: 1 << 0)
|
||||
public static let locationWithinMonth = MessageHistoryViewOrderStatistics(rawValue: 1 << 1)
|
||||
}
|
||||
|
||||
public final class MessageHistoryViewExternalInput: Equatable {
|
||||
|
@ -80,7 +80,7 @@ private extension MessageHistoryInput {
|
||||
if let automatic = automatic {
|
||||
return postbox.messageHistoryTagsTable.getMessageCountInRange(tag: automatic.tag, peerId: peerId, namespace: namespace, lowerBound: lowerBound, upperBound: upperBound)
|
||||
} else {
|
||||
return 0
|
||||
return postbox.messageHistoryTable.getMessageCountInRange(peerId: peerId, namespace: namespace, tag: nil, lowerBound: lowerBound, upperBound: upperBound)
|
||||
}
|
||||
case .external:
|
||||
return 0
|
||||
@ -981,7 +981,7 @@ final class HistoryViewLoadedState {
|
||||
|
||||
var entries = OrderedHistoryViewEntries(lowerOrAtAnchor: lowerOrAtAnchorMessages, higherThanAnchor: higherThanAnchorMessages)
|
||||
|
||||
if case let .automatic(automaticValue) = self.input, let _ = automaticValue, self.statistics.contains(.combinedLocation), let first = entries.first {
|
||||
if case .automatic = self.input, self.statistics.contains(.combinedLocation), let first = entries.first {
|
||||
let messageIndex = first.index
|
||||
let previousCount = self.input.getMessageCountInRange(postbox: postbox, peerId: space.peerId, namespace: space.namespace, lowerBound: MessageIndex.lowerBound(peerId: space.peerId, namespace: space.namespace), upperBound: messageIndex)
|
||||
let nextCount = self.input.getMessageCountInRange(postbox: postbox, peerId: space.peerId, namespace: space.namespace, lowerBound: messageIndex, upperBound: MessageIndex.upperBound(peerId: space.peerId, namespace: space.namespace))
|
||||
@ -999,30 +999,7 @@ final class HistoryViewLoadedState {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if case let .automatic(tagValue) = self.input, let _ = tagValue, self.statistics.contains(.locationWithinMonth), let first = entries.first {
|
||||
let messageIndex = first.index
|
||||
let monthIndex = MessageMonthIndex(timestamp: messageIndex.timestamp)
|
||||
let count = self.input.getMessageCountInRange(postbox: postbox, peerId: space.peerId, namespace: space.namespace, lowerBound: messageIndex, upperBound: monthUpperBoundIndex(peerId: space.peerId, namespace: space.namespace, index: monthIndex))
|
||||
|
||||
var nextLocation: (MessageMonthIndex, Int) = (monthIndex, count - 1)
|
||||
|
||||
let _ = entries.mutableScan { entry in
|
||||
let messageMonthIndex = MessageMonthIndex(timestamp: entry.index.timestamp)
|
||||
if messageMonthIndex != nextLocation.0 {
|
||||
nextLocation = (messageMonthIndex, 0)
|
||||
}
|
||||
|
||||
let currentIndexInMonth = nextLocation.1
|
||||
nextLocation.1 = max(0, nextLocation.1 - 1)
|
||||
switch entry {
|
||||
case let .IntermediateMessageEntry(message, location, _):
|
||||
return .IntermediateMessageEntry(message, location, MessageHistoryEntryMonthLocation(indexInMonth: Int32(currentIndexInMonth)))
|
||||
case let .MessageEntry(entry, reloadAssociatedMessages, reloadPeers):
|
||||
return .MessageEntry(MessageHistoryMessageEntry(message: entry.message, location: entry.location, monthLocation: MessageHistoryEntryMonthLocation(indexInMonth: Int32(currentIndexInMonth)), attributes: entry.attributes), reloadAssociatedMessages: reloadAssociatedMessages, reloadPeers: reloadPeers)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if canContainHoles(space, input: self.input, seedConfiguration: self.seedConfiguration) {
|
||||
entries.fixMonotony()
|
||||
|
@ -703,6 +703,11 @@ public final class Transaction {
|
||||
assert(!self.disposed)
|
||||
return self.postbox?.messageHistoryTable.findClosestMessageIndex(peerId: peerId, timestamp: timestamp)?.id
|
||||
}
|
||||
|
||||
public func findMessageAtAbsoluteIndex(peerId: PeerId, namespace: MessageId.Namespace, index: Int) -> MessageIndex? {
|
||||
assert(!self.disposed)
|
||||
return self.postbox?.messageHistoryTable.findMessageAtAbsoluteIndex(peerId: peerId, namespace: namespace, index: index)
|
||||
}
|
||||
|
||||
public func findRandomMessage(peerId: PeerId, namespace: MessageId.Namespace, tag: MessageTags, ignoreIds: ([MessageId], Set<MessageId>)) -> MessageIndex? {
|
||||
assert(!self.disposed)
|
||||
|
@ -102,6 +102,10 @@ public final class SparseDiscreteScrollingArea: ASDisplayNode {
|
||||
private var containerSize: CGSize?
|
||||
private var indicatorPosition: CGFloat?
|
||||
private var scrollIndicatorHeight: CGFloat?
|
||||
private var scrollIndicatorRange: (CGFloat, CGFloat)?
|
||||
|
||||
private var initialDraggingOffset: CGFloat?
|
||||
private var draggingOffset: CGFloat?
|
||||
|
||||
private var dragGesture: DragGesture?
|
||||
public private(set) var isDragging: Bool = false
|
||||
@ -110,11 +114,25 @@ public final class SparseDiscreteScrollingArea: ASDisplayNode {
|
||||
|
||||
public var openCurrentDate: (() -> Void)?
|
||||
|
||||
public var navigateToPosition: ((Float) -> Void)?
|
||||
private var navigatingToPositionOffset: CGFloat?
|
||||
|
||||
private var offsetBarTimer: SwiftSignalKit.Timer?
|
||||
private let hapticFeedback = HapticFeedback()
|
||||
|
||||
private var theme: PresentationTheme?
|
||||
|
||||
private struct State {
|
||||
var containerSize: CGSize
|
||||
var containerInsets: UIEdgeInsets
|
||||
var scrollingState: ListView.ScrollingIndicatorState?
|
||||
var isScrolling: Bool
|
||||
var isDragging: Bool
|
||||
var theme: PresentationTheme
|
||||
}
|
||||
|
||||
private var state: State?
|
||||
|
||||
override public init() {
|
||||
self.dateIndicator = ComponentHostView<Empty>()
|
||||
self.lineIndicator = UIImageView()
|
||||
@ -153,12 +171,19 @@ public final class SparseDiscreteScrollingArea: ASDisplayNode {
|
||||
offsetBarTimer.start()
|
||||
|
||||
strongSelf.isDragging = true
|
||||
strongSelf.initialDraggingOffset = strongSelf.lineIndicator.frame.minY
|
||||
strongSelf.draggingOffset = 0.0
|
||||
|
||||
/*if let scrollView = strongSelf.beginScrolling?() {
|
||||
strongSelf.draggingScrollView = scrollView
|
||||
strongSelf.scrollingInitialOffset = scrollView.contentOffset.y
|
||||
strongSelf.setContentOffset?(scrollView.contentOffset)
|
||||
}*/
|
||||
if let state = strongSelf.state {
|
||||
strongSelf.update(
|
||||
containerSize: state.containerSize,
|
||||
containerInsets: state.containerInsets,
|
||||
scrollingState: state.scrollingState,
|
||||
isScrolling: state.isScrolling,
|
||||
theme: state.theme,
|
||||
transition: .animated(duration: 0.2, curve: .easeInOut)
|
||||
)
|
||||
}
|
||||
|
||||
strongSelf.updateActivityTimer(isScrolling: false)
|
||||
},
|
||||
@ -177,8 +202,29 @@ public final class SparseDiscreteScrollingArea: ASDisplayNode {
|
||||
transition.updateSublayerTransformOffset(layer: strongSelf.dateIndicator.layer, offset: CGPoint(x: 0.0, y: 0.0))
|
||||
|
||||
strongSelf.isDragging = false
|
||||
if let _ = strongSelf.initialDraggingOffset, let _ = strongSelf.draggingOffset, let scrollIndicatorRange = strongSelf.scrollIndicatorRange {
|
||||
strongSelf.navigatingToPositionOffset = strongSelf.lineIndicator.frame.minY
|
||||
var absoluteOffset = strongSelf.lineIndicator.frame.minY - scrollIndicatorRange.0
|
||||
absoluteOffset /= (scrollIndicatorRange.1 - scrollIndicatorRange.0)
|
||||
absoluteOffset = abs(absoluteOffset)
|
||||
absoluteOffset = 1.0 - absoluteOffset
|
||||
strongSelf.navigateToPosition?(Float(absoluteOffset))
|
||||
} else {
|
||||
strongSelf.navigatingToPositionOffset = nil
|
||||
}
|
||||
strongSelf.initialDraggingOffset = nil
|
||||
strongSelf.draggingOffset = nil
|
||||
|
||||
//strongSelf.updateLineIndicator(transition: transition)
|
||||
if let state = strongSelf.state {
|
||||
strongSelf.update(
|
||||
containerSize: state.containerSize,
|
||||
containerInsets: state.containerInsets,
|
||||
scrollingState: state.scrollingState,
|
||||
isScrolling: state.isScrolling,
|
||||
theme: state.theme,
|
||||
transition: transition
|
||||
)
|
||||
}
|
||||
|
||||
strongSelf.updateActivityTimer(isScrolling: false)
|
||||
},
|
||||
@ -187,13 +233,24 @@ public final class SparseDiscreteScrollingArea: ASDisplayNode {
|
||||
return
|
||||
}
|
||||
|
||||
let _ = relativeOffset
|
||||
|
||||
if strongSelf.offsetBarTimer != nil {
|
||||
strongSelf.offsetBarTimer?.invalidate()
|
||||
strongSelf.offsetBarTimer = nil
|
||||
strongSelf.performOffsetBarTimerEvent()
|
||||
}
|
||||
|
||||
strongSelf.draggingOffset = relativeOffset
|
||||
|
||||
if let state = strongSelf.state {
|
||||
strongSelf.update(
|
||||
containerSize: state.containerSize,
|
||||
containerInsets: state.containerInsets,
|
||||
scrollingState: state.scrollingState,
|
||||
isScrolling: state.isScrolling,
|
||||
theme: state.theme,
|
||||
transition: .immediate
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
self.dragGesture = dragGesture
|
||||
@ -214,6 +271,20 @@ public final class SparseDiscreteScrollingArea: ASDisplayNode {
|
||||
self.hapticFeedback.tap()
|
||||
}
|
||||
|
||||
public func resetNavigatingToPosition() {
|
||||
self.navigatingToPositionOffset = nil
|
||||
if let state = self.state {
|
||||
self.update(
|
||||
containerSize: state.containerSize,
|
||||
containerInsets: state.containerInsets,
|
||||
scrollingState: state.scrollingState,
|
||||
isScrolling: state.isScrolling,
|
||||
theme: state.theme,
|
||||
transition: .animated(duration: 0.2, curve: .easeInOut)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
public func update(
|
||||
containerSize: CGSize,
|
||||
containerInsets: UIEdgeInsets,
|
||||
@ -222,6 +293,17 @@ public final class SparseDiscreteScrollingArea: ASDisplayNode {
|
||||
theme: PresentationTheme,
|
||||
transition: ContainedViewLayoutTransition
|
||||
) {
|
||||
let updateLineImage = self.state?.isDragging != self.isDragging || self.state?.theme !== theme
|
||||
|
||||
self.state = State(
|
||||
containerSize: containerSize,
|
||||
containerInsets: containerInsets,
|
||||
scrollingState: scrollingState,
|
||||
isScrolling: isScrolling,
|
||||
isDragging: self.isDragging,
|
||||
theme: theme
|
||||
)
|
||||
|
||||
self.containerSize = containerSize
|
||||
if self.theme !== theme {
|
||||
self.theme = theme
|
||||
@ -239,13 +321,24 @@ public final class SparseDiscreteScrollingArea: ASDisplayNode {
|
||||
default:
|
||||
break
|
||||
}*/
|
||||
|
||||
}
|
||||
|
||||
if updateLineImage {
|
||||
let lineColor: UIColor
|
||||
if theme.overallDarkAppearance {
|
||||
lineColor = UIColor(white: 0.0, alpha: 0.3)
|
||||
} else {
|
||||
lineColor = UIColor(white: 0.0, alpha: 0.3)
|
||||
}
|
||||
self.lineIndicator.image = generateStretchableFilledCircleImage(diameter: 3.0, color: lineColor, strokeColor: nil, strokeWidth: nil, backgroundColor: nil)
|
||||
if let image = generateStretchableFilledCircleImage(diameter: self.isDragging ? 6.0 : 3.0, color: lineColor, strokeColor: nil, strokeWidth: nil, backgroundColor: nil) {
|
||||
if transition.isAnimated, let previousImage = self.lineIndicator.image {
|
||||
self.lineIndicator.image = image
|
||||
self.lineIndicator.layer.animate(from: previousImage.cgImage!, to: image.cgImage!, keyPath: "contents", timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, duration: 0.2)
|
||||
} else {
|
||||
self.lineIndicator.image = image
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if self.dateIndicator.alpha.isZero {
|
||||
@ -253,9 +346,7 @@ public final class SparseDiscreteScrollingArea: ASDisplayNode {
|
||||
transition.updateSublayerTransformOffset(layer: self.dateIndicator.layer, offset: CGPoint())
|
||||
}
|
||||
|
||||
if isScrolling {
|
||||
self.updateActivityTimer(isScrolling: true)
|
||||
}
|
||||
self.updateActivityTimer(isScrolling: isScrolling)
|
||||
|
||||
let indicatorSize = self.dateIndicator.update(
|
||||
transition: .immediate,
|
||||
@ -272,7 +363,6 @@ public final class SparseDiscreteScrollingArea: ASDisplayNode {
|
||||
|
||||
self.dateIndicator.isHidden = true
|
||||
|
||||
|
||||
if let scrollingIndicatorState = scrollingState {
|
||||
let averageRangeItemHeight: CGFloat = 44.0
|
||||
|
||||
@ -317,7 +407,7 @@ public final class SparseDiscreteScrollingArea: ASDisplayNode {
|
||||
if approximateContentHeight <= 0 {
|
||||
indicatorHeight = 0.0
|
||||
} else {
|
||||
indicatorHeight = max(minIndicatorContentHeight, floor(visibleHeightWithoutIndicatorInsets * (containerSize.height - scrollingIndicatorState.insets.top - scrollingIndicatorState.insets.bottom) / approximateContentHeight))
|
||||
indicatorHeight = max(minIndicatorContentHeight, 44.0)//max(minIndicatorContentHeight, floor(visibleHeightWithoutIndicatorInsets * (containerSize.height - scrollingIndicatorState.insets.top - scrollingIndicatorState.insets.bottom) / approximateContentHeight))
|
||||
}
|
||||
|
||||
let upperBound = containerInsets.top + indicatorTopInset
|
||||
@ -325,8 +415,6 @@ public final class SparseDiscreteScrollingArea: ASDisplayNode {
|
||||
|
||||
let indicatorOffset = ceilToScreenPixels(upperBound * (1.0 - approximateScrollingProgress) + lowerBound * approximateScrollingProgress)
|
||||
|
||||
//var indicatorFrame = CGRect(origin: CGPoint(x: self.rotated ? indicatorSideInset : (self.visibleSize.width - 3.0 - indicatorSideInset), y: indicatorOffset), size: CGSize(width: 3.0, height: indicatorHeight))
|
||||
|
||||
var indicatorFrame = CGRect(origin: CGPoint(x: containerSize.width - 3.0 - indicatorSideInset, y: indicatorOffset), size: CGSize(width: 3.0, height: indicatorHeight))
|
||||
|
||||
if indicatorFrame.minY < containerInsets.top + indicatorTopInset {
|
||||
@ -344,39 +432,71 @@ public final class SparseDiscreteScrollingArea: ASDisplayNode {
|
||||
indicatorFrame.origin.y = indicatorTopInset
|
||||
}
|
||||
|
||||
if indicatorHeight >= visibleHeightWithoutIndicatorInsets {
|
||||
self.lineIndicator.isHidden = true
|
||||
self.lineIndicator.frame = indicatorFrame
|
||||
} else {
|
||||
if self.lineIndicator.isHidden {
|
||||
self.lineIndicator.isHidden = false
|
||||
self.lineIndicator.frame = indicatorFrame
|
||||
} else {
|
||||
self.lineIndicator.frame = indicatorFrame
|
||||
indicatorFrame.origin.y = containerSize.height - indicatorFrame.origin.y - indicatorFrame.height
|
||||
|
||||
if self.isDragging {
|
||||
indicatorFrame.origin.x -= 3.0
|
||||
indicatorFrame.size.width += 3.0
|
||||
}
|
||||
|
||||
var alternativeOffset: CGFloat?
|
||||
if let navigatingToPositionOffset = self.navigatingToPositionOffset {
|
||||
alternativeOffset = navigatingToPositionOffset
|
||||
} else if let initialDraggingOffset = self.initialDraggingOffset, let draggingOffset = self.draggingOffset {
|
||||
alternativeOffset = initialDraggingOffset + draggingOffset
|
||||
}
|
||||
|
||||
if let alternativeOffset = alternativeOffset {
|
||||
indicatorFrame.origin.y = alternativeOffset
|
||||
|
||||
if indicatorFrame.origin.y > containerSize.height - (containerInsets.top + indicatorBottomInset) - indicatorFrame.height {
|
||||
indicatorFrame.origin.y = containerSize.height - (containerInsets.top + indicatorBottomInset) - indicatorFrame.height
|
||||
}
|
||||
if indicatorFrame.origin.y < containerInsets.bottom + indicatorTopInset {
|
||||
indicatorFrame.origin.y = containerInsets.bottom + indicatorTopInset
|
||||
}
|
||||
}
|
||||
|
||||
transition.updateFrame(view: self.lineIndicator, frame: indicatorFrame)
|
||||
|
||||
if indicatorHeight >= visibleHeightWithoutIndicatorInsets {
|
||||
self.lineIndicator.isHidden = true
|
||||
} else {
|
||||
self.lineIndicator.isHidden = false
|
||||
}
|
||||
|
||||
self.scrollIndicatorRange = (
|
||||
containerInsets.bottom + indicatorTopInset,
|
||||
containerSize.height - (containerInsets.top + indicatorBottomInset) - self.lineIndicator.bounds.height
|
||||
)
|
||||
} else {
|
||||
self.lineIndicator.isHidden = true
|
||||
self.scrollIndicatorRange = nil
|
||||
}
|
||||
}
|
||||
|
||||
private func updateActivityTimer(isScrolling: Bool) {
|
||||
self.activityTimer?.invalidate()
|
||||
if self.isDragging || isScrolling {
|
||||
self.activityTimer?.invalidate()
|
||||
self.activityTimer = nil
|
||||
|
||||
if self.isDragging {
|
||||
let transition: ContainedViewLayoutTransition = .animated(duration: 0.3, curve: .easeInOut)
|
||||
transition.updateAlpha(layer: self.dateIndicator.layer, alpha: 1.0)
|
||||
transition.updateAlpha(layer: self.lineIndicator.layer, alpha: 1.0)
|
||||
} else {
|
||||
self.activityTimer = SwiftSignalKit.Timer(timeout: 2.0, repeat: false, completion: { [weak self] in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
let transition: ContainedViewLayoutTransition = .animated(duration: 0.3, curve: .easeInOut)
|
||||
transition.updateAlpha(layer: strongSelf.dateIndicator.layer, alpha: 0.0)
|
||||
transition.updateAlpha(layer: strongSelf.lineIndicator.layer, alpha: 0.0)
|
||||
}, queue: .mainQueue())
|
||||
self.activityTimer?.start()
|
||||
if self.activityTimer == nil {
|
||||
self.activityTimer = SwiftSignalKit.Timer(timeout: 1.0, repeat: false, completion: { [weak self] in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
strongSelf.activityTimer = nil
|
||||
|
||||
let transition: ContainedViewLayoutTransition = .animated(duration: 0.3, curve: .easeInOut)
|
||||
transition.updateAlpha(layer: strongSelf.dateIndicator.layer, alpha: 0.0)
|
||||
transition.updateAlpha(layer: strongSelf.lineIndicator.layer, alpha: 0.0)
|
||||
}, queue: .mainQueue())
|
||||
self.activityTimer?.start()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -327,6 +327,7 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
self.historyNode.rotated = true
|
||||
|
||||
self.historyScrollingArea = SparseDiscreteScrollingArea()
|
||||
self.historyNode.historyScrollingArea = self.historyScrollingArea
|
||||
|
||||
self.historyNodeContainer = ASDisplayNode()
|
||||
self.historyNodeContainer.addSubnode(self.historyNode)
|
||||
@ -529,23 +530,6 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
self.textInputPanelNode?.updateActivity = { [weak self] in
|
||||
self?.updateTypingActivity(true)
|
||||
}
|
||||
|
||||
self.historyNode.updateScrollingIndicator = { [weak self] scrollingState, transition in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
guard let (_, _) = strongSelf.validLayout else {
|
||||
return
|
||||
}
|
||||
strongSelf.historyScrollingArea.update(
|
||||
containerSize: strongSelf.historyNode.bounds.size,
|
||||
containerInsets: UIEdgeInsets(top: strongSelf.historyNode.scrollIndicatorInsets.bottom, left: 0.0, bottom: strongSelf.historyNode.scrollIndicatorInsets.top, right: 0.0),
|
||||
scrollingState: scrollingState,
|
||||
isScrolling: true,
|
||||
theme: strongSelf.chatPresentationInterfaceState.theme,
|
||||
transition: transition
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
deinit {
|
||||
|
@ -76,7 +76,7 @@ func chatHistoryEntriesForView(
|
||||
}
|
||||
|
||||
|
||||
var groupBucket: [(Message, Bool, ChatHistoryMessageSelection, ChatMessageEntryAttributes)] = []
|
||||
var groupBucket: [(Message, Bool, ChatHistoryMessageSelection, ChatMessageEntryAttributes, MessageHistoryEntryLocation?)] = []
|
||||
var count = 0
|
||||
loop: for entry in view.entries {
|
||||
var message = entry.message
|
||||
@ -154,7 +154,7 @@ func chatHistoryEntriesForView(
|
||||
} else {
|
||||
selection = .none
|
||||
}
|
||||
groupBucket.append((message, isRead, selection, ChatMessageEntryAttributes(rank: adminRank, isContact: entry.attributes.authorIsContact, contentTypeHint: contentTypeHint, updatingMedia: updatingMedia[message.id], isPlaying: false)))
|
||||
groupBucket.append((message, isRead, selection, ChatMessageEntryAttributes(rank: adminRank, isContact: entry.attributes.authorIsContact, contentTypeHint: contentTypeHint, updatingMedia: updatingMedia[message.id], isPlaying: false), entry.location))
|
||||
} else {
|
||||
let selection: ChatHistoryMessageSelection
|
||||
if let selectedMessages = selectedMessages {
|
||||
@ -162,7 +162,7 @@ func chatHistoryEntriesForView(
|
||||
} else {
|
||||
selection = .none
|
||||
}
|
||||
entries.append(.MessageEntry(message, presentationData, isRead, entry.monthLocation, selection, ChatMessageEntryAttributes(rank: adminRank, isContact: entry.attributes.authorIsContact, contentTypeHint: contentTypeHint, updatingMedia: updatingMedia[message.id], isPlaying: message.index == associatedData.currentlyPlayingMessageId)))
|
||||
entries.append(.MessageEntry(message, presentationData, isRead, entry.location, selection, ChatMessageEntryAttributes(rank: adminRank, isContact: entry.attributes.authorIsContact, contentTypeHint: contentTypeHint, updatingMedia: updatingMedia[message.id], isPlaying: message.index == associatedData.currentlyPlayingMessageId)))
|
||||
}
|
||||
} else {
|
||||
let selection: ChatHistoryMessageSelection
|
||||
@ -171,7 +171,7 @@ func chatHistoryEntriesForView(
|
||||
} else {
|
||||
selection = .none
|
||||
}
|
||||
entries.append(.MessageEntry(message, presentationData, isRead, entry.monthLocation, selection, ChatMessageEntryAttributes(rank: adminRank, isContact: entry.attributes.authorIsContact, contentTypeHint: contentTypeHint, updatingMedia: updatingMedia[message.id], isPlaying: message.index == associatedData.currentlyPlayingMessageId)))
|
||||
entries.append(.MessageEntry(message, presentationData, isRead, entry.location, selection, ChatMessageEntryAttributes(rank: adminRank, isContact: entry.attributes.authorIsContact, contentTypeHint: contentTypeHint, updatingMedia: updatingMedia[message.id], isPlaying: message.index == associatedData.currentlyPlayingMessageId)))
|
||||
}
|
||||
}
|
||||
|
||||
@ -225,9 +225,9 @@ func chatHistoryEntriesForView(
|
||||
|
||||
addedThreadHead = true
|
||||
if messages.count > 1, let groupInfo = messages[0].groupInfo {
|
||||
var groupMessages: [(Message, Bool, ChatHistoryMessageSelection, ChatMessageEntryAttributes)] = []
|
||||
var groupMessages: [(Message, Bool, ChatHistoryMessageSelection, ChatMessageEntryAttributes, MessageHistoryEntryLocation?)] = []
|
||||
for message in messages {
|
||||
groupMessages.append((message, false, .none, ChatMessageEntryAttributes(rank: adminRank, isContact: false, contentTypeHint: contentTypeHint, updatingMedia: updatingMedia[message.id], isPlaying: false)))
|
||||
groupMessages.append((message, false, .none, ChatMessageEntryAttributes(rank: adminRank, isContact: false, contentTypeHint: contentTypeHint, updatingMedia: updatingMedia[message.id], isPlaying: false), nil))
|
||||
}
|
||||
entries.insert(.MessageGroupEntry(groupInfo, groupMessages, presentationData), at: 0)
|
||||
} else {
|
||||
|
@ -36,8 +36,8 @@ public struct ChatMessageEntryAttributes: Equatable {
|
||||
}
|
||||
|
||||
enum ChatHistoryEntry: Identifiable, Comparable {
|
||||
case MessageEntry(Message, ChatPresentationData, Bool, MessageHistoryEntryMonthLocation?, ChatHistoryMessageSelection, ChatMessageEntryAttributes)
|
||||
case MessageGroupEntry(MessageGroupInfo, [(Message, Bool, ChatHistoryMessageSelection, ChatMessageEntryAttributes)], ChatPresentationData)
|
||||
case MessageEntry(Message, ChatPresentationData, Bool, MessageHistoryEntryLocation?, ChatHistoryMessageSelection, ChatMessageEntryAttributes)
|
||||
case MessageGroupEntry(MessageGroupInfo, [(Message, Bool, ChatHistoryMessageSelection, ChatMessageEntryAttributes, MessageHistoryEntryLocation?)], ChatPresentationData)
|
||||
case UnreadEntry(MessageIndex, ChatPresentationData)
|
||||
case ReplyCountEntry(MessageIndex, Bool, Int, ChatPresentationData)
|
||||
case ChatInfoEntry(String, String, ChatPresentationData)
|
||||
@ -130,8 +130,8 @@ enum ChatHistoryEntry: Identifiable, Comparable {
|
||||
case let .MessageGroupEntry(lhsGroupInfo, lhsMessages, lhsPresentationData):
|
||||
if case let .MessageGroupEntry(rhsGroupInfo, rhsMessages, rhsPresentationData) = rhs, lhsGroupInfo == rhsGroupInfo, lhsPresentationData === rhsPresentationData, lhsMessages.count == rhsMessages.count {
|
||||
for i in 0 ..< lhsMessages.count {
|
||||
let (lhsMessage, lhsRead, lhsSelection, lhsAttributes) = lhsMessages[i]
|
||||
let (rhsMessage, rhsRead, rhsSelection, rhsAttributes) = rhsMessages[i]
|
||||
let (lhsMessage, lhsRead, lhsSelection, lhsAttributes, lhsLocation) = lhsMessages[i]
|
||||
let (rhsMessage, rhsRead, rhsSelection, rhsAttributes, rhsLocation) = rhsMessages[i]
|
||||
|
||||
if lhsMessage.id != rhsMessage.id {
|
||||
return false
|
||||
@ -177,6 +177,9 @@ enum ChatHistoryEntry: Identifiable, Comparable {
|
||||
if lhsAttributes != rhsAttributes {
|
||||
return false
|
||||
}
|
||||
if lhsLocation != rhsLocation {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
|
@ -18,6 +18,7 @@ import AccountContext
|
||||
import ChatInterfaceState
|
||||
import ChatListUI
|
||||
import ComponentFlow
|
||||
import SparseItemGrid
|
||||
|
||||
extension ChatReplyThreadMessage {
|
||||
var effectiveTopId: MessageId {
|
||||
@ -212,11 +213,11 @@ extension ListMessageItemInteraction {
|
||||
private func mappedInsertEntries(context: AccountContext, chatLocation: ChatLocation, associatedData: ChatMessageItemAssociatedData, controllerInteraction: ChatControllerInteraction, mode: ChatHistoryListMode, lastHeaderId: Int64, entries: [ChatHistoryViewTransitionInsertEntry]) -> [ListViewInsertItem] {
|
||||
return entries.map { entry -> ListViewInsertItem in
|
||||
switch entry.entry {
|
||||
case let .MessageEntry(message, presentationData, read, _, selection, attributes):
|
||||
case let .MessageEntry(message, presentationData, read, location, selection, attributes):
|
||||
let item: ListViewItem
|
||||
switch mode {
|
||||
case .bubbles:
|
||||
item = ChatMessageItem(presentationData: presentationData, context: context, chatLocation: chatLocation, associatedData: associatedData, controllerInteraction: controllerInteraction, content: .message(message: message, read: read, selection: selection, attributes: attributes))
|
||||
item = ChatMessageItem(presentationData: presentationData, context: context, chatLocation: chatLocation, associatedData: associatedData, controllerInteraction: controllerInteraction, content: .message(message: message, read: read, selection: selection, attributes: attributes, location: location))
|
||||
case let .list(_, _, displayHeaders, hintLinks, isGlobalSearch):
|
||||
let displayHeader: Bool
|
||||
switch displayHeaders {
|
||||
@ -257,11 +258,11 @@ private func mappedInsertEntries(context: AccountContext, chatLocation: ChatLoca
|
||||
private func mappedUpdateEntries(context: AccountContext, chatLocation: ChatLocation, associatedData: ChatMessageItemAssociatedData, controllerInteraction: ChatControllerInteraction, mode: ChatHistoryListMode, lastHeaderId: Int64, entries: [ChatHistoryViewTransitionUpdateEntry]) -> [ListViewUpdateItem] {
|
||||
return entries.map { entry -> ListViewUpdateItem in
|
||||
switch entry.entry {
|
||||
case let .MessageEntry(message, presentationData, read, _, selection, attributes):
|
||||
case let .MessageEntry(message, presentationData, read, location, selection, attributes):
|
||||
let item: ListViewItem
|
||||
switch mode {
|
||||
case .bubbles:
|
||||
item = ChatMessageItem(presentationData: presentationData, context: context, chatLocation: chatLocation, associatedData: associatedData, controllerInteraction: controllerInteraction, content: .message(message: message, read: read, selection: selection, attributes: attributes))
|
||||
item = ChatMessageItem(presentationData: presentationData, context: context, chatLocation: chatLocation, associatedData: associatedData, controllerInteraction: controllerInteraction, content: .message(message: message, read: read, selection: selection, attributes: attributes, location: location))
|
||||
case let .list(_, _, displayHeaders, hintLinks, isGlobalSearch):
|
||||
let displayHeader: Bool
|
||||
switch displayHeaders {
|
||||
@ -563,7 +564,22 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
||||
private var preloadAdPeerId: PeerId?
|
||||
private let preloadAdPeerDisposable = MetaDisposable()
|
||||
|
||||
var historyScrollingArea: SparseDiscreteScrollingArea? {
|
||||
didSet {
|
||||
oldValue?.navigateToPosition = nil
|
||||
if let historyScrollingArea = self.historyScrollingArea {
|
||||
historyScrollingArea.navigateToPosition = { [weak self] position in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
strongSelf.navigateToAbsolutePosition(position: position)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
private var scrollingState: ListView.ScrollingIndicatorState?
|
||||
private let sparseScrollingContext: SparseMessageScrollingContext?
|
||||
private let scrollNavigationDisposable = MetaDisposable()
|
||||
|
||||
private let clientId: Atomic<Int32>
|
||||
|
||||
@ -774,7 +790,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
||||
historyViewUpdate = self.chatHistoryLocationPromise.get()
|
||||
|> distinctUntilChanged
|
||||
|> mapToSignal { location in
|
||||
return chatHistoryViewForLocation(location, context: context, chatLocation: chatLocation, chatLocationContextHolder: chatLocationContextHolder, scheduled: isScheduledMessages, fixedCombinedReadStates: fixedCombinedReadStates.with { $0 }, tagMask: tagMask, appendMessagesFromTheSameGroup: appendMessagesFromTheSameGroup, additionalData: additionalData)
|
||||
return chatHistoryViewForLocation(location, context: context, chatLocation: chatLocation, chatLocationContextHolder: chatLocationContextHolder, scheduled: isScheduledMessages, fixedCombinedReadStates: fixedCombinedReadStates.with { $0 }, tagMask: tagMask, appendMessagesFromTheSameGroup: appendMessagesFromTheSameGroup, additionalData: additionalData, orderStatistics: [.combinedLocation])
|
||||
|> beforeNext { viewUpdate in
|
||||
switch viewUpdate {
|
||||
case let .HistoryView(view, _, _, _, _, _, _):
|
||||
@ -974,7 +990,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
||||
break loop
|
||||
}
|
||||
case let .MessageGroupEntry(_, messages, _):
|
||||
for (message, _, _, _) in messages {
|
||||
for (message, _, _, _, _) in messages {
|
||||
if message.adAttribute == nil {
|
||||
anchorIndex = message.index
|
||||
break loop
|
||||
@ -1383,6 +1399,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
||||
self?.isInteractivelyScrollingValue = true
|
||||
self?.isInteractivelyScrollingPromise.set(true)
|
||||
self?.beganDragging?()
|
||||
self?.updateHistoryScrollingArea(transition: .immediate)
|
||||
}
|
||||
|
||||
self.endedInteractiveDragging = { [weak self] _ in
|
||||
@ -1424,6 +1441,15 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
||||
}
|
||||
strongSelf.isInteractivelyScrollingValue = false
|
||||
strongSelf.isInteractivelyScrollingPromise.set(false)
|
||||
strongSelf.updateHistoryScrollingArea(transition: .immediate)
|
||||
}
|
||||
|
||||
self.updateScrollingIndicator = { [weak self] scrollingState, transition in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
strongSelf.scrollingState = scrollingState
|
||||
strongSelf.updateHistoryScrollingArea(transition: transition)
|
||||
}
|
||||
|
||||
let selectionRecognizer = ChatHistoryListSelectionRecognizer(target: self, action: #selector(self.selectionPanGesture(_:)))
|
||||
@ -1443,12 +1469,136 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
||||
self.canReadHistoryDisposable?.dispose()
|
||||
self.loadedMessagesFromCachedDataDisposable?.dispose()
|
||||
self.preloadAdPeerDisposable.dispose()
|
||||
self.scrollNavigationDisposable.dispose()
|
||||
}
|
||||
|
||||
public func setLoadStateUpdated(_ f: @escaping (ChatHistoryNodeLoadState, Bool) -> Void) {
|
||||
self.loadStateUpdated = f
|
||||
}
|
||||
|
||||
private func updateHistoryScrollingArea(transition: ContainedViewLayoutTransition) {
|
||||
guard let historyScrollingArea = self.historyScrollingArea else {
|
||||
return
|
||||
}
|
||||
guard let transactionState = self.opaqueTransactionState as? ChatHistoryTransactionOpaqueState else {
|
||||
return
|
||||
}
|
||||
|
||||
let historyView = transactionState.historyView
|
||||
|
||||
var updatedScrollingState = self.scrollingState
|
||||
if var scrollingState = updatedScrollingState {
|
||||
let convertedIndex = historyView.filteredEntries.count - scrollingState.topItem.index - 1
|
||||
if convertedIndex < 0 || convertedIndex >= historyView.filteredEntries.count {
|
||||
return
|
||||
}
|
||||
let firstItem = historyView.filteredEntries[convertedIndex]
|
||||
var location: MessageHistoryEntryLocation?
|
||||
switch firstItem {
|
||||
case let .MessageEntry(_, _, _, locationValue, _, _):
|
||||
location = locationValue
|
||||
case let .MessageGroupEntry(_, group, _):
|
||||
if let locationValue = group.last?.4 {
|
||||
location = locationValue
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
if let location = location {
|
||||
let locationDelta = (location.count - location.index - 1) - scrollingState.topItem.index
|
||||
scrollingState.topItem.index += locationDelta
|
||||
scrollingState.bottomItem.index += locationDelta
|
||||
scrollingState.itemCount = max(scrollingState.itemCount, location.count)
|
||||
}
|
||||
|
||||
updatedScrollingState = scrollingState
|
||||
}
|
||||
|
||||
historyScrollingArea.update(
|
||||
containerSize: self.bounds.size,
|
||||
containerInsets: UIEdgeInsets(top: self.scrollIndicatorInsets.top, left: 0.0, bottom: self.scrollIndicatorInsets.bottom, right: 0.0),
|
||||
scrollingState: updatedScrollingState,
|
||||
isScrolling: self.isDragging || self.isDeceleratingAfterTracking,
|
||||
theme: self.currentPresentationData.theme.theme,
|
||||
transition: transition
|
||||
)
|
||||
}
|
||||
|
||||
private func navigateToAbsolutePosition(position: Float) {
|
||||
guard let transactionState = self.opaqueTransactionState as? ChatHistoryTransactionOpaqueState else {
|
||||
return
|
||||
}
|
||||
|
||||
let historyView = transactionState.historyView
|
||||
|
||||
let convertedIndex = 0
|
||||
if convertedIndex < 0 || convertedIndex >= historyView.filteredEntries.count {
|
||||
self.historyScrollingArea?.resetNavigatingToPosition()
|
||||
return
|
||||
}
|
||||
let firstItem = historyView.filteredEntries[convertedIndex]
|
||||
var location: MessageHistoryEntryLocation?
|
||||
switch firstItem {
|
||||
case let .MessageEntry(_, _, _, locationValue, _, _):
|
||||
location = locationValue
|
||||
case let .MessageGroupEntry(_, group, _):
|
||||
if let locationValue = group.last?.4 {
|
||||
location = locationValue
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
if let location = location {
|
||||
var absoluteIndex = Int(Float(location.count) * position)
|
||||
if absoluteIndex >= location.count {
|
||||
absoluteIndex = location.count - 1
|
||||
}
|
||||
if absoluteIndex < 0 {
|
||||
absoluteIndex = 0
|
||||
}
|
||||
if case let .peer(peerId) = self.chatLocation {
|
||||
let _ = (self.context.account.postbox.transaction { transaction -> MessageIndex? in
|
||||
return transaction.findMessageAtAbsoluteIndex(peerId: peerId, namespace: Namespaces.Message.Cloud, index: absoluteIndex)
|
||||
}
|
||||
|> deliverOnMainQueue).start(next: { [weak self] index in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
if let index = index {
|
||||
let content: ChatHistoryLocation = .Scroll(index: .message(index), anchorIndex: .message(index), sourceIndex: .message(index), scrollPosition: .top(0.0), animated: false, highlight: false)
|
||||
|
||||
strongSelf.scrollNavigationDisposable.set((preloadedChatHistoryViewForLocation(ChatHistoryLocationInput(content: content, id: 0), context: strongSelf.context, chatLocation: strongSelf.chatLocation, subject: strongSelf.subject, chatLocationContextHolder: strongSelf.chatLocationContextHolder, fixedCombinedReadStates: nil, tagMask: nil, additionalData: [])
|
||||
|> map { historyView -> Bool in
|
||||
switch historyView {
|
||||
case .Loading:
|
||||
return false
|
||||
case .HistoryView:
|
||||
return true
|
||||
}
|
||||
}
|
||||
|> filter { $0 }
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { _ in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
strongSelf.chatHistoryLocationValue = ChatHistoryLocationInput(content: content, id: (strongSelf.chatHistoryLocationValue?.id).flatMap({ $0 + 1 }) ?? 0)
|
||||
Queue.mainQueue().after(0.5, {
|
||||
self?.historyScrollingArea?.resetNavigatingToPosition()
|
||||
})
|
||||
}))
|
||||
} else {
|
||||
strongSelf.historyScrollingArea?.resetNavigatingToPosition()
|
||||
}
|
||||
})
|
||||
}
|
||||
} else {
|
||||
self.historyScrollingArea?.resetNavigatingToPosition()
|
||||
}
|
||||
}
|
||||
|
||||
private func maybeUpdateOverscrollAction(offset: CGFloat?) {
|
||||
if self.freezeOverscrollControl {
|
||||
return
|
||||
@ -1663,7 +1813,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
||||
topVisibleMessageRange = ChatTopVisibleMessageRange(lowerBound: message.id, upperBound: message.id, isLast: i == historyView.filteredEntries.count - 1)
|
||||
}
|
||||
case let .MessageGroupEntry(_, messages, _):
|
||||
for (message, _, _, _) in messages {
|
||||
for (message, _, _, _, _) in messages {
|
||||
var hasUnconsumedMention = false
|
||||
var hasUnconsumedContent = false
|
||||
if message.tags.contains(.unseenPersonalMessage) {
|
||||
@ -1726,7 +1876,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
||||
}
|
||||
}
|
||||
case let .MessageGroupEntry(_, messages, _):
|
||||
for (message, _, _, _) in messages {
|
||||
for (message, _, _, _, _) in messages {
|
||||
var stop = false
|
||||
for media in message.media {
|
||||
if !addMediaToPrefetch(message, media, &toEarlierMediaMessages) {
|
||||
@ -1754,7 +1904,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
||||
}
|
||||
}
|
||||
case let .MessageGroupEntry(_, messages, _):
|
||||
for (message, _, _, _) in messages {
|
||||
for (message, _, _, _, _) in messages {
|
||||
for media in message.media {
|
||||
if !addMediaToPrefetch(message, media, &toLaterMediaMessages) {
|
||||
break outer
|
||||
@ -1979,7 +2129,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
||||
return message
|
||||
}
|
||||
} else if case let .MessageGroupEntry(_, messages, _) = entry {
|
||||
for (message, _, _, _) in messages {
|
||||
for (message, _, _, _, _) in messages {
|
||||
if message.id == id {
|
||||
return message
|
||||
}
|
||||
@ -1998,7 +2148,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
||||
return [message]
|
||||
}
|
||||
} else if case let .MessageGroupEntry(_, messages, _) = entry {
|
||||
for (message, _, _, _) in messages {
|
||||
for (message, _, _, _, _) in messages {
|
||||
if message.id == id {
|
||||
return messages.map { $0.0 }
|
||||
}
|
||||
@ -2017,7 +2167,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
||||
return
|
||||
}
|
||||
} else if case let .MessageGroupEntry(_, messages, _) = entry {
|
||||
for (message, _, _, _) in messages {
|
||||
for (message, _, _, _, _) in messages {
|
||||
if !f(message) {
|
||||
return
|
||||
}
|
||||
@ -2449,13 +2599,13 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
||||
|
||||
loop: for i in 0 ..< historyView.filteredEntries.count {
|
||||
switch historyView.filteredEntries[i] {
|
||||
case let .MessageEntry(message, presentationData, read, _, selection, attributes):
|
||||
case let .MessageEntry(message, presentationData, read, location, selection, attributes):
|
||||
if message.id == id {
|
||||
let index = historyView.filteredEntries.count - 1 - i
|
||||
let item: ListViewItem
|
||||
switch self.mode {
|
||||
case .bubbles:
|
||||
item = ChatMessageItem(presentationData: presentationData, context: self.context, chatLocation: self.chatLocation, associatedData: associatedData, controllerInteraction: self.controllerInteraction, content: .message(message: message, read: read, selection: selection, attributes: attributes))
|
||||
item = ChatMessageItem(presentationData: presentationData, context: self.context, chatLocation: self.chatLocation, associatedData: associatedData, controllerInteraction: self.controllerInteraction, content: .message(message: message, read: read, selection: selection, attributes: attributes, location: location))
|
||||
case let .list(_, _, displayHeaders, hintLinks, isGlobalSearch):
|
||||
let displayHeader: Bool
|
||||
switch displayHeaders {
|
||||
@ -2499,13 +2649,13 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
||||
|
||||
loop: for i in 0 ..< historyView.filteredEntries.count {
|
||||
switch historyView.filteredEntries[i] {
|
||||
case let .MessageEntry(message, presentationData, read, _, selection, attributes):
|
||||
case let .MessageEntry(message, presentationData, read, location, selection, attributes):
|
||||
if message.stableId == stableId {
|
||||
let index = historyView.filteredEntries.count - 1 - i
|
||||
let item: ListViewItem
|
||||
switch self.mode {
|
||||
case .bubbles:
|
||||
item = ChatMessageItem(presentationData: presentationData, context: self.context, chatLocation: self.chatLocation, associatedData: associatedData, controllerInteraction: self.controllerInteraction, content: .message(message: message, read: read, selection: selection, attributes: attributes))
|
||||
item = ChatMessageItem(presentationData: presentationData, context: self.context, chatLocation: self.chatLocation, associatedData: associatedData, controllerInteraction: self.controllerInteraction, content: .message(message: message, read: read, selection: selection, attributes: attributes, location: location))
|
||||
case let .list(_, _, displayHeaders, hintLinks, isGlobalSearch):
|
||||
let displayHeader: Bool
|
||||
switch displayHeaders {
|
||||
@ -2536,7 +2686,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
||||
if resultMessages == nil, let itemNode = itemNode as? ListViewItemNode, itemNode.frame.contains(point) {
|
||||
if let itemNode = itemNode as? ChatMessageItemView, let item = itemNode.item {
|
||||
switch item.content {
|
||||
case let .message(message, _, _ , _):
|
||||
case let .message(message, _, _ , _, _):
|
||||
resultMessages = [message]
|
||||
case let .group(messages):
|
||||
resultMessages = messages.map { $0.0 }
|
||||
|
@ -1166,7 +1166,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
|
||||
var authorRank: CachedChannelAdminRank?
|
||||
var authorIsChannel: Bool = false
|
||||
switch content {
|
||||
case let .message(message, _, _, attributes):
|
||||
case let .message(message, _, _, attributes, _):
|
||||
if let peer = message.peers[message.id.peerId] as? TelegramChannel {
|
||||
if case .broadcast = peer.info {
|
||||
} else {
|
||||
@ -1241,7 +1241,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
|
||||
var isItemEdited = false
|
||||
|
||||
switch item.content {
|
||||
case let .message(message, value, _, _):
|
||||
case let .message(message, value, _, _, _):
|
||||
read = value
|
||||
isItemPinned = message.tags.contains(.pinned)
|
||||
case let .group(messages):
|
||||
@ -1322,7 +1322,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
|
||||
case .message:
|
||||
break
|
||||
case let .group(messages):
|
||||
for (m, _, selection, _) in messages {
|
||||
for (m, _, selection, _, _) in messages {
|
||||
if m.id == message.id {
|
||||
switch selection {
|
||||
case .none:
|
||||
@ -3312,7 +3312,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
|
||||
|
||||
var canHaveSelection = true
|
||||
switch item.content {
|
||||
case let .message(message, _, _, _):
|
||||
case let .message(message, _, _, _, _):
|
||||
for media in message.media {
|
||||
if let action = media as? TelegramMediaAction {
|
||||
if case .phoneCall = action.action { } else {
|
||||
@ -3336,11 +3336,11 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
|
||||
let incoming = item.content.effectivelyIncoming(item.context.account.peerId, associatedData: item.associatedData)
|
||||
|
||||
switch item.content {
|
||||
case let .message(message, _, _, _):
|
||||
case let .message(message, _, _, _, _):
|
||||
selected = selectionState.selectedIds.contains(message.id)
|
||||
case let .group(messages: messages):
|
||||
var allSelected = !messages.isEmpty
|
||||
for (message, _, _, _) in messages {
|
||||
for (message, _, _, _, _) in messages {
|
||||
if !selectionState.selectedIds.contains(message.id) {
|
||||
allSelected = false
|
||||
break
|
||||
@ -3361,7 +3361,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
|
||||
let selectionNode = ChatMessageSelectionNode(wallpaper: item.presentationData.theme.wallpaper, theme: item.presentationData.theme.theme, toggle: { [weak self] value in
|
||||
if let strongSelf = self, let item = strongSelf.item {
|
||||
switch item.content {
|
||||
case let .message(message, _, _, _):
|
||||
case let .message(message, _, _, _, _):
|
||||
item.controllerInteraction.toggleMessagesSelection([message.id], value)
|
||||
case let .group(messages):
|
||||
item.controllerInteraction.toggleMessagesSelection(messages.map { $0.0.id }, value)
|
||||
|
@ -12,15 +12,15 @@ import Emoji
|
||||
import PersistentStringHash
|
||||
|
||||
public enum ChatMessageItemContent: Sequence {
|
||||
case message(message: Message, read: Bool, selection: ChatHistoryMessageSelection, attributes: ChatMessageEntryAttributes)
|
||||
case group(messages: [(Message, Bool, ChatHistoryMessageSelection, ChatMessageEntryAttributes)])
|
||||
case message(message: Message, read: Bool, selection: ChatHistoryMessageSelection, attributes: ChatMessageEntryAttributes, location: MessageHistoryEntryLocation?)
|
||||
case group(messages: [(Message, Bool, ChatHistoryMessageSelection, ChatMessageEntryAttributes, MessageHistoryEntryLocation?)])
|
||||
|
||||
func effectivelyIncoming(_ accountPeerId: PeerId, associatedData: ChatMessageItemAssociatedData? = nil) -> Bool {
|
||||
if let subject = associatedData?.subject, case .forwardedMessages = subject {
|
||||
return false
|
||||
}
|
||||
switch self {
|
||||
case let .message(message, _, _, _):
|
||||
case let .message(message, _, _, _, _):
|
||||
return message.effectivelyIncoming(accountPeerId)
|
||||
case let .group(messages):
|
||||
return messages[0].0.effectivelyIncoming(accountPeerId)
|
||||
@ -29,7 +29,7 @@ public enum ChatMessageItemContent: Sequence {
|
||||
|
||||
var index: MessageIndex {
|
||||
switch self {
|
||||
case let .message(message, _, _, _):
|
||||
case let .message(message, _, _, _, _):
|
||||
return message.index
|
||||
case let .group(messages):
|
||||
return messages[0].0.index
|
||||
@ -38,7 +38,7 @@ public enum ChatMessageItemContent: Sequence {
|
||||
|
||||
var firstMessage: Message {
|
||||
switch self {
|
||||
case let .message(message, _, _, _):
|
||||
case let .message(message, _, _, _, _):
|
||||
return message
|
||||
case let .group(messages):
|
||||
return messages[0].0
|
||||
@ -47,7 +47,7 @@ public enum ChatMessageItemContent: Sequence {
|
||||
|
||||
var firstMessageAttributes: ChatMessageEntryAttributes {
|
||||
switch self {
|
||||
case let .message(_, _, _, attributes):
|
||||
case let .message(_, _, _, attributes, _):
|
||||
return attributes
|
||||
case let .group(messages):
|
||||
return messages[0].3
|
||||
@ -58,7 +58,7 @@ public enum ChatMessageItemContent: Sequence {
|
||||
var index = 0
|
||||
return AnyIterator { () -> (Message, ChatMessageEntryAttributes)? in
|
||||
switch self {
|
||||
case let .message(message, _, _, attributes):
|
||||
case let .message(message, _, _, attributes, _):
|
||||
if index == 0 {
|
||||
index += 1
|
||||
return (message, attributes)
|
||||
@ -265,7 +265,7 @@ public final class ChatMessageItem: ListViewItem, CustomStringConvertible {
|
||||
|
||||
var message: Message {
|
||||
switch self.content {
|
||||
case let .message(message, _, _, _):
|
||||
case let .message(message, _, _, _, _):
|
||||
return message
|
||||
case let .group(messages):
|
||||
return messages[0].0
|
||||
@ -274,7 +274,7 @@ public final class ChatMessageItem: ListViewItem, CustomStringConvertible {
|
||||
|
||||
var read: Bool {
|
||||
switch self.content {
|
||||
case let .message(_, read, _, _):
|
||||
case let .message(_, read, _, _, _):
|
||||
return read
|
||||
case let .group(messages):
|
||||
return messages[0].1
|
||||
@ -433,7 +433,7 @@ public final class ChatMessageItem: ListViewItem, CustomStringConvertible {
|
||||
}
|
||||
|
||||
if viewClassName == ChatMessageBubbleItemNode.self && self.presentationData.largeEmoji && self.message.media.isEmpty {
|
||||
if case let .message(_, _, _, attributes) = self.content {
|
||||
if case let .message(_, _, _, attributes, _) = self.content {
|
||||
switch attributes.contentTypeHint {
|
||||
case .largeEmoji:
|
||||
viewClassName = ChatMessageStickerItemNode.self
|
||||
|
@ -774,12 +774,12 @@ public class ChatMessageItemView: ListViewItemNode {
|
||||
var isHighlightedInOverlay = false
|
||||
if let item = self.item, let contextHighlightedState = item.controllerInteraction.contextHighlightedState {
|
||||
switch item.content {
|
||||
case let .message(message, _, _, _):
|
||||
case let .message(message, _, _, _, _):
|
||||
if contextHighlightedState.messageStableId == message.stableId {
|
||||
isHighlightedInOverlay = true
|
||||
}
|
||||
case let .group(messages):
|
||||
for (message, _, _, _) in messages {
|
||||
for (message, _, _, _, _) in messages {
|
||||
if contextHighlightedState.messageStableId == message.stableId {
|
||||
isHighlightedInOverlay = true
|
||||
break
|
||||
|
@ -114,7 +114,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
|
||||
let action = TelegramMediaActionType.titleUpdated(title: new)
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes()))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
case let .changeAbout(prev, new):
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
var author: Peer?
|
||||
@ -145,14 +145,14 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
}
|
||||
let action = TelegramMediaActionType.customText(text: text, entities: entities)
|
||||
let message = Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: 1), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes()))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
case .content:
|
||||
let peers = SimpleDictionary<PeerId, Peer>()
|
||||
let attributes: [MessageAttribute] = []
|
||||
let prevMessage = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: prev, attributes: [], media: [], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: new, attributes: attributes, media: [], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes()), additionalContent: !prev.isEmpty ? .eventLogPreviousDescription(prevMessage) : nil)
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil), additionalContent: !prev.isEmpty ? .eventLogPreviousDescription(prevMessage) : nil)
|
||||
}
|
||||
case let .changeUsername(prev, new):
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
@ -183,7 +183,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
}
|
||||
let action: TelegramMediaActionType = TelegramMediaActionType.customText(text: text, entities: entities)
|
||||
let message = Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: 1), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes()))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
case .content:
|
||||
var previousAttributes: [MessageAttribute] = []
|
||||
var attributes: [MessageAttribute] = []
|
||||
@ -202,7 +202,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
|
||||
let prevMessage = Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: 1), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: prevText, attributes: previousAttributes, media: [], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: text, attributes: attributes, media: [], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes()), additionalContent: !prev.isEmpty ? .eventLogPreviousLink(prevMessage) : nil)
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil), additionalContent: !prev.isEmpty ? .eventLogPreviousLink(prevMessage) : nil)
|
||||
}
|
||||
case let .changePhoto(_, new):
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
@ -221,7 +221,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
|
||||
let action = TelegramMediaActionType.photoUpdated(image: photo)
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes()))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
case let .toggleInvites(value):
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
var author: Peer?
|
||||
@ -248,7 +248,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
}
|
||||
let action = TelegramMediaActionType.customText(text: text, entities: entities)
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes()))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
case let .toggleSignatures(value):
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
var author: Peer?
|
||||
@ -275,7 +275,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
}
|
||||
let action = TelegramMediaActionType.customText(text: text, entities: entities)
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes()))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
case let .updatePinned(message):
|
||||
switch self.id.contentIndex {
|
||||
case .header:
|
||||
@ -299,7 +299,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
|
||||
let action = TelegramMediaActionType.customText(text: text, entities: entities)
|
||||
let message = Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: 1), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes()))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
case .content:
|
||||
if let message = message {
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
@ -317,7 +317,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
}
|
||||
}
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: message.effectiveAuthor, text: message.text, attributes: attributes, media: message.media, peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes()))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
} else {
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
var author: Peer?
|
||||
@ -339,7 +339,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
let action = TelegramMediaActionType.customText(text: text, entities: entities)
|
||||
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: 0), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes()))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
}
|
||||
}
|
||||
case let .editMessage(prev, message):
|
||||
@ -384,7 +384,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
let action = TelegramMediaActionType.customText(text: text, entities: entities)
|
||||
|
||||
let message = Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: 1), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes()))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
case .content:
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
var attributes: [MessageAttribute] = []
|
||||
@ -401,7 +401,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
}
|
||||
}
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: message.effectiveAuthor, text: message.text, attributes: attributes, media: message.media, peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: filterOriginalMessageFlags(message), read: true, selection: .none, attributes: ChatMessageEntryAttributes()), additionalContent: !prev.text.isEmpty || !message.text.isEmpty ? .eventLogPreviousMessage(filterOriginalMessageFlags(prev)) : nil)
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: filterOriginalMessageFlags(message), read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil), additionalContent: !prev.text.isEmpty || !message.text.isEmpty ? .eventLogPreviousMessage(filterOriginalMessageFlags(prev)) : nil)
|
||||
}
|
||||
case let .deleteMessage(message):
|
||||
switch self.id.contentIndex {
|
||||
@ -427,7 +427,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
let action = TelegramMediaActionType.customText(text: text, entities: entities)
|
||||
|
||||
let message = Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: 1), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes()))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
case .content:
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
var attributes: [MessageAttribute] = []
|
||||
@ -451,7 +451,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
}
|
||||
}
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: message.effectiveAuthor, text: message.text, attributes: attributes, media: message.media, peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes()))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
}
|
||||
case .participantJoin, .participantLeave:
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
@ -469,7 +469,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
action = TelegramMediaActionType.removedMembers(peerIds: [self.entry.event.peerId])
|
||||
}
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes()))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
case let .participantInvite(participant):
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
var author: Peer?
|
||||
@ -486,7 +486,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
let action: TelegramMediaActionType
|
||||
action = TelegramMediaActionType.addedMembers(peerIds: [participant.peer.id])
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes()))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
case let .participantToggleBan(prev, new):
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
var attributes: [MessageAttribute] = []
|
||||
@ -616,7 +616,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
}
|
||||
}
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: text, attributes: attributes, media: [], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes()))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
case let .participantToggleAdmin(prev, new):
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
var attributes: [MessageAttribute] = []
|
||||
@ -832,7 +832,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
}
|
||||
}
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: text, attributes: attributes, media: [], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes()))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
case let .changeStickerPack(_, new):
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
var author: Peer?
|
||||
@ -861,7 +861,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
let action = TelegramMediaActionType.customText(text: text, entities: entities)
|
||||
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes()))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
case let .togglePreHistoryHidden(value):
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
var author: Peer?
|
||||
@ -891,7 +891,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
let action = TelegramMediaActionType.customText(text: text, entities: entities)
|
||||
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes()))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
case let .updateDefaultBannedRights(prev, new):
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
var attributes: [MessageAttribute] = []
|
||||
@ -949,7 +949,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
}
|
||||
}
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: text, attributes: attributes, media: [], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes()))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
case let .pollStopped(message):
|
||||
switch self.id.contentIndex {
|
||||
case .header:
|
||||
@ -977,7 +977,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
let action = TelegramMediaActionType.customText(text: text, entities: entities)
|
||||
|
||||
let message = Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: 1), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes()))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
case .content:
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
var attributes: [MessageAttribute] = []
|
||||
@ -994,7 +994,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
}
|
||||
}
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: message.author, text: message.text, attributes: attributes, media: message.media, peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: filterOriginalMessageFlags(message), read: true, selection: .none, attributes: ChatMessageEntryAttributes()), additionalContent: nil)
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: filterOriginalMessageFlags(message), read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil), additionalContent: nil)
|
||||
}
|
||||
case let .linkedPeerUpdated(previous, updated):
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
@ -1050,7 +1050,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
let action = TelegramMediaActionType.customText(text: text, entities: entities)
|
||||
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes()))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
case let .changeGeoLocation(_, updated):
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
var author: Peer?
|
||||
@ -1072,12 +1072,12 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
let mediaMap = TelegramMediaMap(latitude: updated.latitude, longitude: updated.longitude, heading: nil, accuracyRadius: nil, geoPlace: nil, venue: nil, liveBroadcastingTimeout: nil, liveProximityNotificationRadius: nil)
|
||||
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: text, attributes: [], media: [mediaMap], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes()))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
} else {
|
||||
let action = TelegramMediaActionType.customText(text: text, entities: entities)
|
||||
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes()))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
}
|
||||
case let .updateSlowmode(_, newValue):
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
@ -1108,7 +1108,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
let action = TelegramMediaActionType.customText(text: text, entities: entities)
|
||||
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes()))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
case .startGroupCall, .endGroupCall:
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
var author: Peer?
|
||||
@ -1145,7 +1145,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
let action = TelegramMediaActionType.customText(text: text, entities: entities)
|
||||
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes()))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
case let .groupCallUpdateParticipantMuteStatus(participantId, isMuted):
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
var author: Peer?
|
||||
@ -1179,7 +1179,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
let action = TelegramMediaActionType.customText(text: text, entities: entities)
|
||||
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes()))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
case let .updateGroupCallSettings(joinMuted):
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
var author: Peer?
|
||||
@ -1208,7 +1208,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
let action = TelegramMediaActionType.customText(text: text, entities: entities)
|
||||
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes()))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
case let .groupCallUpdateParticipantVolume(participantId, volume):
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
var author: Peer?
|
||||
@ -1239,7 +1239,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
let action = TelegramMediaActionType.customText(text: text, entities: entities)
|
||||
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes()))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
case let .deleteExportedInvitation(invite):
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
var author: Peer?
|
||||
@ -1265,7 +1265,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
let action = TelegramMediaActionType.customText(text: text, entities: entities)
|
||||
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes()))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
case let .revokeExportedInvitation(invite):
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
var author: Peer?
|
||||
@ -1291,7 +1291,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
let action = TelegramMediaActionType.customText(text: text, entities: entities)
|
||||
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes()))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
case let .editExportedInvitation(_, updatedInvite):
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
var author: Peer?
|
||||
@ -1317,7 +1317,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
let action = TelegramMediaActionType.customText(text: text, entities: entities)
|
||||
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes()))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
case let .participantJoinedViaInvite(invite):
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
var author: Peer?
|
||||
@ -1343,7 +1343,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
let action = TelegramMediaActionType.customText(text: text, entities: entities)
|
||||
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes()))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
case let .changeHistoryTTL(_, updatedValue):
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
var author: Peer?
|
||||
@ -1374,7 +1374,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
let action = TelegramMediaActionType.customText(text: text, entities: entities)
|
||||
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes()))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
case let .changeTheme(_, updatedValue):
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
var author: Peer?
|
||||
@ -1405,7 +1405,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
let action = TelegramMediaActionType.customText(text: text, entities: entities)
|
||||
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes()))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
case let .participantJoinByRequest(invite, approvedBy):
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
var author: Peer?
|
||||
@ -1438,7 +1438,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
let action = TelegramMediaActionType.customText(text: text, entities: entities)
|
||||
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes()))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
case let .toggleCopyProtection(value):
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
var author: Peer?
|
||||
@ -1465,7 +1465,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
}
|
||||
let action = TelegramMediaActionType.customText(text: text, entities: entities)
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes()))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1298,10 +1298,10 @@ public final class SharedAccountContextImpl: SharedAccountContext {
|
||||
let content: ChatMessageItemContent
|
||||
let chatLocation: ChatLocation
|
||||
if messages.count > 1 {
|
||||
content = .group(messages: messages.map { ($0, true, .none, ChatMessageEntryAttributes()) })
|
||||
content = .group(messages: messages.map { ($0, true, .none, ChatMessageEntryAttributes(), nil) })
|
||||
chatLocation = .peer(messages.first!.id.peerId)
|
||||
} else {
|
||||
content = .message(message: messages.first!, read: true, selection: .none, attributes: ChatMessageEntryAttributes())
|
||||
content = .message(message: messages.first!, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil)
|
||||
chatLocation = .peer(messages.first!.id.peerId)
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user