Fix sharing to topics

This commit is contained in:
Ilya Laktyushin 2022-10-23 00:17:15 +03:00
parent 5c9a7b8068
commit 23e6f10a12
7 changed files with 124 additions and 65 deletions

View File

@ -732,12 +732,12 @@ func chatForumTopicMenuItems(context: AccountContext, peerId: PeerId, threadId:
})))
}
items.append(.separator)
items.append(.action(ContextMenuActionItem(text: strings.ChatList_Context_Select, textColor: .primary, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Select"), color: theme.contextMenu.primaryColor) }, action: { _, f in
f(.default)
})))
// items.append(.separator)
// items.append(.action(ContextMenuActionItem(text: strings.ChatList_Context_Select, textColor: .primary, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Select"), color: theme.contextMenu.primaryColor) }, action: { _, f in
// f(.default)
//
//
// })))
return .single(items)
}

View File

@ -371,32 +371,42 @@ final class ShareControllerNode: ViewControllerTracingNode, UIScrollViewDelegate
}
func transitionToPeerTopics(_ peer: EngineRenderedPeer) {
guard let context = self.context, let mainPeer = peer.chatMainPeer else {
guard let context = self.context, let mainPeer = peer.chatMainPeer, let controllerInteraction = self.controllerInteraction else {
return
}
let _ = (threadList(context: context, peerId: mainPeer.id)
|> take(1)
|> deliverOnMainQueue).start(next: { [weak self] threads in
guard let strongSelf = self, let context = strongSelf.context, let controllerInteraction = strongSelf.controllerInteraction else {
var didPresent = false
var presentImpl: (() -> Void)?
let threads = threadList(context: context, peerId: mainPeer.id)
|> deliverOnMainQueue
|> beforeNext { _ in
if !didPresent {
didPresent = true
presentImpl?()
}
}
let topicsContentNode = ShareTopicsContainerNode(
sharedContext: self.sharedContext,
context: context,
theme: self.presentationData.theme,
strings: self.presentationData.strings,
peer: mainPeer,
topics: threads,
controllerInteraction: controllerInteraction
)
topicsContentNode.backPressed = { [weak self] in
if let strongSelf = self {
strongSelf.closePeerTopics(peer.peerId, selected: false)
}
}
self.topicsContentNode = topicsContentNode
presentImpl = { [weak self] in
guard let strongSelf = self else {
return
}
let topicsContentNode = ShareTopicsContainerNode(
sharedContext: strongSelf.sharedContext,
context: context,
theme: strongSelf.presentationData.theme,
strings: strongSelf.presentationData.strings,
peer: mainPeer,
topics: threads.items.reversed(),
controllerInteraction: controllerInteraction
)
topicsContentNode.backPressed = { [weak self] in
if let strongSelf = self {
strongSelf.closePeerTopics(peer.peerId, selected: false)
}
}
strongSelf.topicsContentNode = topicsContentNode
strongSelf.contentNode?.supernode?.addSubnode(topicsContentNode)
if let (layout, navigationBarHeight, _) = strongSelf.containerLayout {
@ -423,7 +433,7 @@ final class ShareControllerNode: ViewControllerTracingNode, UIScrollViewDelegate
strongSelf.contentNodeOffsetUpdated(topicsContentNode.contentGridNode.scrollView.contentOffset.y, transition: .animated(duration: 0.4, curve: .spring))
strongSelf.view.endEditing(true)
})
}
}
func closePeerTopics(_ peerId: EnginePeer.Id, selected: Bool) {
@ -1259,6 +1269,16 @@ private func threadList(context: AccountContext, peerId: EnginePeer.Id) -> Signa
)
return context.account.postbox.combinedView(keys: [viewKey])
|> mapToSignal { view -> Signal<CombinedView, NoError> in
return context.account.postbox.transaction { transaction -> CombinedView in
if let peer = transaction.getPeer(context.account.peerId) {
transaction.updatePeersInternal([peer]) { current, _ in
return current ?? peer
}
}
return view
}
}
|> map { views -> EngineChatList in
guard let view = views.views[viewKey] as? MessageHistoryThreadIndexView else {
preconditionFailure()
@ -1299,7 +1319,7 @@ private func threadList(context: AccountContext, peerId: EnginePeer.Id) -> Signa
}
let list = EngineChatList(
items: items.reversed(),
items: items,
groupItems: [],
additionalItems: [],
hasEarlier: false,

View File

@ -176,20 +176,23 @@ final class ShareTopicsContainerNode: ASDisplayNode, ShareContentContainerNode {
private var validLayout: (CGSize, CGFloat)?
private var overrideGridOffsetTransition: ContainedViewLayoutTransition?
let peersValue = Promise<[EngineChatList.Item]>()
let topicsValue = Promise<[EngineChatList.Item]>()
var backPressed: () -> Void = {}
init(sharedContext: SharedAccountContext, context: AccountContext, theme: PresentationTheme, strings: PresentationStrings, peer: EnginePeer, topics: [EngineChatList.Item], controllerInteraction: ShareControllerInteraction) {
init(sharedContext: SharedAccountContext, context: AccountContext, theme: PresentationTheme, strings: PresentationStrings, peer: EnginePeer, topics: Signal<EngineChatList, NoError>, controllerInteraction: ShareControllerInteraction) {
self.sharedContext = sharedContext
self.context = context
self.theme = theme
self.strings = strings
self.controllerInteraction = controllerInteraction
self.peersValue.set(.single(topics))
self.topicsValue.set(topics
|> map {
return $0.items
})
let items: Signal<[ShareTopicEntry], NoError> = self.peersValue.get()
let items: Signal<[ShareTopicEntry], NoError> = self.topicsValue.get()
|> map { topics -> [ShareTopicEntry] in
var entries: [ShareTopicEntry] = []
var index: Int32 = 0

View File

@ -1394,6 +1394,8 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
isSelectionEnabled = false
} else if case .pinnedMessages = self.chatPresentationInterfaceState.subject {
isSelectionEnabled = false
} else if case .forum = self.chatLocation {
isSelectionEnabled = false
}
self.historyNode.isSelectionGestureEnabled = isSelectionEnabled

View File

@ -411,6 +411,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
private let context: AccountContext
private let chatLocation: ChatLocation
private let chatLocationContextHolder: Atomic<ChatLocationContextHolder?>
private let source: ChatHistoryListSource
private let subject: ChatControllerSubject?
private let tagMask: MessageTags?
private let controllerInteraction: ChatControllerInteraction
@ -556,6 +557,15 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
}
}
private let justSentTextMessagePromise = ValuePromise<Bool>(false)
var justSentTextMessage: Bool = false {
didSet {
if self.justSentTextMessage != oldValue {
self.justSentTextMessagePromise.set(self.justSentTextMessage)
}
}
}
private var appliedScrollToMessageId: MessageIndex? = nil
private let scrollToMessageIdPromise = Promise<MessageIndex?>(nil)
@ -619,6 +629,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
self.context = context
self.chatLocation = chatLocation
self.chatLocationContextHolder = chatLocationContextHolder
self.source = source
self.subject = subject
self.tagMask = tagMask
self.controllerInteraction = controllerInteraction
@ -1044,10 +1055,10 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
topicAuthorId = .single(nil)
}
let suggestAudioTranscription = context.engine.data.get(TelegramEngine.EngineData.Item.Notices.Notice(key: ApplicationSpecificNotice.audioTranscriptionSuggestionKey()))
|> map { entry -> Int32 in
return entry?.get(ApplicationSpecificCounterNotice.self)?.value ?? 0
}
let audioTranscriptionSuggestion = combineLatest(
ApplicationSpecificNotice.getAudioTranscriptionSuggestion(accountManager: context.sharedContext.accountManager),
self.justSentTextMessagePromise.get()
)
let promises = combineLatest(
self.historyAppearsClearedPromise.get(),
@ -1071,7 +1082,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
availableReactions,
defaultReaction,
accountPeer,
suggestAudioTranscription,
audioTranscriptionSuggestion,
promises,
topicAuthorId
).start(next: { [weak self] update, chatPresentationData, selectedMessages, updatingMedia, networkType, animatedEmojiStickers, additionalAnimatedEmojiStickers, customChannelDiscussionReadState, customThreadOutgoingReadState, adMessages, availableReactions, defaultReaction, accountPeer, suggestAudioTranscription, promises, topicAuthorId in
@ -1209,7 +1220,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
isPremium = true
}
let associatedData = extractAssociatedData(chatLocation: chatLocation, view: view, automaticDownloadNetworkType: networkType, animatedEmojiStickers: animatedEmojiStickers, additionalAnimatedEmojiStickers: additionalAnimatedEmojiStickers, subject: subject, currentlyPlayingMessageId: currentlyPlayingMessageId, isCopyProtectionEnabled: isCopyProtectionEnabled, availableReactions: availableReactions, defaultReaction: defaultReaction, isPremium: isPremium, alwaysDisplayTranscribeButton: suggestAudioTranscription < 2, accountPeer: accountPeer, topicAuthorId: topicAuthorId)
let associatedData = extractAssociatedData(chatLocation: chatLocation, view: view, automaticDownloadNetworkType: networkType, animatedEmojiStickers: animatedEmojiStickers, additionalAnimatedEmojiStickers: additionalAnimatedEmojiStickers, subject: subject, currentlyPlayingMessageId: currentlyPlayingMessageId, isCopyProtectionEnabled: isCopyProtectionEnabled, availableReactions: availableReactions, defaultReaction: defaultReaction, isPremium: isPremium, alwaysDisplayTranscribeButton: suggestAudioTranscription.0 < 2, accountPeer: accountPeer, topicAuthorId: topicAuthorId)
let filteredEntries = chatHistoryEntriesForView(
location: chatLocation,
@ -2551,7 +2562,9 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
strongSelf.historyView = transition.historyView
let loadState: ChatHistoryNodeLoadState
if let historyView = strongSelf.historyView {
if case .custom = strongSelf.source {
loadState = .messages
} else if let historyView = strongSelf.historyView {
if historyView.filteredEntries.isEmpty {
if let firstEntry = historyView.originalView.entries.first {
var emptyType = ChatHistoryNodeLoadState.EmptyType.generic

View File

@ -542,45 +542,32 @@ final class ChatMessageInteractiveFileNode: ASDisplayNode {
}
updatedPlaybackStatusSignal = messageFileMediaPlaybackStatus(context: arguments.context, file: arguments.file, message: arguments.message, isRecentActions: arguments.isRecentActions, isGlobalSearch: false, isDownloadList: false)
}
var isAudio = false
var audioWaveform: AudioWaveform?
var isVoice = false
var audioDuration: Int32 = 0
var isConsumed: Bool?
var consumableContentIcon: UIImage?
for attribute in arguments.message.attributes {
if let attribute = attribute as? ConsumableContentMessageAttribute {
let isConsumed = attribute.consumed
if !isConsumed {
if !attribute.consumed {
if arguments.incoming {
consumableContentIcon = PresentationResourcesChat.chatBubbleConsumableContentIncomingIcon(arguments.presentationData.theme.theme)
} else {
consumableContentIcon = PresentationResourcesChat.chatBubbleConsumableContentOutgoingIcon(arguments.presentationData.theme.theme)
}
}
isConsumed = attribute.consumed
break
}
}
var candidateTitleString: NSAttributedString?
var candidateDescriptionString: NSAttributedString?
var isAudio = false
var audioWaveform: AudioWaveform?
var isVoice = false
var audioDuration: Int32 = 0
let displayTranscribe: Bool
if arguments.message.id.peerId.namespace != Namespaces.Peer.SecretChat {
if arguments.associatedData.isPremium {
displayTranscribe = true
} else if arguments.associatedData.alwaysDisplayTranscribeButton {
displayTranscribe = true
} else {
displayTranscribe = false
}
} else {
displayTranscribe = false
}
let messageTheme = arguments.incoming ? arguments.presentationData.theme.theme.chat.message.incoming : arguments.presentationData.theme.theme.chat.message.outgoing
let isInstantVideo = arguments.file.isInstantVideo
for attribute in arguments.file.attributes {
if case let .Video(videoDuration, _, flags) = attribute, flags.contains(.instantRoundVideo) {
@ -635,7 +622,7 @@ final class ChatMessageInteractiveFileNode: ASDisplayNode {
}
}
}
var titleString: NSAttributedString?
var descriptionString: NSAttributedString?
@ -680,6 +667,25 @@ final class ChatMessageInteractiveFileNode: ASDisplayNode {
var textString: NSAttributedString?
var updatedAudioTranscriptionState: AudioTranscriptionButtonComponent.TranscriptionState?
let displayTranscribe: Bool
if arguments.message.id.peerId.namespace != Namespaces.Peer.SecretChat {
if arguments.associatedData.isPremium {
displayTranscribe = true
} else if arguments.associatedData.alwaysDisplayTranscribeButton {
if audioDuration >= 60 {
displayTranscribe = true
} else if isConsumed == false {
displayTranscribe = true
} else {
displayTranscribe = false
}
} else {
displayTranscribe = false
}
} else {
displayTranscribe = false
}
let transcribedText = forcedAudioTranscriptionText ?? transcribedText(message: arguments.message)
switch audioTranscriptionState {
@ -1180,6 +1186,7 @@ final class ChatMessageInteractiveFileNode: ASDisplayNode {
animation.animator.updateFrame(layer: waveformView.componentView!.layer, frame: CGRect(origin: CGPoint(), size: scrubbingFrame.size), completion: nil)
if displayTranscribe {
var added = false
let audioTranscriptionButton: ComponentHostView<Empty>
if let current = strongSelf.audioTranscriptionButton {
audioTranscriptionButton = current
@ -1187,6 +1194,7 @@ final class ChatMessageInteractiveFileNode: ASDisplayNode {
audioTranscriptionButton = ComponentHostView<Empty>()
strongSelf.audioTranscriptionButton = audioTranscriptionButton
strongSelf.view.addSubview(audioTranscriptionButton)
added = true
}
let audioTranscriptionButtonSize = audioTranscriptionButton.update(
transition: animation.isAnimated ? .easeInOut(duration: 0.3) : .immediate,
@ -1203,7 +1211,14 @@ final class ChatMessageInteractiveFileNode: ASDisplayNode {
environment: {},
containerSize: CGSize(width: 30.0, height: 30.0)
)
animation.animator.updateFrame(layer: audioTranscriptionButton.layer, frame: CGRect(origin: CGPoint(x: boundingWidth - 30.0 + 3.0, y: -6.0), size: audioTranscriptionButtonSize), completion: nil)
let audioTranscriptionButtonFrame = CGRect(origin: CGPoint(x: boundingWidth - 30.0 + 3.0, y: -6.0), size: audioTranscriptionButtonSize)
if added {
audioTranscriptionButton.layer.frame = audioTranscriptionButtonFrame
audioTranscriptionButton.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
} else {
animation.animator.updateFrame(layer: audioTranscriptionButton.layer, frame: audioTranscriptionButtonFrame, completion: nil)
}
} else {
if let audioTranscriptionButton = strongSelf.audioTranscriptionButton {
strongSelf.audioTranscriptionButton = nil

View File

@ -600,6 +600,7 @@ class ChatMessageInteractiveInstantVideoNode: ASDisplayNode {
}
if displayTranscribe, let durationBlurColor = durationBlurColor {
var added = false
let audioTranscriptionButton: ComponentHostView<Empty>
if let current = strongSelf.audioTranscriptionButton {
audioTranscriptionButton = current
@ -607,6 +608,7 @@ class ChatMessageInteractiveInstantVideoNode: ASDisplayNode {
audioTranscriptionButton = ComponentHostView<Empty>()
strongSelf.audioTranscriptionButton = audioTranscriptionButton
strongSelf.view.addSubview(audioTranscriptionButton)
added = true
}
let audioTranscriptionButtonSize = audioTranscriptionButton.update(
transition: animation.isAnimated ? .easeInOut(duration: 0.3) : .immediate,
@ -637,8 +639,12 @@ class ChatMessageInteractiveInstantVideoNode: ASDisplayNode {
}
}
animation.animator.updateFrame(layer: audioTranscriptionButton.layer, frame: audioTranscriptionButtonFrame, completion: nil)
if animation.isAnimated && added {
audioTranscriptionButton.layer.frame = audioTranscriptionButtonFrame
audioTranscriptionButton.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
} else {
animation.animator.updateFrame(layer: audioTranscriptionButton.layer, frame: audioTranscriptionButtonFrame, completion: nil)
}
animation.animator.updateAlpha(layer: audioTranscriptionButton.layer, alpha: scaleProgress.isZero ? 1.0 : 0.0, completion: nil)
if !scaleProgress.isZero {
displayTranscribe = false