Files
isaac 2ac8a490b0 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>
2026-04-26 02:46:44 +04:00

98 lines
4.1 KiB
Swift

import Foundation
import UIKit
import LegacyComponents
import SwiftSignalKit
import TelegramCore
import SSignalKit
import Display
import TelegramPresentationData
import AccountContext
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(engine: context.engine, result: result) else {
return
}
var screenImage: Signal<UIImage?, NoError> = .single(nil)
if let resource = item.thumbnailResource {
screenImage = context.engine.resources.data(resource: EngineMediaResource(resource), attemptSynchronously: true)
|> map { maybeData -> UIImage? in
if maybeData.isComplete {
if let loadedData = try? Data(contentsOf: URL(fileURLWithPath: maybeData.path), options: []), let image = UIImage(data: loadedData) {
return image
}
}
return nil
}
}
let _ = (screenImage
|> take(1)
|> deliverOnMainQueue).start(next: { screenImage in
let legacyController = LegacyController(presentation: .custom, theme: theme, initialLayout: initialLayout)
legacyController.statusBar.statusBarStyle = theme.rootController.statusBarStyle.style
let paintStickersContext = LegacyPaintStickersContext(context: context)
let controller = TGPhotoEditorController(context: legacyController.context, item: item, intent: TGPhotoEditorControllerAvatarIntent, adjustments: nil, caption: nil, screenImage: screenImage ?? UIImage(), availableTabs: TGPhotoEditorController.defaultTabs(forAvatarIntent: true), selectedTab: .cropTab)!
controller.stickersContext = paintStickersContext
legacyController.bind(controller: controller)
controller.editingContext = TGMediaEditingContext()
controller.didFinishEditing = { [weak controller] _, result, _, hasChanges, commit in
if !hasChanges {
return
}
if let result = result {
completed(result)
}
commit?()
controller?.dismiss(animated: true)
}
controller.requestThumbnailImage = { _ -> SSignal in
return item.thumbnailImageSignal()
}
controller.requestOriginalScreenSizeImage = { _, position -> SSignal in
return item.screenImageSignal(position)
}
controller.requestOriginalFullSizeImage = { _, position -> SSignal in
return item.originalImageSignal(position)
}
let fromView = transitionView(result)!
let transition = TGMediaAvatarEditorTransition(controller: controller, from: fromView)!
transition.transitionHostView = transitionHostView()
transition.referenceFrame = {
return fromView.frame
}
transition.referenceImageSize = {
return item.dimensions
}
transition.referenceScreenImageSignal = {
return item.screenImageSignal(0.0)
}
transition.imageReady = {
updateHiddenMedia(result.id)
}
controller.beginCustomTransitionOut = { [weak legacyController] outFrame, outView, completion in
transition.outReferenceFrame = outFrame
transition.repView = outView
transition.dismiss(animated: true, completion: {
updateHiddenMedia(nil)
if let completion = completion {
DispatchQueue.main.async {
completion()
}
}
legacyController?.dismiss()
})
}
present(legacyController, nil)
transition.present(animated: true)
})
}