Various fixes

This commit is contained in:
Ilya Laktyushin 2023-07-10 04:00:52 +02:00
parent 80079dba5a
commit fdff55d7ea
14 changed files with 219 additions and 149 deletions

View File

@ -870,7 +870,7 @@ public protocol SharedAccountContext: AnyObject {
func makeStorageManagementController(context: AccountContext) -> ViewController
func makeAttachmentFileController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?, bannedSendMedia: (Int32, Bool)?, presentGallery: @escaping () -> Void, presentFiles: @escaping () -> Void, send: @escaping (AnyMediaReference) -> Void) -> AttachmentFileController
func makeGalleryCaptionPanelView(context: AccountContext, chatLocation: ChatLocation, customEmojiAvailable: Bool, present: @escaping (ViewController) -> Void, presentInGlobalOverlay: @escaping (ViewController) -> Void) -> NSObject?
func makeHashtagSearchController(context: AccountContext, peer: EnginePeer?, query: String) -> ViewController
func makeHashtagSearchController(context: AccountContext, peer: EnginePeer?, query: String, all: Bool) -> ViewController
func makeMyStoriesController(context: AccountContext, isArchive: Bool) -> ViewController
func navigateToChatController(_ params: NavigateToChatControllerParams)
func navigateToForumChannel(context: AccountContext, peerId: EnginePeer.Id, navigationController: NavigationController)

View File

@ -3368,13 +3368,13 @@ private final class ShimmerEffectNode: ASDisplayNode {
}
}
private final class ChatListSearchShimmerNode: ASDisplayNode {
public final class ChatListSearchShimmerNode: ASDisplayNode {
private let backgroundColorNode: ASDisplayNode
private let effectNode: ShimmerEffectNode
private let maskNode: ASImageNode
private var currentParams: (size: CGSize, presentationData: PresentationData, key: ChatListSearchPaneKey)?
init(key: ChatListSearchPaneKey) {
public init(key: ChatListSearchPaneKey) {
self.backgroundColorNode = ASDisplayNode()
self.effectNode = ShimmerEffectNode()
self.maskNode = ASImageNode()
@ -3388,7 +3388,7 @@ private final class ChatListSearchShimmerNode: ASDisplayNode {
self.addSubnode(self.maskNode)
}
func update(context: AccountContext, size: CGSize, presentationData: PresentationData, animationCache: AnimationCache, animationRenderer: MultiAnimationRenderer, key: ChatListSearchPaneKey, hasSelection: Bool, transition: ContainedViewLayoutTransition) {
public func update(context: AccountContext, size: CGSize, presentationData: PresentationData, animationCache: AnimationCache, animationRenderer: MultiAnimationRenderer, key: ChatListSearchPaneKey, hasSelection: Bool, transition: ContainedViewLayoutTransition) {
if self.currentParams?.size != size || self.currentParams?.presentationData !== presentationData || self.currentParams?.key != key {
self.currentParams = (size, presentationData, key)

View File

@ -52,6 +52,7 @@ private func prepareForRendering(entityView: DrawingEntityView) {
public final class DrawingEntitiesView: UIView, TGPhotoDrawingEntitiesView {
private let context: AccountContext
private let size: CGSize
private let hasBin: Bool
weak var drawingView: DrawingView?
public weak var selectionContainerView: DrawingSelectionContainerView?
@ -85,9 +86,10 @@ public final class DrawingEntitiesView: UIView, TGPhotoDrawingEntitiesView {
private let hapticFeedback = HapticFeedback()
public init(context: AccountContext, size: CGSize) {
public init(context: AccountContext, size: CGSize, hasBin: Bool = false) {
self.context = context
self.size = size
self.hasBin = hasBin
super.init(frame: CGRect(origin: .zero, size: size))
@ -690,6 +692,9 @@ public final class DrawingEntitiesView: UIView, TGPhotoDrawingEntitiesView {
public func handlePan(_ gestureRecognizer: UIPanGestureRecognizer) {
let location = gestureRecognizer.location(in: self)
if let selectedEntityView = self.selectedEntityView, let selectionView = selectedEntityView.selectionView {
if !self.hasBin {
selectionView.handlePan(gestureRecognizer)
} else {
var isTrappedInBin = false
let scale = 100.0 / selectedEntityView.bounds.size.width
switch gestureRecognizer.state {
@ -752,6 +757,7 @@ public final class DrawingEntitiesView: UIView, TGPhotoDrawingEntitiesView {
}
selectionView.handlePan(gestureRecognizer)
}
}
} else if gestureRecognizer.numberOfTouches == 1, let viewToSelect = self.entity(at: location) {
self.selectEntity(viewToSelect.entity)
} else if gestureRecognizer.numberOfTouches == 2, let mediaEntityView = self.subviews.first(where: { $0 is DrawingEntityMediaView }) as? DrawingEntityMediaView {

View File

@ -2965,7 +2965,7 @@ public final class DrawingToolsInteraction {
private let onInteractionUpdated: (Bool) -> Void
private let onTextEditingEnded: (Bool) -> Void
private let getCurrentImage: () -> UIImage?
public let getCurrentImage: () -> UIImage?
private let getControllerNode: () -> ASDisplayNode?
private let present: (ViewController, PresentationContextType, Any?) -> Void
private let addSubview: (UIView) -> Void

View File

@ -329,7 +329,7 @@ public final class DrawingStickerEntityView: DrawingEntityView {
if size.width > 0 && self.currentSize != size {
self.currentSize = size
let sideSize: CGFloat = size.width
let sideSize: CGFloat = max(size.width, size.height)
let boundingSize = CGSize(width: sideSize, height: sideSize)
let imageSize = self.dimensions.aspectFitted(boundingSize)
@ -657,6 +657,46 @@ final class DrawingStickerEntititySelectionView: DrawingEntitySelectionView {
let handlePath = CGPath(ellipseIn: CGRect(origin: CGPoint(x: (bounds.width - handleSize.width) / 2.0, y: (bounds.height - handleSize.height) / 2.0), size: handleSize), transform: nil)
let lineWidth = (1.0 + UIScreenPixel) / self.scale
let radius = (self.bounds.width - inset * 2.0) / 2.0
let circumference: CGFloat = 2.0 * .pi * radius
let relativeDashLength: CGFloat = 0.25
self.border.lineWidth = 2.0 / self.scale
let actualInset: CGFloat
if entity.isRectangle {
let aspectRatio = entity.baseSize.width / entity.baseSize.height
let width: CGFloat
let height: CGFloat
if entity.baseSize.width > entity.baseSize.height {
width = self.bounds.width - inset * 2.0
height = self.bounds.height / aspectRatio - inset * 2.0
} else {
width = self.bounds.width * aspectRatio - inset * 2.0
height = self.bounds.height - inset * 2.0
}
actualInset = floorToScreenPixels((self.bounds.width - width) / 2.0)
let cornerRadius: CGFloat = 12.0 - self.scale
let perimeter: CGFloat = 2.0 * (width + height - cornerRadius * (4.0 - .pi))
let count = 12
let dashLength = perimeter / CGFloat(count)
self.border.lineDashPattern = [dashLength * relativeDashLength, dashLength * relativeDashLength] as [NSNumber]
self.border.path = UIBezierPath(roundedRect: CGRect(origin: CGPoint(x: floorToScreenPixels((self.bounds.width - width) / 2.0), y: floorToScreenPixels((self.bounds.height - height) / 2.0)), size: CGSize(width: width, height: height)), cornerRadius: cornerRadius).cgPath
} else {
actualInset = inset
let count = 10
let dashLength = circumference / CGFloat(count)
self.border.lineDashPattern = [dashLength * relativeDashLength, dashLength * relativeDashLength] as [NSNumber]
self.border.path = UIBezierPath(ovalIn: CGRect(origin: CGPoint(x: inset, y: inset), size: CGSize(width: self.bounds.width - inset * 2.0, height: self.bounds.height - inset * 2.0))).cgPath
}
let handles = [
self.leftHandle,
self.rightHandle
@ -668,29 +708,8 @@ final class DrawingStickerEntititySelectionView: DrawingEntitySelectionView {
handle.lineWidth = lineWidth
}
self.leftHandle.position = CGPoint(x: inset, y: self.bounds.midY)
self.rightHandle.position = CGPoint(x: self.bounds.maxX - inset, y: self.bounds.midY)
let radius = (self.bounds.width - inset * 2.0) / 2.0
let circumference: CGFloat = 2.0 * .pi * radius
let count = 10
let relativeDashLength: CGFloat = 0.25
let dashLength = circumference / CGFloat(count)
self.border.lineDashPattern = [dashLength * relativeDashLength, dashLength * relativeDashLength] as [NSNumber]
self.border.lineWidth = 2.0 / self.scale
if entity.isRectangle {
let aspectRatio = entity.baseSize.width / entity.baseSize.height
let width: CGFloat = self.bounds.width - inset * 2.0
let height: CGFloat = self.bounds.height / aspectRatio - inset * 2.0
let cornerRadius: CGFloat = 12.0 - self.scale
self.border.path = UIBezierPath(roundedRect: CGRect(origin: CGPoint(x: floorToScreenPixels((self.bounds.width - width) / 2.0), y: floorToScreenPixels((self.bounds.height - height) / 2.0)), size: CGSize(width: width, height: height)), cornerRadius: cornerRadius).cgPath
} else {
self.border.path = UIBezierPath(ovalIn: CGRect(origin: CGPoint(x: inset, y: inset), size: CGSize(width: self.bounds.width - inset * 2.0, height: self.bounds.height - inset * 2.0))).cgPath
}
self.leftHandle.position = CGPoint(x: actualInset, y: self.bounds.midY)
self.rightHandle.position = CGPoint(x: self.bounds.maxX - actualInset, y: self.bounds.midY)
}
}

View File

@ -17,6 +17,7 @@ public final class HashtagSearchController: TelegramBaseController {
private let context: AccountContext
private let peer: EnginePeer?
private let query: String
let all: Bool
private var transitionDisposable: Disposable?
private let openMessageFromSearchDisposable = MetaDisposable()
@ -30,10 +31,11 @@ public final class HashtagSearchController: TelegramBaseController {
return self.displayNode as! HashtagSearchControllerNode
}
public init(context: AccountContext, peer: EnginePeer?, query: String) {
public init(context: AccountContext, peer: EnginePeer?, query: String, all: Bool = false) {
self.context = context
self.peer = peer
self.query = query
self.all = all
self.animationCache = context.animationCache
self.animationRenderer = context.animationRenderer

View File

@ -11,17 +11,16 @@ import ChatListSearchItemHeader
final class HashtagSearchControllerNode: ASDisplayNode {
private let context: AccountContext
private weak var controller: HashtagSearchController?
private let query: String
private let navigationBar: NavigationBar?
private let segmentedControlNode: SegmentedControlNode
let listNode: ListView
let shimmerNode: ChatListSearchShimmerNode
let chatController: ChatController?
private let query: String
private var containerLayout: (ContainerViewLayout, CGFloat)?
private var enqueuedTransitions: [(ChatListSearchContainerTransition, Bool)] = []
private var hasValidLayout = false
@ -34,6 +33,10 @@ final class HashtagSearchControllerNode: ASDisplayNode {
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
self.shimmerNode = ChatListSearchShimmerNode(key: .chats)
self.shimmerNode.isUserInteractionEnabled = false
self.shimmerNode.allowsGroupOpacity = true
self.listNode = ListView()
self.listNode.accessibilityPageScrolledString = { row, count in
return presentationData.strings.VoiceOver_ScrollStatus(row, count).string
@ -48,7 +51,7 @@ final class HashtagSearchControllerNode: ASDisplayNode {
items.append(peer?.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder) ?? "")
}
items.append(presentationData.strings.HashtagSearch_AllChats)
self.segmentedControlNode = SegmentedControlNode(theme: SegmentedControlTheme(theme: presentationData.theme), items: items.map { SegmentedControlItem(title: $0) }, selectedIndex: 0)
self.segmentedControlNode = SegmentedControlNode(theme: SegmentedControlTheme(theme: presentationData.theme), items: items.map { SegmentedControlItem(title: $0) }, selectedIndex: controller.all ? 1 : 0)
if let peer = peer {
self.chatController = context.sharedContext.makeChatController(context: context, chatLocation: .peer(id: peer.id), subject: nil, botStart: nil, mode: .inline(navigationController))
@ -65,7 +68,15 @@ final class HashtagSearchControllerNode: ASDisplayNode {
self.backgroundColor = presentationData.theme.chatList.backgroundColor
self.addSubnode(self.listNode)
// self.addSubnode(self.shimmerNode)
if controller.all {
self.chatController?.displayNode.isHidden = true
self.listNode.isHidden = false
} else {
self.chatController?.displayNode.isHidden = false
self.listNode.isHidden = true
}
self.segmentedControlNode.selectedIndexChanged = { [weak self] index in
if let strongSelf = self {
@ -164,6 +175,11 @@ final class HashtagSearchControllerNode: ASDisplayNode {
self.listNode.bounds = CGRect(x: 0.0, y: 0.0, width: layout.size.width, height: layout.size.height)
self.listNode.position = CGPoint(x: layout.size.width / 2.0, y: layout.size.height / 2.0)
let overflowInset: CGFloat = 0.0
let topInset = navigationBarHeight
self.shimmerNode.frame = CGRect(origin: CGPoint(x: overflowInset, y: topInset), size: CGSize(width: layout.size.width - overflowInset * 2.0, height: layout.size.height))
self.shimmerNode.update(context: self.context, size: CGSize(width: layout.size.width - overflowInset * 2.0, height: layout.size.height), presentationData: self.context.sharedContext.currentPresentationData.with { $0 }, animationCache: self.context.animationCache, animationRenderer: self.context.animationRenderer, key: .chats, hasSelection: false, transition: transition)
insets.top += 4.0
let (duration, curve) = listViewAnimationDurationAndCurve(transition: transition)

View File

@ -188,6 +188,10 @@ final class MediaPickerGridItemNode: GridItemNode {
} else {
return nil
}
} else if let (draft, _) = self.currentDraftState {
let tag = Month(localTimestamp: draft.timestamp).packedValue
self._cachedTag = tag
return tag
} else {
return nil
}

View File

@ -433,7 +433,7 @@ private final class CameraScreenComponent: CombinedComponent {
case .began:
return .single(.pendingImage)
case let .finished(image, additionalImage, _):
return .single(.image(CameraScreen.Result.Image(image: image, additionalImage: additionalImage, additionalImagePosition: .bottomRight)))
return .single(.image(CameraScreen.Result.Image(image: image, additionalImage: additionalImage, additionalImagePosition: .topRight)))
case .failed:
return .complete()
}
@ -470,7 +470,7 @@ private final class CameraScreenComponent: CombinedComponent {
self.resultDisposable.set((self.camera.stopRecording()
|> deliverOnMainQueue).start(next: { [weak self] result in
if let self, case let .finished(mainResult, additionalResult, duration, positionChangeTimestamps, _) = result {
self.completion.invoke(.single(.video(CameraScreen.Result.Video(videoPath: mainResult.0, coverImage: mainResult.1, mirror: mainResult.2, additionalVideoPath: additionalResult?.0, additionalCoverImage: additionalResult?.1, dimensions: PixelDimensions(width: 1080, height: 1920), duration: duration, positionChangeTimestamps: positionChangeTimestamps, additionalVideoPosition: .bottomRight))))
self.completion.invoke(.single(.video(CameraScreen.Result.Video(videoPath: mainResult.0, coverImage: mainResult.1, mirror: mainResult.2, additionalVideoPath: additionalResult?.0, additionalCoverImage: additionalResult?.1, dimensions: PixelDimensions(width: 1080, height: 1920), duration: duration, positionChangeTimestamps: positionChangeTimestamps, additionalVideoPosition: .topRight))))
}
}))
self.isTransitioning = true
@ -1075,7 +1075,7 @@ public class CameraScreen: ViewController {
private var appliedDualCam = false
private var cameraPosition: Camera.Position = .back
private var pipPosition: PIPPosition = .bottomRight
private var pipPosition: PIPPosition = .topRight
fileprivate var previewBlurPromise = ValuePromise<Bool>(false)
private let animateFlipAction = ActionSlot<Void>()
@ -1941,7 +1941,9 @@ public class CameraScreen: ViewController {
transition.setPosition(view: self.backgroundView, position: CGPoint(x: layout.size.width / 2.0, y: layout.size.height / 2.0))
transition.setBounds(view: self.backgroundView, bounds: CGRect(origin: .zero, size: layout.size))
if !self.hasGallery {
transition.setPosition(view: self.containerView, position: CGPoint(x: layout.size.width / 2.0, y: layout.size.height / 2.0))
}
transition.setBounds(view: self.containerView, bounds: CGRect(origin: .zero, size: layout.size))
transition.setFrame(view: self.transitionDimView, frame: CGRect(origin: .zero, size: layout.size))
@ -2293,11 +2295,16 @@ public class CameraScreen: ViewController {
let transitionFraction = max(0.0, min(1.0, transitionFraction))
let offsetX = floorToScreenPixels((1.0 - transitionFraction) * self.node.frame.width * -1.0)
transition.updateTransform(layer: self.node.backgroundView.layer, transform: CGAffineTransform(translationX: offsetX, y: 0.0))
transition.updateTransform(layer: self.node.containerView.layer, transform: CGAffineTransform(translationX: offsetX, y: 0.0))
let scale: CGFloat = max(0.8, min(1.0, 0.8 + 0.2 * transitionFraction))
if !self.node.hasGallery {
transition.updateTransform(layer: self.node.containerView.layer, transform: CGAffineTransform(translationX: offsetX, y: 0.0))
transition.updateSublayerTransformScaleAndOffset(layer: self.node.containerView.layer, scale: scale, offset: CGPoint(x: -offsetX * 1.0 / scale * 0.5, y: 0.0), completion: { _ in
completion()
})
} else {
completion()
}
let dimAlpha = 0.6 * (1.0 - transitionFraction)
transition.updateAlpha(layer: self.node.transitionDimView.layer, alpha: dimAlpha)
@ -2549,7 +2556,7 @@ private func pipPositionForLocation(layout: ContainerViewLayout, position: CGPoi
}
}
var position: CameraScreen.PIPPosition = .bottomRight
var position: CameraScreen.PIPPosition = .topRight
if result.x == 0.0 && result.y == 0.0 {
position = .topLeft
} else if result.x == 1.0 && result.y == 0.0 {

View File

@ -271,9 +271,6 @@ private func makeEditorImageFrameComposition(context: CIContext, inputImage: CII
baseScale = entityBaseScale
} else if let baseSize = entity.baseSize {
baseScale = baseSize.width / image.extent.width
if baseSize.width != baseSize.height {
baseScale *= min(baseSize.width, baseSize.height) / max(baseSize.width, baseSize.height)
}
}
var transform = CGAffineTransform.identity

View File

@ -66,6 +66,7 @@ public final class MediaEditorDraft: Codable, Equatable {
case values
case caption
case privacy
case timestamp
}
public let path: String
@ -76,8 +77,9 @@ public final class MediaEditorDraft: Codable, Equatable {
public let values: MediaEditorValues
public let caption: NSAttributedString
public let privacy: MediaEditorResultPrivacy?
public let timestamp: Int32
public init(path: String, isVideo: Bool, thumbnail: UIImage, dimensions: PixelDimensions, duration: Double?, values: MediaEditorValues, caption: NSAttributedString, privacy: MediaEditorResultPrivacy?) {
public init(path: String, isVideo: Bool, thumbnail: UIImage, dimensions: PixelDimensions, duration: Double?, values: MediaEditorValues, caption: NSAttributedString, privacy: MediaEditorResultPrivacy?, timestamp: Int32) {
self.path = path
self.isVideo = isVideo
self.thumbnail = thumbnail
@ -86,6 +88,7 @@ public final class MediaEditorDraft: Codable, Equatable {
self.values = values
self.caption = caption
self.privacy = privacy
self.timestamp = timestamp
}
public init(from decoder: Decoder) throws {
@ -117,6 +120,8 @@ public final class MediaEditorDraft: Codable, Equatable {
} else {
self.privacy = nil
}
self.timestamp = try container.decodeIfPresent(Int32.self, forKey: .timestamp) ?? 1688909663
}
public func encode(to encoder: Encoder) throws {
@ -145,6 +150,7 @@ public final class MediaEditorDraft: Codable, Equatable {
} else {
try container.encodeNil(forKey: .privacy)
}
try container.encode(self.timestamp, forKey: .timestamp)
}
}

View File

@ -1719,7 +1719,7 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
self.gradientView = UIImageView()
self.entitiesContainerView = UIView(frame: CGRect(origin: .zero, size: storyDimensions))
self.entitiesView = DrawingEntitiesView(context: controller.context, size: storyDimensions)
self.entitiesView = DrawingEntitiesView(context: controller.context, size: storyDimensions, hasBin: true)
self.entitiesView.getEntityCenterPosition = {
return CGPoint(x: storyDimensions.width / 2.0, y: storyDimensions.height / 2.0)
}
@ -2100,8 +2100,37 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
}).start()
}
},
getCurrentImage: {
getCurrentImage: { [weak self] in
guard let self else {
return nil
}
let colorSpace = CGColorSpaceCreateDeviceRGB()
let imageSize = CGSize(width: 1080, height: 1920)
let context = DrawingContext(size: imageSize, scale: 1.0, opaque: true, colorSpace: colorSpace)
context?.withFlippedContext { context in
if let gradientImage = self.gradientView.image?.cgImage {
context.draw(gradientImage, in: CGRect(origin: .zero, size: imageSize))
}
if let image = self.mediaEditor?.resultImage, let values = self.mediaEditor?.values {
let initialScale: CGFloat
if image.size.height > image.size.width {
initialScale = max(imageSize.width / image.size.width, imageSize.height / image.size.height)
} else {
initialScale = imageSize.width / image.size.width
}
let scale = initialScale * values.cropScale
context.translateBy(x: imageSize.width / 2.0 + values.cropOffset.x, y: imageSize.height / 2.0 - values.cropOffset.y)
context.rotate(by: -values.cropRotation)
context.scaleBy(x: scale, y: scale)
if let cgImage = image.cgImage {
context.draw(cgImage, in: CGRect(x: -image.size.width / 2.0, y: -image.size.height / 2.0, width: image.size.width, height: image.size.height))
}
}
}
return context?.generateImage(colorSpace: colorSpace)
},
getControllerNode: { [weak self] in
return self
@ -2718,6 +2747,12 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
}
}
})
galleryController.customModalStyleOverlayTransitionFactorUpdated = { [weak self, weak galleryController] transition in
if let self, let galleryController {
let transitionFactor = galleryController.modalStyleOverlayTransitionFactor
self.updateModalTransitionFactor(transitionFactor, transition: transition)
}
}
controller.push(galleryController)
}
@ -2906,36 +2941,7 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
existingStickerPickerInputData: self.stickerPickerInputData
)
controller.getCurrentImage = { [weak self] in
guard let self else {
return nil
}
let colorSpace = CGColorSpaceCreateDeviceRGB()
let imageSize = CGSize(width: 1080, height: 1920)
let context = DrawingContext(size: imageSize, scale: 1.0, opaque: true, colorSpace: colorSpace)
context?.withFlippedContext { context in
if let gradientImage = self.gradientView.image?.cgImage {
context.draw(gradientImage, in: CGRect(origin: .zero, size: imageSize))
}
if let image = self.mediaEditor?.resultImage, let values = self.mediaEditor?.values {
let initialScale: CGFloat
if image.size.height > image.size.width {
initialScale = max(imageSize.width / image.size.width, imageSize.height / image.size.height)
} else {
initialScale = imageSize.width / image.size.width
}
let scale = initialScale * values.cropScale
context.translateBy(x: imageSize.width / 2.0 + values.cropOffset.x, y: imageSize.height / 2.0 - values.cropOffset.y)
context.rotate(by: -values.cropRotation)
context.scaleBy(x: scale, y: scale)
if let cgImage = image.cgImage {
context.draw(cgImage, in: CGRect(x: -image.size.width / 2.0, y: -image.size.height / 2.0, width: image.size.width, height: image.size.height))
}
}
}
return context?.generateImage(colorSpace: colorSpace)
return self?.interaction?.getCurrentImage()
}
controller.updateVideoPlayback = { [weak self] play in
guard let self else {
@ -3592,6 +3598,13 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
let caption = self.getCaption()
let duration = mediaEditor.duration ?? 0.0
var timestamp: Int32
if case let .draft(draft, _) = subject {
timestamp = draft.timestamp
} else {
timestamp = Int32(CFAbsoluteTimeGetCurrent() + kCFAbsoluteTimeIntervalSince1970)
}
if let resultImage = mediaEditor.resultImage {
mediaEditor.seek(0.0, andPlay: false)
makeEditorImageComposition(context: self.node.ciContext, account: self.context.account, inputImage: resultImage, dimensions: storyDimensions, values: values, time: .zero, completion: { resultImage in
@ -3604,7 +3617,7 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
if let thumbnailImage = generateScaledImage(image: resultImage, size: fittedSize) {
let path = "\(Int64.random(in: .min ... .max)).jpg"
if let data = image.jpegData(compressionQuality: 0.87) {
let draft = MediaEditorDraft(path: path, isVideo: false, thumbnail: thumbnailImage, dimensions: dimensions, duration: nil, values: values, caption: caption, privacy: privacy)
let draft = MediaEditorDraft(path: path, isVideo: false, thumbnail: thumbnailImage, dimensions: dimensions, duration: nil, values: values, caption: caption, privacy: privacy, timestamp: timestamp)
try? data.write(to: URL(fileURLWithPath: draft.fullPath()))
if let id {
saveStorySource(engine: self.context.engine, item: draft, id: id)
@ -3618,7 +3631,7 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
let saveVideoDraft: (String, PixelDimensions, Double) -> Void = { videoPath, dimensions, duration in
if let thumbnailImage = generateScaledImage(image: resultImage, size: fittedSize) {
let path = "\(Int64.random(in: .min ... .max)).mp4"
let draft = MediaEditorDraft(path: path, isVideo: true, thumbnail: thumbnailImage, dimensions: dimensions, duration: duration, values: values, caption: caption, privacy: privacy)
let draft = MediaEditorDraft(path: path, isVideo: true, thumbnail: thumbnailImage, dimensions: dimensions, duration: duration, values: values, caption: caption, privacy: privacy, timestamp: timestamp)
try? FileManager.default.moveItem(atPath: videoPath, toPath: draft.fullPath())
if let id {
saveStorySource(engine: self.context.engine, item: draft, id: id)
@ -3860,7 +3873,7 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
})
if case let .draft(draft, id) = subject, id == nil {
removeStoryDraft(engine: self.context.engine, path: draft.path, delete: !draft.isVideo)
removeStoryDraft(engine: self.context.engine, path: draft.path, delete: false)
}
} else {
if let image = mediaEditor.resultImage {

View File

@ -2472,7 +2472,7 @@ final class StoryItemSetContainerSendMessage {
return
}
if !hashtag.isEmpty {
let searchController = component.context.sharedContext.makeHashtagSearchController(context: component.context, peer: peer.flatMap(EnginePeer.init), query: hashtag)
let searchController = component.context.sharedContext.makeHashtagSearchController(context: component.context, peer: peer.flatMap(EnginePeer.init), query: hashtag, all: true)
navigationController.pushViewController(searchController)
}
}))

View File

@ -1720,8 +1720,8 @@ public final class SharedAccountContextImpl: SharedAccountContext {
return inputPanelNode
}
public func makeHashtagSearchController(context: AccountContext, peer: EnginePeer?, query: String) -> ViewController {
return HashtagSearchController(context: context, peer: peer, query: query)
public func makeHashtagSearchController(context: AccountContext, peer: EnginePeer?, query: String, all: Bool) -> ViewController {
return HashtagSearchController(context: context, peer: peer, query: query, all: all)
}
public func makeMyStoriesController(context: AccountContext, isArchive: Bool) -> ViewController {