Telegram-iOS/submodules/AccountContext/Sources/FetchMediaUtils.swift
isaac e918b353ec Postbox refactor waves 278-356: squash
Squashes 79 sequential refactor waves into a single commit.

Highlights:
- Drop `import Postbox` (and matching `//submodules/Postbox` BUILD deps) from a wide swath of consumer files: ChatList, ChatMessage*BubbleContentNode subclasses, ListMessageNode/ListMessageItem, GalleryData, ChatHistorySearchContainerNode, ChatPanelInterfaceInteraction, ChatControllerInteraction, ChatMessageStickerItemNode, ChatMessageReplyInfoNode, ChatMessageInstantVideoItemNode, ChatPresentationInterfaceState, BrowserMarkdown/Readability, MediaResources, LocalMediaResources, ICloudResources, FetchManager, ShareController, OpenChatMessage, GalleryController, GroupStickerSearchContainerNode, GroupStickerPackCurrentItem, ChatPinnedMessageTitlePanelNode, OverlayAudioPlayerController, PresentationThemeSettings, StatisticsUI/StoryIconNode, TextFormat/StringWithAppliedEntities, GalleryUI/VideoAdComponent, StickerPackPreviewUI, WallpaperPreviewMedia, WallpaperResources, YoutubeEmbedImplementation, InstantPageExternalMediaResource, PlatformRestrictionMatching, TelegramUIDeclareEncodables, ChatListNode/ChatListSearchContainerNode.
- Add `TelegramEngine` facades: `Themes.wallpapers`, `Themes.themes`, `AccountData.addAppLogEvent`.
- Add `EngineMessageHistoryEntryLocation` wrapper.
- Add `EngineRaw*` escape-hatch typealiases (`EngineRawMessage`, `EngineRawPeer`, `EngineRawMedia`, `EngineRawMediaResource`, `EngineRawMediaResourceData`, `EngineRawItemCollectionItem`, `EngineRawItemCollectionInfo`) and `engineDeclareEncodable` forwarder.
- Drop unused `account:`/`postbox:`/`network:` parameters from several public functions and delete the dead overloads/types/functions left over: `automaticThemeShouldSwitchNow`, `cancelFreeMediaFileInteractiveFetch`, `legacyEnqueueVideoMessage`, `TelegramMediaFileReference`, plus assorted dead public TelegramCore/AccountContext SecureId entry points.
- Delete entire dead modules: `LegacyDataImport`, `TonBinding`, `SpotlightSupport`, `SvgRendering`, third-party `AppCenter`/`VectorPlus`/`SwiftColor`/`SwiftSVG`.
- Drop orphan `//submodules/Postbox` BUILD deps across 3 cleanup rounds.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 14:11:06 +02:00

104 lines
7.6 KiB
Swift

import Foundation
import UIKit
import TelegramCore
import Postbox
import SwiftSignalKit
import TelegramUIPreferences
import RangeSet
public func freeMediaFileInteractiveFetched(account: Account, userLocation: MediaResourceUserLocation, fileReference: FileMediaReference) -> Signal<FetchResourceSourceType, FetchResourceError> {
return fetchedMediaResource(mediaBox: account.postbox.mediaBox, userLocation: userLocation, userContentType: MediaResourceUserContentType(file: fileReference.media), reference: fileReference.resourceReference(fileReference.media.resource))
}
public func freeMediaFileInteractiveFetched(fetchManager: FetchManager, fileReference: FileMediaReference, priority: FetchManagerPriority) -> Signal<Void, NoError> {
let file = fileReference.media
let mediaReference = AnyMediaReference.standalone(media: fileReference.media)
return fetchManager.interactivelyFetched(category: fetchCategoryForFile(file), location: .chat(PeerId(0)), locationKey: .free, mediaReference: mediaReference, resourceReference: mediaReference.resourceReference(file.resource), ranges: RangeSet<Int64>(0 ..< Int64.max), statsCategory: statsCategoryForFileWithAttributes(file.attributes), elevatedPriority: false, userInitiated: false, priority: priority, storeToDownloadsPeerId: nil)
}
public func freeMediaFileResourceInteractiveFetched(account: Account, userLocation: MediaResourceUserLocation, fileReference: FileMediaReference, resource: MediaResource) -> Signal<FetchResourceSourceType, FetchResourceError> {
return fetchedMediaResource(mediaBox: account.postbox.mediaBox, userLocation: userLocation, userContentType: MediaResourceUserContentType(file: fileReference.media), reference: fileReference.resourceReference(resource))
}
public func freeMediaFileResourceInteractiveFetched(postbox: Postbox, userLocation: MediaResourceUserLocation, fileReference: FileMediaReference, resource: MediaResource, range: (Range<Int64>, MediaBoxFetchPriority)? = nil) -> Signal<FetchResourceSourceType, FetchResourceError> {
return fetchedMediaResource(mediaBox: postbox.mediaBox, userLocation: userLocation, userContentType: MediaResourceUserContentType(file: fileReference.media), reference: fileReference.resourceReference(resource), range: range)
}
private func fetchCategoryForFile(_ file: TelegramMediaFile) -> FetchManagerCategory {
if file.isVoice || file.isInstantVideo {
return .voice
} else if file.isAnimated {
return .animation
} else {
return .file
}
}
public func messageMediaFileInteractiveFetched(context: AccountContext, message: Message, file: TelegramMediaFile, userInitiated: Bool, storeToDownloadsPeerId: EnginePeer.Id? = nil) -> Signal<Void, NoError> {
return messageMediaFileInteractiveFetched(fetchManager: context.fetchManager, messageId: message.id, messageReference: MessageReference(message), file: file, userInitiated: userInitiated, priority: .userInitiated, storeToDownloadsPeerId: storeToDownloadsPeerId)
}
public func messageMediaFileInteractiveFetched(fetchManager: FetchManager, messageId: MessageId, messageReference: MessageReference, file: TelegramMediaFile, ranges: RangeSet<Int64> = RangeSet<Int64>(0 ..< Int64.max), userInitiated: Bool, priority: FetchManagerPriority, storeToDownloadsPeerId: EnginePeer.Id? = nil) -> Signal<Void, NoError> {
let mediaReference = AnyMediaReference.message(message: messageReference, media: file)
return fetchManager.interactivelyFetched(category: fetchCategoryForFile(file), location: .chat(messageId.peerId), locationKey: .messageId(messageId), mediaReference: mediaReference, resourceReference: mediaReference.resourceReference(file.resource), ranges: ranges, statsCategory: statsCategoryForFileWithAttributes(file.attributes), elevatedPriority: false, userInitiated: userInitiated, priority: priority, storeToDownloadsPeerId: storeToDownloadsPeerId)
}
public func messageMediaFileCancelInteractiveFetch(context: AccountContext, messageId: MessageId, file: TelegramMediaFile) {
context.fetchManager.cancelInteractiveFetches(category: fetchCategoryForFile(file), location: .chat(messageId.peerId), locationKey: .messageId(messageId), resource: file.resource)
}
public func messageMediaImageInteractiveFetched(context: AccountContext, message: Message, image: TelegramMediaImage, resource: MediaResource, range: Range<Int64>? = nil, userInitiated: Bool = true, storeToDownloadsPeerId: EnginePeer.Id?) -> Signal<Void, NoError> {
return messageMediaImageInteractiveFetched(fetchManager: context.fetchManager, messageId: message.id, messageReference: MessageReference(message), image: image, resource: resource, range: range, userInitiated: userInitiated, priority: .userInitiated, storeToDownloadsPeerId: storeToDownloadsPeerId)
}
public func messageMediaImageInteractiveFetched(fetchManager: FetchManager, messageId: MessageId, messageReference: MessageReference, image: TelegramMediaImage, resource: MediaResource, range: Range<Int64>? = nil, userInitiated: Bool, priority: FetchManagerPriority, storeToDownloadsPeerId: EnginePeer.Id?) -> Signal<Void, NoError> {
let mediaReference = AnyMediaReference.message(message: messageReference, media: image)
let ranges: RangeSet<Int64>
if let range = range {
ranges = RangeSet(range.lowerBound ..< range.upperBound)
} else {
ranges = RangeSet(0 ..< Int64.max)
}
return fetchManager.interactivelyFetched(category: .image, location: .chat(messageId.peerId), locationKey: .messageId(messageId), mediaReference: mediaReference, resourceReference: mediaReference.resourceReference(resource), ranges: ranges, statsCategory: .image, elevatedPriority: false, userInitiated: userInitiated, priority: priority, storeToDownloadsPeerId: storeToDownloadsPeerId)
}
public func messageMediaImageCancelInteractiveFetch(context: AccountContext, messageId: MessageId, image: TelegramMediaImage, resource: MediaResource) {
context.fetchManager.cancelInteractiveFetches(category: .image, location: .chat(messageId.peerId), locationKey: .messageId(messageId), resource: resource)
}
public func messageMediaFileStatus(context: AccountContext, messageId: MessageId, file: TelegramMediaFile, adjustForVideoThumbnail: Bool = false) -> Signal<MediaResourceStatus, NoError> {
let fileStatus = context.fetchManager.fetchStatus(category: fetchCategoryForFile(file), location: .chat(messageId.peerId), locationKey: .messageId(messageId), resource: file.resource)
if !adjustForVideoThumbnail {
return fileStatus
}
var thumbnailStatus: Signal<MediaResourceStatus?, NoError> = .single(nil)
if let videoThumbnail = file.videoThumbnails.first {
thumbnailStatus = context.engine.resources.status(resource: EngineMediaResource(videoThumbnail.resource))
|> map { $0._asStatus() }
|> map(Optional.init)
}
return combineLatest(queue: context.fetchManager.queue,
fileStatus,
thumbnailStatus
)
|> map { fileStatus, thumbnailStatus -> MediaResourceStatus in
guard let thumbnailStatus = thumbnailStatus else {
return fileStatus
}
if case .Local = thumbnailStatus {
return thumbnailStatus
} else {
return fileStatus
}
}
|> distinctUntilChanged
}
public func messageMediaImageStatus(context: AccountContext, messageId: MessageId, image: TelegramMediaImage) -> Signal<MediaResourceStatus, NoError> {
guard let representation = image.representations.last else {
return .single(.Remote(progress: 0.0))
}
return context.fetchManager.fetchStatus(category: .image, location: .chat(messageId.peerId), locationKey: .messageId(messageId), resource: representation.resource)
}