Various fixes

This commit is contained in:
Ilya Laktyushin
2023-12-20 20:22:11 +04:00
parent 2f0070cccb
commit 4a4917f704
14 changed files with 182 additions and 84 deletions

View File

@@ -10777,3 +10777,5 @@ Sorry for the inconvenience.";
"ChatList.PremiumGiftInSettingsInfo" = "You can gift **Telegram Premium** to a friend later in **Settings**."; "ChatList.PremiumGiftInSettingsInfo" = "You can gift **Telegram Premium** to a friend later in **Settings**.";
"ChannelAppearance.BoostLevel" = "Level %@"; "ChannelAppearance.BoostLevel" = "Level %@";
"Message.FullDateFormat" = "%1$@, %2$@";

View File

@@ -276,21 +276,28 @@ public class DrawingStickerEntityView: DrawingEntityView {
self.animatedImageView = imageView self.animatedImageView = imageView
self.addSubview(imageView) self.addSubview(imageView)
self.setNeedsLayout() self.setNeedsLayout()
} else if case let .message(_, innerFile, _) = self.stickerEntity.content { } else if case .message = self.stickerEntity.content {
let imageView = UIImageView() if let image = self.stickerEntity.renderImage {
imageView.contentMode = .scaleAspectFit self.setupWithImage(image)
imageView.image = self.stickerEntity.renderImage }
self.animatedImageView = imageView
self.addSubview(imageView)
self.setNeedsLayout()
let _ = innerFile
// if let innerFile, innerFile.isAnimated {
// self.setupWithVideo(innerFile)
// }
} }
} }
private func setupWithImage(_ image: UIImage) {
let imageView: UIImageView
if let current = self.animatedImageView {
imageView = current
} else {
imageView = UIImageView()
imageView.contentMode = .scaleAspectFit
self.addSubview(imageView)
self.animatedImageView = imageView
}
imageView.image = image
self.currentSize = nil
self.setNeedsLayout()
}
private func setupWithVideo(_ file: TelegramMediaFile) { private func setupWithVideo(_ file: TelegramMediaFile) {
let videoNode = UniversalVideoNode( let videoNode = UniversalVideoNode(
postbox: self.context.account.postbox, postbox: self.context.account.postbox,
@@ -366,10 +373,10 @@ public class DrawingStickerEntityView: DrawingEntityView {
self.applyVisibility() self.applyVisibility()
} }
private var isNight = false public var isNightTheme = false {
public func toggleNightTheme() { didSet {
self.isNight = !self.isNight self.animatedImageView?.image = self.isNightTheme ? self.stickerEntity.secondaryRenderImage : self.stickerEntity.renderImage
self.animatedImageView?.image = self.isNight ? self.stickerEntity.secondaryRenderImage : self.stickerEntity.renderImage }
} }
func applyVisibility() { func applyVisibility() {
@@ -615,6 +622,13 @@ public class DrawingStickerEntityView: DrawingEntityView {
self.transform = CGAffineTransformScale(CGAffineTransformMakeRotation(self.stickerEntity.rotation), self.stickerEntity.scale, self.stickerEntity.scale) self.transform = CGAffineTransformScale(CGAffineTransformMakeRotation(self.stickerEntity.rotation), self.stickerEntity.scale, self.stickerEntity.scale)
self.updateAnimationColor() self.updateAnimationColor()
if case .message = self.stickerEntity.content, self.animatedImageView == nil {
let image = self.isNightTheme ? self.stickerEntity.secondaryRenderImage : self.stickerEntity.renderImage
if let image {
self.setupWithImage(image)
}
}
self.updateMirroring(animated: animated) self.updateMirroring(animated: animated)

View File

@@ -634,8 +634,8 @@ public final class ChatMessageAttachedContentNode: ASDisplayNode {
let statusLayoutAndContinueValue = makeStatusLayout(ChatMessageDateAndStatusNode.Arguments( let statusLayoutAndContinueValue = makeStatusLayout(ChatMessageDateAndStatusNode.Arguments(
context: context, context: context,
presentationData: presentationData, presentationData: presentationData,
edited: edited, edited: edited && !isPreview,
impressionCount: viewCount, impressionCount: !isPreview ? viewCount : nil,
dateText: dateText, dateText: dateText,
type: statusType, type: statusType,
layoutInput: .trailingContent( layoutInput: .trailingContent(

View File

@@ -2093,7 +2093,7 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
context: item.context, context: item.context,
presentationData: item.presentationData, presentationData: item.presentationData,
edited: edited && !item.presentationData.isPreview, edited: edited && !item.presentationData.isPreview,
impressionCount: viewCount, impressionCount: !item.presentationData.isPreview ? viewCount : nil,
dateText: dateText, dateText: dateText,
type: statusType, type: statusType,
layoutInput: .standalone(reactionSettings: shouldDisplayInlineDateReactions(message: item.message, isPremium: item.associatedData.isPremium, forceInline: item.associatedData.forceInlineReactions) ? ChatMessageDateAndStatusNode.StandaloneReactionSettings() : nil), layoutInput: .standalone(reactionSettings: shouldDisplayInlineDateReactions(message: item.message, isPremium: item.associatedData.isPremium, forceInline: item.associatedData.forceInlineReactions) ? ChatMessageDateAndStatusNode.StandaloneReactionSettings() : nil),

View File

@@ -111,9 +111,7 @@ public func stringForMessageTimestampStatus(accountPeerId: PeerId, message: Mess
} else { } else {
dayText = strings.Date_ChatDateHeaderYear(monthAtIndex(Int(timeinfo.tm_mon), strings: strings), "\(timeinfo.tm_mday)", "\(1900 + timeinfo.tm_year)").string dayText = strings.Date_ChatDateHeaderYear(monthAtIndex(Int(timeinfo.tm_mon), strings: strings), "\(timeinfo.tm_mday)", "\(1900 + timeinfo.tm_year)").string
} }
dateText = strings.Message_FullDateFormat(dayText, stringForMessageTimestamp(timestamp: timestamp, dateTimeFormat: dateTimeFormat)).string
//TODO:localize
dateText = "\(dayText), \(stringForMessageTimestamp(timestamp: timestamp, dateTimeFormat: dateTimeFormat))"
} }
else if let forwardInfo = message.forwardInfo, forwardInfo.flags.contains(.isImported) { else if let forwardInfo = message.forwardInfo, forwardInfo.flags.contains(.isImported) {
dateText = strings.Message_ImportedDateFormat(dateStringForDay(strings: strings, dateTimeFormat: dateTimeFormat, timestamp: forwardInfo.date), stringForMessageTimestamp(timestamp: forwardInfo.date, dateTimeFormat: dateTimeFormat), dateText).string dateText = strings.Message_ImportedDateFormat(dateStringForDay(strings: strings, dateTimeFormat: dateTimeFormat, timestamp: forwardInfo.date), stringForMessageTimestamp(timestamp: forwardInfo.date, dateTimeFormat: dateTimeFormat), dateText).string

View File

@@ -508,7 +508,7 @@ public class ChatMessageGiveawayBubbleContentNode: ChatMessageBubbleContentNode,
context: item.context, context: item.context,
presentationData: item.presentationData, presentationData: item.presentationData,
edited: edited, edited: edited,
impressionCount: viewCount, impressionCount: !item.presentationData.isPreview ? viewCount : nil,
dateText: dateText, dateText: dateText,
type: statusType, type: statusType,
layoutInput: .trailingContent(contentWidth: 1000.0, reactionSettings: shouldDisplayInlineDateReactions(message: item.message, isPremium: item.associatedData.isPremium, forceInline: item.associatedData.forceInlineReactions) ? ChatMessageDateAndStatusNode.TrailingReactionSettings(displayInline: true, preferAdditionalInset: false) : nil), layoutInput: .trailingContent(contentWidth: 1000.0, reactionSettings: shouldDisplayInlineDateReactions(message: item.message, isPremium: item.associatedData.isPremium, forceInline: item.associatedData.forceInlineReactions) ? ChatMessageDateAndStatusNode.TrailingReactionSettings(displayInline: true, preferAdditionalInset: false) : nil),

View File

@@ -919,8 +919,8 @@ public final class ChatMessageInteractiveFileNode: ASDisplayNode {
statusSuggestedWidthAndContinue = statusLayout(ChatMessageDateAndStatusNode.Arguments( statusSuggestedWidthAndContinue = statusLayout(ChatMessageDateAndStatusNode.Arguments(
context: arguments.context, context: arguments.context,
presentationData: arguments.presentationData, presentationData: arguments.presentationData,
edited: edited, edited: edited && !arguments.presentationData.isPreview,
impressionCount: viewCount, impressionCount: !arguments.presentationData.isPreview ? viewCount : nil,
dateText: dateText, dateText: dateText,
type: statusType, type: statusType,
layoutInput: statusLayoutInput, layoutInput: statusLayoutInput,

View File

@@ -554,7 +554,7 @@ public class ChatMessageInteractiveInstantVideoNode: ASDisplayNode {
context: item.context, context: item.context,
presentationData: item.presentationData, presentationData: item.presentationData,
edited: edited && !sentViaBot && !item.presentationData.isPreview, edited: edited && !sentViaBot && !item.presentationData.isPreview,
impressionCount: item.presentationData.isPreview ? nil : viewCount, impressionCount: !item.presentationData.isPreview ? viewCount : nil,
dateText: dateText, dateText: dateText,
type: statusType, type: statusType,
layoutInput: .standalone(reactionSettings: shouldDisplayInlineDateReactions(message: item.message, isPremium: item.associatedData.isPremium, forceInline: item.associatedData.forceInlineReactions) ? ChatMessageDateAndStatusNode.StandaloneReactionSettings() : nil), layoutInput: .standalone(reactionSettings: shouldDisplayInlineDateReactions(message: item.message, isPremium: item.associatedData.isPremium, forceInline: item.associatedData.forceInlineReactions) ? ChatMessageDateAndStatusNode.StandaloneReactionSettings() : nil),

View File

@@ -862,7 +862,7 @@ public final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTr
context: context, context: context,
presentationData: presentationData, presentationData: presentationData,
edited: dateAndStatus.edited && !presentationData.isPreview, edited: dateAndStatus.edited && !presentationData.isPreview,
impressionCount: dateAndStatus.viewCount, impressionCount: !presentationData.isPreview ? dateAndStatus.viewCount : nil,
dateText: dateAndStatus.dateText, dateText: dateAndStatus.dateText,
type: dateAndStatus.type, type: dateAndStatus.type,
layoutInput: .standalone(reactionSettings: shouldDisplayInlineDateReactions(message: message, isPremium: associatedData.isPremium, forceInline: associatedData.forceInlineReactions) ? ChatMessageDateAndStatusNode.StandaloneReactionSettings() : nil), layoutInput: .standalone(reactionSettings: shouldDisplayInlineDateReactions(message: message, isPremium: associatedData.isPremium, forceInline: associatedData.forceInlineReactions) ? ChatMessageDateAndStatusNode.StandaloneReactionSettings() : nil),

View File

@@ -267,7 +267,7 @@ public class ChatMessageMapBubbleContentNode: ChatMessageBubbleContentNode {
context: item.context, context: item.context,
presentationData: item.presentationData, presentationData: item.presentationData,
edited: edited, edited: edited,
impressionCount: viewCount, impressionCount: !item.presentationData.isPreview ? viewCount : nil,
dateText: dateText, dateText: dateText,
type: statusType, type: statusType,
layoutInput: .standalone(reactionSettings: shouldDisplayInlineDateReactions(message: item.message, isPremium: item.associatedData.isPremium, forceInline: item.associatedData.forceInlineReactions) ? ChatMessageDateAndStatusNode.StandaloneReactionSettings() : nil), layoutInput: .standalone(reactionSettings: shouldDisplayInlineDateReactions(message: item.message, isPremium: item.associatedData.isPremium, forceInline: item.associatedData.forceInlineReactions) ? ChatMessageDateAndStatusNode.StandaloneReactionSettings() : nil),

View File

@@ -564,7 +564,7 @@ public class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode {
context: item.context, context: item.context,
presentationData: item.presentationData, presentationData: item.presentationData,
edited: edited && !item.presentationData.isPreview, edited: edited && !item.presentationData.isPreview,
impressionCount: viewCount, impressionCount: !item.presentationData.isPreview ? viewCount : nil,
dateText: dateText, dateText: dateText,
type: statusType, type: statusType,
layoutInput: dateLayoutInput, layoutInput: dateLayoutInput,

View File

@@ -73,6 +73,7 @@ public final class MediaEditorDraft: Codable, Equatable {
case values case values
case caption case caption
case privacy case privacy
case forwardInfo
case timestamp case timestamp
case locationLatitude case locationLatitude
case locationLongitude case locationLongitude
@@ -87,11 +88,12 @@ public final class MediaEditorDraft: Codable, Equatable {
public let values: MediaEditorValues public let values: MediaEditorValues
public let caption: NSAttributedString public let caption: NSAttributedString
public let privacy: MediaEditorResultPrivacy? public let privacy: MediaEditorResultPrivacy?
public let forwardInfo: StoryId?
public let timestamp: Int32 public let timestamp: Int32
public let location: CLLocationCoordinate2D? public let location: CLLocationCoordinate2D?
public let expiresOn: Int32? public let expiresOn: Int32?
public init(path: String, isVideo: Bool, thumbnail: UIImage, dimensions: PixelDimensions, duration: Double?, values: MediaEditorValues, caption: NSAttributedString, privacy: MediaEditorResultPrivacy?, timestamp: Int32, location: CLLocationCoordinate2D?, expiresOn: Int32?) { public init(path: String, isVideo: Bool, thumbnail: UIImage, dimensions: PixelDimensions, duration: Double?, values: MediaEditorValues, caption: NSAttributedString, privacy: MediaEditorResultPrivacy?, forwardInfo: StoryId?, timestamp: Int32, location: CLLocationCoordinate2D?, expiresOn: Int32?) {
self.path = path self.path = path
self.isVideo = isVideo self.isVideo = isVideo
self.thumbnail = thumbnail self.thumbnail = thumbnail
@@ -100,6 +102,7 @@ public final class MediaEditorDraft: Codable, Equatable {
self.values = values self.values = values
self.caption = caption self.caption = caption
self.privacy = privacy self.privacy = privacy
self.forwardInfo = forwardInfo
self.timestamp = timestamp self.timestamp = timestamp
self.location = location self.location = location
self.expiresOn = expiresOn self.expiresOn = expiresOn
@@ -135,6 +138,8 @@ public final class MediaEditorDraft: Codable, Equatable {
self.privacy = nil self.privacy = nil
} }
self.forwardInfo = try container.decodeIfPresent(StoryId.self, forKey: .forwardInfo)
self.timestamp = try container.decodeIfPresent(Int32.self, forKey: .timestamp) ?? 1688909663 self.timestamp = try container.decodeIfPresent(Int32.self, forKey: .timestamp) ?? 1688909663
if let latitude = try container.decodeIfPresent(Double.self, forKey: .locationLatitude), let longitude = try container.decodeIfPresent(Double.self, forKey: .locationLongitude) { if let latitude = try container.decodeIfPresent(Double.self, forKey: .locationLatitude), let longitude = try container.decodeIfPresent(Double.self, forKey: .locationLongitude) {
@@ -172,6 +177,8 @@ public final class MediaEditorDraft: Codable, Equatable {
} else { } else {
try container.encodeNil(forKey: .privacy) try container.encodeNil(forKey: .privacy)
} }
try container.encodeIfPresent(self.forwardInfo, forKey: .forwardInfo)
try container.encode(self.timestamp, forKey: .timestamp) try container.encode(self.timestamp, forKey: .timestamp)
if let location = self.location { if let location = self.location {

View File

@@ -52,6 +52,7 @@ extension MediaEditorScreen {
let values = mediaEditor.values let values = mediaEditor.values
let privacy = self.state.privacy let privacy = self.state.privacy
let forwardSource = self.forwardSource
let caption = self.getCaption() let caption = self.getCaption()
let duration = mediaEditor.duration ?? 0.0 let duration = mediaEditor.duration ?? 0.0
@@ -85,29 +86,74 @@ extension MediaEditorScreen {
guard let resultImage else { guard let resultImage else {
return return
} }
let fittedSize = resultImage.size.aspectFitted(CGSize(width: 128.0, height: 128.0)) enum MediaInput {
case image(image: UIImage, dimensions: PixelDimensions)
let context = self.context case video(path: String, dimensions: PixelDimensions, duration: Double)
let saveImageDraft: (UIImage, PixelDimensions) -> Void = { image, dimensions in
if let thumbnailImage = generateScaledImage(image: resultImage, size: fittedSize) { var isVideo: Bool {
let path = "\(Int64.random(in: .min ... .max)).jpg" switch self {
if let data = image.jpegData(compressionQuality: 0.87) { case .video:
let draft = MediaEditorDraft(path: path, isVideo: false, thumbnail: thumbnailImage, dimensions: dimensions, duration: nil, values: values, caption: caption, privacy: privacy, timestamp: timestamp, location: location, expiresOn: expiresOn) return true
try? data.write(to: URL(fileURLWithPath: draft.fullPath(engine: context.engine))) case .image:
if let id { return false
saveStorySource(engine: context.engine, item: draft, peerId: context.account.peerId, id: id) }
} else { }
addStoryDraft(engine: context.engine, item: draft)
} var dimensions: PixelDimensions {
switch self {
case let .image(_, dimensions):
return dimensions
case let .video(_, dimensions, _):
return dimensions
}
}
var duration: Double? {
switch self {
case .image:
return nil
case let .video(_, _, duration):
return duration
}
}
var fileExtension: String {
switch self {
case .image:
return "jpg"
case .video:
return "mp4"
} }
} }
} }
let saveVideoDraft: (String, PixelDimensions, Double) -> Void = { videoPath, dimensions, duration in let context = self.context
func innerSaveDraft(media: MediaInput) {
let fittedSize = resultImage.size.aspectFitted(CGSize(width: 128.0, height: 128.0))
if let thumbnailImage = generateScaledImage(image: resultImage, size: fittedSize) { if let thumbnailImage = generateScaledImage(image: resultImage, size: fittedSize) {
let path = "\(Int64.random(in: .min ... .max)).mp4" let path = "\(Int64.random(in: .min ... .max)).\(media.fileExtension)"
let draft = MediaEditorDraft(path: path, isVideo: true, thumbnail: thumbnailImage, dimensions: dimensions, duration: duration, values: values, caption: caption, privacy: privacy, timestamp: timestamp, location: location, expiresOn: expiresOn) let draft = MediaEditorDraft(
try? FileManager.default.copyItem(atPath: videoPath, toPath: draft.fullPath(engine: context.engine)) path: path,
isVideo: media.isVideo,
thumbnail: thumbnailImage,
dimensions: media.dimensions,
duration: media.duration,
values: values,
caption: caption,
privacy: privacy,
forwardInfo: forwardSource.flatMap { StoryId(peerId: $0.0.id, id: $0.1.id) },
timestamp: timestamp,
location: location,
expiresOn: expiresOn
)
switch media {
case let .image(image, _):
if let data = image.jpegData(compressionQuality: 0.87) {
try? data.write(to: URL(fileURLWithPath: draft.fullPath(engine: context.engine)))
}
case let .video(path, _, _):
try? FileManager.default.copyItem(atPath: path, toPath: draft.fullPath(engine: context.engine))
}
if let id { if let id {
saveStorySource(engine: context.engine, item: draft, peerId: context.account.peerId, id: id) saveStorySource(engine: context.engine, item: draft, peerId: context.account.peerId, id: id)
} else { } else {
@@ -118,14 +164,14 @@ extension MediaEditorScreen {
switch subject { switch subject {
case let .image(image, dimensions, _, _): case let .image(image, dimensions, _, _):
saveImageDraft(image, dimensions) innerSaveDraft(media: .image(image: image, dimensions: dimensions))
case let .video(path, _, _, _, _, dimensions, _, _, _): case let .video(path, _, _, _, _, dimensions, _, _, _):
saveVideoDraft(path, dimensions, duration) innerSaveDraft(media: .video(path: path, dimensions: dimensions, duration: duration))
case let .asset(asset): case let .asset(asset):
if asset.mediaType == .video { if asset.mediaType == .video {
PHImageManager.default().requestAVAsset(forVideo: asset, options: nil) { avAsset, _, _ in PHImageManager.default().requestAVAsset(forVideo: asset, options: nil) { avAsset, _, _ in
if let urlAsset = avAsset as? AVURLAsset { if let urlAsset = avAsset as? AVURLAsset {
saveVideoDraft(urlAsset.url.relativePath, PixelDimensions(width: Int32(asset.pixelWidth), height: Int32(asset.pixelHeight)), duration) innerSaveDraft(media: .video(path: urlAsset.url.relativePath, dimensions: PixelDimensions(width: Int32(asset.pixelWidth), height: Int32(asset.pixelHeight)), duration: duration))
} }
} }
} else { } else {
@@ -133,19 +179,21 @@ extension MediaEditorScreen {
options.deliveryMode = .highQualityFormat options.deliveryMode = .highQualityFormat
PHImageManager.default().requestImage(for: asset, targetSize: PHImageManagerMaximumSize, contentMode: .default, options: options) { image, _ in PHImageManager.default().requestImage(for: asset, targetSize: PHImageManagerMaximumSize, contentMode: .default, options: options) { image, _ in
if let image { if let image {
saveImageDraft(image, PixelDimensions(image.size)) innerSaveDraft(media: .image(image: image, dimensions: PixelDimensions(image.size)))
} }
} }
} }
case let .draft(draft, _): case let .draft(draft, _):
if draft.isVideo { if draft.isVideo {
saveVideoDraft(draft.fullPath(engine: context.engine), draft.dimensions, draft.duration ?? 0.0) innerSaveDraft(media: .video(path: draft.fullPath(engine: context.engine), dimensions: draft.dimensions, duration: draft.duration ?? 0.0))
} else if let image = UIImage(contentsOfFile: draft.fullPath(engine: context.engine)) { } else if let image = UIImage(contentsOfFile: draft.fullPath(engine: context.engine)) {
saveImageDraft(image, draft.dimensions) innerSaveDraft(media: .image(image: image, dimensions: draft.dimensions))
} }
removeStoryDraft(engine: self.context.engine, path: draft.path, delete: false) removeStoryDraft(engine: self.context.engine, path: draft.path, delete: false)
case let .message(messageId): case .message:
let _ = messageId if let pixel = generateSingleColorImage(size: CGSize(width: 1, height: 1), color: .black) {
innerSaveDraft(media: .image(image: pixel, dimensions: PixelDimensions(width: 1080, height: 1920)))
}
} }
}) })
} }

View File

@@ -668,7 +668,7 @@ final class MediaEditorScreenComponent: Component {
if self.component == nil { if self.component == nil {
if let initialCaption = controller.initialCaption { if let initialCaption = controller.initialCaption {
self.inputPanelExternalState.initialText = initialCaption self.inputPanelExternalState.initialText = initialCaption
} else if case let .draft(draft, _) = controller.node.subject { } else if case let .draft(draft, _) = controller.node.actualSubject {
self.inputPanelExternalState.initialText = draft.caption self.inputPanelExternalState.initialText = draft.caption
} }
} }
@@ -1633,7 +1633,7 @@ final class MediaEditorScreenComponent: Component {
mediaEditor.toggleNightTheme() mediaEditor.toggleNightTheme()
controller.node.entitiesView.eachView { view in controller.node.entitiesView.eachView { view in
if let stickerEntityView = view as? DrawingStickerEntityView { if let stickerEntityView = view as? DrawingStickerEntityView {
stickerEntityView.toggleNightTheme() stickerEntityView.isNightTheme = mediaEditor.values.nightTheme
} }
} }
} }
@@ -2036,6 +2036,8 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
private let initializationTimestamp = CACurrentMediaTime() private let initializationTimestamp = CACurrentMediaTime()
var subject: MediaEditorScreen.Subject? var subject: MediaEditorScreen.Subject?
var actualSubject: MediaEditorScreen.Subject?
private var subjectDisposable: Disposable? private var subjectDisposable: Disposable?
private var appInForegroundDisposable: Disposable? private var appInForegroundDisposable: Disposable?
@@ -2270,7 +2272,19 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
} }
private func setup(with subject: MediaEditorScreen.Subject) { private func setup(with subject: MediaEditorScreen.Subject) {
self.subject = subject self.actualSubject = subject
var effectiveSubject = subject
if case let .draft(draft, _ ) = subject {
for entity in draft.values.entities {
if case let .sticker(sticker) = entity, case let .message(ids, _, _) = sticker.content {
effectiveSubject = .message(ids)
break
}
}
}
self.subject = effectiveSubject
guard let controller = self.controller else { guard let controller = self.controller else {
return return
} }
@@ -2299,7 +2313,7 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
controller.isSavingAvailable = isSavingAvailable controller.isSavingAvailable = isSavingAvailable
controller.requestLayout(transition: .immediate) controller.requestLayout(transition: .immediate)
let mediaDimensions = subject.dimensions let mediaDimensions = effectiveSubject.dimensions
let maxSide: CGFloat = 1920.0 / UIScreen.main.scale let maxSide: CGFloat = 1920.0 / UIScreen.main.scale
let fittedSize = mediaDimensions.cgSize.fitted(CGSize(width: maxSide, height: maxSide)) let fittedSize = mediaDimensions.cgSize.fitted(CGSize(width: maxSide, height: maxSide))
let mediaEntity = DrawingMediaEntity(size: fittedSize) let mediaEntity = DrawingMediaEntity(size: fittedSize)
@@ -2354,7 +2368,7 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
} }
} }
let mediaEditor = MediaEditor(context: self.context, subject: subject.editorSubject, values: initialValues, hasHistogram: true) let mediaEditor = MediaEditor(context: self.context, subject: effectiveSubject.editorSubject, values: initialValues, hasHistogram: true)
if let initialVideoPosition = controller.initialVideoPosition { if let initialVideoPosition = controller.initialVideoPosition {
mediaEditor.seek(initialVideoPosition, andPlay: true) mediaEditor.seek(initialVideoPosition, andPlay: true)
} }
@@ -2372,12 +2386,12 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
} }
} }
if case .message = subject { if case .message = effectiveSubject {
} else { } else {
self.readyValue.set(.single(true)) self.readyValue.set(.single(true))
} }
if case let .image(_, _, additionalImage, position) = subject, let additionalImage { if case let .image(_, _, additionalImage, position) = effectiveSubject, let additionalImage {
let image = generateImage(CGSize(width: additionalImage.size.width, height: additionalImage.size.width), contextGenerator: { size, context in let image = generateImage(CGSize(width: additionalImage.size.width, height: additionalImage.size.width), contextGenerator: { size, context in
let bounds = CGRect(origin: .zero, size: size) let bounds = CGRect(origin: .zero, size: size)
context.clear(bounds) context.clear(bounds)
@@ -2393,7 +2407,7 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
imageEntity.scale = 1.625 imageEntity.scale = 1.625
imageEntity.position = position.getPosition(storyDimensions) imageEntity.position = position.getPosition(storyDimensions)
self.entitiesView.add(imageEntity, announce: false) self.entitiesView.add(imageEntity, announce: false)
} else if case let .video(_, _, mirror, additionalVideoPath, _, _, _, changes, position) = subject { } else if case let .video(_, _, mirror, additionalVideoPath, _, _, _, changes, position) = effectiveSubject {
mediaEditor.setVideoIsMirrored(mirror) mediaEditor.setVideoIsMirrored(mirror)
if let additionalVideoPath { if let additionalVideoPath {
let videoEntity = DrawingStickerEntity(content: .dualVideoReference(false)) let videoEntity = DrawingStickerEntity(content: .dualVideoReference(false))
@@ -2412,7 +2426,8 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
} }
} }
} }
} else if case let .message(messageIds) = subject { } else if case let .message(messageIds) = effectiveSubject {
let isNightTheme = mediaEditor.values.nightTheme
let _ = ((self.context.engine.data.get( let _ = ((self.context.engine.data.get(
EngineDataMap(messageIds.map(TelegramEngine.EngineData.Item.Messages.Message.init(id:))) EngineDataMap(messageIds.map(TelegramEngine.EngineData.Item.Messages.Message.init(id:)))
)) ))
@@ -2431,16 +2446,30 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
let renderer = DrawingMessageRenderer(context: self.context, messages: messages) let renderer = DrawingMessageRenderer(context: self.context, messages: messages)
renderer.render(completion: { size, dayImage, nightImage in renderer.render(completion: { size, dayImage, nightImage in
let messageEntity = DrawingStickerEntity(content: .message(messageIds, maybeFile?.isVideo == true ? maybeFile : nil, size)) if case .draft = subject, let existingEntityView = self.entitiesView.getView(where: { entityView in
messageEntity.renderImage = dayImage if let stickerEntityView = entityView as? DrawingStickerEntityView, case .message = (stickerEntityView.entity as! DrawingStickerEntity).content {
messageEntity.secondaryRenderImage = nightImage return true
messageEntity.referenceDrawingSize = storyDimensions } else {
messageEntity.position = CGPoint(x: storyDimensions.width / 2.0, y: storyDimensions.height / 2.0) return false
}
let fraction = max(size.width, size.height) / 353.0 }) as? DrawingStickerEntityView {
messageEntity.scale = min(6.0, 3.3 * fraction) existingEntityView.isNightTheme = isNightTheme
let messageEntity = existingEntityView.entity as! DrawingStickerEntity
self.entitiesView.add(messageEntity, announce: false) messageEntity.renderImage = dayImage
messageEntity.secondaryRenderImage = nightImage
existingEntityView.update(animated: false)
} else {
let messageEntity = DrawingStickerEntity(content: .message(messageIds, maybeFile?.isVideo == true ? maybeFile : nil, size))
messageEntity.renderImage = dayImage
messageEntity.secondaryRenderImage = nightImage
messageEntity.referenceDrawingSize = storyDimensions
messageEntity.position = CGPoint(x: storyDimensions.width / 2.0, y: storyDimensions.height / 2.0)
let fraction = max(size.width, size.height) / 353.0
messageEntity.scale = min(6.0, 3.3 * fraction)
self.entitiesView.add(messageEntity, announce: false)
}
self.readyValue.set(.single(true)) self.readyValue.set(.single(true))
}) })
@@ -2477,7 +2506,7 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
if controller.isEmbeddedEditor == true { if controller.isEmbeddedEditor == true {
mediaEditor.onFirstDisplay = { [weak self] in mediaEditor.onFirstDisplay = { [weak self] in
if let self { if let self {
if subject.isPhoto { if effectiveSubject.isPhoto {
self.previewContainerView.layer.allowsGroupOpacity = true self.previewContainerView.layer.allowsGroupOpacity = true
self.previewContainerView.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.25, completion: { _ in self.previewContainerView.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.25, completion: { _ in
self.previewContainerView.layer.allowsGroupOpacity = false self.previewContainerView.layer.allowsGroupOpacity = false
@@ -2955,7 +2984,7 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
} }
} }
} else { } else {
if case .message = self.subject, let layout = self.validLayout { if case .message = self.actualSubject, let layout = self.validLayout {
self.layer.animatePosition(from: CGPoint(x: 0.0, y: layout.size.height), to: .zero, duration: 0.4, timingFunction: kCAMediaTimingFunctionSpring, additive: true) self.layer.animatePosition(from: CGPoint(x: 0.0, y: layout.size.height), to: .zero, duration: 0.4, timingFunction: kCAMediaTimingFunctionSpring, additive: true)
completion() completion()
} else if let view = self.componentHost.view as? MediaEditorScreenComponent.View { } else if let view = self.componentHost.view as? MediaEditorScreenComponent.View {
@@ -4862,7 +4891,7 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
let presentationData = self.context.sharedContext.currentPresentationData.with { $0 } let presentationData = self.context.sharedContext.currentPresentationData.with { $0 }
let title: String let title: String
let save: String let save: String
if case .draft = self.node.subject { if case .draft = self.node.actualSubject {
title = presentationData.strings.Story_Editor_DraftDiscardDraft title = presentationData.strings.Story_Editor_DraftDiscardDraft
save = presentationData.strings.Story_Editor_DraftKeepDraft save = presentationData.strings.Story_Editor_DraftKeepDraft
} else { } else {
@@ -4898,7 +4927,7 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
self.dismissAllTooltips() self.dismissAllTooltips()
var showDraftTooltip = saveDraft var showDraftTooltip = saveDraft
if let subject = self.node.subject, case .draft = subject { if let subject = self.node.actualSubject, case .draft = subject {
showDraftTooltip = false showDraftTooltip = false
} }
if saveDraft { if saveDraft {
@@ -4957,7 +4986,7 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
private var didComplete = false private var didComplete = false
func requestCompletion(animated: Bool) { func requestCompletion(animated: Bool) {
guard let mediaEditor = self.node.mediaEditor, let subject = self.node.subject, !self.didComplete else { guard let mediaEditor = self.node.mediaEditor, let subject = self.node.subject, let actualSubject = self.node.actualSubject, !self.didComplete else {
return return
} }
@@ -4983,14 +5012,14 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
var hasEntityChanges = false var hasEntityChanges = false
let randomId: Int64 let randomId: Int64
if case let .draft(_, id) = subject, let id { if case let .draft(_, id) = actualSubject, let id {
randomId = id randomId = id
} else { } else {
randomId = Int64.random(in: .min ... .max) randomId = Int64.random(in: .min ... .max)
} }
var mediaAreas: [MediaArea] = [] var mediaAreas: [MediaArea] = []
if case let .draft(draft, _) = subject { if case let .draft(draft, _) = actualSubject {
if draft.values.entities != codableEntities { if draft.values.entities != codableEntities {
hasEntityChanges = true hasEntityChanges = true
} }
@@ -5281,7 +5310,7 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
} }
}) })
if case let .draft(draft, id) = subject, id == nil { if case let .draft(draft, id) = actualSubject, id == nil {
removeStoryDraft(engine: self.context.engine, path: draft.path, delete: false) removeStoryDraft(engine: self.context.engine, path: draft.path, delete: false)
} }
} else { } else {
@@ -5299,7 +5328,7 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
} }
}) })
}) })
if case let .draft(draft, id) = subject, id == nil { if case let .draft(draft, id) = actualSubject, id == nil {
removeStoryDraft(engine: self.context.engine, path: draft.path, delete: true) removeStoryDraft(engine: self.context.engine, path: draft.path, delete: true)
} }
} }