Swiftgram/TelegramUI/LegacyInstantVideoController.swift
Peter fc8fa045a6 Fixed Apple Pay
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
2018-10-13 03:31:39 +03:00

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
}