mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Video avatar fixes
This commit is contained in:
parent
37cfe95fb6
commit
688d692993
@ -563,8 +563,8 @@ public class ItemListAvatarAndNameInfoItemNode: ListViewItemNode, ItemListItemNo
|
|||||||
if strongSelf.updatingAvatarOverlay.supernode == nil {
|
if strongSelf.updatingAvatarOverlay.supernode == nil {
|
||||||
strongSelf.insertSubnode(strongSelf.updatingAvatarOverlay, aboveSubnode: strongSelf.avatarNode)
|
strongSelf.insertSubnode(strongSelf.updatingAvatarOverlay, aboveSubnode: strongSelf.avatarNode)
|
||||||
}
|
}
|
||||||
if let updatingImage = item.updatingImage, case .image(_, true) = updatingImage {
|
if let updatingImage = item.updatingImage, case let .image(_, loading) = updatingImage {
|
||||||
strongSelf.activityIndicator.isHidden = false
|
strongSelf.activityIndicator.isHidden = !loading
|
||||||
}
|
}
|
||||||
} else if strongSelf.updatingAvatarOverlay.supernode != nil {
|
} else if strongSelf.updatingAvatarOverlay.supernode != nil {
|
||||||
if animated {
|
if animated {
|
||||||
|
@ -83,7 +83,7 @@ final class AuthorizationSequenceSignUpController: ViewController {
|
|||||||
let currentAvatarMixin = Atomic<NSObject?>(value: nil)
|
let currentAvatarMixin = Atomic<NSObject?>(value: nil)
|
||||||
|
|
||||||
self.displayNode = AuthorizationSequenceSignUpControllerNode(theme: self.presentationData.theme, strings: self.presentationData.strings, addPhoto: { [weak self] in
|
self.displayNode = AuthorizationSequenceSignUpControllerNode(theme: self.presentationData.theme, strings: self.presentationData.strings, addPhoto: { [weak self] in
|
||||||
presentLegacyAvatarPicker(holder: currentAvatarMixin, signup: true, theme: defaultPresentationTheme, present: { c, a in
|
presentLegacyAvatarPicker(holder: currentAvatarMixin, signup: false, theme: defaultPresentationTheme, present: { c, a in
|
||||||
self?.view.endEditing(true)
|
self?.view.endEditing(true)
|
||||||
self?.present(c, in: .window(.root), with: a)
|
self?.present(c, in: .window(.root), with: a)
|
||||||
}, openCurrent: nil, completion: { image in
|
}, openCurrent: nil, completion: { image in
|
||||||
|
@ -17,6 +17,7 @@ import ItemListAvatarAndNameInfoItem
|
|||||||
import WebSearchUI
|
import WebSearchUI
|
||||||
import PeerInfoUI
|
import PeerInfoUI
|
||||||
import MapResourceToAvatarSizes
|
import MapResourceToAvatarSizes
|
||||||
|
import LegacyMediaPickerUI
|
||||||
|
|
||||||
private struct CreateChannelArguments {
|
private struct CreateChannelArguments {
|
||||||
let context: AccountContext
|
let context: AccountContext
|
||||||
@ -214,6 +215,7 @@ public func createChannelController(context: AccountContext) -> ViewController {
|
|||||||
let currentAvatarMixin = Atomic<TGMediaAvatarMenuMixin?>(value: nil)
|
let currentAvatarMixin = Atomic<TGMediaAvatarMenuMixin?>(value: nil)
|
||||||
|
|
||||||
let uploadedAvatar = Promise<UploadedPeerPhotoData>()
|
let uploadedAvatar = Promise<UploadedPeerPhotoData>()
|
||||||
|
var uploadedVideoAvatar: (Promise<UploadedPeerPhotoData?>, Double?)? = nil
|
||||||
|
|
||||||
let arguments = CreateChannelArguments(context: context, updateEditingName: { editingName in
|
let arguments = CreateChannelArguments(context: context, updateEditingName: { editingName in
|
||||||
updateState { current in
|
updateState { current in
|
||||||
@ -260,7 +262,7 @@ public func createChannelController(context: AccountContext) -> ViewController {
|
|||||||
return $0.avatar
|
return $0.avatar
|
||||||
}
|
}
|
||||||
if let _ = updatingAvatar {
|
if let _ = updatingAvatar {
|
||||||
let _ = updatePeerPhoto(postbox: context.account.postbox, network: context.account.network, stateManager: context.account.stateManager, accountPeerId: context.account.peerId, peerId: peerId, photo: uploadedAvatar.get(), mapResourceToAvatarSizes: { resource, representations in
|
let _ = updatePeerPhoto(postbox: context.account.postbox, network: context.account.network, stateManager: context.account.stateManager, accountPeerId: context.account.peerId, peerId: peerId, photo: uploadedAvatar.get(), video: uploadedVideoAvatar?.0.get(), videoStartTimestamp: uploadedVideoAvatar?.1, mapResourceToAvatarSizes: { resource, representations in
|
||||||
return mapResourceToAvatarSizes(postbox: context.account.postbox, resource: resource, representations: representations)
|
return mapResourceToAvatarSizes(postbox: context.account.postbox, resource: resource, representations: representations)
|
||||||
}).start()
|
}).start()
|
||||||
}
|
}
|
||||||
@ -311,12 +313,13 @@ public func createChannelController(context: AccountContext) -> ViewController {
|
|||||||
endEditingImpl?()
|
endEditingImpl?()
|
||||||
presentControllerImpl?(legacyController, nil)
|
presentControllerImpl?(legacyController, nil)
|
||||||
|
|
||||||
let completedImpl: (UIImage) -> Void = { image in
|
let completedChannelPhotoImpl: (UIImage) -> Void = { image in
|
||||||
if let data = image.jpegData(compressionQuality: 0.6) {
|
if let data = image.jpegData(compressionQuality: 0.6) {
|
||||||
let resource = LocalFileMediaResource(fileId: arc4random64())
|
let resource = LocalFileMediaResource(fileId: arc4random64())
|
||||||
context.account.postbox.mediaBox.storeResourceData(resource.id, data: data)
|
context.account.postbox.mediaBox.storeResourceData(resource.id, data: data)
|
||||||
let representation = TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 640, height: 640), resource: resource)
|
let representation = TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 640, height: 640), resource: resource)
|
||||||
uploadedAvatar.set(uploadedPeerPhoto(postbox: context.account.postbox, network: context.account.network, resource: resource))
|
uploadedAvatar.set(uploadedPeerPhoto(postbox: context.account.postbox, network: context.account.network, resource: resource))
|
||||||
|
uploadedVideoAvatar = nil
|
||||||
updateState { current in
|
updateState { current in
|
||||||
var current = current
|
var current = current
|
||||||
current.avatar = .image(representation, false)
|
current.avatar = .image(representation, false)
|
||||||
@ -325,18 +328,113 @@ public func createChannelController(context: AccountContext) -> ViewController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let completedChannelVideoImpl: (UIImage, URL, TGVideoEditAdjustments?) -> Void = { image, url, adjustments in
|
||||||
|
if let data = image.jpegData(compressionQuality: 0.6) {
|
||||||
|
let photoResource = LocalFileMediaResource(fileId: arc4random64())
|
||||||
|
context.account.postbox.mediaBox.storeResourceData(photoResource.id, data: data)
|
||||||
|
let representation = TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 640, height: 640), resource: photoResource)
|
||||||
|
updateState { state in
|
||||||
|
var state = state
|
||||||
|
state.avatar = .image(representation, true)
|
||||||
|
return state
|
||||||
|
}
|
||||||
|
|
||||||
|
var videoStartTimestamp: Double? = nil
|
||||||
|
if let adjustments = adjustments, adjustments.videoStartValue > 0.0 {
|
||||||
|
videoStartTimestamp = adjustments.videoStartValue - adjustments.trimStartValue
|
||||||
|
}
|
||||||
|
|
||||||
|
let signal = Signal<TelegramMediaResource?, UploadPeerPhotoError> { subscriber in
|
||||||
|
var filteredPath = url.path
|
||||||
|
if filteredPath.hasPrefix("file://") {
|
||||||
|
filteredPath = String(filteredPath[filteredPath.index(filteredPath.startIndex, offsetBy: "file://".count)])
|
||||||
|
}
|
||||||
|
|
||||||
|
let avAsset = AVURLAsset(url: URL(fileURLWithPath: filteredPath))
|
||||||
|
let entityRenderer: LegacyPaintEntityRenderer? = adjustments.flatMap { adjustments in
|
||||||
|
if let paintingData = adjustments.paintingData, paintingData.hasAnimation {
|
||||||
|
return LegacyPaintEntityRenderer(account: context.account, adjustments: adjustments)
|
||||||
|
} else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let uploadInterface = LegacyLiveUploadInterface(account: context.account)
|
||||||
|
let signal = TGMediaVideoConverter.convert(avAsset, adjustments: adjustments, watcher: uploadInterface, entityRenderer: entityRenderer)!
|
||||||
|
|
||||||
|
let signalDisposable = signal.start(next: { next in
|
||||||
|
if let result = next as? TGMediaVideoConversionResult {
|
||||||
|
if let image = result.coverImage, let data = image.jpegData(compressionQuality: 0.7) {
|
||||||
|
context.account.postbox.mediaBox.storeResourceData(photoResource.id, data: data)
|
||||||
|
}
|
||||||
|
|
||||||
|
updateState { state in
|
||||||
|
var state = state
|
||||||
|
state.avatar = .image(representation, false)
|
||||||
|
return state
|
||||||
|
}
|
||||||
|
|
||||||
|
var value = stat()
|
||||||
|
if stat(result.fileURL.path, &value) == 0 {
|
||||||
|
if let data = try? Data(contentsOf: result.fileURL) {
|
||||||
|
let resource: TelegramMediaResource
|
||||||
|
if let liveUploadData = result.liveUploadData as? LegacyLiveUploadInterfaceResult {
|
||||||
|
resource = LocalFileMediaResource(fileId: liveUploadData.id)
|
||||||
|
} else {
|
||||||
|
resource = LocalFileMediaResource(fileId: arc4random64())
|
||||||
|
}
|
||||||
|
context.account.postbox.mediaBox.storeResourceData(resource.id, data: data, synchronous: true)
|
||||||
|
subscriber.putNext(resource)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
subscriber.putCompletion()
|
||||||
|
}
|
||||||
|
}, error: { _ in
|
||||||
|
}, completed: nil)
|
||||||
|
|
||||||
|
let disposable = ActionDisposable {
|
||||||
|
signalDisposable?.dispose()
|
||||||
|
}
|
||||||
|
|
||||||
|
return ActionDisposable {
|
||||||
|
disposable.dispose()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uploadedAvatar.set(uploadedPeerPhoto(postbox: context.account.postbox, network: context.account.network, resource: photoResource))
|
||||||
|
|
||||||
|
let promise = Promise<UploadedPeerPhotoData?>()
|
||||||
|
promise.set(signal
|
||||||
|
|> `catch` { _ -> Signal<TelegramMediaResource?, NoError> in
|
||||||
|
return .single(nil)
|
||||||
|
}
|
||||||
|
|> mapToSignal { resource -> Signal<UploadedPeerPhotoData?, NoError> in
|
||||||
|
if let resource = resource {
|
||||||
|
return uploadedPeerVideo(postbox: context.account.postbox, network: context.account.network, messageMediaPreuploadManager: context.account.messageMediaPreuploadManager, resource: resource) |> map(Optional.init)
|
||||||
|
} else {
|
||||||
|
return .single(nil)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
uploadedVideoAvatar = (promise, videoStartTimestamp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let mixin = TGMediaAvatarMenuMixin(context: legacyController.context, parentController: emptyController, hasSearchButton: true, hasDeleteButton: stateValue.with({ $0.avatar }) != nil, hasViewButton: false, personalPhoto: false, isVideo: false, saveEditedPhotos: false, saveCapturedMedia: false, signup: false)!
|
let mixin = TGMediaAvatarMenuMixin(context: legacyController.context, parentController: emptyController, hasSearchButton: true, hasDeleteButton: stateValue.with({ $0.avatar }) != nil, hasViewButton: false, personalPhoto: false, isVideo: false, saveEditedPhotos: false, saveCapturedMedia: false, signup: false)!
|
||||||
let _ = currentAvatarMixin.swap(mixin)
|
let _ = currentAvatarMixin.swap(mixin)
|
||||||
mixin.requestSearchController = { assetsController in
|
mixin.requestSearchController = { assetsController in
|
||||||
let controller = WebSearchController(context: context, peer: peer, configuration: searchBotsConfiguration, mode: .avatar(initialQuery: title, completion: { result in
|
let controller = WebSearchController(context: context, peer: peer, configuration: searchBotsConfiguration, mode: .avatar(initialQuery: title, completion: { result in
|
||||||
assetsController?.dismiss()
|
assetsController?.dismiss()
|
||||||
completedImpl(result)
|
completedChannelPhotoImpl(result)
|
||||||
}))
|
}))
|
||||||
presentControllerImpl?(controller, ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
|
presentControllerImpl?(controller, ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
|
||||||
}
|
}
|
||||||
mixin.didFinishWithImage = { image in
|
mixin.didFinishWithImage = { image in
|
||||||
if let image = image {
|
if let image = image {
|
||||||
completedImpl(image)
|
completedChannelPhotoImpl(image)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mixin.didFinishWithVideo = { image, url, adjustments in
|
||||||
|
if let image = image, let url = url {
|
||||||
|
completedChannelVideoImpl(image, url, adjustments)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if stateValue.with({ $0.avatar }) != nil {
|
if stateValue.with({ $0.avatar }) != nil {
|
||||||
|
@ -384,7 +384,7 @@ public func createGroupControllerImpl(context: AccountContext, peerIds: [PeerId]
|
|||||||
let currentAvatarMixin = Atomic<TGMediaAvatarMenuMixin?>(value: nil)
|
let currentAvatarMixin = Atomic<TGMediaAvatarMenuMixin?>(value: nil)
|
||||||
|
|
||||||
let uploadedAvatar = Promise<UploadedPeerPhotoData>()
|
let uploadedAvatar = Promise<UploadedPeerPhotoData>()
|
||||||
var uploadedVideoAvatar: Promise<UploadedPeerPhotoData?>? = nil
|
var uploadedVideoAvatar: (Promise<UploadedPeerPhotoData?>, Double?)? = nil
|
||||||
|
|
||||||
let addressPromise = Promise<String?>(nil)
|
let addressPromise = Promise<String?>(nil)
|
||||||
let venuesPromise = Promise<[TelegramMediaMap]?>(nil)
|
let venuesPromise = Promise<[TelegramMediaMap]?>(nil)
|
||||||
@ -482,7 +482,7 @@ public func createGroupControllerImpl(context: AccountContext, peerIds: [PeerId]
|
|||||||
return $0.avatar
|
return $0.avatar
|
||||||
}
|
}
|
||||||
if let _ = updatingAvatar {
|
if let _ = updatingAvatar {
|
||||||
return updatePeerPhoto(postbox: context.account.postbox, network: context.account.network, stateManager: context.account.stateManager, accountPeerId: context.account.peerId, peerId: peerId, photo: uploadedAvatar.get(), video: uploadedVideoAvatar?.get(), mapResourceToAvatarSizes: { resource, representations in
|
return updatePeerPhoto(postbox: context.account.postbox, network: context.account.network, stateManager: context.account.stateManager, accountPeerId: context.account.peerId, peerId: peerId, photo: uploadedAvatar.get(), video: uploadedVideoAvatar?.0.get(), videoStartTimestamp: uploadedVideoAvatar?.1, mapResourceToAvatarSizes: { resource, representations in
|
||||||
return mapResourceToAvatarSizes(postbox: context.account.postbox, resource: resource, representations: representations)
|
return mapResourceToAvatarSizes(postbox: context.account.postbox, resource: resource, representations: representations)
|
||||||
})
|
})
|
||||||
|> ignoreValues
|
|> ignoreValues
|
||||||
@ -602,7 +602,7 @@ public func createGroupControllerImpl(context: AccountContext, peerIds: [PeerId]
|
|||||||
videoStartTimestamp = adjustments.videoStartValue - adjustments.trimStartValue
|
videoStartTimestamp = adjustments.videoStartValue - adjustments.trimStartValue
|
||||||
}
|
}
|
||||||
|
|
||||||
let signal = Signal<TelegramMediaResource, UploadPeerPhotoError> { subscriber in
|
let signal = Signal<TelegramMediaResource?, UploadPeerPhotoError> { subscriber in
|
||||||
var filteredPath = url.path
|
var filteredPath = url.path
|
||||||
if filteredPath.hasPrefix("file://") {
|
if filteredPath.hasPrefix("file://") {
|
||||||
filteredPath = String(filteredPath[filteredPath.index(filteredPath.startIndex, offsetBy: "file://".count)])
|
filteredPath = String(filteredPath[filteredPath.index(filteredPath.startIndex, offsetBy: "file://".count)])
|
||||||
@ -625,6 +625,12 @@ public func createGroupControllerImpl(context: AccountContext, peerIds: [PeerId]
|
|||||||
context.account.postbox.mediaBox.storeResourceData(photoResource.id, data: data)
|
context.account.postbox.mediaBox.storeResourceData(photoResource.id, data: data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateState { state in
|
||||||
|
var state = state
|
||||||
|
state.avatar = .image(representation, false)
|
||||||
|
return state
|
||||||
|
}
|
||||||
|
|
||||||
var value = stat()
|
var value = stat()
|
||||||
if stat(result.fileURL.path, &value) == 0 {
|
if stat(result.fileURL.path, &value) == 0 {
|
||||||
if let data = try? Data(contentsOf: result.fileURL) {
|
if let data = try? Data(contentsOf: result.fileURL) {
|
||||||
@ -652,14 +658,21 @@ public func createGroupControllerImpl(context: AccountContext, peerIds: [PeerId]
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// let promise = Promise<UploadedPeerPhotoData?>()
|
uploadedAvatar.set(uploadedPeerPhoto(postbox: context.account.postbox, network: context.account.network, resource: photoResource))
|
||||||
// promise.set(signal |> mapToSignal { resource in
|
|
||||||
// return uploadedPeerVideo(postbox: context.account.postbox, network: context.account.network, messageMediaPreuploadManager: context.account.messageMediaPreuploadManager, resource: resource) |> map(Optional.init)
|
let promise = Promise<UploadedPeerPhotoData?>()
|
||||||
// |> `catch` { _ -> Signal<UploadedPeerPhotoData?, NoError> in
|
promise.set(signal
|
||||||
// return .single(nil)
|
|> `catch` { _ -> Signal<TelegramMediaResource?, NoError> in
|
||||||
// }
|
return .single(nil)
|
||||||
// })
|
}
|
||||||
// uploadedVideoAvatar = promise
|
|> mapToSignal { resource -> Signal<UploadedPeerPhotoData?, NoError> in
|
||||||
|
if let resource = resource {
|
||||||
|
return uploadedPeerVideo(postbox: context.account.postbox, network: context.account.network, messageMediaPreuploadManager: context.account.messageMediaPreuploadManager, resource: resource) |> map(Optional.init)
|
||||||
|
} else {
|
||||||
|
return .single(nil)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
uploadedVideoAvatar = (promise, videoStartTimestamp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -677,8 +690,10 @@ public func createGroupControllerImpl(context: AccountContext, peerIds: [PeerId]
|
|||||||
completedGroupPhotoImpl(image)
|
completedGroupPhotoImpl(image)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mixin.didFinishWithVideo = { _, _, _ in
|
mixin.didFinishWithVideo = { image, url, adjustments in
|
||||||
|
if let image = image, let url = url {
|
||||||
|
completedGroupVideoImpl(image, url, adjustments)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if stateValue.with({ $0.avatar }) != nil {
|
if stateValue.with({ $0.avatar }) != nil {
|
||||||
mixin.didFinishWithDelete = {
|
mixin.didFinishWithDelete = {
|
||||||
|
@ -175,9 +175,11 @@ private final class PeerInfoScreenMemberItemNode: PeerInfoScreenItemNode {
|
|||||||
|
|
||||||
let itemHeight: ItemListPeerItemHeight
|
let itemHeight: ItemListPeerItemHeight
|
||||||
let itemText: ItemListPeerItemText
|
let itemText: ItemListPeerItemText
|
||||||
|
var synchronousLoads = false
|
||||||
if case .account = item.member {
|
if case .account = item.member {
|
||||||
itemHeight = .generic
|
itemHeight = .generic
|
||||||
itemText = .none
|
itemText = .none
|
||||||
|
synchronousLoads = true
|
||||||
} else {
|
} else {
|
||||||
itemHeight = .peerList
|
itemHeight = .peerList
|
||||||
itemText = .presence
|
itemText = .presence
|
||||||
@ -207,7 +209,7 @@ private final class PeerInfoScreenMemberItemNode: PeerInfoScreenItemNode {
|
|||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
var itemNodeValue: ListViewItemNode?
|
var itemNodeValue: ListViewItemNode?
|
||||||
peerItem.nodeConfiguredForParams(async: { $0() }, params: params, synchronousLoads: false, previousItem: nil, nextItem: nil, completion: { node, apply in
|
peerItem.nodeConfiguredForParams(async: { $0() }, params: params, synchronousLoads: synchronousLoads, previousItem: nil, nextItem: nil, completion: { node, apply in
|
||||||
itemNodeValue = node
|
itemNodeValue = node
|
||||||
apply().1(ListViewItemApply(isOnScreen: true))
|
apply().1(ListViewItemApply(isOnScreen: true))
|
||||||
})
|
})
|
||||||
|
Loading…
x
Reference in New Issue
Block a user