Various improvements

This commit is contained in:
Ilya Laktyushin 2024-06-15 20:34:07 +04:00
parent d050cf8ce9
commit 5d2377bcb7
36 changed files with 460 additions and 312 deletions

View File

@ -12337,6 +12337,8 @@ Sorry for the inconvenience.";
"Stars.BotRevenue.Withdraw.Withdraw" = "Withdraw via Fragment";
"Stars.BotRevenue.Withdraw.Info" = "You can withdraw Stars using Fragment, or use Stars to advertise your bot. [Learn More >]()";
"Stars.BotRevenue.Transactions.Title" = "Transaction History";
"Stars.Withdraw.Title" = "Withdraw";
"Stars.Withdraw.AmountTitle" = "ENTER AMOUNT TO WITHDRAW";
"Stars.Withdraw.AmountPlaceholder" = "Stars Amount";

View File

@ -884,11 +884,28 @@ public enum CollectibleItemInfoScreenSubject {
case username(String)
}
public enum StorySearchControllerScope {
case query(String)
case location(coordinates: MediaArea.Coordinates, venue: MediaArea.Venue)
}
public struct ChatControllerParams {
public let forcedTheme: PresentationTheme?
public let forcedNavigationBarTheme: PresentationTheme?
public let forcedWallpaper: TelegramWallpaper?
public init(
forcedTheme: PresentationTheme? = nil,
forcedNavigationBarTheme: PresentationTheme? = nil,
forcedWallpaper: TelegramWallpaper? = nil
) {
self.forcedTheme = forcedTheme
self.forcedNavigationBarTheme = forcedNavigationBarTheme
self.forcedWallpaper = forcedWallpaper
}
}
public protocol SharedAccountContext: AnyObject {
var sharedContainerPath: String { get }
var basePath: String { get }
@ -943,7 +960,7 @@ public protocol SharedAccountContext: AnyObject {
func makePeersNearbyController(context: AccountContext) -> ViewController
func makeComposeController(context: AccountContext) -> ViewController
func makeChatListController(context: AccountContext, location: ChatListControllerLocation, controlsHistoryPreload: Bool, hideNetworkActivityStatus: Bool, previewing: Bool, enableDebugActions: Bool) -> ChatListController
func makeChatController(context: AccountContext, chatLocation: ChatLocation, subject: ChatControllerSubject?, botStart: ChatControllerInitialBotStart?, mode: ChatControllerPresentationMode) -> ChatController
func makeChatController(context: AccountContext, chatLocation: ChatLocation, subject: ChatControllerSubject?, botStart: ChatControllerInitialBotStart?, mode: ChatControllerPresentationMode, params: ChatControllerParams?) -> ChatController
func makeChatHistoryListNode(
context: AccountContext,
updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>),

View File

@ -731,9 +731,11 @@ public enum ChatControllerSubject: Equatable {
public struct Link: Equatable {
public var options: Signal<LinkOptions, NoError>
public var isCentered: Bool
public init(options: Signal<LinkOptions, NoError>) {
public init(options: Signal<LinkOptions, NoError>, isCentered: Bool) {
self.options = options
self.isCentered = isCentered
}
public static func ==(lhs: Link, rhs: Link) -> Bool {

View File

@ -1369,7 +1369,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
let source: ContextContentSource
let chatController = strongSelf.context.sharedContext.makeChatController(context: strongSelf.context, chatLocation: .replyThread(message: ChatReplyThreadMessage(
peerId: peer.peerId, threadId: threadId, channelMessageId: nil, isChannelPost: false, isForumPost: true, maxMessage: nil, maxReadIncomingMessageId: nil, maxReadOutgoingMessageId: nil, unreadCount: 0, initialFilledHoles: IndexSet(), initialAnchor: .automatic, isNotAvailable: false
)), subject: nil, botStart: nil, mode: .standard(.previewing))
)), subject: nil, botStart: nil, mode: .standard(.previewing), params: nil)
chatController.canReadHistory.set(false)
source = .controller(ContextControllerContentSourceImpl(controller: chatController, sourceNode: node, navigationController: strongSelf.navigationController as? NavigationController))
@ -1398,7 +1398,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
if let location = location {
source = .location(ChatListContextLocationContentSource(controller: strongSelf, location: location))
} else {
let chatController = strongSelf.context.sharedContext.makeChatController(context: strongSelf.context, chatLocation: .peer(id: peer.peerId), subject: nil, botStart: nil, mode: .standard(.previewing))
let chatController = strongSelf.context.sharedContext.makeChatController(context: strongSelf.context, chatLocation: .peer(id: peer.peerId), subject: nil, botStart: nil, mode: .standard(.previewing), params: nil)
chatController.canReadHistory.set(false)
source = .controller(ContextControllerContentSourceImpl(controller: chatController, sourceNode: node, navigationController: strongSelf.navigationController as? NavigationController))
}
@ -1417,7 +1417,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
let source: ContextContentSource
let chatController = strongSelf.context.sharedContext.makeChatController(context: strongSelf.context, chatLocation: .replyThread(message: ChatReplyThreadMessage(
peerId: peer.peerId, threadId: threadId, channelMessageId: nil, isChannelPost: false, isForumPost: true, maxMessage: nil, maxReadIncomingMessageId: nil, maxReadOutgoingMessageId: nil, unreadCount: 0, initialFilledHoles: IndexSet(), initialAnchor: .automatic, isNotAvailable: false
)), subject: nil, botStart: nil, mode: .standard(.previewing))
)), subject: nil, botStart: nil, mode: .standard(.previewing), params: nil)
chatController.canReadHistory.set(false)
source = .controller(ContextControllerContentSourceImpl(controller: chatController, sourceNode: node, navigationController: strongSelf.navigationController as? NavigationController))
@ -1467,7 +1467,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
if case let .search(messageId) = source, let id = messageId {
subject = .message(id: .id(id), highlight: nil, timecode: nil)
}
let chatController = strongSelf.context.sharedContext.makeChatController(context: strongSelf.context, chatLocation: .peer(id: peer.id), subject: subject, botStart: nil, mode: .standard(.previewing))
let chatController = strongSelf.context.sharedContext.makeChatController(context: strongSelf.context, chatLocation: .peer(id: peer.id), subject: subject, botStart: nil, mode: .standard(.previewing), params: nil)
chatController.canReadHistory.set(false)
contextContentSource = .controller(ContextControllerContentSourceImpl(controller: chatController, sourceNode: node, navigationController: strongSelf.navigationController as? NavigationController))
}
@ -3500,7 +3500,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
return
}
let chatController = context.sharedContext.makeChatController(context: context, chatLocation: .peer(id: peerId), subject: nil, botStart: nil, mode: .standard(.default))
let chatController = context.sharedContext.makeChatController(context: context, chatLocation: .peer(id: peerId), subject: nil, botStart: nil, mode: .standard(.default), params: nil)
if let sourceController = sourceController as? ChatListControllerImpl, case .forum(peerId) = sourceController.location {
navigationController.replaceController(sourceController, with: chatController, animated: false)
@ -6699,7 +6699,7 @@ private final class ChatListLocationContext {
if let channel = peerView.peers[peerView.peerId] as? TelegramChannel, !channel.flags.contains(.isForum) {
if let parentController = self.parentController, let navigationController = parentController.navigationController as? NavigationController {
let chatController = self.context.sharedContext.makeChatController(context: self.context, chatLocation: .peer(id: peerId), subject: nil, botStart: nil, mode: .standard(.default))
let chatController = self.context.sharedContext.makeChatController(context: self.context, chatLocation: .peer(id: peerId), subject: nil, botStart: nil, mode: .standard(.default), params: nil)
navigationController.replaceController(parentController, with: chatController, animated: true)
}
} else {

View File

@ -1150,7 +1150,7 @@ final class ChatListControllerNode: ASDisplayNode, ASGestureRecognizerDelegate {
return
}
let chatController = strongSelf.context.sharedContext.makeChatController(context: strongSelf.context, chatLocation: .peer(id: peerId), subject: nil, botStart: nil, mode: .standard(.default))
let chatController = strongSelf.context.sharedContext.makeChatController(context: strongSelf.context, chatLocation: .peer(id: peerId), subject: nil, botStart: nil, mode: .standard(.default), params: nil)
(controller.navigationController as? NavigationController)?.replaceController(controller, with: chatController, animated: false)
}

View File

@ -1530,7 +1530,7 @@ func chatListFilterPresetController(context: AccountContext, currentPreset initi
})
},
peerContextAction: { peer, node, gesture, location in
let chatController = context.sharedContext.makeChatController(context: context, chatLocation: .peer(id: peer.id), subject: nil, botStart: nil, mode: .standard(.previewing))
let chatController = context.sharedContext.makeChatController(context: context, chatLocation: .peer(id: peer.id), subject: nil, botStart: nil, mode: .standard(.previewing), params: nil)
chatController.canReadHistory.set(false)
let presentationData = context.sharedContext.currentPresentationData.with { $0 }

View File

@ -1544,7 +1544,7 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
proceed(chatController)
})
} else {
proceed(strongSelf.context.sharedContext.makeChatController(context: strongSelf.context, chatLocation: .peer(id: peerId), subject: nil, botStart: nil, mode: .standard(.default)))
proceed(strongSelf.context.sharedContext.makeChatController(context: strongSelf.context, chatLocation: .peer(id: peerId), subject: nil, botStart: nil, mode: .standard(.default), params: nil))
}
strongSelf.updateState { state in

View File

@ -465,7 +465,7 @@ final class ContactsControllerNode: ASDisplayNode, ASGestureRecognizerDelegate {
let controller = ContextController(presentationData: self.presentationData, source: .extracted(ContactContextExtractedContentSource(sourceNode: node, shouldBeDismissed: .single(false))), items: items, recognizer: nil, gesture: gesture)
contactsController.presentInGlobalOverlay(controller)
} else {
let chatController = self.context.sharedContext.makeChatController(context: self.context, chatLocation: .peer(id: peer.id), subject: nil, botStart: nil, mode: .standard(.previewing))
let chatController = self.context.sharedContext.makeChatController(context: self.context, chatLocation: .peer(id: peer.id), subject: nil, botStart: nil, mode: .standard(.previewing), params: nil)
chatController.canReadHistory.set(false)
let contextController = ContextController(presentationData: self.presentationData, source: .controller(ContextControllerContentSourceImpl(controller: chatController, sourceNode: node)), items: items, gesture: gesture)
contactsController.presentInGlobalOverlay(contextController)

View File

@ -76,7 +76,7 @@ final class HashtagSearchControllerNode: ASDisplayNode, ASGestureRecognizerDeleg
let navigationController = controller.navigationController as? NavigationController
if let peer, !controller.all {
self.currentController = context.sharedContext.makeChatController(context: context, chatLocation: .peer(id: peer.id), subject: nil, botStart: nil, mode: .inline(navigationController))
self.currentController = context.sharedContext.makeChatController(context: context, chatLocation: .peer(id: peer.id), subject: nil, botStart: nil, mode: .inline(navigationController), params: nil)
self.currentController?.alwaysShowSearchResultsAsList = true
self.currentController?.showListEmptyResults = true
self.currentController?.customNavigationController = navigationController
@ -86,14 +86,14 @@ final class HashtagSearchControllerNode: ASDisplayNode, ASGestureRecognizerDeleg
let myChatContents = HashtagSearchGlobalChatContents(context: context, query: query, publicPosts: false)
self.myChatContents = myChatContents
self.myController = context.sharedContext.makeChatController(context: context, chatLocation: .customChatContents, subject: .customChatContents(contents: myChatContents), botStart: nil, mode: .standard(.default))
self.myController = context.sharedContext.makeChatController(context: context, chatLocation: .customChatContents, subject: .customChatContents(contents: myChatContents), botStart: nil, mode: .standard(.default), params: nil)
self.myController?.alwaysShowSearchResultsAsList = true
self.myController?.showListEmptyResults = true
self.myController?.customNavigationController = navigationController
let globalChatContents = HashtagSearchGlobalChatContents(context: context, query: query, publicPosts: true)
self.globalChatContents = globalChatContents
self.globalController = context.sharedContext.makeChatController(context: context, chatLocation: .customChatContents, subject: .customChatContents(contents: globalChatContents), botStart: nil, mode: .standard(.default))
self.globalController = context.sharedContext.makeChatController(context: context, chatLocation: .customChatContents, subject: .customChatContents(contents: globalChatContents), botStart: nil, mode: .standard(.default), params: nil)
self.globalController?.alwaysShowSearchResultsAsList = true
self.globalController?.showListEmptyResults = true
self.globalController?.customNavigationController = navigationController

View File

@ -2339,7 +2339,7 @@ public func channelVisibilityController(context: AccountContext, updatedPresenta
})
} else {
if let navigationController = controller.navigationController as? NavigationController {
navigationController.replaceAllButRootController(context.sharedContext.makeChatController(context: context, chatLocation: .peer(id: peerId), subject: nil, botStart: nil, mode: .standard(.default)), animated: true)
navigationController.replaceAllButRootController(context.sharedContext.makeChatController(context: context, chatLocation: .peer(id: peerId), subject: nil, botStart: nil, mode: .standard(.default), params: nil), animated: true)
}
}
}

View File

@ -149,7 +149,7 @@ public func convertToSupergroupController(context: AccountContext, peerId: Engin
if !alreadyConverting {
convertDisposable.set((context.engine.peers.convertGroupToSupergroup(peerId: peerId)
|> deliverOnMainQueue).start(next: { createdPeerId in
replaceControllerImpl?(context.sharedContext.makeChatController(context: context, chatLocation: .peer(id: createdPeerId), subject: nil, botStart: nil, mode: .standard(.default)))
replaceControllerImpl?(context.sharedContext.makeChatController(context: context, chatLocation: .peer(id: createdPeerId), subject: nil, botStart: nil, mode: .standard(.default), params: nil))
}))
}
})]), nil)

View File

@ -486,7 +486,7 @@ public func peersNearbyController(context: AccountContext) -> ViewController {
}))
}, contextAction: { peer, node, gesture in
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
let chatController = context.sharedContext.makeChatController(context: context, chatLocation: .peer(id: peer.id), subject: nil, botStart: nil, mode: .standard(.previewing))
let chatController = context.sharedContext.makeChatController(context: context, chatLocation: .peer(id: peer.id), subject: nil, botStart: nil, mode: .standard(.previewing), params: nil)
chatController.canReadHistory.set(false)
let contextController = ContextController(presentationData: presentationData, source: .controller(ContextControllerContentSourceImpl(controller: chatController, sourceNode: node)), items: peerNearbyContextMenuItems(context: context, peerId: peer.id, present: { c in
presentControllerImpl?(c, nil)

View File

@ -999,7 +999,7 @@ func settingsSearchableItems(context: AccountContext, notificationExceptionsList
allItems.append(contentsOf: profileItems)
let savedMessages = SettingsSearchableItem(id: .savedMessages(0), title: strings.Settings_SavedMessages, alternate: synonyms(strings.SettingsSearch_Synonyms_SavedMessages), icon: .savedMessages, breadcrumbs: [], present: { context, _, present in
present(.push, context.sharedContext.makeChatController(context: context, chatLocation: .peer(id: context.account.peerId), subject: nil, botStart: nil, mode: .standard(.default)))
present(.push, context.sharedContext.makeChatController(context: context, chatLocation: .peer(id: context.account.peerId), subject: nil, botStart: nil, mode: .standard(.default), params: nil))
})
allItems.append(savedMessages)
@ -1059,7 +1059,7 @@ func settingsSearchableItems(context: AccountContext, notificationExceptionsList
let _ = (context.engine.peers.supportPeerId()
|> deliverOnMainQueue).start(next: { peerId in
if let peerId = peerId {
present(.push, context.sharedContext.makeChatController(context: context, chatLocation: .peer(id: peerId), subject: nil, botStart: nil, mode: .standard(.default)))
present(.push, context.sharedContext.makeChatController(context: context, chatLocation: .peer(id: peerId), subject: nil, botStart: nil, mode: .standard(.default), params: nil))
}
})
})

View File

@ -213,8 +213,12 @@ public final class ChatMessageAttachedContentNode: ASDisplayNode {
let badgeFont = Font.regular(floor(presentationData.fontSize.baseDisplaySize * 11.0 / 17.0))
var incoming = message.effectivelyIncoming(context.account.peerId)
if let subject = associatedData.subject, case let .messageOptions(_, _, info) = subject, case .forward = info {
incoming = false
if let subject = associatedData.subject, case let .messageOptions(_, _, info) = subject {
if case .forward = info {
incoming = false
} else if case let .link(link) = info, link.isCentered {
incoming = true
}
}
var isReplyThread = false
@ -703,6 +707,7 @@ public final class ChatMessageAttachedContentNode: ASDisplayNode {
var statusLayoutAndContinue: (CGFloat, (CGFloat) -> (CGSize, (ListViewItemUpdateAnimation) -> ChatMessageDateAndStatusNode))?
if case .customChatContents = associatedData.subject {
} else if !presentationData.chatBubbleCorners.hasTails {
} else if case let .messageOptions(_, _, info) = associatedData.subject, case let .link(link) = info, link.isCentered {
} else if case let .linear(_, bottom) = position {
switch bottom {
case .None, .Neighbour(_, .footer, _):

View File

@ -853,6 +853,14 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
deinit {
}
override public func updateTrailingItemSpace(_ height: CGFloat, transition: ContainedViewLayoutTransition) {
if height.isLessThanOrEqualTo(0.0) {
transition.updateFrame(node: self.mainContainerNode, frame: CGRect(origin: CGPoint(), size: self.mainContainerNode.bounds.size))
} else {
transition.updateFrame(node: self.mainContainerNode, frame: CGRect(origin: CGPoint(x: 0.0, y: -floorToScreenPixels(height / 2.0)), size: self.mainContainerNode.bounds.size))
}
}
override public func cancelInsertionAnimations() {
self.shadowNode.layer.removeAllAnimations()
@ -3086,6 +3094,12 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
strongSelf.didChangeFromPendingToSent = true
}
if case let .messageOptions(_, _, info) = item.associatedData.subject, case let .link(link) = info, link.isCentered {
strongSelf.wantsTrailingItemSpaceUpdates = true
} else {
strongSelf.wantsTrailingItemSpaceUpdates = false
}
let themeUpdated = strongSelf.appliedItem?.presentationData.theme.theme !== item.presentationData.theme.theme
let previousContextFrame = strongSelf.mainContainerNode.frame
strongSelf.mainContainerNode.frame = CGRect(origin: CGPoint(), size: layout.contentSize)
@ -3126,7 +3140,9 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
} else if !incoming {
backgroundType = .outgoing(mergeType)
} else {
if !item.presentationData.chatBubbleCorners.hasTails {
if case let .messageOptions(_, _, info) = item.associatedData.subject, case let .link(link) = info, link.isCentered {
backgroundType = .incoming(.Extracted)
} else if !item.presentationData.chatBubbleCorners.hasTails {
backgroundType = .incoming(.Extracted)
} else {
backgroundType = .incoming(mergeType)

View File

@ -16,8 +16,12 @@ public enum ChatMessageItemContent: Sequence {
case group(messages: [(Message, Bool, ChatHistoryMessageSelection, ChatMessageEntryAttributes, MessageHistoryEntryLocation?)])
public func effectivelyIncoming(_ accountPeerId: PeerId, associatedData: ChatMessageItemAssociatedData? = nil) -> Bool {
if let subject = associatedData?.subject, case let .messageOptions(_, _, info) = subject, case .forward = info {
return false
if let subject = associatedData?.subject, case let .messageOptions(_, _, info) = subject {
if case .forward = info {
return false
} else if case let .link(link) = info {
return link.isCentered
}
}
switch self {
case let .message(message, _, _, _, _):

View File

@ -238,11 +238,13 @@ public class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode {
let message = item.message
let incoming: Bool
if let subject = item.associatedData.subject, case let .messageOptions(_, _, info) = subject, case .forward = info {
incoming = false
} else {
incoming = item.message.effectivelyIncoming(item.context.account.peerId)
var incoming = item.message.effectivelyIncoming(item.context.account.peerId)
if let subject = item.associatedData.subject, case let .messageOptions(_, _, info) = subject {
if case .forward = info {
incoming = false
} else if case let .link(link) = info, link.isCentered {
incoming = true
}
}
var maxTextWidth = CGFloat.greatestFiniteMagnitude
@ -309,6 +311,8 @@ public class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode {
}
} else if !item.presentationData.chatBubbleCorners.hasTails {
displayStatus = false
} else if case let .messageOptions(_, _, info) = item.associatedData.subject, case let .link(link) = info, link.isCentered {
displayStatus = false
}
if displayStatus {
if incoming {

View File

@ -15,10 +15,10 @@ private enum OptionsId: Hashable {
case link
}
func presentLinkOptionsController(context: AccountContext, selfController: CreateLinkScreen, sourceNode: ASDisplayNode, url: String, name: String, positionBelowText: Bool, largeMedia: Bool?, webPage: TelegramMediaWebpage, completion: @escaping (Bool, Bool?) -> Void, remove: @escaping () -> Void) {
func presentLinkOptionsController(context: AccountContext, selfController: CreateLinkScreen, snapshotImage: UIImage?, isDark: Bool, sourceNode: ASDisplayNode, url: String, name: String, positionBelowText: Bool, largeMedia: Bool?, webPage: TelegramMediaWebpage, completion: @escaping (Bool, Bool?) -> Void, remove: @escaping () -> Void) {
var sources: [ContextController.Source] = []
if let source = linkOptions(context: context, selfController: selfController, sourceNode: sourceNode, url: url, text: name, positionBelowText: positionBelowText, largeMedia: largeMedia, webPage: webPage, completion: completion, remove: remove) {
if let source = linkOptions(context: context, selfController: selfController, snapshotImage: snapshotImage, isDark: isDark, sourceNode: sourceNode, url: url, text: name, positionBelowText: positionBelowText, largeMedia: largeMedia, webPage: webPage, completion: completion, remove: remove) {
sources.append(source)
}
if sources.isEmpty {
@ -35,7 +35,7 @@ func presentLinkOptionsController(context: AccountContext, selfController: Creat
selfController.presentInGlobalOverlay(contextController)
}
private func linkOptions(context: AccountContext, selfController: CreateLinkScreen, sourceNode: ASDisplayNode, url: String, text: String, positionBelowText: Bool, largeMedia: Bool?, webPage: TelegramMediaWebpage, completion: @escaping (Bool, Bool?) -> Void, remove: @escaping () -> Void) -> ContextController.Source? {
private func linkOptions(context: AccountContext, selfController: CreateLinkScreen, snapshotImage: UIImage?, isDark: Bool, sourceNode: ASDisplayNode, url: String, text: String, positionBelowText: Bool, largeMedia: Bool?, webPage: TelegramMediaWebpage, completion: @escaping (Bool, Bool?) -> Void, remove: @escaping () -> Void) -> ContextController.Source? {
let peerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(1))
let presentationData = context.sharedContext.currentPresentationData.with { $0 }.withUpdated(theme: defaultDarkColorPresentationTheme)
@ -86,7 +86,30 @@ private func linkOptions(context: AccountContext, selfController: CreateLinkScre
}
|> distinctUntilChanged
let chatController = context.sharedContext.makeChatController(context: context, chatLocation: .peer(id: peerId), subject: .messageOptions(peerIds: [peerId], ids: [], info: .link(ChatControllerSubject.MessageOptionsInfo.Link(options: linkOptions))), botStart: nil, mode: .standard(.previewing))
let wallpaper: TelegramWallpaper?
if let image = snapshotImage {
let wallpaperResource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max))
if let wallpaperData = image.jpegData(compressionQuality: 0.87) {
context.account.postbox.mediaBox.storeResourceData(wallpaperResource.id, data: wallpaperData, synchronous: true)
}
let wallpaperRepresentation = TelegramMediaImageRepresentation(dimensions: PixelDimensions(image.size), resource: wallpaperResource, progressiveSizes: [], immediateThumbnailData: nil)
wallpaper = .image([wallpaperRepresentation], WallpaperSettings())
} else {
wallpaper = nil
}
let chatController = context.sharedContext.makeChatController(
context: context,
chatLocation: .peer(id: peerId),
subject: .messageOptions(peerIds: [peerId], ids: [], info: .link(ChatControllerSubject.MessageOptionsInfo.Link(options: linkOptions, isCentered: true))),
botStart: nil,
mode: .standard(.previewing),
params: ChatControllerParams(
forcedTheme: isDark ? defaultDarkColorPresentationTheme : defaultPresentationTheme,
forcedNavigationBarTheme: defaultDarkColorPresentationTheme,
forcedWallpaper: wallpaper
)
)
chatController.canReadHistory.set(false)
let items = linkOptions

View File

@ -14,7 +14,6 @@ import SheetComponent
import BalancedTextComponent
import MultilineTextComponent
import BundleIconComponent
import ButtonComponent
import ItemListUI
import AccountContext
import PresentationDataUtils
@ -315,6 +314,7 @@ private final class CreateLinkSheetComponent: CombinedComponent {
}
fileprivate var name: String = ""
fileprivate var webpage: TelegramMediaWebpage?
fileprivate var isDark = false
fileprivate var dismissed = false
private var positionBelowText = true
@ -334,6 +334,7 @@ private final class CreateLinkSheetComponent: CombinedComponent {
self.link = link?.url ?? ""
self.name = link?.name ?? ""
self.webpage = link?.webpage
self.isDark = link?.isDark ?? false
self.positionBelowText = link?.positionBelowText ?? true
self.largeMedia = link?.largeMedia
@ -392,7 +393,8 @@ private final class CreateLinkSheetComponent: CombinedComponent {
if name.isEmpty {
name = self.link
}
presentLinkOptionsController(context: self.context, selfController: controller, sourceNode: sourceNode, url: link, name: name, positionBelowText: self.positionBelowText, largeMedia: self.largeMedia, webPage: webpage, completion: { [weak self] positionBelowText, largeMedia in
presentLinkOptionsController(context: self.context, selfController: controller, snapshotImage: controller.snapshotImage, isDark: self.isDark, sourceNode: sourceNode, url: link, name: name, positionBelowText: self.positionBelowText, largeMedia: self.largeMedia, webPage: webpage, completion: { [weak self] positionBelowText, largeMedia in
guard let self else {
return
}
@ -527,19 +529,22 @@ public final class CreateLinkScreen: ViewControllerComponentContainer {
let webpage: TelegramMediaWebpage?
let positionBelowText: Bool
let largeMedia: Bool?
let isDark: Bool
init(
url: String,
name: String?,
webpage: TelegramMediaWebpage?,
positionBelowText: Bool,
largeMedia: Bool?
largeMedia: Bool?,
isDark: Bool
) {
self.url = url
self.name = name
self.webpage = webpage
self.positionBelowText = positionBelowText
self.largeMedia = largeMedia
self.isDark = isDark
}
}
@ -554,14 +559,17 @@ public final class CreateLinkScreen: ViewControllerComponentContainer {
}
private let context: AccountContext
fileprivate let snapshotImage: UIImage?
fileprivate let completion: (CreateLinkScreen.Result) -> Void
public init(
context: AccountContext,
link: CreateLinkScreen.Link?,
snapshotImage: UIImage?,
completion: @escaping (CreateLinkScreen.Result) -> Void
) {
self.context = context
self.snapshotImage = snapshotImage
self.completion = completion
super.init(

View File

@ -4492,11 +4492,12 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
name: existingEntity.name,
webpage: existingEntity.webpage,
positionBelowText: existingEntity.positionBelowText,
largeMedia: existingEntity.largeMedia
largeMedia: existingEntity.largeMedia,
isDark: existingEntity.style == .black
)
}
let linkController = CreateLinkScreen(context: controller.context, link: link, completion: { [weak self] result in
let linkController = CreateLinkScreen(context: controller.context, link: link, snapshotImage: self.mediaEditor?.resultImage, completion: { [weak self] result in
guard let self else {
return
}

View File

@ -379,7 +379,7 @@ public final class PeerInfoChatListPaneNode: ASDisplayNode, PeerInfoPaneNode, AS
let threadId = peerData.peer.peerId.toInt64()
let chatController = self.context.sharedContext.makeChatController(context: self.context, chatLocation: .replyThread(message: ChatReplyThreadMessage(
peerId: self.context.account.peerId, threadId: threadId, channelMessageId: nil, isChannelPost: false, isForumPost: false, maxMessage: nil, maxReadIncomingMessageId: nil, maxReadOutgoingMessageId: nil, unreadCount: 0, initialFilledHoles: IndexSet(), initialAnchor: .automatic, isNotAvailable: false
)), subject: nil, botStart: nil, mode: .standard(.previewing))
)), subject: nil, botStart: nil, mode: .standard(.previewing), params: nil)
chatController.canReadHistory.set(false)
let source: ContextContentSource = .controller(ContextControllerContentSourceImpl(controller: chatController, sourceNode: node, navigationController: parentController.navigationController as? NavigationController))
@ -400,7 +400,7 @@ public final class PeerInfoChatListPaneNode: ASDisplayNode, PeerInfoPaneNode, AS
public func activateSearch() {
if self.chatController == nil {
let chatController = self.context.sharedContext.makeChatController(context: self.context, chatLocation: .peer(id: self.context.account.peerId), subject: nil, botStart: nil, mode: .standard(.embedded(invertDirection: false)))
let chatController = self.context.sharedContext.makeChatController(context: self.context, chatLocation: .peer(id: self.context.account.peerId), subject: nil, botStart: nil, mode: .standard(.embedded(invertDirection: false)), params: nil)
chatController.alwaysShowSearchResultsAsList = true
chatController.includeSavedPeersInSearchResults = true
self.chatController = chatController

View File

@ -149,7 +149,7 @@ public final class PeerInfoChatPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScro
self.coveringView = UIView()
self.chatController = context.sharedContext.makeChatController(context: context, chatLocation: .replyThread(message: ChatReplyThreadMessage(peerId: context.account.peerId, threadId: peerId.toInt64(), channelMessageId: nil, isChannelPost: false, isForumPost: false, maxMessage: nil, maxReadIncomingMessageId: nil, maxReadOutgoingMessageId: nil, unreadCount: 0, initialFilledHoles: IndexSet(), initialAnchor: .automatic, isNotAvailable: false)), subject: nil, botStart: nil, mode: .standard(.embedded(invertDirection: true)))
self.chatController = context.sharedContext.makeChatController(context: context, chatLocation: .replyThread(message: ChatReplyThreadMessage(peerId: context.account.peerId, threadId: peerId.toInt64(), channelMessageId: nil, isChannelPost: false, isForumPost: false, maxMessage: nil, maxReadIncomingMessageId: nil, maxReadOutgoingMessageId: nil, unreadCount: 0, initialFilledHoles: IndexSet(), initialAnchor: .automatic, isNotAvailable: false)), subject: nil, botStart: nil, mode: .standard(.embedded(invertDirection: true)), params: nil)
self.chatController.navigation_setNavigationController(navigationController())
super.init()

View File

@ -3399,7 +3399,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
return
}
let presentationData = strongSelf.presentationData
let chatController = strongSelf.context.sharedContext.makeChatController(context: context, chatLocation: .peer(id: peer.id), subject: nil, botStart: nil, mode: .standard(.previewing))
let chatController = strongSelf.context.sharedContext.makeChatController(context: context, chatLocation: .peer(id: peer.id), subject: nil, botStart: nil, mode: .standard(.previewing), params: nil)
chatController.canReadHistory.set(false)
let items: [ContextMenuItem]
if recommended {
@ -9654,7 +9654,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
}
}
if !foundController {
let chatController = strongSelf.context.sharedContext.makeChatController(context: strongSelf.context, chatLocation: .peer(id: strongSelf.peerId), subject: nil, botStart: nil, mode: .standard(.default))
let chatController = strongSelf.context.sharedContext.makeChatController(context: strongSelf.context, chatLocation: .peer(id: strongSelf.peerId), subject: nil, botStart: nil, mode: .standard(.default), params: nil)
chatController.hintPlayNextOutgoingGift()
controllers.append(chatController)
}
@ -9941,7 +9941,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
}
self.supportPeerDisposable.set((supportPeer.get() |> take(1) |> deliverOnMainQueue).startStrict(next: { [weak self] peerId in
if let strongSelf = self, let peerId = peerId {
push(strongSelf.context.sharedContext.makeChatController(context: strongSelf.context, chatLocation: .peer(id: peerId), subject: nil, botStart: nil, mode: .standard(.default)))
push(strongSelf.context.sharedContext.makeChatController(context: strongSelf.context, chatLocation: .peer(id: peerId), subject: nil, botStart: nil, mode: .standard(.default), params: nil))
}
}))
})]), in: .window(.root))
@ -10447,7 +10447,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
proceed(chatController)
})
} else {
let chatController = strongSelf.context.sharedContext.makeChatController(context: strongSelf.context, chatLocation: .peer(id: peerId), subject: .none, botStart: nil, mode: .standard(.default))
let chatController = strongSelf.context.sharedContext.makeChatController(context: strongSelf.context, chatLocation: .peer(id: peerId), subject: .none, botStart: nil, mode: .standard(.default), params: nil)
proceed(chatController)
}
}
@ -10913,7 +10913,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
))
})))
let chatController = strongSelf.context.sharedContext.makeChatController(context: strongSelf.context, chatLocation: .peer(id: strongSelf.peerId), subject: .message(id: .id(index.id), highlight: nil, timecode: nil), botStart: nil, mode: .standard(.previewing))
let chatController = strongSelf.context.sharedContext.makeChatController(context: strongSelf.context, chatLocation: .peer(id: strongSelf.peerId), subject: .message(id: .id(index.id), highlight: nil, timecode: nil), botStart: nil, mode: .standard(.previewing), params: nil)
chatController.canReadHistory.set(false)
let contextController = ContextController(presentationData: strongSelf.presentationData, source: .controller(ContextControllerContentSourceImpl(controller: chatController, sourceNode: sourceNode, sourceRect: sourceRect, passthroughTouches: true)), items: .single(ContextController.Items(content: .list(items))), gesture: gesture)
strongSelf.controller?.presentInGlobalOverlay(contextController)
@ -12650,7 +12650,7 @@ public final class PeerInfoScreenImpl: ViewController, PeerInfoScreen, KeyShortc
}) {
let _ = navigationController.popToViewController(chatController, animated: false)
} else {
let chatController = context.sharedContext.makeChatController(context: context, chatLocation: .peer(id: context.account.peerId), subject: nil, botStart: nil, mode: .standard(.default))
let chatController = context.sharedContext.makeChatController(context: context, chatLocation: .peer(id: context.account.peerId), subject: nil, botStart: nil, mode: .standard(.default), params: nil)
navigationController.replaceController(sourceController, with: chatController, animated: false)
}

View File

@ -375,7 +375,8 @@ final class PeerSelectionControllerNode: ASDisplayNode {
chatLocation: .peer(id: strongSelf.context.account.peerId),
subject: .messageOptions(peerIds: peerIds, ids: strongSelf.presentationInterfaceState.interfaceState.forwardMessageIds ?? [], info: .forward(ChatControllerSubject.MessageOptionsInfo.Forward(options: forwardOptions))),
botStart: nil,
mode: .standard(.previewing)
mode: .standard(.previewing),
params: nil
)
chatController.canReadHistory.set(false)

View File

@ -483,7 +483,8 @@ final class AutomaticBusinessMessageSetupScreenComponent: Component {
chatLocation: .customChatContents,
subject: .customChatContents(contents: contents),
botStart: nil,
mode: .standard(.default)
mode: .standard(.default),
params: nil
)
chatController.navigationPresentation = .modal
self.environment?.controller()?.push(chatController)

View File

@ -212,7 +212,8 @@ final class BusinessLinksSetupScreenComponent: Component {
chatLocation: .customChatContents,
subject: .customChatContents(contents: contents),
botStart: nil,
mode: .standard(.default)
mode: .standard(.default),
params: nil
)
if openKeyboard {
chatController.activateInput(type: .text)

View File

@ -578,7 +578,8 @@ final class QuickReplySetupScreenComponent: Component {
chatLocation: .customChatContents,
subject: .customChatContents(contents: contents),
botStart: nil,
mode: .standard(.default)
mode: .standard(.default),
params: nil
)
chatController.navigationPresentation = .modal

View File

@ -98,10 +98,13 @@ final class StarsStatisticsScreenComponent: Component {
private let proceedsView = ComponentView<Empty>()
private let balanceView = ComponentView<Empty>()
private let panelContainer = ComponentView<StarsTransactionsPanelContainerEnvironment>()
private let transactionsHeader = ComponentView<Empty>()
private let transactionsBackground = UIView()
private let transactionsView = ComponentView<StarsTransactionsPanelEnvironment>()
private var component: StarsStatisticsScreenComponent?
private weak var state: EmptyComponentState?
private var environment: Environment<ViewControllerComponentContainer.Environment>?
private var navigationMetrics: (navigationHeight: CGFloat, statusBarHeight: CGFloat)?
private var controller: (() -> ViewController?)?
@ -155,7 +158,8 @@ final class StarsStatisticsScreenComponent: Component {
self.addSubview(self.scrollView)
self.scrollView.addSubview(self.scrollContainerView)
self.scrollContainerView.addSubview(self.transactionsBackground)
self.addSubview(self.navigationBackgroundView)
self.navigationSeparatorLayerContainer.addSublayer(self.navigationSeparatorLayer)
@ -205,12 +209,16 @@ final class StarsStatisticsScreenComponent: Component {
}
private func updateScrolling(transition: ComponentTransition) {
guard let environment = self.environment?[ViewControllerComponentContainer.Environment.self].value else {
return
}
let scrollBounds = self.scrollView.bounds
let isLockedAtPanels = scrollBounds.maxY == self.scrollView.contentSize.height
let topContentOffset = self.scrollView.contentOffset.y
let navigationBackgroundAlpha = min(20.0, max(0.0, topContentOffset - 95.0)) / 20.0
let navigationBackgroundAlpha = min(20.0, max(0.0, topContentOffset)) / 20.0
let animatedTransition = ComponentTransition(animation: .curve(duration: 0.18, curve: .easeInOut))
animatedTransition.setAlpha(view: self.navigationBackgroundView, alpha: navigationBackgroundAlpha)
@ -221,14 +229,18 @@ final class StarsStatisticsScreenComponent: Component {
expansionDistanceFactor = max(0.0, min(1.0, expansionDistanceFactor))
transition.setAlpha(layer: self.navigationSeparatorLayer, alpha: expansionDistanceFactor)
if let panelContainerView = self.panelContainer.view as? StarsTransactionsPanelContainerComponent.View {
panelContainerView.updateNavigationMergeFactor(value: 1.0 - expansionDistanceFactor, transition: transition)
}
let _ = self.panelContainer.updateEnvironment(
let _ = self.transactionsView.updateEnvironment(
transition: transition,
environment: {
StarsTransactionsPanelContainerEnvironment(isScrollable: isLockedAtPanels)
StarsTransactionsPanelEnvironment(
theme: environment.theme,
strings: environment.strings,
dateTimeFormat: environment.dateTimeFormat,
containerInsets: UIEdgeInsets(top: 0.0, left: environment.safeInsets.left, bottom: environment.safeInsets.bottom, right: environment.safeInsets.right),
isScrollable: isLockedAtPanels,
isCurrent: true
)
}
)
}
@ -241,16 +253,9 @@ final class StarsStatisticsScreenComponent: Component {
}
self.component = component
self.environment = environment
self.state = state
var balanceUpdated = false
if let starsState = self.starsState {
if let previousBalance = self.previousBalance, starsState.balances.availableBalance != previousBalance {
balanceUpdated = true
}
self.previousBalance = starsState.balances.availableBalance
}
let environment = environment[ViewControllerComponentContainer.Environment.self].value
let presentationData = component.context.sharedContext.currentPresentationData.with { $0 }
@ -269,7 +274,7 @@ final class StarsStatisticsScreenComponent: Component {
}
var wasLockedAtPanels = false
if let panelContainerView = self.panelContainer.view, let navigationMetrics = self.navigationMetrics {
if let panelContainerView = self.transactionsView.view, let navigationMetrics = self.navigationMetrics {
if self.scrollView.bounds.minY > 0.0 && abs(self.scrollView.bounds.minY - (panelContainerView.frame.minY - navigationMetrics.navigationHeight)) <= UIScreenPixel {
wasLockedAtPanels = true
}
@ -296,7 +301,6 @@ final class StarsStatisticsScreenComponent: Component {
var contentHeight: CGFloat = 0.0
let sideInsets: CGFloat = environment.safeInsets.left + environment.safeInsets.right + 16 * 2.0
let bottomInset: CGFloat = environment.safeInsets.bottom
contentHeight += environment.navigationHeight
contentHeight += 31.0
@ -401,7 +405,7 @@ final class StarsStatisticsScreenComponent: Component {
transition.setFrame(view: proceedsView, frame: proceedsFrame)
}
contentHeight += proceedsSize.height
contentHeight += 44.0
contentHeight += 31.0
let termsFont = Font.regular(13.0)
let termsTextColor = environment.theme.list.freeTextColor
@ -464,71 +468,77 @@ final class StarsStatisticsScreenComponent: Component {
}
contentHeight += balanceSize.height
contentHeight += 44.0
contentHeight += 27.0
var panelItems: [StarsTransactionsPanelContainerComponent.Item] = []
let allTransactionsContext: StarsTransactionsContext
if let current = self.allTransactionsContext {
allTransactionsContext = current
} else {
allTransactionsContext = component.context.engine.payments.peerStarsTransactionsContext(subject: .peer(component.peerId), mode: .all)
component.revenueContext.setUpdated { [weak self] in
if let self, let allTransactionsContext = self.allTransactionsContext {
allTransactionsContext.reload()
}
}
allTransactionsContext = component.context.engine.payments.peerStarsTransactionsContext( subject: .peer(component.peerId), mode: .all)
self.allTransactionsContext = allTransactionsContext
}
panelItems.append(StarsTransactionsPanelContainerComponent.Item(
id: "all",
title: environment.strings.Stars_Intro_AllTransactions,
panel: AnyComponent(StarsTransactionsListPanelComponent(
let transactionsHeaderSize = self.transactionsHeader.update(
transition: transition,
component: AnyComponent(MultilineTextComponent(
text: .plain(NSAttributedString(
string: environment.strings.Stars_BotRevenue_Transactions_Title.uppercased(),
font: Font.regular(presentationData.listsFontSize.itemListBaseHeaderFontSize),
textColor: environment.theme.list.freeTextColor
)),
maximumNumberOfLines: 0
)),
environment: {},
containerSize: availableSize
)
let transactionsHeaderFrame = CGRect(origin: CGPoint(x: environment.safeInsets.left + 32.0, y: contentHeight), size: transactionsHeaderSize)
if let transactionsHeaderView = self.transactionsHeader.view {
if transactionsHeaderView.superview == nil {
self.scrollView.addSubview(transactionsHeaderView)
}
transition.setFrame(view: transactionsHeaderView, frame: transactionsHeaderFrame)
}
contentHeight += transactionsHeaderSize.height
contentHeight += 6.0
self.transactionsBackground.backgroundColor = environment.theme.list.itemBlocksBackgroundColor
self.transactionsBackground.layer.cornerRadius = 11.0
if #available(iOS 13.0, *) {
self.transactionsBackground.layer.cornerCurve = .continuous
}
let transactionsSize = self.transactionsView.update(
transition: .immediate,
component: AnyComponent(StarsTransactionsListPanelComponent(
context: component.context,
transactionsContext: allTransactionsContext,
action: { transaction in
component.openTransaction(transaction)
}
))
))
var panelTransition = transition
if balanceUpdated {
panelTransition = .easeInOut(duration: 0.25)
}
if !panelItems.isEmpty {
let panelContainerSize = self.panelContainer.update(
transition: panelTransition,
component: AnyComponent(StarsTransactionsPanelContainerComponent(
)),
environment: {
StarsTransactionsPanelEnvironment(
theme: environment.theme,
strings: environment.strings,
dateTimeFormat: environment.dateTimeFormat,
insets: UIEdgeInsets(top: 0.0, left: environment.safeInsets.left, bottom: bottomInset, right: environment.safeInsets.right),
items: panelItems,
currentPanelUpdated: { [weak self] id, transition in
guard let self else {
return
}
self.currentSelectedPanelId = id
self.state?.updated(transition: transition)
}
)),
environment: {
StarsTransactionsPanelContainerEnvironment(isScrollable: wasLockedAtPanels)
},
containerSize: CGSize(width: availableSize.width, height: availableSize.height - environment.navigationHeight)
)
if let panelContainerView = self.panelContainer.view {
if panelContainerView.superview == nil {
self.scrollContainerView.addSubview(panelContainerView)
}
transition.setFrame(view: panelContainerView, frame: CGRect(origin: CGPoint(x: 0.0, y: contentHeight), size: panelContainerSize))
containerInsets: UIEdgeInsets(top: 0.0, left: environment.safeInsets.left, bottom: environment.safeInsets.bottom, right: environment.safeInsets.right),
isScrollable: wasLockedAtPanels,
isCurrent: true
)
},
containerSize: CGSize(width: availableSize.width - sideInsets, height: availableSize.height)
)
let transactionsFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((availableSize.width - transactionsSize.width) / 2.0), y: contentHeight), size: transactionsSize)
if let panelContainerView = self.transactionsView.view {
if panelContainerView.superview == nil {
self.scrollContainerView.addSubview(panelContainerView)
}
contentHeight += panelContainerSize.height
} else {
self.panelContainer.view?.removeFromSuperview()
transition.setFrame(view: panelContainerView, frame: transactionsFrame)
}
transition.setFrame(view: self.transactionsBackground, frame: transactionsFrame)
contentHeight += transactionsSize.height
contentHeight += 31.0
self.ignoreScrolling = true
@ -542,7 +552,7 @@ final class StarsStatisticsScreenComponent: Component {
var scrollViewBounds = self.scrollView.bounds
scrollViewBounds.size = availableSize
if wasLockedAtPanels, let panelContainerView = self.panelContainer.view {
if wasLockedAtPanels, let panelContainerView = self.transactionsView.view {
scrollViewBounds.origin.y = panelContainerView.frame.minY - environment.navigationHeight
}
transition.setBounds(view: self.scrollView, bounds: scrollViewBounds)

View File

@ -3912,7 +3912,7 @@ extension ChatControllerImpl {
chatLocation = .peer(id: peerId)
}
let chatController = strongSelf.context.sharedContext.makeChatController(context: strongSelf.context, chatLocation: chatLocation, subject: .pinnedMessages(id: pinnedMessage.message.id), botStart: nil, mode: .standard(.previewing))
let chatController = strongSelf.context.sharedContext.makeChatController(context: strongSelf.context, chatLocation: chatLocation, subject: .pinnedMessages(id: pinnedMessage.message.id), botStart: nil, mode: .standard(.previewing), params: nil)
chatController.canReadHistory.set(false)
strongSelf.chatDisplayNode.messageTransitionNode.dismissMessageReactionContexts()

View File

@ -103,7 +103,7 @@ private func chatForwardOptions(selfController: ChatControllerImpl, sourceNode:
}
|> distinctUntilChanged
let chatController = selfController.context.sharedContext.makeChatController(context: selfController.context, chatLocation: .peer(id: peerId), subject: .messageOptions(peerIds: [peerId], ids: selfController.presentationInterfaceState.interfaceState.forwardMessageIds ?? [], info: .forward(ChatControllerSubject.MessageOptionsInfo.Forward(options: forwardOptions))), botStart: nil, mode: .standard(.previewing))
let chatController = selfController.context.sharedContext.makeChatController(context: selfController.context, chatLocation: .peer(id: peerId), subject: .messageOptions(peerIds: [peerId], ids: selfController.presentationInterfaceState.interfaceState.forwardMessageIds ?? [], info: .forward(ChatControllerSubject.MessageOptionsInfo.Forward(options: forwardOptions))), botStart: nil, mode: .standard(.previewing), params: nil)
chatController.canReadHistory.set(false)
let messageIds = selfController.presentationInterfaceState.interfaceState.forwardMessageIds ?? []
@ -514,7 +514,7 @@ private func chatReplyOptions(selfController: ChatControllerImpl, sourceNode: AS
}
|> distinctUntilChanged)
guard let chatController = selfController.context.sharedContext.makeChatController(context: selfController.context, chatLocation: .peer(id: peerId), subject: .messageOptions(peerIds: [replySubject.messageId.peerId], ids: [replySubject.messageId], info: .reply(ChatControllerSubject.MessageOptionsInfo.Reply(quote: replyQuote, selectionState: selectionState))), botStart: nil, mode: .standard(.previewing)) as? ChatControllerImpl else {
guard let chatController = selfController.context.sharedContext.makeChatController(context: selfController.context, chatLocation: .peer(id: peerId), subject: .messageOptions(peerIds: [replySubject.messageId.peerId], ids: [replySubject.messageId], info: .reply(ChatControllerSubject.MessageOptionsInfo.Reply(quote: replyQuote, selectionState: selectionState))), botStart: nil, mode: .standard(.previewing), params: nil) as? ChatControllerImpl else {
return nil
}
chatController.canReadHistory.set(false)
@ -785,7 +785,7 @@ private func chatLinkOptions(selfController: ChatControllerImpl, sourceNode: ASD
}
|> distinctUntilChanged
guard let chatController = selfController.context.sharedContext.makeChatController(context: selfController.context, chatLocation: .peer(id: peerId), subject: .messageOptions(peerIds: [peerId], ids: selfController.presentationInterfaceState.interfaceState.forwardMessageIds ?? [], info: .link(ChatControllerSubject.MessageOptionsInfo.Link(options: linkOptions))), botStart: nil, mode: .standard(.previewing)) as? ChatControllerImpl else {
guard let chatController = selfController.context.sharedContext.makeChatController(context: selfController.context, chatLocation: .peer(id: peerId), subject: .messageOptions(peerIds: [peerId], ids: selfController.presentationInterfaceState.interfaceState.forwardMessageIds ?? [], info: .link(ChatControllerSubject.MessageOptionsInfo.Link(options: linkOptions, isCentered: false))), botStart: nil, mode: .standard(.previewing), params: nil) as? ChatControllerImpl else {
return nil
}
chatController.canReadHistory.set(false)

View File

@ -412,6 +412,9 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
return (self.presentationData, self.presentationDataPromise.get())
}
var presentationDataDisposable: Disposable?
var forcedTheme: PresentationTheme?
var forcedNavigationBarTheme: PresentationTheme?
var forcedWallpaper: TelegramWallpaper?
var automaticMediaDownloadSettings: MediaAutoDownloadSettings
var automaticMediaDownloadSettingsDisposable: Disposable?
@ -622,7 +625,22 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
}
public init(context: AccountContext, chatLocation: ChatLocation, chatLocationContextHolder: Atomic<ChatLocationContextHolder?> = Atomic<ChatLocationContextHolder?>(value: nil), subject: ChatControllerSubject? = nil, botStart: ChatControllerInitialBotStart? = nil, attachBotStart: ChatControllerInitialAttachBotStart? = nil, botAppStart: ChatControllerInitialBotAppStart? = nil, mode: ChatControllerPresentationMode = .standard(.default), peekData: ChatPeekTimeout? = nil, peerNearbyData: ChatPeerNearbyData? = nil, chatListFilter: Int32? = nil, chatNavigationStack: [ChatNavigationStackItem] = [], customChatNavigationStack: [EnginePeer.Id]? = nil) {
public init(
context: AccountContext,
chatLocation: ChatLocation,
chatLocationContextHolder: Atomic<ChatLocationContextHolder?> = Atomic<ChatLocationContextHolder?>(value: nil),
subject: ChatControllerSubject? = nil,
botStart: ChatControllerInitialBotStart? = nil,
attachBotStart: ChatControllerInitialAttachBotStart? = nil,
botAppStart: ChatControllerInitialBotAppStart? = nil,
mode: ChatControllerPresentationMode = .standard(.default),
peekData: ChatPeekTimeout? = nil,
peerNearbyData: ChatPeerNearbyData? = nil,
chatListFilter: Int32? = nil,
chatNavigationStack: [ChatNavigationStackItem] = [],
customChatNavigationStack: [EnginePeer.Id]? = nil,
params: ChatControllerParams? = nil
) {
let _ = ChatControllerCount.modify { value in
return value + 1
}
@ -638,6 +656,10 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
self.currentChatListFilter = chatListFilter
self.chatNavigationStack = chatNavigationStack
self.customChatNavigationStack = customChatNavigationStack
self.forcedTheme = params?.forcedTheme
self.forcedNavigationBarTheme = params?.forcedNavigationBarTheme
self.forcedWallpaper = params?.forcedWallpaper
var useSharedAnimationPhase = false
switch mode {
@ -684,7 +706,14 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
self.chatLocationInfoData = .customChatContents
}
self.presentationData = context.sharedContext.currentPresentationData.with { $0 }
var presentationData = context.sharedContext.currentPresentationData.with { $0 }
if let forcedTheme = self.forcedTheme {
presentationData = presentationData.withUpdated(theme: forcedTheme)
}
if let forcedWallpaper = self.forcedWallpaper {
presentationData = presentationData.withUpdated(chatWallpaper: forcedWallpaper)
}
self.presentationData = presentationData
self.automaticMediaDownloadSettings = context.sharedContext.currentAutomaticMediaDownloadSettings
self.stickerSettings = ChatInterfaceStickerSettings()
@ -4310,7 +4339,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
return
}
let chatController = self.context.sharedContext.makeChatController(context: self.context, chatLocation: .peer(id: peer.id), subject: nil, botStart: nil, mode: .standard(.previewing))
let chatController = self.context.sharedContext.makeChatController(context: self.context, chatLocation: .peer(id: peer.id), subject: nil, botStart: nil, mode: .standard(.previewing), params: nil)
chatController.canReadHistory.set(false)
var items: [ContextMenuItem] = [
@ -4991,102 +5020,100 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
isScheduledMessages = true
}
if let peer = peerViewMainPeer(peerView) {
if case let .messageOptions(_, _, info) = presentationInterfaceState.subject {
if case .reply = info {
let titleContent: ChatTitleContent
if case let .reply(hasQuote) = messageOptionsTitleInfo, hasQuote {
titleContent = .custom(presentationInterfaceState.strings.Chat_TitleQuoteSelection, subtitleText, false)
} else {
titleContent = .custom(presentationInterfaceState.strings.Chat_TitleReply, subtitleText, false)
}
if strongSelf.chatTitleView?.titleContent != titleContent {
if strongSelf.chatTitleView?.titleContent != nil {
strongSelf.chatTitleView?.animateLayoutTransition()
}
strongSelf.chatTitleView?.titleContent = titleContent
}
} else if case .link = info {
strongSelf.chatTitleView?.titleContent = .custom(presentationInterfaceState.strings.Chat_TitleLinkOptions, subtitleText, false)
} else if displayedCount == 1 {
strongSelf.chatTitleView?.titleContent = .custom(presentationInterfaceState.strings.Conversation_ForwardOptions_ForwardTitleSingle, subtitleText, false)
if case let .messageOptions(_, _, info) = presentationInterfaceState.subject {
if case .reply = info {
let titleContent: ChatTitleContent
if case let .reply(hasQuote) = messageOptionsTitleInfo, hasQuote {
titleContent = .custom(presentationInterfaceState.strings.Chat_TitleQuoteSelection, subtitleText, false)
} else {
strongSelf.chatTitleView?.titleContent = .custom(presentationInterfaceState.strings.Conversation_ForwardOptions_ForwardTitle(Int32(displayedCount ?? 1)), subtitleText, false)
titleContent = .custom(presentationInterfaceState.strings.Chat_TitleReply, subtitleText, false)
}
} else if let selectionState = presentationInterfaceState.interfaceState.selectionState {
if selectionState.selectedIds.count > 0 {
strongSelf.chatTitleView?.titleContent = .custom(presentationInterfaceState.strings.Conversation_SelectedMessages(Int32(selectionState.selectedIds.count)), nil, false)
} else {
if let reportReason = presentationInterfaceState.reportReason {
let title: String
switch reportReason {
case .spam:
title = presentationInterfaceState.strings.ReportPeer_ReasonSpam
case .fake:
title = presentationInterfaceState.strings.ReportPeer_ReasonFake
case .violence:
title = presentationInterfaceState.strings.ReportPeer_ReasonViolence
case .porno:
title = presentationInterfaceState.strings.ReportPeer_ReasonPornography
case .childAbuse:
title = presentationInterfaceState.strings.ReportPeer_ReasonChildAbuse
case .copyright:
title = presentationInterfaceState.strings.ReportPeer_ReasonCopyright
case .illegalDrugs:
title = presentationInterfaceState.strings.ReportPeer_ReasonIllegalDrugs
case .personalDetails:
title = presentationInterfaceState.strings.ReportPeer_ReasonPersonalDetails
case .custom:
title = presentationInterfaceState.strings.ReportPeer_ReasonOther
case .irrelevantLocation:
title = ""
}
strongSelf.chatTitleView?.titleContent = .custom(title, presentationInterfaceState.strings.Conversation_SelectMessages, false)
} else {
strongSelf.chatTitleView?.titleContent = .custom(presentationInterfaceState.strings.Conversation_SelectMessages, nil, false)
if strongSelf.chatTitleView?.titleContent != titleContent {
if strongSelf.chatTitleView?.titleContent != nil {
strongSelf.chatTitleView?.animateLayoutTransition()
}
strongSelf.chatTitleView?.titleContent = titleContent
}
} else if case .link = info {
strongSelf.chatTitleView?.titleContent = .custom(presentationInterfaceState.strings.Chat_TitleLinkOptions, subtitleText, false)
} else if displayedCount == 1 {
strongSelf.chatTitleView?.titleContent = .custom(presentationInterfaceState.strings.Conversation_ForwardOptions_ForwardTitleSingle, subtitleText, false)
} else {
if case .pinnedMessages = presentationInterfaceState.subject {
strongSelf.chatTitleView?.titleContent = .custom(presentationInterfaceState.strings.Chat_TitlePinnedMessages(Int32(displayedCount ?? 1)), nil, false)
strongSelf.chatTitleView?.titleContent = .custom(presentationInterfaceState.strings.Conversation_ForwardOptions_ForwardTitle(Int32(displayedCount ?? 1)), subtitleText, false)
}
} else if let selectionState = presentationInterfaceState.interfaceState.selectionState {
if selectionState.selectedIds.count > 0 {
strongSelf.chatTitleView?.titleContent = .custom(presentationInterfaceState.strings.Conversation_SelectedMessages(Int32(selectionState.selectedIds.count)), nil, false)
} else {
if let reportReason = presentationInterfaceState.reportReason {
let title: String
switch reportReason {
case .spam:
title = presentationInterfaceState.strings.ReportPeer_ReasonSpam
case .fake:
title = presentationInterfaceState.strings.ReportPeer_ReasonFake
case .violence:
title = presentationInterfaceState.strings.ReportPeer_ReasonViolence
case .porno:
title = presentationInterfaceState.strings.ReportPeer_ReasonPornography
case .childAbuse:
title = presentationInterfaceState.strings.ReportPeer_ReasonChildAbuse
case .copyright:
title = presentationInterfaceState.strings.ReportPeer_ReasonCopyright
case .illegalDrugs:
title = presentationInterfaceState.strings.ReportPeer_ReasonIllegalDrugs
case .personalDetails:
title = presentationInterfaceState.strings.ReportPeer_ReasonPersonalDetails
case .custom:
title = presentationInterfaceState.strings.ReportPeer_ReasonOther
case .irrelevantLocation:
title = ""
}
strongSelf.chatTitleView?.titleContent = .custom(title, presentationInterfaceState.strings.Conversation_SelectMessages, false)
} else {
strongSelf.chatTitleView?.titleContent = .peer(peerView: ChatTitleContent.PeerData(peerView: peerView), customTitle: nil, onlineMemberCount: onlineMemberCount, isScheduledMessages: isScheduledMessages, isMuted: nil, customMessageCount: nil, isEnabled: hasPeerInfo)
let imageOverride: AvatarNodeImageOverride?
if strongSelf.context.account.peerId == peer.id {
imageOverride = .savedMessagesIcon
} else if peer.id.isReplies {
imageOverride = .repliesIcon
} else if peer.id.isAnonymousSavedMessages {
imageOverride = .anonymousSavedMessagesIcon
} else if peer.isDeleted {
imageOverride = .deletedIcon
} else {
imageOverride = nil
}
(strongSelf.chatInfoNavigationButton?.buttonItem.customDisplayNode as? ChatAvatarNavigationNode)?.setPeer(context: strongSelf.context, theme: strongSelf.presentationData.theme, peer: EnginePeer(peer), overrideImage: imageOverride)
(strongSelf.chatInfoNavigationButton?.buttonItem.customDisplayNode as? ChatAvatarNavigationNode)?.contextActionIsEnabled = strongSelf.chatLocation.threadId == nil && peer.restrictionText(platform: "ios", contentSettings: strongSelf.context.currentContentSettings.with { $0 }) == nil
strongSelf.chatInfoNavigationButton?.buttonItem.accessibilityLabel = presentationInterfaceState.strings.Conversation_ContextMenuOpenProfile
strongSelf.storyStats = peerView.storyStats
if let avatarNode = strongSelf.avatarNode {
avatarNode.avatarNode.setStoryStats(storyStats: peerView.storyStats.flatMap { storyStats -> AvatarNode.StoryStats? in
if storyStats.totalCount == 0 {
return nil
}
if storyStats.unseenCount == 0 {
return nil
}
return AvatarNode.StoryStats(
totalCount: storyStats.totalCount,
unseenCount: storyStats.unseenCount,
hasUnseenCloseFriendsItems: storyStats.hasUnseenCloseFriends
)
}, presentationParams: AvatarNode.StoryPresentationParams(
colors: AvatarNode.Colors(theme: strongSelf.presentationData.theme),
lineWidth: 1.5,
inactiveLineWidth: 1.5
), transition: .immediate)
}
strongSelf.chatTitleView?.titleContent = .custom(presentationInterfaceState.strings.Conversation_SelectMessages, nil, false)
}
}
} else if let peer = peerViewMainPeer(peerView) {
if case .pinnedMessages = presentationInterfaceState.subject {
strongSelf.chatTitleView?.titleContent = .custom(presentationInterfaceState.strings.Chat_TitlePinnedMessages(Int32(displayedCount ?? 1)), nil, false)
} else {
strongSelf.chatTitleView?.titleContent = .peer(peerView: ChatTitleContent.PeerData(peerView: peerView), customTitle: nil, onlineMemberCount: onlineMemberCount, isScheduledMessages: isScheduledMessages, isMuted: nil, customMessageCount: nil, isEnabled: hasPeerInfo)
let imageOverride: AvatarNodeImageOverride?
if strongSelf.context.account.peerId == peer.id {
imageOverride = .savedMessagesIcon
} else if peer.id.isReplies {
imageOverride = .repliesIcon
} else if peer.id.isAnonymousSavedMessages {
imageOverride = .anonymousSavedMessagesIcon
} else if peer.isDeleted {
imageOverride = .deletedIcon
} else {
imageOverride = nil
}
(strongSelf.chatInfoNavigationButton?.buttonItem.customDisplayNode as? ChatAvatarNavigationNode)?.setPeer(context: strongSelf.context, theme: strongSelf.presentationData.theme, peer: EnginePeer(peer), overrideImage: imageOverride)
(strongSelf.chatInfoNavigationButton?.buttonItem.customDisplayNode as? ChatAvatarNavigationNode)?.contextActionIsEnabled = strongSelf.chatLocation.threadId == nil && peer.restrictionText(platform: "ios", contentSettings: strongSelf.context.currentContentSettings.with { $0 }) == nil
strongSelf.chatInfoNavigationButton?.buttonItem.accessibilityLabel = presentationInterfaceState.strings.Conversation_ContextMenuOpenProfile
strongSelf.storyStats = peerView.storyStats
if let avatarNode = strongSelf.avatarNode {
avatarNode.avatarNode.setStoryStats(storyStats: peerView.storyStats.flatMap { storyStats -> AvatarNode.StoryStats? in
if storyStats.totalCount == 0 {
return nil
}
if storyStats.unseenCount == 0 {
return nil
}
return AvatarNode.StoryStats(
totalCount: storyStats.totalCount,
unseenCount: storyStats.unseenCount,
hasUnseenCloseFriendsItems: storyStats.hasUnseenCloseFriends
)
}, presentationParams: AvatarNode.StoryPresentationParams(
colors: AvatarNode.Colors(theme: strongSelf.presentationData.theme),
lineWidth: 1.5,
inactiveLineWidth: 1.5
), transition: .immediate)
}
}
}
@ -6443,82 +6470,85 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
var presentationData = presentationData
var useDarkAppearance = presentationData.theme.overallDarkAppearance
if let wallpaper = chatWallpaper, case let .emoticon(wallpaperEmoticon) = wallpaper, let theme = chatThemes.first(where: { $0.emoticon?.strippedEmoji == wallpaperEmoticon.strippedEmoji }) {
let themeSettings: TelegramThemeSettings?
if let matching = theme.settings?.first(where: { $0.baseTheme == presentationData.theme.referenceTheme.baseTheme }) {
themeSettings = matching
} else {
themeSettings = theme.settings?.first
if let forcedTheme = strongSelf.forcedTheme {
presentationData = presentationData.withUpdated(theme: forcedTheme)
} else {
if let wallpaper = chatWallpaper, case let .emoticon(wallpaperEmoticon) = wallpaper, let theme = chatThemes.first(where: { $0.emoticon?.strippedEmoji == wallpaperEmoticon.strippedEmoji }) {
let themeSettings: TelegramThemeSettings?
if let matching = theme.settings?.first(where: { $0.baseTheme == presentationData.theme.referenceTheme.baseTheme }) {
themeSettings = matching
} else {
themeSettings = theme.settings?.first
}
if let themeWallpaper = themeSettings?.wallpaper {
chatWallpaper = themeWallpaper
}
}
if let themeWallpaper = themeSettings?.wallpaper {
chatWallpaper = themeWallpaper
}
}
if let themeEmoticon = themeEmoticon, let theme = chatThemes.first(where: { $0.emoticon?.strippedEmoji == themeEmoticon.strippedEmoji }) {
if let darkAppearancePreview = darkAppearancePreview {
if let themeEmoticon = themeEmoticon, let theme = chatThemes.first(where: { $0.emoticon?.strippedEmoji == themeEmoticon.strippedEmoji }) {
if let darkAppearancePreview = darkAppearancePreview {
useDarkAppearance = darkAppearancePreview
}
if let theme = makePresentationTheme(cloudTheme: theme, dark: useDarkAppearance) {
theme.forceSync = true
presentationData = presentationData.withUpdated(theme: theme).withUpdated(chatWallpaper: theme.chat.defaultWallpaper)
Queue.mainQueue().after(1.0, {
theme.forceSync = false
})
}
} else if let darkAppearancePreview = darkAppearancePreview {
useDarkAppearance = darkAppearancePreview
}
if let theme = makePresentationTheme(cloudTheme: theme, dark: useDarkAppearance) {
theme.forceSync = true
presentationData = presentationData.withUpdated(theme: theme).withUpdated(chatWallpaper: theme.chat.defaultWallpaper)
let lightTheme: PresentationTheme
let lightWallpaper: TelegramWallpaper
Queue.mainQueue().after(1.0, {
theme.forceSync = false
})
}
} else if let darkAppearancePreview = darkAppearancePreview {
useDarkAppearance = darkAppearancePreview
let lightTheme: PresentationTheme
let lightWallpaper: TelegramWallpaper
let darkTheme: PresentationTheme
let darkWallpaper: TelegramWallpaper
if presentationData.autoNightModeTriggered {
darkTheme = presentationData.theme
darkWallpaper = presentationData.chatWallpaper
let darkTheme: PresentationTheme
let darkWallpaper: TelegramWallpaper
var currentColors = themeSettings.themeSpecificAccentColors[themeSettings.theme.index]
if let colors = currentColors, colors.baseColor == .theme {
currentColors = nil
}
let themeSpecificWallpaper = (themeSettings.themeSpecificChatWallpapers[coloredThemeIndex(reference: themeSettings.theme, accentColor: currentColors)] ?? themeSettings.themeSpecificChatWallpapers[themeSettings.theme.index])
if let themeSpecificWallpaper = themeSpecificWallpaper {
lightWallpaper = themeSpecificWallpaper
if presentationData.autoNightModeTriggered {
darkTheme = presentationData.theme
darkWallpaper = presentationData.chatWallpaper
var currentColors = themeSettings.themeSpecificAccentColors[themeSettings.theme.index]
if let colors = currentColors, colors.baseColor == .theme {
currentColors = nil
}
let themeSpecificWallpaper = (themeSettings.themeSpecificChatWallpapers[coloredThemeIndex(reference: themeSettings.theme, accentColor: currentColors)] ?? themeSettings.themeSpecificChatWallpapers[themeSettings.theme.index])
if let themeSpecificWallpaper = themeSpecificWallpaper {
lightWallpaper = themeSpecificWallpaper
} else {
let theme = makePresentationTheme(mediaBox: accountManager.mediaBox, themeReference: themeSettings.theme, accentColor: currentColors?.color, bubbleColors: currentColors?.customBubbleColors ?? [], wallpaper: currentColors?.wallpaper, baseColor: currentColors?.baseColor, preview: true) ?? defaultPresentationTheme
lightWallpaper = theme.chat.defaultWallpaper
}
var preferredBaseTheme: TelegramBaseTheme?
if let baseTheme = themeSettings.themePreferredBaseTheme[themeSettings.theme.index], [.classic, .day].contains(baseTheme) {
preferredBaseTheme = baseTheme
}
lightTheme = makePresentationTheme(mediaBox: accountManager.mediaBox, themeReference: themeSettings.theme, baseTheme: preferredBaseTheme, accentColor: currentColors?.color, bubbleColors: currentColors?.customBubbleColors ?? [], wallpaper: currentColors?.wallpaper, baseColor: currentColors?.baseColor, serviceBackgroundColor: defaultServiceBackgroundColor) ?? defaultPresentationTheme
} else {
let theme = makePresentationTheme(mediaBox: accountManager.mediaBox, themeReference: themeSettings.theme, accentColor: currentColors?.color, bubbleColors: currentColors?.customBubbleColors ?? [], wallpaper: currentColors?.wallpaper, baseColor: currentColors?.baseColor, preview: true) ?? defaultPresentationTheme
lightWallpaper = theme.chat.defaultWallpaper
}
var preferredBaseTheme: TelegramBaseTheme?
if let baseTheme = themeSettings.themePreferredBaseTheme[themeSettings.theme.index], [.classic, .day].contains(baseTheme) {
preferredBaseTheme = baseTheme
}
lightTheme = makePresentationTheme(mediaBox: accountManager.mediaBox, themeReference: themeSettings.theme, baseTheme: preferredBaseTheme, accentColor: currentColors?.color, bubbleColors: currentColors?.customBubbleColors ?? [], wallpaper: currentColors?.wallpaper, baseColor: currentColors?.baseColor, serviceBackgroundColor: defaultServiceBackgroundColor) ?? defaultPresentationTheme
} else {
lightTheme = presentationData.theme
lightWallpaper = presentationData.chatWallpaper
let automaticTheme = themeSettings.automaticThemeSwitchSetting.theme
let effectiveColors = themeSettings.themeSpecificAccentColors[automaticTheme.index]
let themeSpecificWallpaper = (themeSettings.themeSpecificChatWallpapers[coloredThemeIndex(reference: automaticTheme, accentColor: effectiveColors)] ?? themeSettings.themeSpecificChatWallpapers[automaticTheme.index])
var preferredBaseTheme: TelegramBaseTheme?
if let baseTheme = themeSettings.themePreferredBaseTheme[automaticTheme.index], [.night, .tinted].contains(baseTheme) {
preferredBaseTheme = baseTheme
} else {
preferredBaseTheme = .night
}
darkTheme = makePresentationTheme(mediaBox: accountManager.mediaBox, themeReference: automaticTheme, baseTheme: preferredBaseTheme, accentColor: effectiveColors?.color, bubbleColors: effectiveColors?.customBubbleColors ?? [], wallpaper: effectiveColors?.wallpaper, baseColor: effectiveColors?.baseColor, serviceBackgroundColor: defaultServiceBackgroundColor) ?? defaultPresentationTheme
if let themeSpecificWallpaper = themeSpecificWallpaper {
darkWallpaper = themeSpecificWallpaper
} else {
switch lightWallpaper {
lightTheme = presentationData.theme
lightWallpaper = presentationData.chatWallpaper
let automaticTheme = themeSettings.automaticThemeSwitchSetting.theme
let effectiveColors = themeSettings.themeSpecificAccentColors[automaticTheme.index]
let themeSpecificWallpaper = (themeSettings.themeSpecificChatWallpapers[coloredThemeIndex(reference: automaticTheme, accentColor: effectiveColors)] ?? themeSettings.themeSpecificChatWallpapers[automaticTheme.index])
var preferredBaseTheme: TelegramBaseTheme?
if let baseTheme = themeSettings.themePreferredBaseTheme[automaticTheme.index], [.night, .tinted].contains(baseTheme) {
preferredBaseTheme = baseTheme
} else {
preferredBaseTheme = .night
}
darkTheme = makePresentationTheme(mediaBox: accountManager.mediaBox, themeReference: automaticTheme, baseTheme: preferredBaseTheme, accentColor: effectiveColors?.color, bubbleColors: effectiveColors?.customBubbleColors ?? [], wallpaper: effectiveColors?.wallpaper, baseColor: effectiveColors?.baseColor, serviceBackgroundColor: defaultServiceBackgroundColor) ?? defaultPresentationTheme
if let themeSpecificWallpaper = themeSpecificWallpaper {
darkWallpaper = themeSpecificWallpaper
} else {
switch lightWallpaper {
case .builtin, .color, .gradient:
darkWallpaper = darkTheme.chat.defaultWallpaper
case .file:
@ -6529,26 +6559,29 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
default:
darkWallpaper = lightWallpaper
}
}
}
}
if darkAppearancePreview {
darkTheme.forceSync = true
Queue.mainQueue().after(1.0, {
darkTheme.forceSync = false
})
presentationData = presentationData.withUpdated(theme: darkTheme).withUpdated(chatWallpaper: darkWallpaper)
} else {
lightTheme.forceSync = true
Queue.mainQueue().after(1.0, {
lightTheme.forceSync = false
})
presentationData = presentationData.withUpdated(theme: lightTheme).withUpdated(chatWallpaper: lightWallpaper)
if darkAppearancePreview {
darkTheme.forceSync = true
Queue.mainQueue().after(1.0, {
darkTheme.forceSync = false
})
presentationData = presentationData.withUpdated(theme: darkTheme).withUpdated(chatWallpaper: darkWallpaper)
} else {
lightTheme.forceSync = true
Queue.mainQueue().after(1.0, {
lightTheme.forceSync = false
})
presentationData = presentationData.withUpdated(theme: lightTheme).withUpdated(chatWallpaper: lightWallpaper)
}
}
}
if let chatWallpaper {
if let forcedWallpaper = strongSelf.forcedWallpaper {
presentationData = presentationData.withUpdated(chatWallpaper: forcedWallpaper)
} else if let chatWallpaper {
presentationData = presentationData.withUpdated(chatWallpaper: chatWallpaper)
}
@ -6805,16 +6838,22 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
func updateNavigationBarPresentation() {
let navigationBarTheme: NavigationBarTheme
if self.hasEmbeddedTitleContent {
let presentationTheme: PresentationTheme
if let forcedNavigationBarTheme = self.forcedNavigationBarTheme {
presentationTheme = forcedNavigationBarTheme
navigationBarTheme = NavigationBarTheme(rootControllerTheme: forcedNavigationBarTheme, hideBackground: false, hideBadge: true)
} else if self.hasEmbeddedTitleContent {
presentationTheme = self.presentationData.theme
navigationBarTheme = NavigationBarTheme(rootControllerTheme: defaultDarkPresentationTheme, hideBackground: self.context.sharedContext.immediateExperimentalUISettings.playerEmbedding ? true : false, hideBadge: true)
} else {
presentationTheme = self.presentationData.theme
navigationBarTheme = NavigationBarTheme(rootControllerTheme: self.presentationData.theme, hideBackground: self.context.sharedContext.immediateExperimentalUISettings.playerEmbedding ? true : false, hideBadge: false)
}
self.navigationBar?.updatePresentationData(NavigationBarPresentationData(theme: navigationBarTheme, strings: NavigationBarStrings(presentationStrings: self.presentationData.strings)))
self.chatTitleView?.updateThemeAndStrings(theme: self.presentationData.theme, strings: self.presentationData.strings, hasEmbeddedTitleContent: self.hasEmbeddedTitleContent)
self.chatTitleView?.updateThemeAndStrings(theme: presentationTheme, strings: self.presentationData.strings, hasEmbeddedTitleContent: self.hasEmbeddedTitleContent)
}
func topPinnedMessageSignal(latest: Bool) -> Signal<ChatPinnedMessage?, NoError> {

View File

@ -538,6 +538,13 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate {
var peers = SimpleDictionary<PeerId, Peer>()
peers[accountPeer.id] = accountPeer
let author: Peer
if link.isCentered {
author = TelegramUser(id: EnginePeer.Id(namespace: Namespaces.Peer.CloudUser, id: EnginePeer.Id.Id._internalFromInt64Value(0)), accessHash: nil, firstName: "FirstName", lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: .blue, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil)
} else {
author = accountPeer
}
var associatedMessages = SimpleDictionary<MessageId, Message>()
var media: [Media] = []
@ -578,7 +585,7 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate {
localTags: [],
customTags: [],
forwardInfo: nil,
author: accountPeer,
author: author,
text: options.messageText,
attributes: attributes,
media: media,

View File

@ -128,7 +128,7 @@ extension ChatControllerImpl {
})))
}
let chatController = strongSelf.context.sharedContext.makeChatController(context: strongSelf.context, chatLocation: .peer(id: peerId), subject: .message(id: .timestamp(timestamp), highlight: nil, timecode: nil), botStart: nil, mode: .standard(.previewing))
let chatController = strongSelf.context.sharedContext.makeChatController(context: strongSelf.context, chatLocation: .peer(id: peerId), subject: .message(id: .timestamp(timestamp), highlight: nil, timecode: nil), botStart: nil, mode: .standard(.previewing), params: nil)
chatController.canReadHistory.set(false)
strongSelf.chatDisplayNode.messageTransitionNode.dismissMessageReactionContexts()

View File

@ -231,7 +231,13 @@ func chatHistoryEntriesForView(
} else {
selection = .none
}
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, isCentered: false, authorStoryStats: message.author.flatMap { view.peerStoryStats[$0.id] })))
var isCentered = false
if case let .messageOptions(_, _, info) = associatedData.subject, case let .link(link) = info {
isCentered = link.isCentered
}
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, isCentered: isCentered, authorStoryStats: message.author.flatMap { view.peerStoryStats[$0.id] })))
}
} else {
let selection: ChatHistoryMessageSelection

View File

@ -267,7 +267,7 @@ class ChatSearchResultsControllerNode: ViewControllerTracingNode, ASScrollViewDe
switch item.content {
case let .peer(peerData):
if let message = peerData.messages.first {
let chatController = strongSelf.context.sharedContext.makeChatController(context: strongSelf.context, chatLocation: .peer(id: peerData.peer.peerId), subject: .message(id: .id(message.id), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: nil), botStart: nil, mode: .standard(.previewing))
let chatController = strongSelf.context.sharedContext.makeChatController(context: strongSelf.context, chatLocation: .peer(id: peerData.peer.peerId), subject: .message(id: .id(message.id), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: nil), botStart: nil, mode: .standard(.previewing), params: nil)
chatController.canReadHistory.set(false)
let contextController = ContextController(presentationData: strongSelf.presentationData, source: .controller(ContextControllerContentSourceImpl(controller: chatController, sourceNode: node)), items: .single(ContextController.Items(content: .list([]))), gesture: gesture)
presentInGlobalOverlay(contextController)

View File

@ -1611,8 +1611,8 @@ public final class SharedAccountContextImpl: SharedAccountContext {
return peersNearbyController(context: context)
}
public func makeChatController(context: AccountContext, chatLocation: ChatLocation, subject: ChatControllerSubject?, botStart: ChatControllerInitialBotStart?, mode: ChatControllerPresentationMode) -> ChatController {
return ChatControllerImpl(context: context, chatLocation: chatLocation, subject: subject, botStart: botStart, mode: mode)
public func makeChatController(context: AccountContext, chatLocation: ChatLocation, subject: ChatControllerSubject?, botStart: ChatControllerInitialBotStart?, mode: ChatControllerPresentationMode, params: ChatControllerParams?) -> ChatController {
return ChatControllerImpl(context: context, chatLocation: chatLocation, subject: subject, botStart: botStart, mode: mode, params: params)
}
public func makeChatHistoryListNode(