mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-10-09 03:20:48 +00:00
Various fixes
This commit is contained in:
parent
c302b7d4a5
commit
f319c0fe76
@ -1141,7 +1141,7 @@ private final class DrawingScreenComponent: CombinedComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let previewSize: CGSize
|
let previewSize: CGSize
|
||||||
let previewTopInset: CGFloat = environment.statusBarHeight + 12.0
|
let previewTopInset: CGFloat = environment.statusBarHeight + 5.0
|
||||||
if case .regular = environment.metrics.widthClass {
|
if case .regular = environment.metrics.widthClass {
|
||||||
let previewHeight = context.availableSize.height - previewTopInset - 75.0
|
let previewHeight = context.availableSize.height - previewTopInset - 75.0
|
||||||
previewSize = CGSize(width: floorToScreenPixels(previewHeight / 1.77778), height: previewHeight)
|
previewSize = CGSize(width: floorToScreenPixels(previewHeight / 1.77778), height: previewHeight)
|
||||||
|
@ -226,7 +226,11 @@ private final class FeaturedStickersScreenNode: ViewControllerTracingNode {
|
|||||||
|
|
||||||
init(context: AccountContext, controller: FeaturedStickersScreen, sendSticker: ((FileMediaReference, UIView, CGRect) -> Bool)?) {
|
init(context: AccountContext, controller: FeaturedStickersScreen, sendSticker: ((FileMediaReference, UIView, CGRect) -> Bool)?) {
|
||||||
self.context = context
|
self.context = context
|
||||||
self.presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
var presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||||
|
if let forceTheme = controller.forceTheme {
|
||||||
|
presentationData = presentationData.withUpdated(theme: forceTheme)
|
||||||
|
}
|
||||||
|
self.presentationData = presentationData
|
||||||
self.controller = controller
|
self.controller = controller
|
||||||
self.sendSticker = sendSticker
|
self.sendSticker = sendSticker
|
||||||
|
|
||||||
|
@ -1425,7 +1425,7 @@ public class CameraScreen: ViewController {
|
|||||||
let progress = 1.0 - value
|
let progress = 1.0 - value
|
||||||
let maxScale = (layout.size.width - 16.0 * 2.0) / layout.size.width
|
let maxScale = (layout.size.width - 16.0 * 2.0) / layout.size.width
|
||||||
|
|
||||||
let topInset: CGFloat = (layout.statusBarHeight ?? 0.0) + 12.0
|
let topInset: CGFloat = (layout.statusBarHeight ?? 0.0) + 5.0
|
||||||
let targetTopInset = ceil((layout.statusBarHeight ?? 0.0) - (layout.size.height - layout.size.height * maxScale) / 2.0)
|
let targetTopInset = ceil((layout.statusBarHeight ?? 0.0) - (layout.size.height - layout.size.height * maxScale) / 2.0)
|
||||||
let deltaOffset = (targetTopInset - topInset)
|
let deltaOffset = (targetTopInset - topInset)
|
||||||
|
|
||||||
@ -1510,7 +1510,7 @@ public class CameraScreen: ViewController {
|
|||||||
} else {
|
} else {
|
||||||
previewSize = CGSize(width: layout.size.width, height: floorToScreenPixels(layout.size.width * 1.77778))
|
previewSize = CGSize(width: layout.size.width, height: floorToScreenPixels(layout.size.width * 1.77778))
|
||||||
}
|
}
|
||||||
let topInset: CGFloat = (layout.statusBarHeight ?? 0.0) + 12.0
|
let topInset: CGFloat = (layout.statusBarHeight ?? 0.0) + 5.0
|
||||||
let bottomInset = layout.size.height - previewSize.height - topInset
|
let bottomInset = layout.size.height - previewSize.height - topInset
|
||||||
|
|
||||||
let panelWidth: CGFloat
|
let panelWidth: CGFloat
|
||||||
|
@ -184,18 +184,18 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode {
|
|||||||
return hasPremium
|
return hasPremium
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func inputData(context: AccountContext, chatPeerId: PeerId?, areCustomEmojiEnabled: Bool, hasSearch: Bool = true, hideBackground: Bool = false, sendGif: ((FileMediaReference, UIView, CGRect, Bool, Bool) -> Bool)?) -> Signal<InputData, NoError> {
|
public static func inputData(context: AccountContext, chatPeerId: PeerId?, areCustomEmojiEnabled: Bool, hasTrending: Bool = true, hasSearch: Bool = true, hideBackground: Bool = false, sendGif: ((FileMediaReference, UIView, CGRect, Bool, Bool) -> Bool)?) -> Signal<InputData, NoError> {
|
||||||
let animationCache = context.animationCache
|
let animationCache = context.animationCache
|
||||||
let animationRenderer = context.animationRenderer
|
let animationRenderer = context.animationRenderer
|
||||||
|
|
||||||
let emojiItems = EmojiPagerContentComponent.emojiInputData(context: context, animationCache: animationCache, animationRenderer: animationRenderer, isStandalone: false, isStatusSelection: false, isReactionSelection: false, isEmojiSelection: true, hasTrending: true, topReactionItems: [], areUnicodeEmojiEnabled: true, areCustomEmojiEnabled: areCustomEmojiEnabled, chatPeerId: chatPeerId, hasSearch: hasSearch, hideBackground: hideBackground)
|
let emojiItems = EmojiPagerContentComponent.emojiInputData(context: context, animationCache: animationCache, animationRenderer: animationRenderer, isStandalone: false, isStatusSelection: false, isReactionSelection: false, isEmojiSelection: true, hasTrending: hasTrending, topReactionItems: [], areUnicodeEmojiEnabled: true, areCustomEmojiEnabled: areCustomEmojiEnabled, chatPeerId: chatPeerId, hasSearch: hasSearch, hideBackground: hideBackground)
|
||||||
|
|
||||||
let stickerNamespaces: [ItemCollectionId.Namespace] = [Namespaces.ItemCollection.CloudStickerPacks]
|
let stickerNamespaces: [ItemCollectionId.Namespace] = [Namespaces.ItemCollection.CloudStickerPacks]
|
||||||
let stickerOrderedItemListCollectionIds: [Int32] = [Namespaces.OrderedItemList.CloudSavedStickers, Namespaces.OrderedItemList.CloudRecentStickers, Namespaces.OrderedItemList.CloudAllPremiumStickers]
|
let stickerOrderedItemListCollectionIds: [Int32] = [Namespaces.OrderedItemList.CloudSavedStickers, Namespaces.OrderedItemList.CloudRecentStickers, Namespaces.OrderedItemList.CloudAllPremiumStickers]
|
||||||
|
|
||||||
let strings = context.sharedContext.currentPresentationData.with({ $0 }).strings
|
let strings = context.sharedContext.currentPresentationData.with({ $0 }).strings
|
||||||
|
|
||||||
let stickerItems = EmojiPagerContentComponent.stickerInputData(context: context, animationCache: animationCache, animationRenderer: animationRenderer, stickerNamespaces: stickerNamespaces, stickerOrderedItemListCollectionIds: stickerOrderedItemListCollectionIds, chatPeerId: chatPeerId, hasSearch: hasSearch, hasTrending: true, forceHasPremium: false, hideBackground: hideBackground)
|
let stickerItems = EmojiPagerContentComponent.stickerInputData(context: context, animationCache: animationCache, animationRenderer: animationRenderer, stickerNamespaces: stickerNamespaces, stickerOrderedItemListCollectionIds: stickerOrderedItemListCollectionIds, chatPeerId: chatPeerId, hasSearch: hasSearch, hasTrending: hasTrending, forceHasPremium: false, hideBackground: hideBackground)
|
||||||
|
|
||||||
let reactions: Signal<[String], NoError> = context.engine.data.subscribe(TelegramEngine.EngineData.Item.Configuration.App())
|
let reactions: Signal<[String], NoError> = context.engine.data.subscribe(TelegramEngine.EngineData.Item.Configuration.App())
|
||||||
|> map { appConfiguration -> [String] in
|
|> map { appConfiguration -> [String] in
|
||||||
|
@ -458,6 +458,10 @@ public final class MediaEditor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let player {
|
if let player {
|
||||||
|
if let initialSeekPosition = self.initialSeekPosition {
|
||||||
|
self.initialSeekPosition = nil
|
||||||
|
player.seek(to: CMTime(seconds: initialSeekPosition, preferredTimescale: CMTimeScale(1000)), toleranceBefore: .zero, toleranceAfter: .zero)
|
||||||
|
}
|
||||||
self.timeObserver = player.addPeriodicTimeObserver(forInterval: CMTimeMake(value: 1, timescale: 10), queue: DispatchQueue.main) { [weak self] time in
|
self.timeObserver = player.addPeriodicTimeObserver(forInterval: CMTimeMake(value: 1, timescale: 10), queue: DispatchQueue.main) { [weak self] time in
|
||||||
guard let self, let duration = player.currentItem?.duration.seconds else {
|
guard let self, let duration = player.currentItem?.duration.seconds else {
|
||||||
return
|
return
|
||||||
@ -552,11 +556,16 @@ public final class MediaEditor {
|
|||||||
|
|
||||||
public var onPlaybackAction: (PlaybackAction) -> Void = { _ in }
|
public var onPlaybackAction: (PlaybackAction) -> Void = { _ in }
|
||||||
|
|
||||||
|
private var initialSeekPosition: Double?
|
||||||
private var targetTimePosition: (CMTime, Bool)?
|
private var targetTimePosition: (CMTime, Bool)?
|
||||||
private var updatingTimePosition = false
|
private var updatingTimePosition = false
|
||||||
public func seek(_ position: Double, andPlay play: Bool) {
|
public func seek(_ position: Double, andPlay play: Bool) {
|
||||||
|
guard let player = self.player else {
|
||||||
|
self.initialSeekPosition = position
|
||||||
|
return
|
||||||
|
}
|
||||||
if !play {
|
if !play {
|
||||||
self.player?.pause()
|
player.pause()
|
||||||
self.onPlaybackAction(.pause)
|
self.onPlaybackAction(.pause)
|
||||||
}
|
}
|
||||||
let targetPosition = CMTime(seconds: position, preferredTimescale: CMTimeScale(60.0))
|
let targetPosition = CMTime(seconds: position, preferredTimescale: CMTimeScale(60.0))
|
||||||
@ -567,7 +576,7 @@ public final class MediaEditor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if play {
|
if play {
|
||||||
self.player?.play()
|
player.play()
|
||||||
self.onPlaybackAction(.play)
|
self.onPlaybackAction(.play)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -470,7 +470,7 @@ final class MediaEditorScreenComponent: Component {
|
|||||||
for button in buttons {
|
for button in buttons {
|
||||||
if let view = button.view {
|
if let view = button.view {
|
||||||
view.layer.animatePosition(from: .zero, to: CGPoint(x: 0.0, y: 64.0), duration: 0.3, timingFunction: kCAMediaTimingFunctionSpring, removeOnCompletion: false, additive: true)
|
view.layer.animatePosition(from: .zero, to: CGPoint(x: 0.0, y: 64.0), duration: 0.3, timingFunction: kCAMediaTimingFunctionSpring, removeOnCompletion: false, additive: true)
|
||||||
view.layer.animateAlpha(from: view.alpha, to: 0.0, duration: 0.2, removeOnCompletion: false)
|
view.layer.animateAlpha(from: view.alpha, to: 0.0, duration: 0.15, removeOnCompletion: false)
|
||||||
view.layer.animateScale(from: 1.0, to: 0.1, duration: 0.2)
|
view.layer.animateScale(from: 1.0, to: 0.1, duration: 0.2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -634,7 +634,7 @@ final class MediaEditorScreenComponent: Component {
|
|||||||
let buttonSideInset: CGFloat
|
let buttonSideInset: CGFloat
|
||||||
let buttonBottomInset: CGFloat = 8.0
|
let buttonBottomInset: CGFloat = 8.0
|
||||||
let previewSize: CGSize
|
let previewSize: CGSize
|
||||||
let topInset: CGFloat = environment.statusBarHeight + 12.0
|
let topInset: CGFloat = environment.statusBarHeight + 5.0
|
||||||
if isTablet {
|
if isTablet {
|
||||||
let previewHeight = availableSize.height - topInset - 75.0
|
let previewHeight = availableSize.height - topInset - 75.0
|
||||||
previewSize = CGSize(width: floorToScreenPixels(previewHeight / 1.77778), height: previewHeight)
|
previewSize = CGSize(width: floorToScreenPixels(previewHeight / 1.77778), height: previewHeight)
|
||||||
@ -1820,6 +1820,9 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
|
|||||||
initialValues = nil
|
initialValues = nil
|
||||||
}
|
}
|
||||||
let mediaEditor = MediaEditor(subject: subject.editorSubject, values: initialValues, hasHistogram: true)
|
let mediaEditor = MediaEditor(subject: subject.editorSubject, values: initialValues, hasHistogram: true)
|
||||||
|
if let initialVideoPosition = self.controller?.initialVideoPosition {
|
||||||
|
mediaEditor.seek(initialVideoPosition, andPlay: true)
|
||||||
|
}
|
||||||
mediaEditor.attachPreviewView(self.previewView)
|
mediaEditor.attachPreviewView(self.previewView)
|
||||||
mediaEditor.valuesUpdated = { [weak self] values in
|
mediaEditor.valuesUpdated = { [weak self] values in
|
||||||
if let self, let controller = self.controller, values.gradientColors != nil, controller.previousSavedValues != values {
|
if let self, let controller = self.controller, values.gradientColors != nil, controller.previousSavedValues != values {
|
||||||
@ -1841,15 +1844,19 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
|
|||||||
Queue.mainQueue().async {
|
Queue.mainQueue().async {
|
||||||
self.gradientView.image = gradientImage
|
self.gradientView.image = gradientImage
|
||||||
|
|
||||||
self.previewContainerView.alpha = 1.0
|
if self.controller?.isEditingStory == true && subject.isVideo {
|
||||||
if CACurrentMediaTime() - self.initializationTimestamp > 0.2 {
|
|
||||||
self.previewContainerView.layer.allowsGroupOpacity = true
|
|
||||||
self.previewContainerView.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.25, completion: { _ in
|
|
||||||
self.previewContainerView.layer.allowsGroupOpacity = false
|
|
||||||
self.backgroundDimView.isHidden = false
|
|
||||||
})
|
|
||||||
} else {
|
} else {
|
||||||
self.backgroundDimView.isHidden = false
|
self.previewContainerView.alpha = 1.0
|
||||||
|
if CACurrentMediaTime() - self.initializationTimestamp > 0.2 {
|
||||||
|
self.previewContainerView.layer.allowsGroupOpacity = true
|
||||||
|
self.previewContainerView.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.25, completion: { _ in
|
||||||
|
self.previewContainerView.layer.allowsGroupOpacity = false
|
||||||
|
self.previewContainerView.alpha = 1.0
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
self.backgroundDimView.isHidden = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1857,6 +1864,15 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
|
|||||||
self.mediaEditor = mediaEditor
|
self.mediaEditor = mediaEditor
|
||||||
self.mediaEditorPromise.set(.single(mediaEditor))
|
self.mediaEditorPromise.set(.single(mediaEditor))
|
||||||
|
|
||||||
|
if self.controller?.isEditingStory == true && subject.isVideo {
|
||||||
|
mediaEditor.onFirstDisplay = { [weak self] in
|
||||||
|
if let self {
|
||||||
|
self.previewContainerView.alpha = 1.0
|
||||||
|
self.backgroundDimView.isHidden = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mediaEditor.onPlaybackAction = { [weak self] action in
|
mediaEditor.onPlaybackAction = { [weak self] action in
|
||||||
if let self {
|
if let self {
|
||||||
switch action {
|
switch action {
|
||||||
@ -2312,6 +2328,11 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
|
|||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
if controller.isEditingStory {
|
if controller.isEditingStory {
|
||||||
|
if let view = self.componentHost.view as? MediaEditorScreenComponent.View {
|
||||||
|
view.animateOut(to: .gallery)
|
||||||
|
}
|
||||||
|
|
||||||
|
self.layer.allowsGroupOpacity = true
|
||||||
self.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.4, removeOnCompletion: false, completion: { _ in
|
self.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.4, removeOnCompletion: false, completion: { _ in
|
||||||
completion()
|
completion()
|
||||||
})
|
})
|
||||||
@ -2507,7 +2528,7 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
|
|||||||
let progress = 1.0 - value
|
let progress = 1.0 - value
|
||||||
let maxScale = (layout.size.width - 16.0 * 2.0) / layout.size.width
|
let maxScale = (layout.size.width - 16.0 * 2.0) / layout.size.width
|
||||||
|
|
||||||
let topInset: CGFloat = (layout.statusBarHeight ?? 0.0) + 12.0
|
let topInset: CGFloat = (layout.statusBarHeight ?? 0.0) + 5.0
|
||||||
let targetTopInset = ceil((layout.statusBarHeight ?? 0.0) - (layout.size.height - layout.size.height * maxScale) / 2.0)
|
let targetTopInset = ceil((layout.statusBarHeight ?? 0.0) - (layout.size.height - layout.size.height * maxScale) / 2.0)
|
||||||
let deltaOffset = (targetTopInset - topInset)
|
let deltaOffset = (targetTopInset - topInset)
|
||||||
|
|
||||||
@ -2548,7 +2569,7 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
|
|||||||
isTablet = false
|
isTablet = false
|
||||||
}
|
}
|
||||||
|
|
||||||
let topInset: CGFloat = (layout.statusBarHeight ?? 0.0) + 12.0
|
let topInset: CGFloat = (layout.statusBarHeight ?? 0.0) + 5.0
|
||||||
let previewSize: CGSize
|
let previewSize: CGSize
|
||||||
if isTablet {
|
if isTablet {
|
||||||
let previewHeight = layout.size.height - topInset - 75.0
|
let previewHeight = layout.size.height - topInset - 75.0
|
||||||
@ -2870,6 +2891,19 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
|
|||||||
return .image(draft.thumbnail, draft.dimensions)
|
return .image(draft.thumbnail, draft.dimensions)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var isVideo: Bool {
|
||||||
|
switch self {
|
||||||
|
case .image:
|
||||||
|
return false
|
||||||
|
case .video:
|
||||||
|
return true
|
||||||
|
case let .asset(asset):
|
||||||
|
return asset.mediaType == .video
|
||||||
|
case let .draft(draft, _):
|
||||||
|
return draft.isVideo
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum Result {
|
public enum Result {
|
||||||
@ -2888,6 +2922,7 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
|
|||||||
|
|
||||||
fileprivate let initialCaption: NSAttributedString?
|
fileprivate let initialCaption: NSAttributedString?
|
||||||
fileprivate let initialPrivacy: EngineStoryPrivacy?
|
fileprivate let initialPrivacy: EngineStoryPrivacy?
|
||||||
|
fileprivate let initialVideoPosition: Double?
|
||||||
|
|
||||||
fileprivate let transitionIn: TransitionIn?
|
fileprivate let transitionIn: TransitionIn?
|
||||||
fileprivate let transitionOut: (Bool, Bool?) -> TransitionOut?
|
fileprivate let transitionOut: (Bool, Bool?) -> TransitionOut?
|
||||||
@ -2905,6 +2940,7 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
|
|||||||
isEditing: Bool,
|
isEditing: Bool,
|
||||||
initialCaption: NSAttributedString? = nil,
|
initialCaption: NSAttributedString? = nil,
|
||||||
initialPrivacy: EngineStoryPrivacy? = nil,
|
initialPrivacy: EngineStoryPrivacy? = nil,
|
||||||
|
initialVideoPosition: Double? = nil,
|
||||||
transitionIn: TransitionIn?,
|
transitionIn: TransitionIn?,
|
||||||
transitionOut: @escaping (Bool, Bool?) -> TransitionOut?,
|
transitionOut: @escaping (Bool, Bool?) -> TransitionOut?,
|
||||||
completion: @escaping (Int64, MediaEditorScreen.Result?, NSAttributedString, MediaEditorResultPrivacy, @escaping (@escaping () -> Void) -> Void) -> Void
|
completion: @escaping (Int64, MediaEditorScreen.Result?, NSAttributedString, MediaEditorResultPrivacy, @escaping (@escaping () -> Void) -> Void) -> Void
|
||||||
@ -2914,6 +2950,7 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
|
|||||||
self.isEditingStory = isEditing
|
self.isEditingStory = isEditing
|
||||||
self.initialCaption = initialCaption
|
self.initialCaption = initialCaption
|
||||||
self.initialPrivacy = initialPrivacy
|
self.initialPrivacy = initialPrivacy
|
||||||
|
self.initialVideoPosition = initialVideoPosition
|
||||||
self.transitionIn = transitionIn
|
self.transitionIn = transitionIn
|
||||||
self.transitionOut = transitionOut
|
self.transitionOut = transitionOut
|
||||||
self.completion = completion
|
self.completion = completion
|
||||||
|
@ -337,7 +337,7 @@ private final class MediaToolsScreenComponent: Component {
|
|||||||
let buttonSideInset: CGFloat
|
let buttonSideInset: CGFloat
|
||||||
let buttonBottomInset: CGFloat = 8.0
|
let buttonBottomInset: CGFloat = 8.0
|
||||||
let previewSize: CGSize
|
let previewSize: CGSize
|
||||||
let topInset: CGFloat = environment.statusBarHeight + 12.0
|
let topInset: CGFloat = environment.statusBarHeight + 5.0
|
||||||
if isTablet {
|
if isTablet {
|
||||||
let previewHeight = availableSize.height - topInset - 75.0
|
let previewHeight = availableSize.height - topInset - 75.0
|
||||||
previewSize = CGSize(width: floorToScreenPixels(previewHeight / 1.77778), height: previewHeight)
|
previewSize = CGSize(width: floorToScreenPixels(previewHeight / 1.77778), height: previewHeight)
|
||||||
@ -995,7 +995,7 @@ public final class MediaToolsScreen: ViewController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let previewSize: CGSize
|
let previewSize: CGSize
|
||||||
let topInset: CGFloat = (layout.statusBarHeight ?? 0.0) + 12.0
|
let topInset: CGFloat = (layout.statusBarHeight ?? 0.0) + 5.0
|
||||||
if isTablet {
|
if isTablet {
|
||||||
let previewHeight = layout.size.height - topInset - 75.0
|
let previewHeight = layout.size.height - topInset - 75.0
|
||||||
previewSize = CGSize(width: floorToScreenPixels(previewHeight / 1.77778), height: previewHeight)
|
previewSize = CGSize(width: floorToScreenPixels(previewHeight / 1.77778), height: previewHeight)
|
||||||
|
@ -753,7 +753,7 @@ private final class StoryContainerScreenComponent: Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var itemSetContainerSize = availableSize
|
var itemSetContainerSize = availableSize
|
||||||
var itemSetContainerInsets = UIEdgeInsets(top: environment.statusBarHeight + 12.0, left: 0.0, bottom: 0.0, right: 0.0)
|
var itemSetContainerInsets = UIEdgeInsets(top: environment.statusBarHeight + 5.0, left: 0.0, bottom: 0.0, right: 0.0)
|
||||||
var itemSetContainerSafeInsets = environment.safeInsets
|
var itemSetContainerSafeInsets = environment.safeInsets
|
||||||
if case .regular = environment.metrics.widthClass {
|
if case .regular = environment.metrics.widthClass {
|
||||||
let availableHeight = min(1080.0, availableSize.height - max(45.0, environment.safeInsets.bottom) * 2.0)
|
let availableHeight = min(1080.0, availableSize.height - max(45.0, environment.safeInsets.bottom) * 2.0)
|
||||||
|
@ -29,6 +29,10 @@ public final class StoryContentItem {
|
|||||||
|
|
||||||
open func leaveAmbientMode() {
|
open func leaveAmbientMode() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
open var videoPlaybackPosition: Double? {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public final class Environment: Equatable {
|
public final class Environment: Equatable {
|
||||||
|
@ -1373,7 +1373,6 @@ public final class StoryItemSetContainerComponent: Component {
|
|||||||
|
|
||||||
self.sendMessageContext.updateInputMediaNode(inputPanel: self.inputPanel, availableSize: availableSize, bottomInset: component.safeInsets.bottom, inputHeight: component.inputHeight, effectiveInputHeight: inputHeight, metrics: component.metrics, deviceMetrics: component.deviceMetrics, transition: transition)
|
self.sendMessageContext.updateInputMediaNode(inputPanel: self.inputPanel, availableSize: availableSize, bottomInset: component.safeInsets.bottom, inputHeight: component.inputHeight, effectiveInputHeight: inputHeight, metrics: component.metrics, deviceMetrics: component.deviceMetrics, transition: transition)
|
||||||
|
|
||||||
//let bottomContentInsetWithoutInput = bottomContentInset
|
|
||||||
var viewListInset: CGFloat = 0.0
|
var viewListInset: CGFloat = 0.0
|
||||||
|
|
||||||
var inputPanelBottomInset: CGFloat
|
var inputPanelBottomInset: CGFloat
|
||||||
@ -1701,13 +1700,14 @@ public final class StoryItemSetContainerComponent: Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let itemSize = CGSize(width: availableSize.width, height: ceil(availableSize.width * 1.77778))
|
||||||
let contentDefaultBottomInset: CGFloat = bottomContentInset
|
let contentDefaultBottomInset: CGFloat = bottomContentInset
|
||||||
let contentSize = CGSize(width: availableSize.width, height: availableSize.height - component.containerInsets.top - contentDefaultBottomInset)
|
let contentSize = itemSize
|
||||||
|
|
||||||
let contentVisualBottomInset: CGFloat = max(contentDefaultBottomInset, viewListInset)
|
let contentVisualBottomInset: CGFloat = max(contentDefaultBottomInset, viewListInset)
|
||||||
|
|
||||||
let contentVisualHeight = availableSize.height - component.containerInsets.top - contentVisualBottomInset
|
let contentVisualHeight = min(contentSize.height, availableSize.height - component.containerInsets.top - contentVisualBottomInset)
|
||||||
let contentVisualScale = contentVisualHeight / contentSize.height
|
let contentVisualScale = min(1.0, contentVisualHeight / contentSize.height)
|
||||||
|
|
||||||
let contentFrame = CGRect(origin: CGPoint(x: 0.0, y: component.containerInsets.top - (contentSize.height - contentVisualHeight) * 0.5), size: contentSize)
|
let contentFrame = CGRect(origin: CGPoint(x: 0.0, y: component.containerInsets.top - (contentSize.height - contentVisualHeight) * 0.5), size: contentSize)
|
||||||
|
|
||||||
@ -1914,8 +1914,7 @@ public final class StoryItemSetContainerComponent: Component {
|
|||||||
transition.setFrame(layer: self.topContentGradientLayer, frame: CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: contentFrame.width, height: gradientHeight)))
|
transition.setFrame(layer: self.topContentGradientLayer, frame: CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: contentFrame.width, height: gradientHeight)))
|
||||||
transition.setAlpha(layer: self.topContentGradientLayer, alpha: (component.hideUI || self.displayViewList || self.isEditingStory) ? 0.0 : 1.0)
|
transition.setAlpha(layer: self.topContentGradientLayer, alpha: (component.hideUI || self.displayViewList || self.isEditingStory) ? 0.0 : 1.0)
|
||||||
|
|
||||||
let itemSize = CGSize(width: contentFrame.width, height: floorToScreenPixels(contentFrame.width * 1.77778))
|
let itemLayout = ItemLayout(size: itemSize)
|
||||||
let itemLayout = ItemLayout(size: itemSize) //ItemLayout(size: CGSize(width: contentFrame.width, height: availableSize.height - component.containerInsets.top - 44.0 - bottomContentInsetWithoutInput))
|
|
||||||
self.itemLayout = itemLayout
|
self.itemLayout = itemLayout
|
||||||
|
|
||||||
let inputPanelFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((availableSize.width - inputPanelSize.width) / 2.0), y: availableSize.height - inputPanelBottomInset - inputPanelSize.height), size: inputPanelSize)
|
let inputPanelFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((availableSize.width - inputPanelSize.width) / 2.0), y: availableSize.height - inputPanelBottomInset - inputPanelSize.height), size: inputPanelSize)
|
||||||
@ -2418,21 +2417,27 @@ public final class StoryItemSetContainerComponent: Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func openStoryEditing() {
|
private func openStoryEditing() {
|
||||||
guard let context = self.component?.context, let item = self.component?.slice.item.storyItem else {
|
guard let component = self.component, let peerReference = PeerReference(component.slice.peer._asPeer()) else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
let context = component.context
|
||||||
|
let item = component.slice.item.storyItem
|
||||||
let id = item.id
|
let id = item.id
|
||||||
|
|
||||||
self.isEditingStory = true
|
self.isEditingStory = true
|
||||||
self.updateIsProgressPaused()
|
self.updateIsProgressPaused()
|
||||||
self.state?.updated(transition: .easeInOut(duration: 0.2))
|
self.state?.updated(transition: .easeInOut(duration: 0.2))
|
||||||
|
|
||||||
|
var videoPlaybackPosition: Double?
|
||||||
|
if let visibleItem = self.visibleItems[component.slice.item.id], let view = visibleItem.view.view as? StoryContentItem.View {
|
||||||
|
videoPlaybackPosition = view.videoPlaybackPosition
|
||||||
|
}
|
||||||
|
|
||||||
let subject: Signal<MediaEditorScreen.Subject?, NoError>
|
let subject: Signal<MediaEditorScreen.Subject?, NoError>
|
||||||
// if let source {
|
// if let source {
|
||||||
// subject = .single(.draft(source, Int64(id)))
|
// subject = .single(.draft(source, Int64(id)))
|
||||||
// } else {
|
// } else {
|
||||||
let media = item.media._asMedia()
|
subject = fetchMediaData(context: context, postbox: context.account.postbox, userLocation: .other, mediaReference: .story(peer: peerReference, id: item.id, media: item.media._asMedia()))
|
||||||
subject = fetchMediaData(context: context, postbox: context.account.postbox, userLocation: .other, mediaReference: .standalone(media: media))
|
|
||||||
|> mapToSignal { (value, isImage) -> Signal<MediaEditorScreen.Subject?, NoError> in
|
|> mapToSignal { (value, isImage) -> Signal<MediaEditorScreen.Subject?, NoError> in
|
||||||
guard case let .data(data) = value, data.complete else {
|
guard case let .data(data) = value, data.complete else {
|
||||||
return .complete()
|
return .complete()
|
||||||
@ -2448,7 +2453,11 @@ public final class StoryItemSetContainerComponent: Component {
|
|||||||
if fileSize(symlinkPath) == nil {
|
if fileSize(symlinkPath) == nil {
|
||||||
let _ = try? FileManager.default.linkItem(atPath: data.path, toPath: symlinkPath)
|
let _ = try? FileManager.default.linkItem(atPath: data.path, toPath: symlinkPath)
|
||||||
}
|
}
|
||||||
return .single(.video(symlinkPath, nil, nil, nil, PixelDimensions(width: 720, height: 1280), .bottomRight))
|
return .single(nil)
|
||||||
|
|> then(
|
||||||
|
.single(.video(symlinkPath, nil, nil, nil, PixelDimensions(width: 720, height: 1280), .bottomRight))
|
||||||
|
|> delay(0.1, queue: Queue.mainQueue())
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2459,6 +2468,7 @@ public final class StoryItemSetContainerComponent: Component {
|
|||||||
isEditing: true,
|
isEditing: true,
|
||||||
initialCaption: chatInputStateStringWithAppliedEntities(item.text, entities: item.entities),
|
initialCaption: chatInputStateStringWithAppliedEntities(item.text, entities: item.entities),
|
||||||
initialPrivacy: item.privacy,
|
initialPrivacy: item.privacy,
|
||||||
|
initialVideoPosition: videoPlaybackPosition,
|
||||||
transitionIn: nil,
|
transitionIn: nil,
|
||||||
transitionOut: { _, _ in return nil },
|
transitionOut: { _, _ in return nil },
|
||||||
completion: { [weak self] _, mediaResult, caption, privacy, commit in
|
completion: { [weak self] _, mediaResult, caption, privacy, commit in
|
||||||
@ -2582,149 +2592,6 @@ public final class StoryItemSetContainerComponent: Component {
|
|||||||
updateProgressImpl = { [weak controller] progress in
|
updateProgressImpl = { [weak controller] progress in
|
||||||
controller?.updateEditProgress(progress)
|
controller?.updateEditProgress(progress)
|
||||||
}
|
}
|
||||||
|
|
||||||
// }
|
|
||||||
|
|
||||||
// let _ = (getStorySource(engine: context.engine, id: Int64(id))
|
|
||||||
// |> deliverOnMainQueue).start(next: { [weak self] source in
|
|
||||||
// guard let self else {
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// self.isEditingStory = true
|
|
||||||
// self.updateIsProgressPaused()
|
|
||||||
//
|
|
||||||
// let subject: Signal<MediaEditorScreen.Subject?, NoError>
|
|
||||||
// if let source {
|
|
||||||
// subject = .single(.draft(source, Int64(id)))
|
|
||||||
// } else {
|
|
||||||
// let media = item.media._asMedia()
|
|
||||||
// subject = fetchMediaData(context: context, postbox: context.account.postbox, userLocation: .other, mediaReference: .standalone(media: media))
|
|
||||||
// |> mapToSignal { (value, isImage) -> Signal<MediaEditorScreen.Subject?, NoError> in
|
|
||||||
// guard case let .data(data) = value, data.complete else {
|
|
||||||
// return .complete()
|
|
||||||
// }
|
|
||||||
// if let image = UIImage(contentsOfFile: data.path) {
|
|
||||||
// return .single(.image(image, PixelDimensions(image.size), nil, .bottomRight))
|
|
||||||
// } else {
|
|
||||||
// return .single(.video(data.path, nil, nil, nil, PixelDimensions(width: 720, height: 1280), .bottomRight))
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// var updateProgressImpl: ((Float) -> Void)?
|
|
||||||
// let controller = MediaEditorScreen(
|
|
||||||
// context: context,
|
|
||||||
// subject: subject,
|
|
||||||
// isEditing: true,
|
|
||||||
// transitionIn: nil,
|
|
||||||
// transitionOut: { _, _ in return nil },
|
|
||||||
// completion: { [weak self] randomId, mediaResult, caption, privacy, commit in
|
|
||||||
// let entities = generateChatInputTextEntities(caption)
|
|
||||||
// var updatedText: String?
|
|
||||||
// var updatedEntities: [MessageTextEntity]?
|
|
||||||
// var updatedPrivacy: EngineStoryPrivacy?
|
|
||||||
// if caption.string != item.text || entities != item.entities {
|
|
||||||
// updatedText = caption.string
|
|
||||||
// updatedEntities = entities
|
|
||||||
// }
|
|
||||||
// if privacy.privacy != item.privacy {
|
|
||||||
// updatedPrivacy = privacy.privacy
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if let mediaResult {
|
|
||||||
// switch mediaResult {
|
|
||||||
// case let .image(image, dimensions, caption):
|
|
||||||
// if let imageData = compressImageToJPEG(image, quality: 0.7) {
|
|
||||||
// let _ = (context.engine.messages.editStory(media: .image(dimensions: dimensions, data: imageData), id: id, text: updatedText, entities: updatedEntities, privacy: updatedPrivacy)
|
|
||||||
// |> deliverOnMainQueue).start(next: { [weak self] result in
|
|
||||||
// switch result {
|
|
||||||
// case let .progress(progress):
|
|
||||||
// updateProgressImpl?(progress)
|
|
||||||
// case .completed:
|
|
||||||
// Queue.mainQueue().after(0.1) {
|
|
||||||
// if let self {
|
|
||||||
// self.isEditingStory = false
|
|
||||||
// self.rewindCurrentItem()
|
|
||||||
// self.updateIsProgressPaused()
|
|
||||||
// }
|
|
||||||
// commit({})
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
// case let .video(content, firstFrameImage, values, duration, dimensions, caption):
|
|
||||||
// let adjustments: VideoMediaResourceAdjustments
|
|
||||||
// if let valuesData = try? JSONEncoder().encode(values) {
|
|
||||||
// let data = MemoryBuffer(data: valuesData)
|
|
||||||
// let digest = MemoryBuffer(data: data.md5Digest())
|
|
||||||
// adjustments = VideoMediaResourceAdjustments(data: data, digest: digest, isStory: true)
|
|
||||||
//
|
|
||||||
// let resource: TelegramMediaResource
|
|
||||||
// switch content {
|
|
||||||
// case let .imageFile(path):
|
|
||||||
// resource = LocalFileVideoMediaResource(randomId: Int64.random(in: .min ... .max), path: path, adjustments: adjustments)
|
|
||||||
// case let .videoFile(path):
|
|
||||||
// resource = LocalFileVideoMediaResource(randomId: Int64.random(in: .min ... .max), path: path, adjustments: adjustments)
|
|
||||||
// case let .asset(localIdentifier):
|
|
||||||
// resource = VideoLibraryMediaResource(localIdentifier: localIdentifier, conversion: .compress(adjustments))
|
|
||||||
// }
|
|
||||||
// let imageData = firstFrameImage.flatMap { compressImageToJPEG($0, quality: 0.6) }
|
|
||||||
//
|
|
||||||
// let _ = (context.engine.messages.editStory(media: .video(dimensions: dimensions, duration: duration, resource: resource, firstFrameImageData: imageData), id: id, text: updatedText, entities: updatedEntities, privacy: updatedPrivacy)
|
|
||||||
// |> deliverOnMainQueue).start(next: { [weak self] result in
|
|
||||||
// switch result {
|
|
||||||
// case let .progress(progress):
|
|
||||||
// updateProgressImpl?(progress)
|
|
||||||
// case .completed:
|
|
||||||
// Queue.mainQueue().after(0.1) {
|
|
||||||
// if let self {
|
|
||||||
// self.isEditingStory = false
|
|
||||||
// self.rewindCurrentItem()
|
|
||||||
// self.updateIsProgressPaused()
|
|
||||||
// }
|
|
||||||
// commit({})
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// } else if updatedText != nil || updatedPrivacy != nil {
|
|
||||||
// let _ = (context.engine.messages.editStory(media: nil, id: id, text: updatedText, entities: updatedEntities, privacy: updatedPrivacy)
|
|
||||||
// |> deliverOnMainQueue).start(next: { [weak self] result in
|
|
||||||
// switch result {
|
|
||||||
// case .completed:
|
|
||||||
// Queue.mainQueue().after(0.1) {
|
|
||||||
// if let self {
|
|
||||||
// self.isEditingStory = false
|
|
||||||
// self.rewindCurrentItem()
|
|
||||||
// self.updateIsProgressPaused()
|
|
||||||
// }
|
|
||||||
// commit({})
|
|
||||||
// }
|
|
||||||
// default:
|
|
||||||
// break
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
// } else {
|
|
||||||
// if let self {
|
|
||||||
// self.isEditingStory = false
|
|
||||||
// self.rewindCurrentItem()
|
|
||||||
// self.updateIsProgressPaused()
|
|
||||||
// }
|
|
||||||
// commit({})
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// )
|
|
||||||
// controller.dismissed = { [weak self] in
|
|
||||||
// self?.isEditingStory = false
|
|
||||||
// self?.updateIsProgressPaused()
|
|
||||||
// }
|
|
||||||
// self.component?.controller()?.push(controller)
|
|
||||||
// updateProgressImpl = { [weak controller] progress in
|
|
||||||
// controller?.updateEditProgress(progress)
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private func requestSave() {
|
private func requestSave() {
|
||||||
|
@ -104,6 +104,7 @@ final class StoryItemSetContainerSendMessage {
|
|||||||
context: context,
|
context: context,
|
||||||
chatPeerId: nil,
|
chatPeerId: nil,
|
||||||
areCustomEmojiEnabled: true,
|
areCustomEmojiEnabled: true,
|
||||||
|
hasTrending: false,
|
||||||
hasSearch: false,
|
hasSearch: false,
|
||||||
hideBackground: true,
|
hideBackground: true,
|
||||||
sendGif: nil
|
sendGif: nil
|
||||||
|
@ -65,6 +65,9 @@ final class StoryItemContentComponent: Component {
|
|||||||
private var contentLoaded: Bool = false
|
private var contentLoaded: Bool = false
|
||||||
|
|
||||||
private var videoPlaybackStatus: MediaPlayerStatus?
|
private var videoPlaybackStatus: MediaPlayerStatus?
|
||||||
|
override var videoPlaybackPosition: Double? {
|
||||||
|
return self.videoPlaybackStatus?.timestamp
|
||||||
|
}
|
||||||
|
|
||||||
private let hierarchyTrackingLayer: HierarchyTrackingLayer
|
private let hierarchyTrackingLayer: HierarchyTrackingLayer
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user