Various improvements

This commit is contained in:
Isaac 2025-06-05 19:09:18 +08:00
parent 40b770dde8
commit b5c3d6f34f
14 changed files with 248 additions and 123 deletions

View File

@ -14381,7 +14381,7 @@ Sorry for the inconvenience.";
"ChannelMessages.Info" = "Allow users to send messages to your channel, with the option to charge a fee for each message.";
"ChannelMessages.SwitchTitle" = "Allow Channel Messages";
"ChannelMessages.PriceSectionTitle" = "PRICE FOR EACH MESSAGE";
"ChannelMessages.PriceSectionFooter" = "You will receive 85% of the selected fee for each incoming message.";
"ChannelMessages.PriceSectionFooterValue" = "You will receive %1$@% of the selected fee for each incoming message.";
"ChatList.MonoforumLabel" = "DIRECT";
"ChatList.MonoforumEmptyText" = "No messages here yet...";
@ -14408,7 +14408,7 @@ Sorry for the inconvenience.";
"Stars.SendMessage.AdjustmentPlaceholder" = "Price for each Message";
"Stars.SendMessage.AdjustmentSectionHeader" = "PRICE IN STARS";
"Stars.SendMessage.AdjustmentSectionFooterValue" = "You will receive **%@ Stars**.";
"Stars.SendMessage.AdjustmentSectionFooterEmpty" = "You will receive **80%**.";
"Stars.SendMessage.AdjustmentSectionFooterEmptyValue" = "You will receive **%1$@%**.";
"Stars.SendMessage.AdjustmentAction" = "OK";
"Stars.SendMessage.PriceFree" = "Free";

View File

@ -425,6 +425,28 @@ public extension ChatLocation {
return .replyThread(message: message.normalized)
}
}
var peerId: PeerId? {
switch self {
case let .peer(peerId):
return peerId
case let .replyThread(replyThreadMessage):
return replyThreadMessage.peerId
case .customChatContents:
return nil
}
}
var threadId: Int64? {
switch self {
case .peer:
return nil
case let .replyThread(replyThreadMessage):
return replyThreadMessage.threadId
case .customChatContents:
return nil
}
}
}
public enum ChatControllerActivateInput {

View File

@ -11,6 +11,7 @@ public enum ChatListControllerLocation: Equatable {
public protocol ChatListController: ViewController {
var context: AccountContext { get }
var location: ChatListControllerLocation { get }
var lockViewFrame: CGRect? { get }
var isSearchActive: Bool { get }
@ -25,4 +26,6 @@ public protocol ChatListController: ViewController {
func openStories(peerId: EnginePeer.Id)
func openStoriesFromNotification(peerId: EnginePeer.Id, storyId: Int32)
func resetForumStackIfOpen()
}

View File

@ -3601,6 +3601,12 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
return true
}
public func resetForumStackIfOpen() {
if self.secondaryContext != nil {
self.setInlineChatList(location: nil, animated: false)
}
}
public func setInlineChatList(location: ChatListControllerLocation?, animated: Bool = true) {
if let location {
let inlineNode = self.chatListDisplayNode.makeInlineChatList(location: location)

View File

@ -10,30 +10,6 @@ import ChatInterfaceState
import ChatContextQuery
import AudioWaveform
public extension ChatLocation {
var peerId: PeerId? {
switch self {
case let .peer(peerId):
return peerId
case let .replyThread(replyThreadMessage):
return replyThreadMessage.peerId
case .customChatContents:
return nil
}
}
var threadId: Int64? {
switch self {
case .peer:
return nil
case let .replyThread(replyThreadMessage):
return replyThreadMessage.threadId
case .customChatContents:
return nil
}
}
}
public enum ChatMediaInputMode {
case gif
case other

View File

@ -182,10 +182,6 @@ func _internal_premiumGiftCodeOptions(account: Account, peerId: EnginePeer.Id?,
return .single([])
} |> switchToLatest
var flags: Int32 = 0
if let _ = peerId {
flags |= 1 << 0
}
let remote = account.postbox.transaction { transaction -> Peer? in
if let peerId = peerId {
return transaction.getPeer(peerId)
@ -194,6 +190,10 @@ func _internal_premiumGiftCodeOptions(account: Account, peerId: EnginePeer.Id?,
}
|> mapToSignal { peer in
let inputPeer = peer.flatMap(apiInputPeer)
var flags: Int32 = 0
if let _ = inputPeer {
flags |= 1 << 0
}
return account.network.request(Api.functions.payments.getPremiumGiftCodeOptions(flags: flags, boostPeer: inputPeer))
|> map(Optional.init)
|> `catch` { _ -> Signal<[Api.PremiumGiftCodeOption]?, NoError> in

View File

@ -416,10 +416,22 @@ public final class ChatLoadingPlaceholderNode: ASDisplayNode {
} else if peer is TelegramGroup {
chatType = .group
} else if let channel = peer as? TelegramChannel {
if case .group = channel.info {
chatType = .group
if channel.isMonoForum {
if let mainChannel = chatPresentationInterfaceState.renderedPeer?.chatOrMonoforumMainPeer as? TelegramChannel, mainChannel.hasPermission(.sendSomething) {
if chatPresentationInterfaceState.chatLocation.threadId == nil {
chatType = .group
} else {
chatType = .user
}
} else {
chatType = .user
}
} else {
chatType = .channel
if case .group = channel.info {
chatType = .group
} else {
chatType = .channel
}
}
}
}

View File

@ -2546,7 +2546,13 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
nameNodeOriginY += 5.0
}
headerSize.width = max(headerSize.width, nameAvatarSpaceWidth + nameNodeSizeApply.0.width + 8.0 + adminBadgeSizeAndApply.0.size.width + credibilityIconWidth + boostBadgeWidth + closeButtonWidth + bubbleWidthInsets)
var headerSizeWidth = nameAvatarSpaceWidth + nameNodeSizeApply.0.width + 8.0 + credibilityIconWidth + boostBadgeWidth + closeButtonWidth + bubbleWidthInsets
if hasTitleTopicNavigation {
} else {
headerSizeWidth += adminBadgeSizeAndApply.0.size.width
}
headerSize.width = max(headerSize.width, headerSizeWidth)
headerSize.height += nameNodeSizeApply.0.height
}
@ -3881,12 +3887,14 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
}
strongSelf.clippingNode.addSubnode(adminBadgeNode)
adminBadgeNode.frame = adminBadgeFrame
adminBadgeNode.alpha = hasTitleTopicNavigation ? 0.0 : 1.0
if animation.isAnimated {
adminBadgeNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
if animation.isAnimated, adminBadgeNode.alpha != 0.0 {
adminBadgeNode.layer.animateAlpha(from: 0.0, to: adminBadgeNode.alpha, duration: 0.2)
}
} else {
animation.animator.updateFrame(layer: adminBadgeNode.layer, frame: adminBadgeFrame, completion: nil)
animation.animator.updateAlpha(layer: adminBadgeNode.layer, alpha: hasTitleTopicNavigation ? 0.0 : 1.0, completion: nil)
}
} else {
strongSelf.adminBadgeNode?.removeFromSupernode()

View File

@ -72,6 +72,7 @@ final class ForumSettingsScreenComponent: Component {
private var isOn = false
private var mode: ForumModeComponent.Mode = .tabs
private var initialOnMode: ForumModeComponent.Mode?
override init(frame: CGRect) {
self.scrollView = ScrollView()
@ -143,62 +144,112 @@ final class ForumSettingsScreenComponent: Component {
}
func toggleTopicsEnabled(_ enabled: Bool) {
guard let component = self.component, let peer = self.peer else {
return
}
self.isOn = enabled
let displayForumAsTabs = self.mode == .tabs
self.state?.updated(transition: .spring(duration: 0.4))
}
func attemptNavigation(complete: @escaping () -> Void) -> Bool {
guard let component = self.component, let peer = self.peer else {
return true
}
var isUpdated = false
if self.isOn {
if case .legacyGroup = peer {
let context = component.context
let signal: Signal<EnginePeer.Id?, NoError> = context.engine.peers.convertGroupToSupergroup(peerId: peer.id, additionalProcessing: { upgradedPeerId -> Signal<Never, NoError> in
return context.engine.peers.setChannelForumMode(id: upgradedPeerId, isForum: true, displayForumAsTabs: displayForumAsTabs)
})
|> map(Optional.init)
|> `catch` { [weak self] error -> Signal<PeerId?, NoError> in
guard let self, let controller = self.environment?.controller() else {
return .single(nil)
}
switch error {
case .tooManyChannels:
Queue.mainQueue().async {
let oldChannelsController = context.sharedContext.makeOldChannelsController(context: context, updatedPresentationData: nil, intent: .upgrade, completed: { result in
})
controller.push(oldChannelsController)
}
default:
break
}
return .single(nil)
if let initialOnMode = self.initialOnMode {
if initialOnMode != self.mode {
isUpdated = true
}
|> mapToSignal { upgradedPeerId -> Signal<PeerId?, NoError> in
guard let upgradedPeerId = upgradedPeerId else {
return .single(nil)
}
return .single(upgradedPeerId)
}
|> deliverOnMainQueue
let _ = signal.startStandalone(next: { [weak self] resultPeerId in
guard let self else {
return
}
if let resultPeerId {
self.peerIdPromise.set(resultPeerId)
} else {
self.isOn = false
self.state?.updated(transition: .easeInOut(duration: 0.2))
}
})
} else {
let _ = component.context.engine.peers.setChannelForumMode(id: peer.id, isForum: true, displayForumAsTabs: displayForumAsTabs).startStandalone()
isUpdated = true
}
} else {
let _ = component.context.engine.peers.setChannelForumMode(id: peer.id, isForum: false, displayForumAsTabs: displayForumAsTabs).startStandalone()
if self.initialOnMode != nil {
isUpdated = true
}
}
self.state?.updated(transition: .spring(duration: 0.4))
if isUpdated {
if let controller = self.environment?.controller(), let navigationController = controller.navigationController as? NavigationController {
var viewControllers = navigationController.viewControllers
if self.isOn && self.mode == .list {
for i in 0 ..< viewControllers.count {
if let chatController = viewControllers[i] as? ChatController, chatController.chatLocation.peerId == component.peerId {
let chatListController = component.context.sharedContext.makeChatListController(context: component.context, location: .forum(peerId: component.peerId), controlsHistoryPreload: false, hideNetworkActivityStatus: false, previewing: false, enableDebugActions: false)
viewControllers[i] = chatListController
}
}
navigationController.setViewControllers(viewControllers, animated: false)
} else {
for i in (0 ..< viewControllers.count).reversed() {
if let chatListController = viewControllers[i] as? ChatListController, chatListController.location == .forum(peerId: component.peerId) {
viewControllers.remove(at: i)
}
}
navigationController.setViewControllers(viewControllers, animated: false)
if let baseController = navigationController as? TelegramRootControllerInterface, let chatListController = baseController.getChatsController() as? ChatListController {
chatListController.resetForumStackIfOpen()
}
}
}
if self.isOn {
if case .legacyGroup = peer {
let context = component.context
let mode = self.mode
let signal: Signal<EnginePeer.Id?, NoError> = context.engine.peers.convertGroupToSupergroup(peerId: peer.id, additionalProcessing: { upgradedPeerId -> Signal<Never, NoError> in
return context.engine.peers.setChannelForumMode(id: upgradedPeerId, isForum: true, displayForumAsTabs: mode == .tabs)
})
|> map(Optional.init)
|> `catch` { [weak self] error -> Signal<PeerId?, NoError> in
guard let self, let controller = self.environment?.controller() else {
return .single(nil)
}
switch error {
case .tooManyChannels:
Queue.mainQueue().async {
let oldChannelsController = context.sharedContext.makeOldChannelsController(context: context, updatedPresentationData: nil, intent: .upgrade, completed: { result in
})
controller.push(oldChannelsController)
}
default:
break
}
return .single(nil)
}
|> mapToSignal { upgradedPeerId -> Signal<PeerId?, NoError> in
guard let upgradedPeerId = upgradedPeerId else {
return .single(nil)
}
return .single(upgradedPeerId)
}
|> deliverOnMainQueue
let _ = signal.startStandalone(next: { [weak self] resultPeerId in
guard let self else {
return
}
if let resultPeerId {
self.peerIdPromise.set(resultPeerId)
} else {
self.isOn = false
self.state?.updated(transition: .easeInOut(duration: 0.2))
}
self.environment?.controller()?.dismiss()
})
return false
} else {
let _ = component.context.engine.peers.setChannelForumMode(id: component.peerId, isForum: true, displayForumAsTabs: self.mode == .tabs).startStandalone()
}
} else {
let _ = component.context.engine.peers.setChannelForumMode(id: component.peerId, isForum: false, displayForumAsTabs: false).startStandalone()
}
}
return true
}
func update(component: ForumSettingsScreenComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment<EnvironmentType>, transition: ComponentTransition) -> CGSize {
@ -212,7 +263,7 @@ final class ForumSettingsScreenComponent: Component {
self.peerDisposable = (self.peerIdPromise.get()
|> mapToSignal { peerId in
component.context.engine.data.subscribe(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
component.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
}
|> deliverOnMainQueue).start(next: { [weak self] peer in
guard let self else {
@ -223,6 +274,9 @@ final class ForumSettingsScreenComponent: Component {
self.isOn = channel.flags.contains(.isForum)
if self.isOn {
self.mode = channel.flags.contains(.displayForumAsTabs) ? .tabs : .list
self.initialOnMode = self.mode
} else {
self.initialOnMode = nil
}
}
self.state?.updated()
@ -421,8 +475,6 @@ final class ForumSettingsScreenComponent: Component {
return
}
self.mode = mode
let displayForumAsTabs = self.mode == .tabs
let _ = component.context.engine.peers.setChannelForumMode(id: component.peerId, isForum: true, displayForumAsTabs: displayForumAsTabs).startStandalone()
self.state?.updated(transition: .spring(duration: 0.4))
}
)
@ -514,6 +566,14 @@ public final class ForumSettingsScreen: ViewControllerComponentContainer {
}
componentView.scrollToTop()
}
self.attemptNavigation = { [weak self] complete in
guard let self, let componentView = self.node.hostView.componentView as? ForumSettingsScreenComponent.View else {
return true
}
return componentView.attemptNavigation(complete: complete)
}
}
required public init(coder aDecoder: NSCoder) {

View File

@ -29,6 +29,7 @@ final class PostSuggestionsSettingsScreenComponent: Component {
let context: AccountContext
let usdWithdrawRate: Int64
let paidMessageCommissionPermille: Int
let peer: EnginePeer?
let initialPrice: StarsAmount?
let completion: () -> Void
@ -36,12 +37,14 @@ final class PostSuggestionsSettingsScreenComponent: Component {
init(
context: AccountContext,
usdWithdrawRate: Int64,
paidMessageCommissionPermille: Int,
peer: EnginePeer?,
initialPrice: StarsAmount?,
completion: @escaping () -> Void
) {
self.context = context
self.usdWithdrawRate = usdWithdrawRate
self.paidMessageCommissionPermille = paidMessageCommissionPermille
self.peer = peer
self.initialPrice = initialPrice
self.completion = completion
@ -367,7 +370,7 @@ final class PostSuggestionsSettingsScreenComponent: Component {
}
let currentAmount: StarsAmount = StarsAmount(value: Int64(self.starCount), nanos: 0)
let starsScreen = component.context.sharedContext.makeStarsWithdrawalScreen(context: component.context, subject: .enterAmount(current: currentAmount, minValue: StarsAmount(value: 0, nanos: 0), fractionAfterCommission: 85, kind: .postSuggestion), completion: { [weak self] amount in
let starsScreen = component.context.sharedContext.makeStarsWithdrawalScreen(context: component.context, subject: .enterAmount(current: currentAmount, minValue: StarsAmount(value: 0, nanos: 0), fractionAfterCommission: component.paidMessageCommissionPermille / 10, kind: .postSuggestion), completion: { [weak self] amount in
guard let self else {
return
}
@ -398,9 +401,9 @@ final class PostSuggestionsSettingsScreenComponent: Component {
)),
footer: AnyComponent(MultilineTextComponent(
text: .plain(NSAttributedString(
string: environment.strings.ChannelMessages_PriceSectionFooter,
string: environment.strings.ChannelMessages_PriceSectionFooterValue("\(component.paidMessageCommissionPermille / 10)").string,
font: Font.regular(13.0),
textColor: environment.theme.list.freeTextColor
textColor: self.starCount == 0 ? .clear : environment.theme.list.freeTextColor
)),
maximumNumberOfLines: 0
)),
@ -497,6 +500,7 @@ public final class PostSuggestionsSettingsScreen: ViewControllerComponentContain
super.init(context: context, component: PostSuggestionsSettingsScreenComponent(
context: context,
usdWithdrawRate: configuration.usdWithdrawRate,
paidMessageCommissionPermille: Int(configuration.paidMessageCommissionPermille),
peer: peer,
initialPrice: initialPrice,
completion: completion

View File

@ -295,7 +295,7 @@ private final class SheetContent: CombinedComponent {
let amountValue = StarsAmount(value: fullValue / 1_000_000_000, nanos: Int32(fullValue % 1_000_000_000))
amountInfoString = NSAttributedString(attributedString: parseMarkdownIntoAttributedString(environment.strings.Stars_SendMessage_AdjustmentSectionFooterValue("\(amountValue)").string, attributes: amountMarkdownAttributes, textAlignment: .natural))
} else {
amountInfoString = NSAttributedString(attributedString: parseMarkdownIntoAttributedString(environment.strings.Stars_SendMessage_AdjustmentSectionFooterEmpty, attributes: amountMarkdownAttributes, textAlignment: .natural))
amountInfoString = NSAttributedString(attributedString: parseMarkdownIntoAttributedString(environment.strings.Stars_SendMessage_AdjustmentSectionFooterEmptyValue("\(fractionAfterCommission)").string, attributes: amountMarkdownAttributes, textAlignment: .natural))
}
amountFooter = AnyComponent(MultilineTextComponent(
text: .plain(amountInfoString),
@ -389,6 +389,16 @@ private final class SheetContent: CombinedComponent {
buttonAttributedString.addAttribute(.kern, value: 2.0, range: NSRange(range, in: buttonAttributedString.string))
}
var isButtonEnabled = false
let amount = state.amount ?? StarsAmount.zero
if amount > StarsAmount.zero {
isButtonEnabled = true
} else if case let .paidMessages(_, minValue, _, _) = context.component.mode {
if minValue <= 0 {
isButtonEnabled = true
}
}
let button = button.update(
component: ButtonComponent(
background: ButtonComponent.Background(
@ -401,7 +411,7 @@ private final class SheetContent: CombinedComponent {
id: AnyHashable(0),
component: AnyComponent(MultilineTextComponent(text: .plain(buttonAttributedString)))
),
isEnabled: (state.amount ?? StarsAmount.zero) > StarsAmount.zero,
isEnabled: isButtonEnabled,
displaysProgress: false,
action: { [weak state] in
if let controller = controller() as? StarsWithdrawScreen, let amount = state?.amount {
@ -815,31 +825,40 @@ private final class AmountFieldComponent: Component {
}
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
guard let component = self.component else {
return false
}
if string.rangeOfCharacter(from: invalidAmountCharacters) != nil {
return false
}
var acceptZero = false
if let minValue = component.minValue, minValue <= 0 {
acceptZero = true
}
var newText = ((textField.text ?? "") as NSString).replacingCharacters(in: range, with: string)
if newText == "0" || (newText.count > 1 && newText.hasPrefix("0")) {
if (newText == "0" && !acceptZero) || (newText.count > 1 && newText.hasPrefix("0")) {
newText.removeFirst()
textField.text = newText
self.textChanged(self.textField)
return false
}
if let component = self.component {
let amount: Int64?
if !newText.isEmpty, let value = Int64(normalizeArabicNumeralString(newText, type: .western)) {
amount = value
} else {
amount = nil
}
if let amount, let maxAmount = component.maxValue, amount > maxAmount {
textField.text = "\(maxAmount)"
self.textChanged(self.textField)
self.animateError()
return false
}
let amount: Int64?
if !newText.isEmpty, let value = Int64(normalizeArabicNumeralString(newText, type: .western)) {
amount = value
} else {
amount = nil
}
if let amount, let maxAmount = component.maxValue, amount > maxAmount {
textField.text = "\(maxAmount)"
self.textChanged(self.textField)
self.animateError()
return false
}
return true
}

View File

@ -4804,6 +4804,9 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
if strongSelf.navigationBar?.contentNode != nil {
return false
}
if strongSelf.chatDisplayNode.leftPanel != nil {
return false
}
return true
}

View File

@ -694,7 +694,10 @@ extension ChatControllerImpl {
upgradedToPeerId = migrationReference.peerId
}
if let previous = strongSelf.state.peerView, let channel = previous.peers[previous.peerId] as? TelegramChannel, !channel.isForumOrMonoForum, let updatedChannel = peerView.peers[peerView.peerId] as? TelegramChannel, updatedChannel.isForumOrMonoForum {
movedToForumTopics = true
if updatedChannel.isForum && updatedChannel.flags.contains(.displayForumAsTabs) {
} else {
movedToForumTopics = true
}
}
var shouldDismiss = false
@ -761,6 +764,7 @@ extension ChatControllerImpl {
}
var starGiftsAvailable = false
var peerDiscussionId: PeerId?
var peerMonoforumId: PeerId?
var peerGeoLocation: PeerGeoLocation?
if let peer = peerView.peers[peerView.peerId] as? TelegramChannel, let cachedData = peerView.cachedData as? CachedChannelData {
if case .broadcast = peer.info {
@ -771,6 +775,9 @@ extension ChatControllerImpl {
if case let .known(value) = cachedData.linkedDiscussionPeerId {
peerDiscussionId = value
}
if !peer.isMonoForum {
peerMonoforumId = peer.linkedMonoforumId
}
}
var renderedPeer: RenderedPeer?
var contactStatus: ChatContactStatus?
@ -921,13 +928,14 @@ extension ChatControllerImpl {
explicitelyCanPinMessages = true
}
if strongSelf.preloadHistoryPeerId != peerDiscussionId {
strongSelf.preloadHistoryPeerId = peerDiscussionId
if let peerDiscussionId = peerDiscussionId, let channel = peerView.peers[peerView.peerId] as? TelegramChannel, case .broadcast = channel.info {
let preloadHistoryPeerId = peerMonoforumId ?? peerDiscussionId
if strongSelf.preloadHistoryPeerId != preloadHistoryPeerId {
strongSelf.preloadHistoryPeerId = preloadHistoryPeerId
if let preloadHistoryPeerId, let channel = peerView.peers[peerView.peerId] as? TelegramChannel, case .broadcast = channel.info {
let combinedDisposable = DisposableSet()
strongSelf.preloadHistoryPeerIdDisposable.set(combinedDisposable)
combinedDisposable.add(context.account.viewTracker.polledChannel(peerId: peerDiscussionId).startStrict())
combinedDisposable.add(context.account.addAdditionalPreloadHistoryPeerId(peerId: peerDiscussionId))
combinedDisposable.add(context.account.viewTracker.polledChannel(peerId: preloadHistoryPeerId).startStrict())
combinedDisposable.add(context.account.addAdditionalPreloadHistoryPeerId(peerId: preloadHistoryPeerId))
} else {
strongSelf.preloadHistoryPeerIdDisposable.set(nil)
}
@ -1559,6 +1567,7 @@ extension ChatControllerImpl {
strongSelf.state.threadInfo = messageAndTopic.threadData?.info
var peerDiscussionId: PeerId?
var peerMonoforumId: PeerId?
var peerGeoLocation: PeerGeoLocation?
var currentSendAsPeerId: PeerId?
if let peer = peerView.peers[peerView.peerId] as? TelegramChannel, let cachedData = peerView.cachedData as? CachedChannelData {
@ -1569,6 +1578,8 @@ extension ChatControllerImpl {
currentSendAsPeerId = nil
}
} else {
peerMonoforumId = peer.linkedMonoforumId
currentSendAsPeerId = cachedData.sendAsPeerId
if case .group = peer.info {
peerGeoLocation = cachedData.peerGeoLocation
@ -1610,10 +1621,11 @@ extension ChatControllerImpl {
explicitelyCanPinMessages = true
}
if strongSelf.preloadHistoryPeerId != peerDiscussionId {
strongSelf.preloadHistoryPeerId = peerDiscussionId
if let peerDiscussionId = peerDiscussionId {
strongSelf.preloadHistoryPeerIdDisposable.set(context.account.addAdditionalPreloadHistoryPeerId(peerId: peerDiscussionId))
let preloadHistoryPeerId = peerMonoforumId ?? peerDiscussionId
if strongSelf.preloadHistoryPeerId != preloadHistoryPeerId {
strongSelf.preloadHistoryPeerId = preloadHistoryPeerId
if let preloadHistoryPeerId {
strongSelf.preloadHistoryPeerIdDisposable.set(context.account.addAdditionalPreloadHistoryPeerId(peerId: preloadHistoryPeerId))
} else {
strongSelf.preloadHistoryPeerIdDisposable.set(nil)
}

View File

@ -233,7 +233,7 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate {
private var chatTranslationPanel: ChatTranslationPanelNode?
private var leftPanelContainer: ChatControllerTitlePanelNodeContainer
private var leftPanel: (component: AnyComponentWithIdentity<ChatSidePanelEnvironment>, view: ComponentView<ChatSidePanelEnvironment>)?
private(set) var leftPanel: (component: AnyComponentWithIdentity<ChatSidePanelEnvironment>, view: ComponentView<ChatSidePanelEnvironment>)?
private(set) var inputPanelNode: ChatInputPanelNode?
private(set) var inputPanelOverscrollNode: ChatInputPanelOverscrollNode?