mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Fix sharing to topics
This commit is contained in:
parent
5c9a7b8068
commit
23e6f10a12
@ -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)
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user