Various fixes

This commit is contained in:
Ilya Laktyushin 2024-07-25 21:44:05 +02:00
parent c1fc0da041
commit 4414753d7f
6 changed files with 79 additions and 50 deletions

View File

@ -12646,3 +12646,6 @@ Sorry for the inconvenience.";
"WebBrowser.Download.Confirmation" = "Do you want to download \"%@\"?";
"WebBrowser.Download.Download" = "Download";
"Story.Cover" = "Story Cover";
"Story.SaveCover" = "Save Cover";

View File

@ -623,7 +623,13 @@ final class BrowserWebContent: UIView, BrowserContent, WKNavigationDelegate, WKU
if navigationResponse.canShowMIMEType {
decisionHandler(.allow)
} else if #available(iOS 14.5, *) {
decisionHandler(.download)
self.presentDownloadConfirmation(fileName: navigationResponse.response.suggestedFilename ?? "file", proceed: { download in
if download {
decisionHandler(.download)
} else {
decisionHandler(.cancel)
}
})
} else {
decisionHandler(.cancel)
}

View File

@ -499,6 +499,9 @@ public final class MediaEditor {
} else if case let .video(_, _, _, _, _, duration) = subject {
self.playerPlaybackState = PlaybackState(duration: duration, position: 0.0, isPlaying: false, hasAudio: true)
self.playerPlaybackStatePromise.set(.single(self.playerPlaybackState))
} else if case let .draft(mediaEditorDraft) = subject, mediaEditorDraft.isVideo {
self.playerPlaybackState = PlaybackState(duration: mediaEditorDraft.duration ?? 0.0, position: 0.0, isPlaying: false, hasAudio: true)
self.playerPlaybackStatePromise.set(.single(self.playerPlaybackState))
}
}

View File

@ -154,11 +154,15 @@ public extension MediaEditorScreen {
})
} else {
var updatedText: String?
var updatedCoverTimestamp: Double?
var updatedEntities: [MessageTextEntity]?
if result.caption.string != storyItem.text || entities != storyItem.entities {
updatedText = result.caption.string
updatedEntities = entities
}
if let coverTimestamp = result.coverTimestamp {
updatedCoverTimestamp = coverTimestamp
}
if let mediaResult = result.media {
switch mediaResult {
@ -237,8 +241,22 @@ public extension MediaEditorScreen {
default:
break
}
} else if updatedText != nil {
let _ = (context.engine.messages.editStory(peerId: peer.id, id: storyItem.id, media: nil, mediaAreas: nil, text: updatedText, entities: updatedEntities, privacy: nil)
} else if updatedText != nil || updatedCoverTimestamp != nil {
var media: EngineStoryInputMedia?
if let updatedCoverTimestamp {
if case let .file(file) = storyItem.media {
var updatedAttributes: [TelegramMediaFileAttribute] = []
for attribute in file.attributes {
if case let .Video(duration, size, flags, preloadSize, _) = attribute {
updatedAttributes.append(.Video(duration: duration, size: size, flags: flags, preloadSize: preloadSize, coverTime: updatedCoverTimestamp))
} else {
updatedAttributes.append(attribute)
}
}
media = .existing(media: file.withUpdatedAttributes(updatedAttributes))
}
}
let _ = (context.engine.messages.editStory(peerId: peer.id, id: storyItem.id, media: media, mediaAreas: nil, text: updatedText, entities: updatedEntities, privacy: nil)
|> deliverOnMainQueue).startStandalone(next: { result in
switch result {
case .completed:

View File

@ -19,41 +19,29 @@ private final class MediaCoverScreenComponent: Component {
let context: AccountContext
let mediaEditor: Signal<MediaEditor?, NoError>
let exclusive: Bool
init(
context: AccountContext,
mediaEditor: Signal<MediaEditor?, NoError>
mediaEditor: Signal<MediaEditor?, NoError>,
exclusive: Bool
) {
self.context = context
self.mediaEditor = mediaEditor
self.exclusive = exclusive
}
static func ==(lhs: MediaCoverScreenComponent, rhs: MediaCoverScreenComponent) -> Bool {
if lhs.context !== rhs.context {
return false
}
if lhs.exclusive != rhs.exclusive {
return false
}
return true
}
final class State: ComponentState {
enum ImageKey: Hashable {
case done
}
private var cachedImages: [ImageKey: UIImage] = [:]
func image(_ key: ImageKey) -> UIImage {
if let image = self.cachedImages[key] {
return image
} else {
var image: UIImage
switch key {
case .done:
image = generateTintedImage(image: UIImage(bundleImageName: "Media Editor/Done"), color: .white)!
}
cachedImages[key] = image
return image
}
}
var playerStateDisposable: Disposable?
var playerState: MediaEditorPlayerState?
@ -176,14 +164,6 @@ private final class MediaCoverScreenComponent: Component {
self.state?.updated()
}
// override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
// let result = super.hitTest(point, with: event)
// if let controller = self.environment?.controller() as? MediaCoverScreen, [.erase, .restore].contains(controller.mode), result == self.previewContainerView {
// return nil
// }
// return result
// }
func update(component: MediaCoverScreenComponent, availableSize: CGSize, state: State, environment: Environment<ViewControllerComponentContainer.Environment>, transition: ComponentTransition) -> CGSize {
let environment = environment[ViewControllerComponentContainer.Environment.self].value
self.environment = environment
@ -192,7 +172,6 @@ private final class MediaCoverScreenComponent: Component {
return .zero
}
// let isFirstTime = self.component == nil
self.component = component
self.state = state
@ -217,9 +196,9 @@ private final class MediaCoverScreenComponent: Component {
controlsBottomInset = -75.0
}
}
let previewContainerFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((availableSize.width - previewSize.width) / 2.0), y: environment.safeInsets.top), size: CGSize(width: previewSize.width, height: availableSize.height - environment.safeInsets.top - environment.safeInsets.bottom + controlsBottomInset))
let buttonsContainerFrame = CGRect(origin: CGPoint(x: 0.0, y: availableSize.height - environment.safeInsets.bottom + controlsBottomInset - 31.0), size: CGSize(width: availableSize.width, height: environment.safeInsets.bottom - controlsBottomInset))
let previewContainerFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((availableSize.width - previewSize.width) / 2.0), y: topInset), size: CGSize(width: previewSize.width, height: availableSize.height - environment.safeInsets.top - environment.safeInsets.bottom + controlsBottomInset))
let buttonsContainerFrame = CGRect(origin: CGPoint(x: 0.0, y: availableSize.height - environment.safeInsets.bottom + controlsBottomInset), size: CGSize(width: availableSize.width, height: environment.safeInsets.bottom - controlsBottomInset))
let cancelButtonSize = self.cancelButton.update(
transition: transition,
@ -235,7 +214,7 @@ private final class MediaCoverScreenComponent: Component {
containerSize: CGSize(width: 120.0, height: 44.0)
)
let cancelButtonFrame = CGRect(
origin: CGPoint(x: 16.0, y: 80.0),
origin: CGPoint(x: 16.0, y: previewContainerFrame.minY + 28.0),
size: cancelButtonSize
)
if let cancelButtonView = self.cancelButton.view {
@ -258,7 +237,7 @@ private final class MediaCoverScreenComponent: Component {
content: AnyComponentWithIdentity(
id: AnyHashable(0),
component: AnyComponent(ButtonTextContentComponent(
text: "Save Cover",
text: environment.strings.Story_SaveCover,
badge: 0,
textColor: environment.theme.list.itemCheckColors.foregroundColor,
badgeBackground: .clear,
@ -268,11 +247,16 @@ private final class MediaCoverScreenComponent: Component {
isEnabled: true,
displaysProgress: false,
action: { [weak controller, weak self] in
guard let controller else {
return
}
if let playerState = self?.state?.playerState, let mediaEditor = self?.state?.mediaEditor, let image = mediaEditor.resultImage {
mediaEditor.setCoverImageTimestamp(playerState.position)
controller?.completed(playerState.position, image)
controller.completed(playerState.position, image)
}
if !controller.exclusive {
controller.requestDismiss(animated: true)
}
controller?.requestDismiss(animated: true)
}
)
),
@ -280,7 +264,7 @@ private final class MediaCoverScreenComponent: Component {
containerSize: CGSize(width: availableSize.width - buttonSideInset * 2.0, height: 50.0)
)
let doneButtonFrame = CGRect(
origin: CGPoint(x: floor((availableSize.width - doneButtonSize.width) / 2.0), y: availableSize.height - 99.0),
origin: CGPoint(x: floor((availableSize.width - doneButtonSize.width) / 2.0), y: min(buttonsContainerFrame.minY, availableSize.height - doneButtonSize.height - buttonSideInset)),
size: doneButtonSize
)
if let doneButtonView = self.doneButton.view {
@ -292,12 +276,12 @@ private final class MediaCoverScreenComponent: Component {
let labelSize = self.label.update(
transition: transition,
component: AnyComponent(Text(text: "Story Cover", font: Font.semibold(17.0), color: UIColor(rgb: 0xffffff))),
component: AnyComponent(Text(text: environment.strings.Story_Cover, font: Font.semibold(17.0), color: UIColor(rgb: 0xffffff))),
environment: {},
containerSize: CGSize(width: availableSize.width - 88.0, height: 44.0)
)
let labelFrame = CGRect(
origin: CGPoint(x: floorToScreenPixels((availableSize.width - labelSize.width) / 2.0), y: 80.0),
origin: CGPoint(x: floorToScreenPixels((availableSize.width - labelSize.width) / 2.0), y: previewContainerFrame.minY + 28.0),
size: labelSize
)
if let labelView = self.label.view {
@ -319,9 +303,11 @@ private final class MediaCoverScreenComponent: Component {
labelView.bounds = CGRect(origin: .zero, size: labelFrame.size)
transition.setPosition(view: labelView, position: labelFrame.center)
}
let buttonCoverFrame = CGRect(origin: CGPoint(x: 0.0, y: doneButtonFrame.minY - buttonSideInset - 11.0), size: CGSize(width: previewContainerFrame.width, height: 100.0))
transition.setFrame(view: self.buttonsContainerView, frame: buttonsContainerFrame)
transition.setFrame(view: self.buttonsBackgroundView, frame: CGRect(origin: .zero, size: buttonsContainerFrame.size))
transition.setFrame(view: self.buttonsContainerView, frame: buttonCoverFrame)
transition.setFrame(view: self.buttonsBackgroundView, frame: CGRect(origin: .zero, size: buttonCoverFrame.size))
transition.setFrame(view: self.previewContainerView, frame: previewContainerFrame)
@ -371,7 +357,7 @@ private final class MediaCoverScreenComponent: Component {
containerSize: CGSize(width: previewSize.width - scrubberInset * 2.0, height: availableSize.height)
)
let scrubberFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((availableSize.width - scrubberSize.width) / 2.0), y: availableSize.height - environment.safeInsets.bottom - scrubberSize.height + controlsBottomInset + 3.0 - 40.0), size: scrubberSize)
let scrubberFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((availableSize.width - scrubberSize.width) / 2.0), y: min(previewContainerFrame.maxY, buttonCoverFrame.minY) - scrubberSize.height - 4.0), size: scrubberSize)
if let scrubberView = self.scrubber.view {
var animateIn = false
if scrubberView.superview == nil {
@ -514,7 +500,8 @@ final class MediaCoverScreen: ViewController {
component: AnyComponent(
MediaCoverScreenComponent(
context: self.context,
mediaEditor: controller.mediaEditor
mediaEditor: controller.mediaEditor,
exclusive: controller.exclusive
)
),
environment: {

View File

@ -4740,6 +4740,9 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
coverController.completed = { [weak self] position, image in
if let self {
self.controller?.currentCoverImage = image
if exclusive {
self.requestCompletion()
}
}
}
self.controller?.present(coverController, in: .current)
@ -5548,6 +5551,7 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
public let media: MediaResult?
public let mediaAreas: [MediaArea]
public let caption: NSAttributedString
public let coverTimestamp: Double?
public let options: MediaEditorResultPrivacy
public let stickers: [TelegramMediaFile]
public let randomId: Int64
@ -5556,6 +5560,7 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
self.media = nil
self.mediaAreas = []
self.caption = NSAttributedString()
self.coverTimestamp = nil
self.options = MediaEditorResultPrivacy(sendAsPeerId: nil, privacy: EngineStoryPrivacy(base: .everyone, additionallyIncludePeers: []), timeout: 0, isForwardingDisabled: false, pin: false)
self.stickers = []
self.randomId = 0
@ -5565,6 +5570,7 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
media: MediaResult?,
mediaAreas: [MediaArea] = [],
caption: NSAttributedString = NSAttributedString(),
coverTimestamp: Double? = nil,
options: MediaEditorResultPrivacy = MediaEditorResultPrivacy(sendAsPeerId: nil, privacy: EngineStoryPrivacy(base: .everyone, additionallyIncludePeers: []), timeout: 0, isForwardingDisabled: false, pin: false),
stickers: [TelegramMediaFile] = [],
randomId: Int64 = 0
@ -5572,6 +5578,7 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
self.media = media
self.mediaAreas = mediaAreas
self.caption = caption
self.coverTimestamp = coverTimestamp
self.options = options
self.stickers = stickers
self.randomId = randomId
@ -6479,8 +6486,13 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
}
}
if self.isEmbeddedEditor && !(self.node.hasAnyChanges || hasEntityChanges) {
self.completion(MediaEditorScreen.Result(media: nil, mediaAreas: [], caption: caption, options: self.state.privacy, stickers: stickers, randomId: randomId), { [weak self] finished in
var hasAnyChanges = self.node.hasAnyChanges
if self.isEditingStoryCover {
hasAnyChanges = false
}
if self.isEmbeddedEditor && !(hasAnyChanges || hasEntityChanges) {
self.completion(MediaEditorScreen.Result(media: nil, mediaAreas: [], caption: caption, coverTimestamp: mediaEditor.values.coverImageTimestamp, options: self.state.privacy, stickers: stickers, randomId: randomId), { [weak self] finished in
self?.node.animateOut(finished: true, saveDraft: false, completion: { [weak self] in
self?.dismiss()
Queue.mainQueue().justDispatch {
@ -6488,7 +6500,6 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
}
})
})
return
}
@ -6754,7 +6765,7 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
makeEditorImageComposition(context: self.node.ciContext, postbox: self.context.account.postbox, inputImage: inputImage, dimensions: storyDimensions, values: mediaEditor.values, time: firstFrameTime, textScale: 2.0, completion: { [weak self] coverImage in
if let self {
Logger.shared.log("MediaEditor", "Completed with video \(videoResult)")
self.completion(MediaEditorScreen.Result(media: .video(video: videoResult, coverImage: coverImage, values: mediaEditor.values, duration: duration, dimensions: mediaEditor.values.resultDimensions), mediaAreas: mediaAreas, caption: caption, options: self.state.privacy, stickers: stickers, randomId: randomId), { [weak self] finished in
self.completion(MediaEditorScreen.Result(media: .video(video: videoResult, coverImage: coverImage, values: mediaEditor.values, duration: duration, dimensions: mediaEditor.values.resultDimensions), mediaAreas: mediaAreas, caption: caption, coverTimestamp: mediaEditor.values.coverImageTimestamp, options: self.state.privacy, stickers: stickers, randomId: randomId), { [weak self] finished in
self?.node.animateOut(finished: true, saveDraft: false, completion: { [weak self] in
self?.dismiss()
Queue.mainQueue().justDispatch {
@ -6777,7 +6788,7 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
makeEditorImageComposition(context: self.node.ciContext, postbox: self.context.account.postbox, inputImage: image, dimensions: storyDimensions, values: mediaEditor.values, time: .zero, textScale: 2.0, completion: { [weak self] resultImage in
if let self, let resultImage {
Logger.shared.log("MediaEditor", "Completed with image \(resultImage)")
self.completion(MediaEditorScreen.Result(media: .image(image: resultImage, dimensions: PixelDimensions(resultImage.size)), mediaAreas: mediaAreas, caption: caption, options: self.state.privacy, stickers: stickers, randomId: randomId), { [weak self] finished in
self.completion(MediaEditorScreen.Result(media: .image(image: resultImage, dimensions: PixelDimensions(resultImage.size)), mediaAreas: mediaAreas, caption: caption, coverTimestamp: nil, options: self.state.privacy, stickers: stickers, randomId: randomId), { [weak self] finished in
self?.node.animateOut(finished: true, saveDraft: false, completion: { [weak self] in
self?.dismiss()
Queue.mainQueue().justDispatch {
@ -6925,6 +6936,7 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
media: .sticker(file: file, emoji: self.effectiveStickerEmoji()),
mediaAreas: [],
caption: NSAttributedString(),
coverTimestamp: nil,
options: MediaEditorResultPrivacy(sendAsPeerId: nil, privacy: EngineStoryPrivacy(base: .everyone, additionallyIncludePeers: []), timeout: 0, isForwardingDisabled: false, pin: false),
stickers: [],
randomId: 0