mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00

Added ability to download music without streaming Added progress indicators for various blocking tasks Fixed image gallery swipe to dismiss after zooming Added online member count indication in supergroups Fixed contact statuses in contact search
170 lines
8.8 KiB
Swift
170 lines
8.8 KiB
Swift
import Foundation
|
|
import Display
|
|
import TelegramCore
|
|
import Postbox
|
|
import SwiftSignalKit
|
|
|
|
import LegacyComponents
|
|
|
|
final class InstantVideoControllerRecordingStatus {
|
|
let micLevel: Signal<Float, NoError>
|
|
|
|
init(micLevel: Signal<Float, NoError>) {
|
|
self.micLevel = micLevel
|
|
}
|
|
}
|
|
|
|
final class InstantVideoController: LegacyController {
|
|
private var captureController: TGVideoMessageCaptureController?
|
|
|
|
var onDismiss: (() -> Void)?
|
|
var onStop: (() -> Void)?
|
|
|
|
private let micLevelValue = ValuePromise<Float>(0.0)
|
|
let audioStatus: InstantVideoControllerRecordingStatus
|
|
|
|
private var dismissedVideo = false
|
|
|
|
override init(presentation: LegacyControllerPresentation, theme: PresentationTheme?, strings: PresentationStrings? = nil, initialLayout: ContainerViewLayout? = nil) {
|
|
self.audioStatus = InstantVideoControllerRecordingStatus(micLevel: self.micLevelValue.get())
|
|
|
|
super.init(presentation: presentation, theme: theme, initialLayout: initialLayout)
|
|
}
|
|
|
|
required public init(coder aDecoder: NSCoder) {
|
|
fatalError("init(coder:) has not been implemented")
|
|
}
|
|
|
|
func bindCaptureController(_ captureController: TGVideoMessageCaptureController?) {
|
|
self.captureController = captureController
|
|
if let captureController = captureController {
|
|
captureController.micLevel = { [weak self] (level: CGFloat) -> Void in
|
|
self?.micLevelValue.set(Float(level))
|
|
}
|
|
captureController.onDismiss = { [weak self] _ in
|
|
self?.onDismiss?()
|
|
}
|
|
captureController.onStop = { [weak self] in
|
|
self?.onStop?()
|
|
}
|
|
}
|
|
}
|
|
|
|
func dismissVideo() {
|
|
if let captureController = self.captureController, !self.dismissedVideo {
|
|
self.dismissedVideo = true
|
|
captureController.dismiss()
|
|
}
|
|
}
|
|
|
|
func completeVideo() {
|
|
if let captureController = self.captureController, !self.dismissedVideo {
|
|
self.dismissedVideo = true
|
|
captureController.complete()
|
|
}
|
|
}
|
|
|
|
func stopVideo() -> Bool {
|
|
if let captureController = self.captureController {
|
|
return captureController.stop()
|
|
}
|
|
return false
|
|
}
|
|
|
|
func lockVideo() {
|
|
if let captureController = self.captureController {
|
|
return captureController.setLocked()
|
|
}
|
|
}
|
|
|
|
func updateRecordButtonInteraction(_ value: CGFloat) {
|
|
if let captureController = self.captureController {
|
|
captureController.buttonInteractionUpdate(CGPoint(x: value, y: 0.0))
|
|
}
|
|
}
|
|
}
|
|
|
|
func legacyInstantVideoController(theme: PresentationTheme, panelFrame: CGRect, account: Account, peerId: PeerId, send: @escaping (EnqueueMessage) -> Void) -> InstantVideoController {
|
|
let legacyController = InstantVideoController(presentation: .custom, theme: theme)
|
|
legacyController.supportedOrientations = ViewControllerSupportedOrientations(regularSize: .portrait, compactSize: .portrait)
|
|
legacyController.statusBar.statusBarStyle = .Hide
|
|
let baseController = TGViewController(context: legacyController.context)!
|
|
legacyController.bind(controller: baseController)
|
|
legacyController.presentationCompleted = { [weak legacyController, weak baseController] in
|
|
if let legacyController = legacyController, let baseController = baseController {
|
|
legacyController.view.disablesInteractiveTransitionGestureRecognizer = true
|
|
let inputPanelTheme = theme.chat.inputPanel
|
|
var uploadInterface: LegacyLiveUploadInterface?
|
|
if peerId.namespace != Namespaces.Peer.SecretChat {
|
|
uploadInterface = LegacyLiveUploadInterface(account: account)
|
|
}
|
|
let controller = TGVideoMessageCaptureController(context: legacyController.context, assets: TGVideoMessageCaptureControllerAssets(send: PresentationResourcesChat.chatInputPanelSendButtonImage(theme)!, slideToCancel: PresentationResourcesChat.chatInputPanelMediaRecordingCancelArrowImage(theme)!, actionDelete: generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Accessory Panels/MessageSelectionThrash"), color: theme.chat.inputPanel.panelControlAccentColor))!, transitionInView: {
|
|
return nil
|
|
}, parentController: baseController, controlsFrame: panelFrame, isAlreadyLocked: {
|
|
return false
|
|
}, liveUploadInterface: uploadInterface, pallete: TGModernConversationInputMicPallete(dark: theme.overallDarkAppearance, buttonColor: inputPanelTheme.actionControlFillColor, iconColor: inputPanelTheme.actionControlForegroundColor, backgroundColor: inputPanelTheme.panelBackgroundColor, borderColor: inputPanelTheme.panelStrokeColor, lock: inputPanelTheme.panelControlAccentColor, textColor: inputPanelTheme.primaryTextColor, secondaryTextColor: inputPanelTheme.secondaryTextColor, recording: inputPanelTheme.mediaRecordingDotColor))!
|
|
controller.finishedWithVideo = { videoUrl, previewImage, _, duration, dimensions, liveUploadData, adjustments in
|
|
guard let videoUrl = videoUrl else {
|
|
return
|
|
}
|
|
|
|
var finalDimensions: CGSize = dimensions
|
|
var finalDuration: Double = duration
|
|
|
|
var previewRepresentations: [TelegramMediaImageRepresentation] = []
|
|
if let previewImage = previewImage {
|
|
let resource = LocalFileMediaResource(fileId: arc4random64())
|
|
let thumbnailSize = finalDimensions.aspectFitted(CGSize(width: 90.0, height: 90.0))
|
|
let thumbnailImage = TGScaleImageToPixelSize(previewImage, thumbnailSize)!
|
|
if let thumbnailData = UIImageJPEGRepresentation(thumbnailImage, 0.4) {
|
|
account.postbox.mediaBox.storeResourceData(resource.id, data: thumbnailData)
|
|
previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: thumbnailSize, resource: resource))
|
|
}
|
|
}
|
|
|
|
finalDimensions = TGMediaVideoConverter.dimensions(for: finalDimensions, adjustments: adjustments, preset: TGMediaVideoConversionPresetVideoMessage)
|
|
|
|
var resourceAdjustments: VideoMediaResourceAdjustments?
|
|
if let adjustments = adjustments {
|
|
if adjustments.trimApplied() {
|
|
finalDuration = adjustments.trimEndValue - adjustments.trimStartValue
|
|
}
|
|
|
|
let adjustmentsData = MemoryBuffer(data: NSKeyedArchiver.archivedData(withRootObject: adjustments.dictionary()))
|
|
let digest = MemoryBuffer(data: adjustmentsData.md5Digest())
|
|
resourceAdjustments = VideoMediaResourceAdjustments(data: adjustmentsData, digest: digest)
|
|
}
|
|
|
|
if finalDuration.isZero || finalDuration.isNaN {
|
|
return
|
|
}
|
|
|
|
let resource: TelegramMediaResource
|
|
if let liveUploadData = liveUploadData as? LegacyLiveUploadInterfaceResult, resourceAdjustments == nil, let data = try? Data(contentsOf: videoUrl) {
|
|
resource = LocalFileMediaResource(fileId: liveUploadData.id)
|
|
account.postbox.mediaBox.storeResourceData(resource.id, data: data)
|
|
} else {
|
|
resource = LocalFileVideoMediaResource(randomId: arc4random64(), path: videoUrl.path, adjustments: resourceAdjustments)
|
|
}
|
|
|
|
if let previewImage = previewImage {
|
|
if let data = compressImageToJPEG(previewImage, quality: 0.7) {
|
|
account.postbox.mediaBox.storeCachedResourceRepresentation(resource, representation: CachedVideoFirstFrameRepresentation(), data: data)
|
|
}
|
|
}
|
|
|
|
let media = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: arc4random64()), partialReference: nil, resource: resource, previewRepresentations: previewRepresentations, mimeType: "video/mp4", size: nil, attributes: [.FileName(fileName: "video.mp4"), .Video(duration: Int(finalDuration), size: finalDimensions, flags: [.instantRoundVideo])])
|
|
let attributes: [MessageAttribute] = []
|
|
send(.message(text: "", attributes: attributes, mediaReference: .standalone(media: media), replyToMessageId: nil, localGroupingKey: nil))
|
|
}
|
|
controller.didDismiss = { [weak legacyController] in
|
|
if let legacyController = legacyController {
|
|
legacyController.dismiss()
|
|
}
|
|
}
|
|
legacyController.bindCaptureController(controller)
|
|
}
|
|
}
|
|
return legacyController
|
|
}
|