Postbox -> TelegramEngine waves 94-102 (squashed)

Adds AccountManagerResources facade in TelegramCore mirroring
TelegramEngine.Resources, drains the entire accountManager-side
mediaBox refactor across consumer modules, and validates the
Shape-C/D handle-migration pattern (account: Account ->
engine: TelegramEngine) on three classes.

Wave 94 (AccountManagerResources facade + 8 sites): new
AccountManagerResources class in TelegramCore with
storeResourceData, completedResourcePath (resource + id overloads),
status (with approximateSynchronousValue), moveResourceData,
fetch. Migrate EditThemeController (5 storeResourceData + 2
completedResourcePath) and WebBrowserSettingsController (1
storeResourceData).

Wave 95 (10 sites): WallpaperUtils.swift sweep, 5 distinct
storeResourceData patterns, replace_all on the two repeated ones.

Wave 96 (7 sites): theme controller triple — TPC (1 store + 2
moveResourceData), TPCN (1 status + 1 fetch + closure type
MediaResourceStatus -> EngineMediaResource.FetchStatus + rename
account local to engine), TAC (1 completedResourcePath + 1 store).

Wave 97 (9 sites): WallpaperGalleryController.swift, 4
completedResourcePath + 5 storeResourceData via replace_all.

Wave 98 (2 files): WallpaperGallery status-type cascade
Promise<MediaResourceStatus> -> Promise<EngineMediaResource.FetchStatus>
across WallpaperGalleryItem.swift + WallpaperGalleryController.swift.
Drops cosmetic `_asStatus()` unwrap.

Wave 99 (2 facade extensions + 7 sites): adds
AccountManagerResources.data() and approximateSynchronousValue
to engine.resources.status(). Migrates OpenResolvedUrl (data +
storeResourceData with .complete -> .isComplete cascade),
SettingsThemeWallpaperNode (paired engine + accountManager
status), WallpaperUploadManager, OpenChatMessage,
LiveChatReactionStreamView.

Wave 100 (Shape-C/D, free function): legacyWebSearchItem
account: Account -> engine: TelegramEngine. 4 files.

Wave 101 (Shape-C/D, small class): VerticalListContextResults
ChatInputPanelItem stored field migration. 2 files. Drops
`|> map(EngineMediaResource.FetchStatus.init)` redundancy.

Wave 102 (Shape-C/D, medium class with weak-context retention):
SharedMediaPlayer account: Account -> engine: TelegramEngine.
Engine field is intentionally a strong handle since the class
stores context as `weak var`. 2 files.

After this squash the accountManager-side mediaBox refactor is
essentially complete; only Postbox-protocol-blocked
cachedResourceRepresentation triple remains as the foundational
deferred item.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
isaac 2026-04-26 02:46:44 +04:00
parent 7ce00a00fa
commit 2ac8a490b0
23 changed files with 158 additions and 102 deletions

View file

@ -465,7 +465,7 @@ private func fetchDomainExceptionInfo(context: AccountContext, url: String) -> S
var image: TelegramMediaImage?
if let imageData, let parsedImage = UIImage(data: imageData) {
let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max))
context.sharedContext.accountManager.mediaBox.storeResourceData(resource.id, data: imageData)
context.sharedContext.accountManager.resources.storeResourceData(id: EngineMediaResource.Id(resource.id), data: imageData)
image = TelegramMediaImage(
imageId: MediaId(namespace: Namespaces.Media.LocalImage, id: Int64.random(in: Int64.min ... Int64.max)),
representations: [

View file

@ -334,7 +334,7 @@ public func editThemeController(context: AccountContext, mode: EditThemeControll
case let .edit(info):
hasSettings = info.theme.settings != nil
settingsPromise.set(.single(info.theme.settings?.first))
if let file = info.theme.file, let path = context.sharedContext.accountManager.mediaBox.completedResourcePath(file.resource), let data = try? Data(contentsOf: URL(fileURLWithPath: path)), let theme = makePresentationTheme(data: data, resolvedWallpaper: info.resolvedWallpaper) {
if let file = info.theme.file, let path = context.sharedContext.accountManager.resources.completedResourcePath(resource: EngineMediaResource(file.resource)), let data = try? Data(contentsOf: URL(fileURLWithPath: path)), let theme = makePresentationTheme(data: data, resolvedWallpaper: info.resolvedWallpaper) {
if case let .file(file) = theme.chat.defaultWallpaper, file.id == 0 {
previewThemePromise.set(cachedWallpaper(account: context.account, slug: file.slug, settings: file.settings)
|> map ({ wallpaper -> PresentationTheme in
@ -415,7 +415,7 @@ public func editThemeController(context: AccountContext, mode: EditThemeControll
guard complete, let fullSizeData = fullSizeData else {
return .complete()
}
context.sharedContext.accountManager.mediaBox.storeResourceData(file.file.resource.id, data: fullSizeData, synchronous: true)
context.sharedContext.accountManager.resources.storeResourceData(id: EngineMediaResource.Id(file.file.resource.id), data: fullSizeData, synchronous: true)
return .single(wallpaper.wallpaper)
}
} else {
@ -576,7 +576,7 @@ public func editThemeController(context: AccountContext, mode: EditThemeControll
if let theme = theme, let themeString = encodePresentationTheme(theme), let data = themeString.data(using: .utf8) {
let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max))
context.engine.resources.storeResourceData(id: EngineMediaResource.Id(resource.id), data: data, synchronous: true)
context.sharedContext.accountManager.mediaBox.storeResourceData(resource.id, data: data, synchronous: true)
context.sharedContext.accountManager.resources.storeResourceData(id: EngineMediaResource.Id(resource.id), data: data, synchronous: true)
themeResource = resource
themeData = data
@ -614,12 +614,12 @@ public func editThemeController(context: AccountContext, mode: EditThemeControll
var data: Data?
if let path = context.engine.resources.completedResourcePath(id: EngineMediaResource.Id(resource.id)), let maybeData = try? Data(contentsOf: URL(fileURLWithPath: path), options: .mappedRead) {
data = maybeData
} else if let path = context.sharedContext.accountManager.mediaBox.completedResourcePath(resource), let maybeData = try? Data(contentsOf: URL(fileURLWithPath: path), options: .mappedRead) {
} else if let path = context.sharedContext.accountManager.resources.completedResourcePath(resource: EngineMediaResource(resource)), let maybeData = try? Data(contentsOf: URL(fileURLWithPath: path), options: .mappedRead) {
data = maybeData
}
if let data = data {
context.sharedContext.accountManager.mediaBox.storeResourceData(resource.id, data: data, synchronous: true)
context.sharedContext.accountManager.resources.storeResourceData(id: EngineMediaResource.Id(resource.id), data: data, synchronous: true)
prepare = .complete()
} else {
prepare = .complete()
@ -637,7 +637,7 @@ public func editThemeController(context: AccountContext, mode: EditThemeControll
let _ = applyTheme(accountManager: context.sharedContext.accountManager, account: context.account, theme: resultTheme).start()
let _ = (updatePresentationThemeSettingsInteractively(accountManager: context.sharedContext.accountManager, { current in
if let resource = resultTheme.file?.resource, let data = themeData {
context.sharedContext.accountManager.mediaBox.storeResourceData(resource.id, data: data, synchronous: true)
context.sharedContext.accountManager.resources.storeResourceData(id: EngineMediaResource.Id(resource.id), data: data, synchronous: true)
}
let themeReference: PresentationThemeReference = .cloud(PresentationCloudTheme(theme: resultTheme, resolvedWallpaper: resolvedWallpaper, creatorAccountId: context.account.id))
@ -671,7 +671,7 @@ public func editThemeController(context: AccountContext, mode: EditThemeControll
let _ = applyTheme(accountManager: context.sharedContext.accountManager, account: context.account, theme: resultTheme).start()
let _ = (updatePresentationThemeSettingsInteractively(accountManager: context.sharedContext.accountManager, { current in
if let resource = resultTheme.file?.resource, let data = themeData {
context.sharedContext.accountManager.mediaBox.storeResourceData(resource.id, data: data, synchronous: true)
context.sharedContext.accountManager.resources.storeResourceData(id: EngineMediaResource.Id(resource.id), data: data, synchronous: true)
}
let themeReference: PresentationThemeReference = .cloud(PresentationCloudTheme(theme: resultTheme, resolvedWallpaper: resolvedWallpaper, creatorAccountId: context.account.id))

View file

@ -268,7 +268,7 @@ public final class ThemePreviewController: ViewController {
if let strings = encodePresentationTheme(previewTheme), let data = strings.data(using: .utf8) {
let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max))
context.engine.resources.storeResourceData(id: EngineMediaResource.Id(resource.id), data: data)
context.sharedContext.accountManager.mediaBox.storeResourceData(resource.id, data: data)
context.sharedContext.accountManager.resources.storeResourceData(id: EngineMediaResource.Id(resource.id), data: data)
theme = .single(.local(PresentationLocalTheme(title: previewTheme.name.string, resource: resource, resolvedWallpaper: nil)))
} else {
theme = .single(.builtin(.dayClassic))
@ -334,7 +334,7 @@ public final class ThemePreviewController: ViewController {
return .single((.local(updatedTheme), true))
}
if case let .result(theme) = result, let file = theme.file {
context.sharedContext.accountManager.mediaBox.moveResourceData(from: info.resource.id, to: file.resource.id)
context.sharedContext.accountManager.resources.moveResourceData(from: EngineMediaResource.Id(info.resource.id), to: EngineMediaResource.Id(file.resource.id))
return .single((.cloud(PresentationCloudTheme(theme: theme, resolvedWallpaper: resolvedWallpaper, creatorAccountId: theme.isCreator ? context.account.id : nil)), true))
} else {
return .complete()
@ -353,7 +353,7 @@ public final class ThemePreviewController: ViewController {
return .single((.local(updatedTheme), true))
}
if case let .result(updatedTheme) = result, let file = updatedTheme.file {
context.sharedContext.accountManager.mediaBox.moveResourceData(from: info.resource.id, to: file.resource.id)
context.sharedContext.accountManager.resources.moveResourceData(from: EngineMediaResource.Id(info.resource.id), to: EngineMediaResource.Id(file.resource.id))
return .single((.cloud(PresentationCloudTheme(theme: updatedTheme, resolvedWallpaper: resolvedWallpaper, creatorAccountId: updatedTheme.isCreator ? context.account.id : nil)), true))
} else {
return .complete()

View file

@ -265,16 +265,16 @@ final class ThemePreviewControllerNode: ASDisplayNode, ASScrollViewDelegate {
}
strongSelf.remoteChatBackgroundNode.setSignal(signal)
strongSelf.fetchDisposable.set(fetchedMediaResource(mediaBox: context.sharedContext.accountManager.mediaBox, userLocation: .other, userContentType: .other, reference: .wallpaper(wallpaper: .slug(file.slug), resource: file.file.resource)).start())
let account = strongSelf.context.account
let statusSignal = strongSelf.context.sharedContext.accountManager.mediaBox.resourceStatus(file.file.resource)
strongSelf.fetchDisposable.set(context.sharedContext.accountManager.resources.fetch(reference: .wallpaper(wallpaper: .slug(file.slug), resource: file.file.resource), userLocation: .other, userContentType: .other).start())
let engine = strongSelf.context.engine
let statusSignal = strongSelf.context.sharedContext.accountManager.resources.status(resource: EngineMediaResource(file.file.resource))
|> take(1)
|> mapToSignal { status -> Signal<MediaResourceStatus, NoError> in
|> mapToSignal { status -> Signal<EngineMediaResource.FetchStatus, NoError> in
if case .Local = status {
return .single(status)
} else {
return account.postbox.mediaBox.resourceStatus(file.file.resource)
return engine.resources.status(resource: EngineMediaResource(file.file.resource))
}
}

View file

@ -0,0 +1,57 @@
import Foundation
import SwiftSignalKit
import Postbox
public final class AccountManagerResources {
private let mediaBox: MediaBox
init(mediaBox: MediaBox) {
self.mediaBox = mediaBox
}
public func data(
resource: EngineMediaResource,
pathExtension: String? = nil,
waitUntilFetchStatus: Bool = false,
attemptSynchronously: Bool = false
) -> Signal<EngineMediaResource.ResourceData, NoError> {
return self.mediaBox.resourceData(
resource._asResource(),
pathExtension: pathExtension,
option: .complete(waitUntilFetchStatus: waitUntilFetchStatus),
attemptSynchronously: attemptSynchronously
)
|> map { EngineMediaResource.ResourceData($0) }
}
public func storeResourceData(id: EngineMediaResource.Id, data: Data, synchronous: Bool = false) {
self.mediaBox.storeResourceData(MediaResourceId(id.stringRepresentation), data: data, synchronous: synchronous)
}
public func completedResourcePath(resource: EngineMediaResource, pathExtension: String? = nil) -> String? {
return self.mediaBox.completedResourcePath(resource._asResource(), pathExtension: pathExtension)
}
public func completedResourcePath(id: EngineMediaResource.Id, pathExtension: String? = nil) -> String? {
return self.mediaBox.completedResourcePath(id: MediaResourceId(id.stringRepresentation), pathExtension: pathExtension)
}
public func status(resource: EngineMediaResource, approximateSynchronousValue: Bool = false) -> Signal<EngineMediaResource.FetchStatus, NoError> {
return self.mediaBox.resourceStatus(resource._asResource(), approximateSynchronousValue: approximateSynchronousValue)
|> map { EngineMediaResource.FetchStatus($0) }
}
public func moveResourceData(from: EngineMediaResource.Id, to: EngineMediaResource.Id, synchronous: Bool = false) {
self.mediaBox.moveResourceData(from: MediaResourceId(from.stringRepresentation), to: MediaResourceId(to.stringRepresentation), synchronous: synchronous)
}
public func fetch(reference: MediaResourceReference, userLocation: MediaResourceUserLocation, userContentType: MediaResourceUserContentType) -> Signal<FetchResourceSourceType, FetchResourceError> {
return fetchedMediaResource(mediaBox: self.mediaBox, userLocation: userLocation, userContentType: userContentType, reference: reference)
}
}
public extension AccountManager {
var resources: AccountManagerResources {
return AccountManagerResources(mediaBox: self.mediaBox)
}
}

View file

@ -435,9 +435,10 @@ public extension TelegramEngine {
}
public func status(
resource: EngineMediaResource
resource: EngineMediaResource,
approximateSynchronousValue: Bool = false
) -> Signal<EngineMediaResource.FetchStatus, NoError> {
return self.account.postbox.mediaBox.resourceStatus(resource._asResource())
return self.account.postbox.mediaBox.resourceStatus(resource._asResource(), approximateSynchronousValue: approximateSynchronousValue)
|> map { EngineMediaResource.FetchStatus($0) }
}

View file

@ -281,8 +281,8 @@ public final class SettingsThemeWallpaperNode: ASDisplayNode {
}
let anyStatus = combineLatest(queue: .mainQueue(),
context.account.postbox.mediaBox.resourceStatus(convertedFullRepresentations[0].reference.resource, approximateSynchronousValue: true),
context.sharedContext.accountManager.mediaBox.resourceStatus(convertedFullRepresentations[0].reference.resource, approximateSynchronousValue: true)
context.engine.resources.status(resource: EngineMediaResource(convertedFullRepresentations[0].reference.resource), approximateSynchronousValue: true),
context.sharedContext.accountManager.resources.status(resource: EngineMediaResource(convertedFullRepresentations[0].reference.resource), approximateSynchronousValue: true)
)
|> map { a, b -> Bool in
switch a {

View file

@ -188,12 +188,12 @@ public final class ThemeAccentColorController: ViewController {
var data: Data?
if let path = strongSelf.context.engine.resources.completedResourcePath(id: EngineMediaResource.Id(resource.id)), let maybeData = try? Data(contentsOf: URL(fileURLWithPath: path), options: .mappedRead) {
data = maybeData
} else if let path = strongSelf.context.sharedContext.accountManager.mediaBox.completedResourcePath(resource), let maybeData = try? Data(contentsOf: URL(fileURLWithPath: path), options: .mappedRead) {
} else if let path = strongSelf.context.sharedContext.accountManager.resources.completedResourcePath(resource: EngineMediaResource(resource)), let maybeData = try? Data(contentsOf: URL(fileURLWithPath: path), options: .mappedRead) {
data = maybeData
}
if let data = data {
strongSelf.context.sharedContext.accountManager.mediaBox.storeResourceData(resource.id, data: data, synchronous: true)
strongSelf.context.sharedContext.accountManager.resources.storeResourceData(id: EngineMediaResource.Id(resource.id), data: data, synchronous: true)
prepareWallpaper = .complete()
} else {
prepareWallpaper = .complete()

View file

@ -215,7 +215,7 @@ public class WallpaperGalleryController: ViewController {
private var previousCentralEntryIndex: Int?
private let centralItemSubtitle = Promise<String?>()
private let centralItemStatus = Promise<MediaResourceStatus>()
private let centralItemStatus = Promise<EngineMediaResource.FetchStatus>()
private let centralItemAction = Promise<UIBarButtonItem?>()
private let centralItemAttributesDisposable = DisposableSet();
@ -567,12 +567,12 @@ public class WallpaperGalleryController: ViewController {
var data: Data?
if let path = strongSelf.context.engine.resources.completedResourcePath(id: EngineMediaResource.Id(resource.id)), let maybeData = try? Data(contentsOf: URL(fileURLWithPath: path), options: .mappedRead) {
data = maybeData
} else if let path = strongSelf.context.sharedContext.accountManager.mediaBox.completedResourcePath(resource), let maybeData = try? Data(contentsOf: URL(fileURLWithPath: path), options: .mappedRead) {
} else if let path = strongSelf.context.sharedContext.accountManager.resources.completedResourcePath(resource: EngineMediaResource(resource)), let maybeData = try? Data(contentsOf: URL(fileURLWithPath: path), options: .mappedRead) {
data = maybeData
}
if let data = data {
strongSelf.context.sharedContext.accountManager.mediaBox.storeResourceData(resource.id, data: data, synchronous: true)
strongSelf.context.sharedContext.accountManager.resources.storeResourceData(id: EngineMediaResource.Id(resource.id), data: data, synchronous: true)
let _ = (strongSelf.context.sharedContext.accountManager.mediaBox.cachedResourceRepresentation(resource, representation: representation, complete: true, fetch: true)
|> filter({ $0.complete })
|> take(1)
@ -656,12 +656,12 @@ public class WallpaperGalleryController: ViewController {
var data: Data?
if let path = strongSelf.context.engine.resources.completedResourcePath(id: EngineMediaResource.Id(resource.id)), let maybeData = try? Data(contentsOf: URL(fileURLWithPath: path), options: .mappedRead) {
data = maybeData
} else if let path = strongSelf.context.sharedContext.accountManager.mediaBox.completedResourcePath(resource), let maybeData = try? Data(contentsOf: URL(fileURLWithPath: path), options: .mappedRead) {
} else if let path = strongSelf.context.sharedContext.accountManager.resources.completedResourcePath(resource: EngineMediaResource(resource)), let maybeData = try? Data(contentsOf: URL(fileURLWithPath: path), options: .mappedRead) {
data = maybeData
}
if let data = data {
strongSelf.context.sharedContext.accountManager.mediaBox.storeResourceData(resource.id, data: data, synchronous: true)
strongSelf.context.sharedContext.accountManager.resources.storeResourceData(id: EngineMediaResource.Id(resource.id), data: data, synchronous: true)
let _ = (strongSelf.context.sharedContext.accountManager.mediaBox.cachedResourceRepresentation(resource, representation: representation, complete: true, fetch: true)
|> filter({ $0.complete })
|> take(1)
@ -676,7 +676,7 @@ public class WallpaperGalleryController: ViewController {
var thumbnailData: Data?
if let path = strongSelf.context.engine.resources.completedResourcePath(id: EngineMediaResource.Id(resource.id)), let maybeData = try? Data(contentsOf: URL(fileURLWithPath: path), options: .mappedRead) {
data = maybeData
} else if let path = strongSelf.context.sharedContext.accountManager.mediaBox.completedResourcePath(resource), let maybeData = try? Data(contentsOf: URL(fileURLWithPath: path), options: .mappedRead) {
} else if let path = strongSelf.context.sharedContext.accountManager.resources.completedResourcePath(resource: EngineMediaResource(resource)), let maybeData = try? Data(contentsOf: URL(fileURLWithPath: path), options: .mappedRead) {
data = maybeData
}
@ -685,20 +685,20 @@ public class WallpaperGalleryController: ViewController {
if let resource = thumbnailResource {
if let path = strongSelf.context.engine.resources.completedResourcePath(id: EngineMediaResource.Id(resource.id)), let maybeData = try? Data(contentsOf: URL(fileURLWithPath: path), options: .mappedRead) {
thumbnailData = maybeData
} else if let path = strongSelf.context.sharedContext.accountManager.mediaBox.completedResourcePath(resource), let maybeData = try? Data(contentsOf: URL(fileURLWithPath: path), options: .mappedRead) {
} else if let path = strongSelf.context.sharedContext.accountManager.resources.completedResourcePath(resource: EngineMediaResource(resource)), let maybeData = try? Data(contentsOf: URL(fileURLWithPath: path), options: .mappedRead) {
thumbnailData = maybeData
}
}
if let data = data {
strongSelf.context.sharedContext.accountManager.mediaBox.storeResourceData(resource.id, data: data, synchronous: true)
strongSelf.context.sharedContext.accountManager.resources.storeResourceData(id: EngineMediaResource.Id(resource.id), data: data, synchronous: true)
if let thumbnailResource = thumbnailResource, let thumbnailData = thumbnailData {
strongSelf.context.sharedContext.accountManager.mediaBox.storeResourceData(thumbnailResource.id, data: thumbnailData, synchronous: true)
strongSelf.context.sharedContext.accountManager.resources.storeResourceData(id: EngineMediaResource.Id(thumbnailResource.id), data: thumbnailData, synchronous: true)
}
completion(wallpaper)
}
} else if let path = strongSelf.context.engine.resources.completedResourcePath(id: EngineMediaResource.Id(file.file.resource.id)), let data = try? Data(contentsOf: URL(fileURLWithPath: path), options: .mappedRead) {
strongSelf.context.sharedContext.accountManager.mediaBox.storeResourceData(file.file.resource.id, data: data)
strongSelf.context.sharedContext.accountManager.resources.storeResourceData(id: EngineMediaResource.Id(file.file.resource.id), data: data)
completion(wallpaper)
}
} else {

View file

@ -131,7 +131,7 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
private let colorDisposable = MetaDisposable()
let subtitle = Promise<String?>(nil)
let status = Promise<MediaResourceStatus>(.Local)
let status = Promise<EngineMediaResource.FetchStatus>(.Local)
let actionButton = Promise<UIBarButtonItem?>(nil)
var action: (() -> Void)?
var requestPatternPanel: ((Bool, TelegramWallpaper) -> Void)?
@ -615,7 +615,7 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
let signal: Signal<(TransformImageArguments) -> DrawingContext?, NoError>
let fetchSignal: Signal<FetchResourceSourceType, FetchResourceError>
let statusSignal: Signal<MediaResourceStatus, NoError>
let statusSignal: Signal<EngineMediaResource.FetchStatus, NoError>
let subtitleSignal: Signal<String?, NoError>
var actionSignal: Signal<UIBarButtonItem?, NoError> = .single(nil)
var colorSignal: Signal<UIColor, NoError> = serviceColor(from: imagePromise.get())
@ -795,14 +795,14 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
signal = wallpaperImage(account: context.account, accountManager: context.sharedContext.accountManager, fileReference: fileReference, representations: convertedRepresentations, alwaysShowThumbnailFirst: true, autoFetchFullSize: false)
}
fetchSignal = context.engine.resources.fetch(reference: convertedRepresentations[convertedRepresentations.count - 1].reference, userLocation: .other, userContentType: .other)
let account = self.context.account
statusSignal = self.context.sharedContext.accountManager.mediaBox.resourceStatus(file.file.resource)
let engine = self.context.engine
statusSignal = self.context.sharedContext.accountManager.resources.status(resource: EngineMediaResource(file.file.resource))
|> take(1)
|> mapToSignal { status -> Signal<MediaResourceStatus, NoError> in
|> mapToSignal { status -> Signal<EngineMediaResource.FetchStatus, NoError> in
if case .Local = status {
return .single(status)
} else {
return account.postbox.mediaBox.resourceStatus(file.file.resource)
return engine.resources.status(resource: EngineMediaResource(file.file.resource))
}
}
if let fileSize = file.file.size {
@ -830,14 +830,14 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
} else {
fetchSignal = .complete()
}
let account = context.account
statusSignal = context.sharedContext.accountManager.mediaBox.resourceStatus(largestSize.resource)
let engine = context.engine
statusSignal = context.sharedContext.accountManager.resources.status(resource: EngineMediaResource(largestSize.resource))
|> take(1)
|> mapToSignal { status -> Signal<MediaResourceStatus, NoError> in
|> mapToSignal { status -> Signal<EngineMediaResource.FetchStatus, NoError> in
if case .Local = status {
return .single(status)
} else {
return account.postbox.mediaBox.resourceStatus(largestSize.resource)
return engine.resources.status(resource: EngineMediaResource(largestSize.resource))
}
}
if let fileSize = largestSize.resource.size {
@ -928,7 +928,6 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
signal = chatMessagePhoto(postbox: context.account.postbox, userLocation: .other, photoReference: .standalone(media: tmpImage))
fetchSignal = context.engine.resources.fetch(reference: .media(media: .standalone(media: tmpImage), resource: imageResource), userLocation: .other, userContentType: .other)
statusSignal = context.engine.resources.status(resource: EngineMediaResource(imageResource))
|> map { $0._asStatus() }
} else {
displaySize = CGSize(width: 1.0, height: 1.0)
contentSize = displaySize
@ -987,7 +986,7 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
if case .asset = entry, let image, let data = image.jpegData(compressionQuality: 0.5) {
let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max))
strongSelf.context.sharedContext.accountManager.mediaBox.storeResourceData(resource.id, data: data, synchronous: true)
strongSelf.context.sharedContext.accountManager.resources.storeResourceData(id: EngineMediaResource.Id(resource.id), data: data, synchronous: true)
let wallpaper: TelegramWallpaper = .image([TelegramMediaImageRepresentation(dimensions: PixelDimensions(image.size), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false, isPersonal: false)], WallpaperSettings())
strongSelf.nativeNode.update(wallpaper: wallpaper, animated: false)

View file

@ -19,7 +19,7 @@ public func uploadCustomWallpaper(context: AccountContext, wallpaper: WallpaperG
switch wallpaper {
case let .file(file):
if let path = context.engine.resources.completedResourcePath(id: EngineMediaResource.Id(file.file.resource.id)), let data = try? Data(contentsOf: URL(fileURLWithPath: path), options: .mappedRead) {
context.sharedContext.accountManager.mediaBox.storeResourceData(file.file.resource.id, data: data)
context.sharedContext.accountManager.resources.storeResourceData(id: EngineMediaResource.Id(file.file.resource.id), data: data)
let _ = context.sharedContext.accountManager.mediaBox.cachedResourceRepresentation(file.file.resource, representation: CachedScaledImageRepresentation(size: CGSize(width: 720.0, height: 720.0), mode: .aspectFit), complete: true, fetch: true).start()
let _ = context.sharedContext.accountManager.mediaBox.cachedResourceRepresentation(file.file.resource, representation: CachedBlurredWallpaperRepresentation(), complete: true, fetch: true).start()
}
@ -27,7 +27,7 @@ public func uploadCustomWallpaper(context: AccountContext, wallpaper: WallpaperG
for representation in representations {
let resource = representation.resource
if let path = context.engine.resources.completedResourcePath(id: EngineMediaResource.Id(resource.id)), let data = try? Data(contentsOf: URL(fileURLWithPath: path), options: .mappedRead) {
context.sharedContext.accountManager.mediaBox.storeResourceData(resource.id, data: data)
context.sharedContext.accountManager.resources.storeResourceData(id: EngineMediaResource.Id(resource.id), data: data)
let _ = context.sharedContext.accountManager.mediaBox.cachedResourceRepresentation(resource, representation: CachedScaledImageRepresentation(size: CGSize(width: 720.0, height: 720.0), mode: .aspectFit), complete: true, fetch: true).start()
}
}
@ -100,11 +100,11 @@ public func uploadCustomWallpaper(context: AccountContext, wallpaper: WallpaperG
if let data = croppedImage.jpegData(compressionQuality: 0.8), let thumbnailImage = thumbnailImage, let thumbnailData = thumbnailImage.jpegData(compressionQuality: 0.4) {
let thumbnailResource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max))
context.sharedContext.accountManager.mediaBox.storeResourceData(thumbnailResource.id, data: thumbnailData, synchronous: true)
context.sharedContext.accountManager.resources.storeResourceData(id: EngineMediaResource.Id(thumbnailResource.id), data: thumbnailData, synchronous: true)
context.engine.resources.storeResourceData(id: EngineMediaResource.Id(thumbnailResource.id), data: thumbnailData, synchronous: true)
let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max))
context.sharedContext.accountManager.mediaBox.storeResourceData(resource.id, data: data, synchronous: true)
context.sharedContext.accountManager.resources.storeResourceData(id: EngineMediaResource.Id(resource.id), data: data, synchronous: true)
context.engine.resources.storeResourceData(id: EngineMediaResource.Id(resource.id), data: data, synchronous: true)
let autoNightModeTriggered = context.sharedContext.currentPresentationData.with {$0 }.autoNightModeTriggered
@ -234,11 +234,11 @@ public func getTemporaryCustomPeerWallpaper(context: AccountContext, wallpaper:
if let data = croppedImage.jpegData(compressionQuality: 0.8), let thumbnailImage = thumbnailImage, let thumbnailData = thumbnailImage.jpegData(compressionQuality: 0.4) {
let thumbnailResource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max))
context.sharedContext.accountManager.mediaBox.storeResourceData(thumbnailResource.id, data: thumbnailData, synchronous: true)
context.sharedContext.accountManager.resources.storeResourceData(id: EngineMediaResource.Id(thumbnailResource.id), data: thumbnailData, synchronous: true)
context.engine.resources.storeResourceData(id: EngineMediaResource.Id(thumbnailResource.id), data: thumbnailData, synchronous: true)
let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max))
context.sharedContext.accountManager.mediaBox.storeResourceData(resource.id, data: data, synchronous: true)
context.sharedContext.accountManager.resources.storeResourceData(id: EngineMediaResource.Id(resource.id), data: data, synchronous: true)
context.engine.resources.storeResourceData(id: EngineMediaResource.Id(resource.id), data: data, synchronous: true)
let _ = context.sharedContext.accountManager.mediaBox.cachedResourceRepresentation(resource, representation: CachedBlurredWallpaperRepresentation(), complete: true, fetch: true).start()
@ -265,7 +265,7 @@ public func uploadCustomPeerWallpaper(context: AccountContext, wallpaper: Wallpa
switch wallpaper {
case let .file(file):
if let path = context.engine.resources.completedResourcePath(id: EngineMediaResource.Id(file.file.resource.id)), let data = try? Data(contentsOf: URL(fileURLWithPath: path), options: .mappedRead), let image = UIImage(data: data) {
context.sharedContext.accountManager.mediaBox.storeResourceData(file.file.resource.id, data: data, synchronous: true)
context.sharedContext.accountManager.resources.storeResourceData(id: EngineMediaResource.Id(file.file.resource.id), data: data, synchronous: true)
let _ = context.sharedContext.accountManager.mediaBox.cachedResourceRepresentation(file.file.resource, representation: CachedScaledImageRepresentation(size: CGSize(width: 720.0, height: 720.0), mode: .aspectFit), complete: true, fetch: true).start()
let _ = context.sharedContext.accountManager.mediaBox.cachedResourceRepresentation(file.file.resource, representation: CachedBlurredWallpaperRepresentation(), complete: true, fetch: true).start()
@ -275,7 +275,7 @@ public func uploadCustomPeerWallpaper(context: AccountContext, wallpaper: Wallpa
for representation in representations {
let resource = representation.resource
if let path = context.engine.resources.completedResourcePath(id: EngineMediaResource.Id(resource.id)), let data = try? Data(contentsOf: URL(fileURLWithPath: path), options: .mappedRead) {
context.sharedContext.accountManager.mediaBox.storeResourceData(resource.id, data: data, synchronous: true)
context.sharedContext.accountManager.resources.storeResourceData(id: EngineMediaResource.Id(resource.id), data: data, synchronous: true)
let _ = context.sharedContext.accountManager.mediaBox.cachedResourceRepresentation(resource, representation: CachedScaledImageRepresentation(size: CGSize(width: 720.0, height: 720.0), mode: .aspectFit), complete: true, fetch: true).start()
}
}
@ -347,11 +347,11 @@ public func uploadCustomPeerWallpaper(context: AccountContext, wallpaper: Wallpa
if let data = croppedImage.jpegData(compressionQuality: 0.8), let thumbnailImage = thumbnailImage, let thumbnailData = thumbnailImage.jpegData(compressionQuality: 0.4) {
let thumbnailResource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max))
context.sharedContext.accountManager.mediaBox.storeResourceData(thumbnailResource.id, data: thumbnailData, synchronous: true)
context.sharedContext.accountManager.resources.storeResourceData(id: EngineMediaResource.Id(thumbnailResource.id), data: thumbnailData, synchronous: true)
context.engine.resources.storeResourceData(id: EngineMediaResource.Id(thumbnailResource.id), data: thumbnailData, synchronous: true)
let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max))
context.sharedContext.accountManager.mediaBox.storeResourceData(resource.id, data: data, synchronous: true)
context.sharedContext.accountManager.resources.storeResourceData(id: EngineMediaResource.Id(resource.id), data: data, synchronous: true)
context.engine.resources.storeResourceData(id: EngineMediaResource.Id(resource.id), data: data, synchronous: true)
let _ = context.sharedContext.accountManager.mediaBox.cachedResourceRepresentation(resource, representation: CachedBlurredWallpaperRepresentation(), complete: true, fetch: true).start()

View file

@ -109,10 +109,10 @@ private func makePeerBadgeImage(engine: TelegramEngine, peer: EnginePeer, count:
var avatarSourceImage: UIImage?
if let resource = smallestImageRepresentation(peer.profileImageRepresentations)?.resource, let peerReference = PeerReference(peer) {
let disposable = engine.resources.fetch(reference: .avatar(peer: peerReference, resource: resource), userLocation: .peer(peer.id), userContentType: .avatar).startStrict()
let signal = engine.account.postbox.mediaBox.resourceData(resource)
|> filter { $0.complete }
let signal = engine.resources.data(resource: EngineMediaResource(resource))
|> filter { $0.isComplete }
|> map { value -> Data? in
if value.complete {
if value.isComplete {
return try? Data(contentsOf: URL(fileURLWithPath: value.path))
} else {
return nil

View file

@ -77,7 +77,7 @@ public final class MediaManagerImpl: NSObject, MediaManager {
didSet {
if self.voiceMediaPlayer !== oldValue {
if let voiceMediaPlayer = self.voiceMediaPlayer {
let account = voiceMediaPlayer.account
let account = voiceMediaPlayer.engine.account
self.voiceMediaPlayerStateDisposable.set((voiceMediaPlayer.playbackState
|> deliverOnMainQueue).startStrict(next: { [weak self, weak voiceMediaPlayer] state in
guard let strongSelf = self else {
@ -116,7 +116,7 @@ public final class MediaManagerImpl: NSObject, MediaManager {
if self.musicMediaPlayer !== oldValue {
if let musicMediaPlayer = self.musicMediaPlayer {
let type = musicMediaPlayer.type
let account = musicMediaPlayer.account
let account = musicMediaPlayer.engine.account
self.musicMediaPlayerStateValue.set(musicMediaPlayer.playbackState
|> map { state -> (Account, SharedMediaPlayerItemPlaybackStateOrLoading, MediaManagerPlayerType)? in
guard let state = state else {
@ -523,7 +523,7 @@ public final class MediaManagerImpl: NSObject, MediaManager {
controlPlaybackWithProximity = playlist.context.sharedContext.currentMediaInputSettings.with({ $0.enableRaiseToSpeak })
}
let voiceMediaPlayer = SharedMediaPlayer(context: context, mediaManager: strongSelf, inForeground: strongSelf.inForeground, account: context.account, audioSession: strongSelf.audioSession, overlayMediaManager: strongSelf.overlayMediaManager, playlist: playlist, initialOrder: .reversed, initialLooping: .none, initialPlaybackRate: settings.voicePlaybackRate, playerIndex: nextPlayerIndex, controlPlaybackWithProximity: controlPlaybackWithProximity, type: type, continueInstantVideoLoopAfterFinish: continueInstantVideoLoopAfterFinish)
let voiceMediaPlayer = SharedMediaPlayer(context: context, mediaManager: strongSelf, inForeground: strongSelf.inForeground, engine: context.engine, audioSession: strongSelf.audioSession, overlayMediaManager: strongSelf.overlayMediaManager, playlist: playlist, initialOrder: .reversed, initialLooping: .none, initialPlaybackRate: settings.voicePlaybackRate, playerIndex: nextPlayerIndex, controlPlaybackWithProximity: controlPlaybackWithProximity, type: type, continueInstantVideoLoopAfterFinish: continueInstantVideoLoopAfterFinish)
strongSelf.voiceMediaPlayer = voiceMediaPlayer
voiceMediaPlayer.playedToEnd = { [weak voiceMediaPlayer] in
if let strongSelf = self, let voiceMediaPlayer = voiceMediaPlayer, voiceMediaPlayer === strongSelf.voiceMediaPlayer {
@ -557,7 +557,7 @@ public final class MediaManagerImpl: NSObject, MediaManager {
strongSelf.musicMediaPlayer?.control(control)
} else {
strongSelf.musicMediaPlayer?.stop()
let musicMediaPlayer = SharedMediaPlayer(context: context, mediaManager: strongSelf, inForeground: strongSelf.inForeground, account: context.account, audioSession: strongSelf.audioSession, overlayMediaManager: strongSelf.overlayMediaManager, playlist: playlist, initialOrder: settings.order, initialLooping: settings.looping, initialPlaybackRate: storedState?.playbackRate ?? .x1, playerIndex: nextPlayerIndex, controlPlaybackWithProximity: false, type: type, continueInstantVideoLoopAfterFinish: true)
let musicMediaPlayer = SharedMediaPlayer(context: context, mediaManager: strongSelf, inForeground: strongSelf.inForeground, engine: context.engine, audioSession: strongSelf.audioSession, overlayMediaManager: strongSelf.overlayMediaManager, playlist: playlist, initialOrder: settings.order, initialLooping: settings.looping, initialPlaybackRate: storedState?.playbackRate ?? .x1, playerIndex: nextPlayerIndex, controlPlaybackWithProximity: false, type: type, continueInstantVideoLoopAfterFinish: true)
strongSelf.musicMediaPlayer = musicMediaPlayer
strongSelf.musicListenTracker = MusicListenTracker(engine: context.engine)
musicMediaPlayer.cancelled = { [weak musicMediaPlayer] in

View file

@ -543,7 +543,7 @@ func openChatTheme(context: AccountContext, message: Message, pushController: @e
}
if case let .theme(slug) = resolvedUrl {
if let file = file {
if let path = context.sharedContext.accountManager.mediaBox.completedResourcePath(file.resource), let data = try? Data(contentsOf: URL(fileURLWithPath: path), options: .mappedRead) {
if let path = context.sharedContext.accountManager.resources.completedResourcePath(resource: EngineMediaResource(file.resource)), let data = try? Data(contentsOf: URL(fileURLWithPath: path), options: .mappedRead) {
if let theme = makePresentationTheme(data: data) {
let controller = ThemePreviewController(context: context, previewTheme: theme, source: .slug(slug, file))
pushController(controller)

View file

@ -747,16 +747,16 @@ func openResolvedUrlImpl(
} else if let resource = themeInfo.file?.resource {
disposables.add(context.engine.resources.fetch(reference: .standalone(resource: resource), userLocation: .other, userContentType: .other).start())
let maybeFetched = context.sharedContext.accountManager.mediaBox.resourceData(resource, option: .complete(waitUntilFetchStatus: false), attemptSynchronously: false)
let maybeFetched = context.sharedContext.accountManager.resources.data(resource: EngineMediaResource(resource))
|> mapToSignal { maybeData -> Signal<Data?, NoError> in
if maybeData.complete {
if maybeData.isComplete {
let loadedData = try? Data(contentsOf: URL(fileURLWithPath: maybeData.path), options: [])
return .single(loadedData)
} else {
return context.engine.resources.data(resource: EngineMediaResource(resource))
|> map { next -> Data? in
if next.availableSize > 0, let data = try? Data(contentsOf: URL(fileURLWithPath: next.path), options: []) {
context.sharedContext.accountManager.mediaBox.storeResourceData(resource.id, data: data)
context.sharedContext.accountManager.resources.storeResourceData(id: EngineMediaResource.Id(resource.id), data: data)
return data
} else {
return nil

View file

@ -113,7 +113,7 @@ private enum SharedMediaPlaybackItem: Equatable {
final class SharedMediaPlayer {
private weak var context: AccountContext?
private weak var mediaManager: MediaManager?
let account: Account
let engine: TelegramEngine
private let audioSession: ManagedAudioSession
private let overlayMediaManager: OverlayMediaManager
private let playerIndex: Int32
@ -180,10 +180,10 @@ final class SharedMediaPlayer {
let type: MediaManagerPlayerType
init(context: AccountContext, mediaManager: MediaManager, inForeground: Signal<Bool, NoError>, account: Account, audioSession: ManagedAudioSession, overlayMediaManager: OverlayMediaManager, playlist: SharedMediaPlaylist, initialOrder: MusicPlaybackSettingsOrder, initialLooping: MusicPlaybackSettingsLooping, initialPlaybackRate: AudioPlaybackRate, playerIndex: Int32, controlPlaybackWithProximity: Bool, type: MediaManagerPlayerType, continueInstantVideoLoopAfterFinish: Bool) {
init(context: AccountContext, mediaManager: MediaManager, inForeground: Signal<Bool, NoError>, engine: TelegramEngine, audioSession: ManagedAudioSession, overlayMediaManager: OverlayMediaManager, playlist: SharedMediaPlaylist, initialOrder: MusicPlaybackSettingsOrder, initialLooping: MusicPlaybackSettingsLooping, initialPlaybackRate: AudioPlaybackRate, playerIndex: Int32, controlPlaybackWithProximity: Bool, type: MediaManagerPlayerType, continueInstantVideoLoopAfterFinish: Bool) {
self.context = context
self.mediaManager = mediaManager
self.account = account
self.engine = engine
self.audioSession = audioSession
self.overlayMediaManager = overlayMediaManager
playlist.setOrder(initialOrder)
@ -232,13 +232,13 @@ final class SharedMediaPlayer {
case .voice, .music:
switch playbackData.source {
case let .telegramFile(fileReference, _, _):
strongSelf.playbackItem = .audio(MediaPlayer(audioSessionManager: strongSelf.audioSession, postbox: strongSelf.account.postbox, userLocation: .other, userContentType: .audio, resourceReference: fileReference.resourceReference(fileReference.media.resource), streamable: playbackData.type == .music ? .conservative : .none, video: false, preferSoftwareDecoding: false, enableSound: true, baseRate: rateValue, fetchAutomatically: true, playAndRecord: controlPlaybackWithProximity, isAudioVideoMessage: playbackData.type == .voice))
strongSelf.playbackItem = .audio(MediaPlayer(audioSessionManager: strongSelf.audioSession, postbox: strongSelf.engine.account.postbox, userLocation: .other, userContentType: .audio, resourceReference: fileReference.resourceReference(fileReference.media.resource), streamable: playbackData.type == .music ? .conservative : .none, video: false, preferSoftwareDecoding: false, enableSound: true, baseRate: rateValue, fetchAutomatically: true, playAndRecord: controlPlaybackWithProximity, isAudioVideoMessage: playbackData.type == .voice))
}
case .instantVideo:
if let mediaManager = strongSelf.mediaManager, let context = strongSelf.context, let item = item as? MessageMediaPlaylistItem {
switch playbackData.source {
case let .telegramFile(fileReference, _, _):
let videoNode = OverlayInstantVideoNode(context: context, postbox: strongSelf.account.postbox, audioSession: strongSelf.audioSession, manager: mediaManager.universalVideoManager, content: NativeVideoContent(id: .message(item.message.stableId, fileReference.media.fileId), userLocation: .peer(item.message.id.peerId), fileReference: fileReference, enableSound: false, baseRate: rateValue, isAudioVideoMessage: true, captureProtected: item.message.isCopyProtected(), storeAfterDownload: nil), close: { [weak mediaManager] in
let videoNode = OverlayInstantVideoNode(context: context, postbox: strongSelf.engine.account.postbox, audioSession: strongSelf.audioSession, manager: mediaManager.universalVideoManager, content: NativeVideoContent(id: .message(item.message.stableId, fileReference.media.fileId), userLocation: .peer(item.message.id.peerId), fileReference: fileReference, enableSound: false, baseRate: rateValue, isAudioVideoMessage: true, captureProtected: item.message.isCopyProtected(), storeAfterDownload: nil), close: { [weak mediaManager] in
mediaManager?.setPlaylist(nil, type: .voice, control: .playback(.pause))
})
strongSelf.playbackItem = .instantVideo(videoNode)
@ -496,9 +496,9 @@ final class SharedMediaPlayer {
let fetchedNextSignal: Signal<Never, NoError>
switch current {
case let .telegramFile(file, _, _):
fetchedCurrentSignal = self.account.postbox.mediaBox.resourceData(file.media.resource)
fetchedCurrentSignal = self.engine.resources.data(resource: EngineMediaResource(file.media.resource))
|> mapToSignal { data -> Signal<Void, NoError> in
if data.complete {
if data.isComplete {
return .single(Void())
} else {
return .complete()
@ -509,7 +509,7 @@ final class SharedMediaPlayer {
}
switch next {
case let .telegramFile(file, _, _):
fetchedNextSignal = fetchedMediaResource(mediaBox: self.account.postbox.mediaBox, userLocation: .other, userContentType: .audio, reference: file.resourceReference(file.media.resource))
fetchedNextSignal = self.engine.resources.fetch(reference: file.resourceReference(file.media.resource), userLocation: .other, userContentType: .audio)
|> ignoreValues
|> `catch` { _ -> Signal<Never, NoError> in
return .complete()

View file

@ -100,12 +100,12 @@ private enum VerticalListContextResultsChatInputContextPanelEntry: Comparable, I
}
}
func item(account: Account, actionSelected: @escaping () -> Void, resultSelected: @escaping (ChatContextResult, ASDisplayNode, CGRect) -> Bool) -> ListViewItem {
func item(engine: TelegramEngine, actionSelected: @escaping () -> Void, resultSelected: @escaping (ChatContextResult, ASDisplayNode, CGRect) -> Bool) -> ListViewItem {
switch self {
case let .action(theme, title):
return VerticalListContextResultsChatInputPanelButtonItem(theme: theme, title: title, pressed: actionSelected)
case let .result(_, theme, result):
return VerticalListContextResultsChatInputPanelItem(account: account, theme: theme, result: result, resultSelected: resultSelected)
return VerticalListContextResultsChatInputPanelItem(engine: engine, theme: theme, result: result, resultSelected: resultSelected)
}
}
}
@ -116,12 +116,12 @@ private struct VerticalListContextResultsChatInputContextPanelTransition {
let updates: [ListViewUpdateItem]
}
private func preparedTransition(from fromEntries: [VerticalListContextResultsChatInputContextPanelEntry], to toEntries: [VerticalListContextResultsChatInputContextPanelEntry], account: Account, actionSelected: @escaping () -> Void, resultSelected: @escaping (ChatContextResult, ASDisplayNode, CGRect) -> Bool) -> VerticalListContextResultsChatInputContextPanelTransition {
private func preparedTransition(from fromEntries: [VerticalListContextResultsChatInputContextPanelEntry], to toEntries: [VerticalListContextResultsChatInputContextPanelEntry], engine: TelegramEngine, actionSelected: @escaping () -> Void, resultSelected: @escaping (ChatContextResult, ASDisplayNode, CGRect) -> Bool) -> VerticalListContextResultsChatInputContextPanelTransition {
let (deleteIndices, indicesAndItems, updateIndices) = mergeListsStableWithUpdates(leftList: fromEntries, rightList: toEntries)
let deletions = deleteIndices.map { ListViewDeleteItem(index: $0, directionHint: nil) }
let insertions = indicesAndItems.map { ListViewInsertItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(account: account, actionSelected: actionSelected, resultSelected: resultSelected), directionHint: nil) }
let updates = updateIndices.map { ListViewUpdateItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(account: account, actionSelected: actionSelected, resultSelected: resultSelected), directionHint: nil) }
let insertions = indicesAndItems.map { ListViewInsertItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(engine: engine, actionSelected: actionSelected, resultSelected: resultSelected), directionHint: nil) }
let updates = updateIndices.map { ListViewUpdateItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(engine: engine, actionSelected: actionSelected, resultSelected: resultSelected), directionHint: nil) }
return VerticalListContextResultsChatInputContextPanelTransition(deletions: deletions, insertions: insertions, updates: updates)
}
@ -239,7 +239,7 @@ final class VerticalListContextResultsChatInputContextPanelNode: ChatInputContex
private func prepareTransition(from: [VerticalListContextResultsChatInputContextPanelEntry]?, to: [VerticalListContextResultsChatInputContextPanelEntry], results: ChatContextResultCollection) {
let firstTime = self.currentEntries == nil
let transition = preparedTransition(from: from ?? [], to: to, account: self.context.account, actionSelected: { [weak self] in
let transition = preparedTransition(from: from ?? [], to: to, engine: self.context.engine, actionSelected: { [weak self] in
if let strongSelf = self, let interfaceInteraction = strongSelf.interfaceInteraction {
if let switchPeer = results.switchPeer {
interfaceInteraction.botSwitchChatWithPayload(results.botId, switchPeer.startParam)

View file

@ -10,15 +10,15 @@ import PhotoResources
import StickerResources
final class VerticalListContextResultsChatInputPanelItem: ListViewItem {
fileprivate let account: Account
fileprivate let engine: TelegramEngine
fileprivate let theme: PresentationTheme
fileprivate let result: ChatContextResult
fileprivate let resultSelected: (ChatContextResult, ASDisplayNode, CGRect) -> Bool
let selectable: Bool = true
public init(account: Account, theme: PresentationTheme, result: ChatContextResult, resultSelected: @escaping (ChatContextResult, ASDisplayNode, CGRect) -> Bool) {
self.account = account
public init(engine: TelegramEngine, theme: PresentationTheme, result: ChatContextResult, resultSelected: @escaping (ChatContextResult, ASDisplayNode, CGRect) -> Bool) {
self.engine = engine
self.theme = theme
self.result = result
self.resultSelected = resultSelected
@ -226,8 +226,7 @@ final class VerticalListContextResultsChatInputPanelItemNode: ListViewItemNode {
let arguments = TransformImageArguments(corners: imageCorners, imageSize: iconSize, boundingSize: boundingSize, intrinsicInsets: UIEdgeInsets())
iconImageApply = iconImageLayout(arguments)
updatedStatusSignal = item.account.postbox.mediaBox.resourceStatus(imageResource)
|> map(EngineMediaResource.FetchStatus.init)
updatedStatusSignal = item.engine.resources.status(resource: EngineMediaResource(imageResource))
}
var updatedIconImageResource = false
@ -242,11 +241,11 @@ final class VerticalListContextResultsChatInputPanelItemNode: ListViewItemNode {
if updatedIconImageResource {
if let imageResource = imageResource {
if let stickerFile = stickerFile {
updateIconImageSignal = chatMessageSticker(account: item.account, userLocation: .other, file: stickerFile, small: false, fetched: true)
updateIconImageSignal = chatMessageSticker(account: item.engine.account, userLocation: .other, file: stickerFile, small: false, fetched: true)
} else {
let tmpRepresentation = TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 55, height: 55), resource: imageResource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false, isPersonal: false)
let tmpImage = TelegramMediaImage(imageId: EngineMedia.Id(namespace: 0, id: 0), representations: [tmpRepresentation], immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: [])
updateIconImageSignal = chatWebpageSnippetPhoto(account: item.account, userLocation: .other, photoReference: .standalone(media: tmpImage))
updateIconImageSignal = chatWebpageSnippetPhoto(account: item.engine.account, userLocation: .other, photoReference: .standalone(media: tmpImage))
}
} else {
updateIconImageSignal = .complete()

View file

@ -95,7 +95,7 @@ final class WallpaperUploadManagerImpl: WallpaperUploadManager {
switch result {
case let .complete(wallpaper):
if case let .file(file) = wallpaper {
sharedContext.accountManager.mediaBox.moveResourceData(from: currentResource.id, to: file.file.resource.id)
sharedContext.accountManager.resources.moveResourceData(from: EngineMediaResource.Id(currentResource.id), to: EngineMediaResource.Id(file.file.resource.id))
account.postbox.mediaBox.moveResourceData(from: currentResource.id, to: file.file.resource.id)
}
default:

View file

@ -11,7 +11,7 @@ import LegacyUI
import LegacyMediaPickerUI
func presentLegacyWebSearchEditor(context: AccountContext, theme: PresentationTheme, result: ChatContextResult, initialLayout: ContainerViewLayout?, updateHiddenMedia: @escaping (String?) -> Void, transitionHostView: @escaping () -> UIView?, transitionView: @escaping (ChatContextResult) -> UIView?, completed: @escaping (UIImage) -> Void, present: @escaping (ViewController, Any?) -> Void) {
guard let item = legacyWebSearchItem(account: context.account, result: result) else {
guard let item = legacyWebSearchItem(engine: context.engine, result: result) else {
return
}

View file

@ -208,7 +208,7 @@ private class LegacyWebSearchGalleryItemView: TGModernGalleryImageItemView, TGMo
}
}
func legacyWebSearchItem(account: Account, result: ChatContextResult) -> LegacyWebSearchItem? {
func legacyWebSearchItem(engine: TelegramEngine, result: ChatContextResult) -> LegacyWebSearchItem? {
var thumbnailDimensions: CGSize?
var thumbnailResource: TelegramMediaResource?
var imageResource: TelegramMediaResource?
@ -245,7 +245,7 @@ func legacyWebSearchItem(account: Account, result: ChatContextResult) -> LegacyW
}
if let imageResource = imageResource {
let progressSignal = account.postbox.mediaBox.resourceStatus(imageResource)
let progressSignal = engine.resources.status(resource: EngineMediaResource(imageResource))
|> map { status -> Float in
switch status {
case .Local:
@ -263,7 +263,7 @@ func legacyWebSearchItem(account: Account, result: ChatContextResult) -> LegacyW
}
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(imageDimensions), resource: imageResource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false, isPersonal: false))
let tmpImage = TelegramMediaImage(imageId: EngineMedia.Id(namespace: 0, id: 0), representations: representations, immediateThumbnailData: immediateThumbnailData, reference: nil, partialReference: nil, flags: [])
thumbnailSignal = chatMessagePhotoDatas(postbox: account.postbox, userLocation: .other, photoReference: .standalone(media: tmpImage), autoFetchFullSize: false)
thumbnailSignal = chatMessagePhotoDatas(postbox: engine.account.postbox, userLocation: .other, photoReference: .standalone(media: tmpImage), autoFetchFullSize: false)
|> mapToSignal { value -> Signal<UIImage, NoError> in
let thumbnailData = value._0
if let data = thumbnailData, let image = UIImage(data: data) {
@ -272,7 +272,7 @@ func legacyWebSearchItem(account: Account, result: ChatContextResult) -> LegacyW
return .complete()
}
}
originalSignal = chatMessagePhotoDatas(postbox: account.postbox, userLocation: .other, photoReference: .standalone(media: tmpImage), autoFetchFullSize: true)
originalSignal = chatMessagePhotoDatas(postbox: engine.account.postbox, userLocation: .other, photoReference: .standalone(media: tmpImage), autoFetchFullSize: true)
|> mapToSignal { value -> Signal<UIImage, NoError> in
let thumbnailData = value._0
let fullSizeData = value._1
@ -294,11 +294,11 @@ func legacyWebSearchItem(account: Account, result: ChatContextResult) -> LegacyW
}
}
private func galleryItems(account: Account, results: [ChatContextResult], current: ChatContextResult, selectionContext: TGMediaSelectionContext?, editingContext: TGMediaEditingContext) -> ([TGModernGalleryItem], TGModernGalleryItem?) {
private func galleryItems(engine: TelegramEngine, results: [ChatContextResult], current: ChatContextResult, selectionContext: TGMediaSelectionContext?, editingContext: TGMediaEditingContext) -> ([TGModernGalleryItem], TGModernGalleryItem?) {
var focusItem: TGModernGalleryItem?
var galleryItems: [TGModernGalleryItem] = []
for result in results {
if let item = legacyWebSearchItem(account: account, result: result) {
if let item = legacyWebSearchItem(engine: engine, result: result) {
let galleryItem = LegacyWebSearchGalleryItem(item: item)
galleryItem.selectionContext = selectionContext
galleryItem.editingContext = editingContext
@ -335,7 +335,7 @@ func presentLegacyWebSearchGallery(context: AccountContext, peer: EnginePeer?, t
controller.asyncTransitionIn = true
legacyController.bind(controller: controller)
let (items, focusItem) = galleryItems(account: context.account, results: results, current: current, selectionContext: selectionContext, editingContext: editingContext)
let (items, focusItem) = galleryItems(engine: context.engine, results: results, current: current, selectionContext: selectionContext, editingContext: editingContext)
let model = TGMediaPickerGalleryModel(context: legacyController.context, items: items, focus: focusItem, selectionContext: selectionContext, editingContext: editingContext, hasCaptions: false, allowCaptionEntities: true, hasTimer: false, onlyCrop: false, inhibitDocumentCaptions: false, hasSelectionPanel: false, hasCamera: false, recipientName: recipientName, isScheduledMessages: false, hasCoverButton: false)!
model.stickersContext = paintStickersContext

View file

@ -792,7 +792,7 @@ class WebSearchControllerNode: ASDisplayNode {
}
} else {
if let mode = self.controller?.mode, case let .editor(completion) = mode {
if let item = legacyWebSearchItem(account: self.context.account, result: currentResult) {
if let item = legacyWebSearchItem(engine: self.context.engine, result: currentResult) {
let _ = (item.originalImage
|> deliverOnMainQueue).start(next: { image in
if !image.degraded() {

View file

@ -122,7 +122,7 @@ final class WebSearchVideoGalleryItemNode: ZoomableContentGalleryItemNode {
switch gesture {
case .tap:
if let item = self.item, let selectionState = item.controllerInteraction?.selectionState {
let legacyItem = legacyWebSearchItem(account: item.context.account, result: item.result)
let legacyItem = legacyWebSearchItem(engine: item.context.engine, result: item.result)
selectionState.toggleItemSelection(legacyItem, success: nil)
}
case .doubleTap: