Various fixes

This commit is contained in:
Ilya Laktyushin
2023-03-02 22:51:15 +04:00
parent c8ac1832a1
commit c544298bd8
6 changed files with 182 additions and 47 deletions

View File

@@ -147,12 +147,47 @@ private func galleryMessageCaptionText(_ message: Message) -> String {
return message.text
}
public func galleryItemForEntry(context: AccountContext, presentationData: PresentationData, entry: MessageHistoryEntry, isCentral: Bool = false, streamVideos: Bool, loopVideos: Bool = false, hideControls: Bool = false, fromPlayingVideo: Bool = false, isSecret: Bool = false, landscape: Bool = false, timecode: Double? = nil, playbackRate: @escaping () -> Double?, displayInfoOnTop: Bool = false, configuration: GalleryConfiguration? = nil, translateToLanguage: String? = nil, tempFilePath: String? = nil, playbackCompleted: @escaping () -> Void = {}, performAction: @escaping (GalleryControllerInteractionTapAction) -> Void = { _ in }, openActionOptions: @escaping (GalleryControllerInteractionTapAction, Message) -> Void = { _, _ in }, storeMediaPlaybackState: @escaping (MessageId, Double?, Double) -> Void = { _, _, _ in }, generateStoreAfterDownload: ((Message, TelegramMediaFile) -> (() -> Void)?)? = nil, present: @escaping (ViewController, Any?) -> Void) -> GalleryItem? {
public func galleryItemForEntry(
context: AccountContext,
presentationData: PresentationData,
entry: MessageHistoryEntry,
isCentral: Bool = false,
streamVideos: Bool,
loopVideos: Bool = false,
hideControls: Bool = false,
fromPlayingVideo: Bool = false,
isSecret: Bool = false,
landscape: Bool = false,
timecode: Double? = nil,
playbackRate: @escaping () -> Double?,
displayInfoOnTop: Bool = false,
configuration: GalleryConfiguration? = nil,
translateToLanguage: String? = nil,
peerIsCopyProtected: Bool = false,
tempFilePath: String? = nil,
playbackCompleted: @escaping () -> Void = {},
performAction: @escaping (GalleryControllerInteractionTapAction) -> Void = { _ in },
openActionOptions: @escaping (GalleryControllerInteractionTapAction, Message) -> Void = { _, _ in },
storeMediaPlaybackState: @escaping (MessageId, Double?, Double) -> Void = { _, _, _ in },
generateStoreAfterDownload: ((Message, TelegramMediaFile) -> (() -> Void)?)? = nil,
present: @escaping (ViewController, Any?) -> Void) -> GalleryItem?
{
let message = entry.message
let location = entry.location
if let (media, mediaImage) = mediaForMessage(message: message) {
if let _ = media as? TelegramMediaImage {
return ChatImageGalleryItem(context: context, presentationData: presentationData, message: message, location: location, translateToLanguage: translateToLanguage, displayInfoOnTop: displayInfoOnTop, performAction: performAction, openActionOptions: openActionOptions, present: present)
return ChatImageGalleryItem(
context: context,
presentationData: presentationData,
message: message,
location: location,
translateToLanguage: translateToLanguage,
peerIsCopyProtected: peerIsCopyProtected,
displayInfoOnTop: displayInfoOnTop,
performAction: performAction,
openActionOptions: openActionOptions,
present: present
)
} else if let file = media as? TelegramMediaFile {
if file.isVideo {
let content: UniversalVideoContent
@@ -189,7 +224,29 @@ public func galleryItemForEntry(context: AccountContext, presentationData: Prese
}
let caption = galleryCaptionStringWithAppliedEntities(text, entities: entities, message: message)
return UniversalVideoGalleryItem(context: context, presentationData: presentationData, content: content, originData: GalleryItemOriginData(title: message.effectiveAuthor.flatMap(EnginePeer.init)?.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder), timestamp: message.timestamp), indexData: location.flatMap { GalleryItemIndexData(position: Int32($0.index), totalCount: Int32($0.count)) }, contentInfo: .message(message), caption: caption, displayInfoOnTop: displayInfoOnTop, hideControls: hideControls, fromPlayingVideo: fromPlayingVideo, isSecret: isSecret, landscape: landscape, timecode: timecode, playbackRate: playbackRate, configuration: configuration, playbackCompleted: playbackCompleted, performAction: performAction, openActionOptions: openActionOptions, storeMediaPlaybackState: storeMediaPlaybackState, present: present)
return UniversalVideoGalleryItem(
context: context,
presentationData: presentationData,
content: content,
originData: GalleryItemOriginData(title: message.effectiveAuthor.flatMap(EnginePeer.init)?.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder), timestamp: message.timestamp),
indexData: location.flatMap { GalleryItemIndexData(position: Int32($0.index), totalCount: Int32($0.count)) },
contentInfo: .message(message),
caption: caption,
displayInfoOnTop: displayInfoOnTop,
hideControls: hideControls,
fromPlayingVideo: fromPlayingVideo,
isSecret: isSecret,
landscape: landscape,
timecode: timecode,
peerIsCopyProtected: peerIsCopyProtected,
playbackRate: playbackRate,
configuration: configuration,
playbackCompleted: playbackCompleted,
performAction: performAction,
openActionOptions: openActionOptions,
storeMediaPlaybackState: storeMediaPlaybackState,
present: present
)
} else {
if let fileName = file.fileName, (fileName as NSString).pathExtension.lowercased() == "json" {
return ChatAnimationGalleryItem(context: context, presentationData: presentationData, message: message, location: location)
@@ -200,14 +257,40 @@ public func galleryItemForEntry(context: AccountContext, presentationData: Prese
pixelsCount = Int(dimensions.width) * Int(dimensions.height)
}
if pixelsCount < 10000 * 10000 {
return ChatImageGalleryItem(context: context, presentationData: presentationData, message: message, location: location, displayInfoOnTop: displayInfoOnTop, performAction: performAction, openActionOptions: openActionOptions, present: present)
return ChatImageGalleryItem(
context: context,
presentationData: presentationData,
message: message,
location: location,
translateToLanguage: translateToLanguage,
peerIsCopyProtected: peerIsCopyProtected,
displayInfoOnTop: displayInfoOnTop,
performAction: performAction,
openActionOptions: openActionOptions,
present: present
)
} else {
return ChatDocumentGalleryItem(context: context, presentationData: presentationData, message: message, location: location)
return ChatDocumentGalleryItem(
context: context,
presentationData: presentationData,
message: message,
location: location
)
}
} else if internalDocumentItemSupportsMimeType(file.mimeType, fileName: file.fileName) {
return ChatDocumentGalleryItem(context: context, presentationData: presentationData, message: message, location: location)
return ChatDocumentGalleryItem(
context: context,
presentationData: presentationData,
message: message,
location: location
)
} else {
return ChatExternalFileGalleryItem(context: context, presentationData: presentationData, message: message, location: location)
return ChatExternalFileGalleryItem(
context: context,
presentationData: presentationData,
message: message,
location: location
)
}
}
} else if let webpage = media as? TelegramMediaWebpage, case let .Loaded(webpageContent) = webpage.content {
@@ -238,7 +321,27 @@ public func galleryItemForEntry(context: AccountContext, presentationData: Prese
}
description = galleryCaptionStringWithAppliedEntities(descriptionText, entities: entities, message: message)
}
return UniversalVideoGalleryItem(context: context, presentationData: presentationData, content: content, originData: GalleryItemOriginData(title: message.effectiveAuthor.flatMap(EnginePeer.init)?.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder), timestamp: message.timestamp), indexData: location.flatMap { GalleryItemIndexData(position: Int32($0.index), totalCount: Int32($0.count)) }, contentInfo: .message(message), caption: NSAttributedString(string: ""), description: description, displayInfoOnTop: displayInfoOnTop, fromPlayingVideo: fromPlayingVideo, isSecret: isSecret, landscape: landscape, timecode: timecode, playbackRate: playbackRate, configuration: configuration, performAction: performAction, openActionOptions: openActionOptions, storeMediaPlaybackState: storeMediaPlaybackState, present: present)
return UniversalVideoGalleryItem(
context: context,
presentationData: presentationData,
content: content,
originData: GalleryItemOriginData(title: message.effectiveAuthor.flatMap(EnginePeer.init)?.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder), timestamp: message.timestamp),
indexData: location.flatMap { GalleryItemIndexData(position: Int32($0.index), totalCount: Int32($0.count)) },
contentInfo: .message(message),
caption: NSAttributedString(string: ""),
description: description,
displayInfoOnTop: displayInfoOnTop,
fromPlayingVideo: fromPlayingVideo,
isSecret: isSecret,
landscape: landscape,
timecode: timecode,
playbackRate: playbackRate,
configuration: configuration,
performAction: performAction,
openActionOptions: openActionOptions,
storeMediaPlaybackState: storeMediaPlaybackState,
present: present
)
} else {
return nil
}
@@ -268,15 +371,15 @@ public final class GalleryControllerPresentationArguments {
}
private enum GalleryMessageHistoryView {
case view(MessageHistoryView)
case view(MessageHistoryView, Bool)
case entries([MessageHistoryEntry], Bool, Bool)
var entries: [MessageHistoryEntry] {
switch self {
case let .view(view):
return view.entries
case let .entries(entries, _, _):
return entries
case let .view(view, _):
return view.entries
case let .entries(entries, _, _):
return entries
}
}
@@ -284,7 +387,7 @@ private enum GalleryMessageHistoryView {
switch self {
case .entries:
return nil
case let .view(view):
case let .view(view, _):
return view.tagMask
}
}
@@ -293,7 +396,7 @@ private enum GalleryMessageHistoryView {
switch self {
case let .entries(_, hasEarlier, _):
return hasEarlier
case let .view(view):
case let .view(view, _):
return view.earlierId != nil
}
}
@@ -302,10 +405,19 @@ private enum GalleryMessageHistoryView {
switch self {
case let .entries(_ , _, hasLater):
return hasLater
case let .view(view):
case let .view(view, _):
return view.laterId != nil
}
}
var peerIsCopyProtected: Bool {
switch self {
case let .view(_, peerIsCopyProtected):
return peerIsCopyProtected
case .entries:
return false
}
}
}
public enum GalleryControllerInteractionTapAction {
@@ -373,6 +485,7 @@ public class GalleryController: ViewController, StandalonePresentableController,
private let accountInUseDisposable = MetaDisposable()
private let disposable = MetaDisposable()
private var peerIsCopyProtected = false
private var entries: [MessageHistoryEntry] = []
private var hasLeftEntries: Bool = false
private var hasRightEntries: Bool = false
@@ -453,11 +566,21 @@ public class GalleryController: ViewController, StandalonePresentableController,
self.statusBar.statusBarStyle = .White
let baseLanguageCode = self.presentationData.strings.baseLanguageCode
let message: Signal<Message?, NoError>
let message: Signal<(Message, Bool)?, NoError>
var translateToLanguage: Signal<String?, NoError> = .single(nil)
switch source {
case let .peerMessagesAtId(messageId, _, _):
message = context.account.postbox.messageAtId(messageId)
|> mapToSignal { message -> Signal<(Message, Bool)?, NoError> in
if let message, let peer = message.peers[message.id.peerId] as? TelegramGroup, let migrationPeerId = peer.migrationReference?.peerId {
return context.account.postbox.loadedPeerWithId(migrationPeerId)
|> map { peer -> (Message, Bool)? in
return (message, peer.isCopyProtectionEnabled)
}
} else {
return .single(message.flatMap { ($0, false) })
}
}
translateToLanguage = chatTranslationState(context: context, peerId: messageId.peerId)
|> map { translationState in
if let translationState, translationState.isEnabled {
@@ -473,36 +596,37 @@ public class GalleryController: ViewController, StandalonePresentableController,
}
}
case let .standaloneMessage(m):
message = .single(m)
message = .single((m, m.isCopyProtected()))
case let .custom(messages, messageId, _):
message = messages
|> take(1)
|> map { messages, _, _ in
return messages.first(where: { $0.id == messageId })
return messages.first(where: { $0.id == messageId }).flatMap { ($0, false) }
}
}
let messageView = message
|> filter({ $0 != nil })
|> mapToSignal { message -> Signal<GalleryMessageHistoryView?, NoError> in
|> mapToSignal { messageAndPeerIsCopyProtected -> Signal<GalleryMessageHistoryView?, NoError> in
let (message, peerIsCopyProtected) = messageAndPeerIsCopyProtected!
switch source {
case let .peerMessagesAtId(_, chatLocation, chatLocationContextHolder):
if let tags = tagsForMessage(message!) {
if let tags = tagsForMessage(message) {
let namespaces: MessageIdNamespaces
if Namespaces.Message.allScheduled.contains(message!.id.namespace) {
if Namespaces.Message.allScheduled.contains(message.id.namespace) {
namespaces = .just(Namespaces.Message.allScheduled)
} else {
namespaces = .not(Namespaces.Message.allScheduled)
}
return context.account.postbox.aroundMessageHistoryViewForLocation(context.chatLocationInput(for: chatLocation, contextHolder: chatLocationContextHolder), anchor: .index(message!.index), ignoreMessagesInTimestampRange: nil, count: 50, clipHoles: false, fixedCombinedReadStates: nil, topTaggedMessageIdNamespaces: [], tagMask: tags, appendMessagesFromTheSameGroup: false, namespaces: namespaces, orderStatistics: [.combinedLocation])
return context.account.postbox.aroundMessageHistoryViewForLocation(context.chatLocationInput(for: chatLocation, contextHolder: chatLocationContextHolder), anchor: .index(message.index), ignoreMessagesInTimestampRange: nil, count: 50, clipHoles: false, fixedCombinedReadStates: nil, topTaggedMessageIdNamespaces: [], tagMask: tags, appendMessagesFromTheSameGroup: false, namespaces: namespaces, orderStatistics: [.combinedLocation])
|> mapToSignal { (view, _, _) -> Signal<GalleryMessageHistoryView?, NoError> in
let mapped = GalleryMessageHistoryView.view(view)
let mapped = GalleryMessageHistoryView.view(view, peerIsCopyProtected)
return .single(mapped)
}
} else {
return .single(GalleryMessageHistoryView.entries([MessageHistoryEntry(message: message!, isRead: false, location: nil, monthLocation: nil, attributes: MutableMessageHistoryEntryAttributes(authorIsContact: false))], false, false))
return .single(GalleryMessageHistoryView.entries([MessageHistoryEntry(message: message, isRead: false, location: nil, monthLocation: nil, attributes: MutableMessageHistoryEntryAttributes(authorIsContact: false))], false, false))
}
case .standaloneMessage:
return .single(GalleryMessageHistoryView.entries([MessageHistoryEntry(message: message!, isRead: false, location: nil, monthLocation: nil, attributes: MutableMessageHistoryEntryAttributes(authorIsContact: false))], false ,false))
return .single(GalleryMessageHistoryView.entries([MessageHistoryEntry(message: message, isRead: false, location: nil, monthLocation: nil, attributes: MutableMessageHistoryEntryAttributes(authorIsContact: false))], false ,false))
case let .custom(messages, _, _):
return messages
|> map { messages, totalCount, hasMore in
@@ -539,6 +663,8 @@ public class GalleryController: ViewController, StandalonePresentableController,
let f: () -> Void = {
if let strongSelf = self {
if let view = view {
strongSelf.peerIsCopyProtected = view.peerIsCopyProtected
let appConfiguration: AppConfiguration = preferencesView.values[PreferencesKeys.appConfiguration]?.get(AppConfiguration.self) ?? .defaultValue
let configuration = GalleryConfiguration.with(appConfiguration: appConfiguration)
strongSelf.configuration = configuration
@@ -589,7 +715,7 @@ public class GalleryController: ViewController, StandalonePresentableController,
if entry.message.stableId == strongSelf.centralEntryStableId {
isCentral = true
}
if let item = galleryItemForEntry(context: context, presentationData: strongSelf.presentationData, entry: entry, isCentral: isCentral, streamVideos: streamSingleVideo, fromPlayingVideo: isCentral && fromPlayingVideo, landscape: isCentral && landscape, timecode: isCentral ? timecode : nil, playbackRate: { return self?.playbackRate }, displayInfoOnTop: displayInfoOnTop, configuration: configuration, translateToLanguage: translateToLanguage, performAction: strongSelf.performAction, openActionOptions: strongSelf.openActionOptions, storeMediaPlaybackState: strongSelf.actionInteraction?.storeMediaPlaybackState ?? { _, _, _ in }, generateStoreAfterDownload: strongSelf.generateStoreAfterDownload, present: { [weak self] c, a in
if let item = galleryItemForEntry(context: context, presentationData: strongSelf.presentationData, entry: entry, isCentral: isCentral, streamVideos: streamSingleVideo, fromPlayingVideo: isCentral && fromPlayingVideo, landscape: isCentral && landscape, timecode: isCentral ? timecode : nil, playbackRate: { return self?.playbackRate }, displayInfoOnTop: displayInfoOnTop, configuration: configuration, translateToLanguage: translateToLanguage, peerIsCopyProtected: view.peerIsCopyProtected, performAction: strongSelf.performAction, openActionOptions: strongSelf.openActionOptions, storeMediaPlaybackState: strongSelf.actionInteraction?.storeMediaPlaybackState ?? { _, _, _ in }, generateStoreAfterDownload: strongSelf.generateStoreAfterDownload, present: { [weak self] c, a in
if let strongSelf = self {
strongSelf.presentInGlobalOverlay(c, with: a)
}
@@ -1162,7 +1288,7 @@ public class GalleryController: ViewController, StandalonePresentableController,
if entry.message.stableId == self.centralEntryStableId {
isCentral = true
}
if let item = galleryItemForEntry(context: self.context, presentationData: self.presentationData, entry: entry, streamVideos: self.streamVideos, fromPlayingVideo: isCentral && self.fromPlayingVideo, landscape: isCentral && self.landscape, timecode: isCentral ? self.timecode : nil, playbackRate: { [weak self] in return self?.playbackRate }, displayInfoOnTop: displayInfoOnTop, configuration: self.configuration, performAction: self.performAction, openActionOptions: self.openActionOptions, storeMediaPlaybackState: self.actionInteraction?.storeMediaPlaybackState ?? { _, _, _ in }, generateStoreAfterDownload: self.generateStoreAfterDownload, present: { [weak self] c, a in
if let item = galleryItemForEntry(context: self.context, presentationData: self.presentationData, entry: entry, streamVideos: self.streamVideos, fromPlayingVideo: isCentral && self.fromPlayingVideo, landscape: isCentral && self.landscape, timecode: isCentral ? self.timecode : nil, playbackRate: { [weak self] in return self?.playbackRate }, displayInfoOnTop: displayInfoOnTop, configuration: self.configuration, peerIsCopyProtected: self.peerIsCopyProtected, performAction: self.performAction, openActionOptions: self.openActionOptions, storeMediaPlaybackState: self.actionInteraction?.storeMediaPlaybackState ?? { _, _, _ in }, generateStoreAfterDownload: self.generateStoreAfterDownload, present: { [weak self] c, a in
if let strongSelf = self {
strongSelf.presentInGlobalOverlay(c, with: a)
}
@@ -1181,6 +1307,7 @@ public class GalleryController: ViewController, StandalonePresentableController,
var hiddenItem: (MessageId, Media)?
if let index = index {
let message = strongSelf.entries[index].message
strongSelf.centralEntryStableId = message.stableId
if let (media, _) = mediaForMessage(message: message) {
hiddenItem = (message.id, media)
@@ -1204,6 +1331,7 @@ public class GalleryController: ViewController, StandalonePresentableController,
} else if index >= strongSelf.entries.count - 3 && strongSelf.hasRightEntries {
reloadAroundIndex = strongSelf.entries.last?.index
}
let peerIsCopyProtected = strongSelf.peerIsCopyProtected
if let reloadAroundIndex = reloadAroundIndex, let tagMask = strongSelf.tagMask {
let namespaces: MessageIdNamespaces
if Namespaces.Message.allScheduled.contains(message.id.namespace) {
@@ -1212,11 +1340,11 @@ public class GalleryController: ViewController, StandalonePresentableController,
namespaces = .not(Namespaces.Message.allScheduled)
}
let signal = strongSelf.context.account.postbox.aroundMessageHistoryViewForLocation(strongSelf.context.chatLocationInput(for: chatLocation, contextHolder: chatLocationContextHolder), anchor: .index(reloadAroundIndex), ignoreMessagesInTimestampRange: nil, count: 50, clipHoles: false, fixedCombinedReadStates: nil, topTaggedMessageIdNamespaces: [], tagMask: tagMask, appendMessagesFromTheSameGroup: false, namespaces: namespaces, orderStatistics: [.combinedLocation])
|> mapToSignal { (view, _, _) -> Signal<GalleryMessageHistoryView?, NoError> in
let mapped = GalleryMessageHistoryView.view(view)
return .single(mapped)
}
|> take(1)
|> mapToSignal { (view, _, _) -> Signal<GalleryMessageHistoryView?, NoError> in
let mapped = GalleryMessageHistoryView.view(view, peerIsCopyProtected)
return .single(mapped)
}
|> take(1)
strongSelf.updateVisibleDisposable.set((signal
|> deliverOnMainQueue).start(next: { view in
@@ -1243,7 +1371,7 @@ public class GalleryController: ViewController, StandalonePresentableController,
if entry.message.stableId == strongSelf.centralEntryStableId {
isCentral = true
}
if let item = galleryItemForEntry(context: strongSelf.context, presentationData: strongSelf.presentationData, entry: entry, isCentral: isCentral, streamVideos: false, fromPlayingVideo: isCentral && strongSelf.fromPlayingVideo, landscape: isCentral && strongSelf.landscape, timecode: isCentral ? strongSelf.timecode : nil, playbackRate: { return self?.playbackRate }, displayInfoOnTop: displayInfoOnTop, configuration: strongSelf.configuration, performAction: strongSelf.performAction, openActionOptions: strongSelf.openActionOptions, storeMediaPlaybackState: strongSelf.actionInteraction?.storeMediaPlaybackState ?? { _, _, _ in }, generateStoreAfterDownload: strongSelf.generateStoreAfterDownload, present: { [weak self] c, a in
if let item = galleryItemForEntry(context: strongSelf.context, presentationData: strongSelf.presentationData, entry: entry, isCentral: isCentral, streamVideos: false, fromPlayingVideo: isCentral && strongSelf.fromPlayingVideo, landscape: isCentral && strongSelf.landscape, timecode: isCentral ? strongSelf.timecode : nil, playbackRate: { return self?.playbackRate }, displayInfoOnTop: displayInfoOnTop, configuration: strongSelf.configuration, peerIsCopyProtected: view.peerIsCopyProtected, performAction: strongSelf.performAction, openActionOptions: strongSelf.openActionOptions, storeMediaPlaybackState: strongSelf.actionInteraction?.storeMediaPlaybackState ?? { _, _, _ in }, generateStoreAfterDownload: strongSelf.generateStoreAfterDownload, present: { [weak self] c, a in
if let strongSelf = self {
strongSelf.presentInGlobalOverlay(c, with: a)
}