mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-22 22:25:57 +00:00
Various fixes
This commit is contained in:
@@ -4596,11 +4596,11 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
|
||||
|
||||
init(
|
||||
media: MediaResult?,
|
||||
mediaAreas: [MediaArea],
|
||||
caption: NSAttributedString,
|
||||
options: MediaEditorResultPrivacy,
|
||||
stickers: [TelegramMediaFile],
|
||||
randomId: Int64
|
||||
mediaAreas: [MediaArea] = [],
|
||||
caption: NSAttributedString = NSAttributedString(),
|
||||
options: MediaEditorResultPrivacy = MediaEditorResultPrivacy(sendAsPeerId: nil, privacy: EngineStoryPrivacy(base: .everyone, additionallyIncludePeers: []), timeout: 0, isForwardingDisabled: false, pin: false),
|
||||
stickers: [TelegramMediaFile] = [],
|
||||
randomId: Int64 = 0
|
||||
) {
|
||||
self.media = media
|
||||
self.mediaAreas = mediaAreas
|
||||
@@ -5755,24 +5755,13 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
|
||||
let values = mediaEditor.values.withUpdatedQualityPreset(.sticker)
|
||||
makeEditorImageComposition(context: self.node.ciContext, postbox: self.context.account.postbox, inputImage: image, dimensions: storyDimensions, outputDimensions: CGSize(width: 512, height: 512), values: values, time: .zero, textScale: 2.0, completion: { [weak self] resultImage in
|
||||
if let self, let resultImage {
|
||||
// let dimensions = CGSize(width: 512, height: 512)
|
||||
// let scaledImage = generateImage(dimensions, contextGenerator: { size, context in
|
||||
// context.clear(CGRect(origin: CGPoint(), size: size))
|
||||
//
|
||||
// context.addPath(CGPath(roundedRect: CGRect(origin: .zero, size: size), cornerWidth: size.width / 8.0, cornerHeight: size.width / 8.0, transform: nil))
|
||||
// context.clip()
|
||||
//
|
||||
// let scaledSize = resultImage.size.aspectFilled(size)
|
||||
// context.draw(resultImage.cgImage!, in: CGRect(origin: CGPoint(x: floor((size.width - scaledSize.width) / 2.0), y: floor((size.height - scaledSize.height) / 2.0)), size: scaledSize))
|
||||
// }, opaque: false, scale: 1.0)!
|
||||
|
||||
self.presentStickerPreview(image: resultImage)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private weak var resultController: PeekController?
|
||||
func presentStickerPreview(image: UIImage) {
|
||||
guard let mediaEditor = self.node.mediaEditor else {
|
||||
return
|
||||
@@ -5783,7 +5772,6 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
|
||||
var isVideo = false
|
||||
if mediaEditor.resultIsVideo {
|
||||
isVideo = true
|
||||
self.performSave(toStickerResource: resource)
|
||||
} else {
|
||||
Queue.concurrentDefaultQueue().async {
|
||||
if let data = try? WebP.convert(toWebP: image, quality: 97.0) {
|
||||
@@ -5804,26 +5792,29 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
if self.videoExport != nil {
|
||||
return
|
||||
}
|
||||
f(.default)
|
||||
|
||||
self.completion(MediaEditorScreen.Result(
|
||||
media: .sticker(file: file),
|
||||
mediaAreas: [],
|
||||
caption: NSAttributedString(),
|
||||
options: MediaEditorResultPrivacy(sendAsPeerId: nil, privacy: EngineStoryPrivacy(base: .everyone, additionallyIncludePeers: []), timeout: 0, isForwardingDisabled: false, pin: false),
|
||||
stickers: [],
|
||||
randomId: 0
|
||||
), { [weak self] finished in
|
||||
self?.node.animateOut(finished: true, saveDraft: false, completion: { [weak self] in
|
||||
self?.dismiss()
|
||||
Queue.mainQueue().justDispatch {
|
||||
finished()
|
||||
}
|
||||
if isVideo {
|
||||
self.uploadSticker(file, action: .send)
|
||||
} else {
|
||||
self.resultController?.disappeared = nil
|
||||
self.completion(MediaEditorScreen.Result(
|
||||
media: .sticker(file: file),
|
||||
mediaAreas: [],
|
||||
caption: NSAttributedString(),
|
||||
options: MediaEditorResultPrivacy(sendAsPeerId: nil, privacy: EngineStoryPrivacy(base: .everyone, additionallyIncludePeers: []), timeout: 0, isForwardingDisabled: false, pin: false),
|
||||
stickers: [],
|
||||
randomId: 0
|
||||
), { [weak self] finished in
|
||||
self?.node.animateOut(finished: true, saveDraft: false, completion: { [weak self] in
|
||||
self?.dismiss()
|
||||
Queue.mainQueue().justDispatch {
|
||||
finished()
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
f(.default)
|
||||
})))
|
||||
menuItems.append(.action(ContextMenuActionItem(text: presentationData.strings.Stickers_AddToFavorites, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Fave"), color: theme.contextMenu.primaryColor) }, action: { [weak self] _, f in
|
||||
f(.default)
|
||||
@@ -5899,6 +5890,10 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
|
||||
}
|
||||
}
|
||||
|
||||
Queue.mainQueue().justDispatch {
|
||||
self.node.entitiesView.selectEntity(nil)
|
||||
}
|
||||
|
||||
let peekController = PeekController(
|
||||
presentationData: presentationData,
|
||||
content: StickerPreviewPeekContent(
|
||||
@@ -5934,6 +5929,7 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
|
||||
self.node.previewView.alpha = 1.0
|
||||
}
|
||||
}
|
||||
self.resultController = peekController
|
||||
self.present(peekController, in: .window(.root))
|
||||
}
|
||||
|
||||
@@ -5942,6 +5938,7 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
|
||||
case createStickerPack(title: String)
|
||||
case addToStickerPack(pack: StickerPackReference, title: String)
|
||||
case upload
|
||||
case send
|
||||
}
|
||||
|
||||
private func presentCreateStickerPack(file: TelegramMediaFile, completion: @escaping () -> Void) {
|
||||
@@ -6014,69 +6011,118 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
|
||||
let context = self.context
|
||||
let dimensions = PixelDimensions(width: 512, height: 512)
|
||||
let mimeType = file.mimeType
|
||||
let isVideo = file.mimeType == "video/webm"
|
||||
|
||||
self.updateEditProgress(0.0, cancel: { [weak self] in
|
||||
self?.stickerUploadDisposable.set(nil)
|
||||
})
|
||||
|
||||
enum PrepareStickerStatus {
|
||||
case progress(Float)
|
||||
case complete(TelegramMediaResource)
|
||||
case failed
|
||||
}
|
||||
let resourceSignal: Signal<PrepareStickerStatus, UploadStickerError>
|
||||
if isVideo {
|
||||
self.performSave(toStickerResource: file.resource)
|
||||
resourceSignal = self.videoExportPromise.get()
|
||||
|> castError(UploadStickerError.self)
|
||||
|> filter { $0 != nil }
|
||||
|> take(1)
|
||||
|> mapToSignal { videoExport -> Signal<PrepareStickerStatus, UploadStickerError> in
|
||||
guard let videoExport else {
|
||||
return .complete()
|
||||
}
|
||||
return videoExport.status
|
||||
|> castError(UploadStickerError.self)
|
||||
|> mapToSignal { status -> Signal<PrepareStickerStatus, UploadStickerError> in
|
||||
switch status {
|
||||
case .unknown:
|
||||
return .single(.progress(0.0))
|
||||
case let .progress(progress):
|
||||
return .single(.progress(progress))
|
||||
case .completed:
|
||||
return .single(.complete(file.resource))
|
||||
|> delay(0.05, queue: Queue.mainQueue())
|
||||
case .failed:
|
||||
return .single(.failed)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
resourceSignal = .single(.complete(file.resource))
|
||||
}
|
||||
|
||||
let signal = context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: context.account.peerId))
|
||||
|> castError(UploadStickerError.self)
|
||||
|> mapToSignal { peer -> Signal<UploadStickerStatus, UploadStickerError> in
|
||||
guard let peer else {
|
||||
return .complete()
|
||||
}
|
||||
return context.engine.stickers.uploadSticker(peer: peer._asPeer(), resource: file.resource, alt: "", dimensions: dimensions, mimeType: mimeType)
|
||||
|> mapToSignal { status -> Signal<UploadStickerStatus, UploadStickerError> in
|
||||
switch status {
|
||||
case .progress:
|
||||
return .single(status)
|
||||
case let .complete(resource, _):
|
||||
let file = stickerFile(resource: resource, size: file.size ?? 0, dimensions: dimensions, isVideo: file.mimeType == "video/webm")
|
||||
switch action {
|
||||
case .addToFavorites:
|
||||
return context.engine.stickers.toggleStickerSaved(file: file, saved: true)
|
||||
|> `catch` { _ -> Signal<SavedStickerResult, UploadStickerError> in
|
||||
return .fail(.generic)
|
||||
}
|
||||
|> map { _ in
|
||||
return status
|
||||
}
|
||||
case let .createStickerPack(title):
|
||||
let sticker = ImportSticker(
|
||||
resource: resource,
|
||||
emojis: ["😀😂"],
|
||||
dimensions: dimensions,
|
||||
mimeType: mimeType,
|
||||
keywords: ""
|
||||
)
|
||||
return context.engine.stickers.createStickerSet(title: title, shortName: "", stickers: [sticker], thumbnail: nil, type: .stickers(content: .image), software: nil)
|
||||
|> `catch` { _ -> Signal<CreateStickerSetStatus, UploadStickerError> in
|
||||
return .fail(.generic)
|
||||
}
|
||||
|> mapToSignal { innerStatus in
|
||||
if case .complete = innerStatus {
|
||||
return resourceSignal
|
||||
|> mapToSignal { result -> Signal<UploadStickerStatus, UploadStickerError> in
|
||||
switch result {
|
||||
case .failed:
|
||||
return .fail(.generic)
|
||||
case let .progress(progress):
|
||||
return .single(.progress(progress * 0.5))
|
||||
case let .complete(resource):
|
||||
return context.engine.stickers.uploadSticker(peer: peer._asPeer(), resource: resource, alt: "", dimensions: dimensions, mimeType: mimeType)
|
||||
|> mapToSignal { status -> Signal<UploadStickerStatus, UploadStickerError> in
|
||||
switch status {
|
||||
case let .progress(progress):
|
||||
return .single(.progress(isVideo ? 0.5 + progress * 0.5 : progress))
|
||||
case let .complete(resource, _):
|
||||
let file = stickerFile(resource: resource, size: file.size ?? 0, dimensions: dimensions, isVideo: isVideo)
|
||||
switch action {
|
||||
case .send:
|
||||
return .single(status)
|
||||
case .addToFavorites:
|
||||
return context.engine.stickers.toggleStickerSaved(file: file, saved: true)
|
||||
|> `catch` { _ -> Signal<SavedStickerResult, UploadStickerError> in
|
||||
return .fail(.generic)
|
||||
}
|
||||
|> map { _ in
|
||||
return status
|
||||
}
|
||||
case let .createStickerPack(title):
|
||||
let sticker = ImportSticker(
|
||||
resource: resource,
|
||||
emojis: ["😀😂"],
|
||||
dimensions: dimensions,
|
||||
mimeType: mimeType,
|
||||
keywords: ""
|
||||
)
|
||||
return context.engine.stickers.createStickerSet(title: title, shortName: "", stickers: [sticker], thumbnail: nil, type: .stickers(content: .image), software: nil)
|
||||
|> `catch` { _ -> Signal<CreateStickerSetStatus, UploadStickerError> in
|
||||
return .fail(.generic)
|
||||
}
|
||||
|> mapToSignal { innerStatus in
|
||||
if case .complete = innerStatus {
|
||||
return .single(status)
|
||||
} else {
|
||||
return .complete()
|
||||
}
|
||||
}
|
||||
case let .addToStickerPack(pack, _):
|
||||
let sticker = ImportSticker(
|
||||
resource: resource,
|
||||
emojis: ["😀😂"],
|
||||
dimensions: dimensions,
|
||||
mimeType: mimeType,
|
||||
keywords: ""
|
||||
)
|
||||
return context.engine.stickers.addStickerToStickerSet(packReference: pack, sticker: sticker)
|
||||
|> `catch` { _ -> Signal<Bool, UploadStickerError> in
|
||||
return .fail(.generic)
|
||||
}
|
||||
|> map { _ in
|
||||
return status
|
||||
}
|
||||
case .upload:
|
||||
return .single(status)
|
||||
} else {
|
||||
return .complete()
|
||||
}
|
||||
}
|
||||
case let .addToStickerPack(pack, _):
|
||||
let sticker = ImportSticker(
|
||||
resource: resource,
|
||||
emojis: ["😀😂"],
|
||||
dimensions: dimensions,
|
||||
mimeType: mimeType,
|
||||
keywords: ""
|
||||
)
|
||||
return context.engine.stickers.addStickerToStickerSet(packReference: pack, sticker: sticker)
|
||||
|> `catch` { _ -> Signal<Bool, UploadStickerError> in
|
||||
return .fail(.generic)
|
||||
}
|
||||
|> map { _ in
|
||||
return status
|
||||
}
|
||||
case .upload:
|
||||
return .single(status)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6090,26 +6136,23 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
|
||||
switch status {
|
||||
case let .progress(progress):
|
||||
self.updateEditProgress(progress, cancel: { [weak self] in
|
||||
self?.videoExport?.cancel()
|
||||
self?.videoExport = nil
|
||||
self?.exportDisposable.set(nil)
|
||||
self?.stickerUploadDisposable.set(nil)
|
||||
})
|
||||
case let .complete(resource, _):
|
||||
let navigationController = self.navigationController as? NavigationController
|
||||
|
||||
let result: MediaEditorScreen.Result
|
||||
if case .upload = action {
|
||||
let file = stickerFile(resource: resource, size: resource.size ?? 0, dimensions: dimensions, isVideo: file.mimeType == "video/webm")
|
||||
result = MediaEditorScreen.Result(
|
||||
media: .sticker(file: file),
|
||||
mediaAreas: [],
|
||||
caption: NSAttributedString(),
|
||||
options: MediaEditorResultPrivacy(sendAsPeerId: nil, privacy: EngineStoryPrivacy(base: .everyone, additionallyIncludePeers: []), timeout: 0, isForwardingDisabled: false, pin: false),
|
||||
stickers: [],
|
||||
randomId: 0
|
||||
)
|
||||
} else {
|
||||
switch action {
|
||||
case .upload, .send:
|
||||
let file = stickerFile(resource: resource, size: resource.size ?? 0, dimensions: dimensions, isVideo: isVideo)
|
||||
result = MediaEditorScreen.Result(media: .sticker(file: file))
|
||||
default:
|
||||
result = MediaEditorScreen.Result()
|
||||
}
|
||||
|
||||
|
||||
self.completion(result, { [weak self] finished in
|
||||
self?.node.animateOut(finished: true, saveDraft: false, completion: { [weak self] in
|
||||
guard let self else {
|
||||
@@ -6147,7 +6190,12 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
|
||||
}))
|
||||
}
|
||||
|
||||
private var videoExport: MediaEditorVideoExport?
|
||||
private var videoExport: MediaEditorVideoExport? {
|
||||
didSet {
|
||||
self.videoExportPromise.set(.single(self.videoExport))
|
||||
}
|
||||
}
|
||||
private var videoExportPromise = Promise<MediaEditorVideoExport?>(nil)
|
||||
private var exportDisposable = MetaDisposable()
|
||||
|
||||
fileprivate var isSavingAvailable = false
|
||||
@@ -6178,7 +6226,6 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
|
||||
mediaEditor.setDrawingAndEntities(data: nil, image: mediaEditor.values.drawing, entities: codableEntities)
|
||||
|
||||
let isSticker = toStickerResource != nil
|
||||
|
||||
if !isSticker {
|
||||
self.previousSavedValues = mediaEditor.values
|
||||
self.isSavingAvailable = false
|
||||
@@ -6207,8 +6254,10 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
|
||||
}
|
||||
|
||||
if mediaEditor.resultIsVideo {
|
||||
mediaEditor.maybePauseVideo()
|
||||
self.node.entitiesView.pause()
|
||||
if !isSticker {
|
||||
mediaEditor.maybePauseVideo()
|
||||
self.node.entitiesView.pause()
|
||||
}
|
||||
|
||||
let exportSubject: Signal<MediaEditorVideoExport.Subject, NoError>
|
||||
switch subject {
|
||||
@@ -6293,8 +6342,10 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
|
||||
switch status {
|
||||
case .completed:
|
||||
self.videoExport = nil
|
||||
if let toStickerResource, let data = try? Data(contentsOf: URL(fileURLWithPath: outputPath)) {
|
||||
self.context.account.postbox.mediaBox.storeResourceData(toStickerResource.id, data: data)
|
||||
if let toStickerResource {
|
||||
if let data = try? Data(contentsOf: URL(fileURLWithPath: outputPath)) {
|
||||
self.context.account.postbox.mediaBox.storeResourceData(toStickerResource.id, data: data, synchronous: true)
|
||||
}
|
||||
} else {
|
||||
saveToPhotos(outputPath, true)
|
||||
self.node.presentSaveTooltip()
|
||||
@@ -6337,16 +6388,18 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
|
||||
}
|
||||
|
||||
fileprivate func cancelVideoExport() {
|
||||
if let videoExport = self.videoExport {
|
||||
self.previousSavedValues = nil
|
||||
|
||||
videoExport.cancel()
|
||||
self.videoExport = nil
|
||||
self.exportDisposable.set(nil)
|
||||
|
||||
self.node.mediaEditor?.play()
|
||||
self.node.entitiesView.play()
|
||||
guard let videoExport = self.videoExport else {
|
||||
return
|
||||
}
|
||||
videoExport.cancel()
|
||||
|
||||
self.videoExport = nil
|
||||
self.exportDisposable.set(nil)
|
||||
|
||||
self.previousSavedValues = nil
|
||||
|
||||
self.node.mediaEditor?.play()
|
||||
self.node.entitiesView.play()
|
||||
}
|
||||
|
||||
public func updateEditProgress(_ progress: Float, cancel: @escaping () -> Void) {
|
||||
|
||||
Reference in New Issue
Block a user