mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Add support for generic dice-like messages
This commit is contained in:
parent
36f89567ad
commit
a63457d7e7
BIN
Telegram/Telegram-iOS/Resources/Darts_Aiming.tgs
Normal file
BIN
Telegram/Telegram-iOS/Resources/Darts_Aiming.tgs
Normal file
Binary file not shown.
@ -160,8 +160,8 @@ public func chatListItemStrings(strings: PresentationStrings, nameDisplayOrder:
|
|||||||
}
|
}
|
||||||
case let poll as TelegramMediaPoll:
|
case let poll as TelegramMediaPoll:
|
||||||
messageText = "📊 \(poll.text)"
|
messageText = "📊 \(poll.text)"
|
||||||
case _ as TelegramMediaDice:
|
case let dice as TelegramMediaDice:
|
||||||
messageText = "🎲"
|
messageText = dice.emoji
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -187,8 +187,8 @@ func mediaContentToUpload(network: Network, postbox: Postbox, auxiliaryMethods:
|
|||||||
}
|
}
|
||||||
let inputPoll = Api.InputMedia.inputMediaPoll(flags: pollMediaFlags, poll: Api.Poll.poll(id: 0, flags: pollFlags, question: poll.text, answers: poll.options.map({ $0.apiOption }), closePeriod: poll.deadlineTimeout, closeDate: nil), correctAnswers: correctAnswers, solution: mappedSolution, solutionEntities: mappedSolutionEntities)
|
let inputPoll = Api.InputMedia.inputMediaPoll(flags: pollMediaFlags, poll: Api.Poll.poll(id: 0, flags: pollFlags, question: poll.text, answers: poll.options.map({ $0.apiOption }), closePeriod: poll.deadlineTimeout, closeDate: nil), correctAnswers: correctAnswers, solution: mappedSolution, solutionEntities: mappedSolutionEntities)
|
||||||
return .single(.content(PendingMessageUploadedContentAndReuploadInfo(content: .media(inputPoll, text), reuploadInfo: nil)))
|
return .single(.content(PendingMessageUploadedContentAndReuploadInfo(content: .media(inputPoll, text), reuploadInfo: nil)))
|
||||||
} else if let _ = media as? TelegramMediaDice {
|
} else if let dice = media as? TelegramMediaDice {
|
||||||
let input = Api.InputMedia.inputMediaDice
|
let input = Api.InputMedia.inputMediaDice(emoticon: dice.emoji)
|
||||||
return .single(.content(PendingMessageUploadedContentAndReuploadInfo(content: .media(input, text), reuploadInfo: nil)))
|
return .single(.content(PendingMessageUploadedContentAndReuploadInfo(content: .media(input, text), reuploadInfo: nil)))
|
||||||
} else {
|
} else {
|
||||||
return nil
|
return nil
|
||||||
|
@ -43,7 +43,7 @@ public enum MessageContentKind: Equatable {
|
|||||||
case expiredVideo
|
case expiredVideo
|
||||||
case poll(String)
|
case poll(String)
|
||||||
case restricted(String)
|
case restricted(String)
|
||||||
case dice
|
case dice(String)
|
||||||
|
|
||||||
public var key: MessageContentKindKey {
|
public var key: MessageContentKindKey {
|
||||||
switch self {
|
switch self {
|
||||||
@ -169,8 +169,8 @@ public func mediaContentKind(_ media: Media, message: Message? = nil, strings: P
|
|||||||
}
|
}
|
||||||
case let poll as TelegramMediaPoll:
|
case let poll as TelegramMediaPoll:
|
||||||
return .poll(poll.text)
|
return .poll(poll.text)
|
||||||
case _ as TelegramMediaDice:
|
case let dice as TelegramMediaDice:
|
||||||
return .dice
|
return .dice(dice.emoji)
|
||||||
default:
|
default:
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -218,8 +218,8 @@ public func stringForMediaKind(_ kind: MessageContentKind, strings: Presentation
|
|||||||
return ("📊 \(text)", false)
|
return ("📊 \(text)", false)
|
||||||
case let .restricted(text):
|
case let .restricted(text):
|
||||||
return (text, false)
|
return (text, false)
|
||||||
case .dice:
|
case let .dice(emoji):
|
||||||
return ("🎲", true)
|
return (emoji, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2260,8 +2260,9 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
var messages: [EnqueueMessage] = []
|
var messages: [EnqueueMessage] = []
|
||||||
|
|
||||||
let effectiveInputText = effectivePresentationInterfaceState.interfaceState.composeInputState.inputText
|
let effectiveInputText = effectivePresentationInterfaceState.interfaceState.composeInputState.inputText
|
||||||
if case let .peer(peerId) = effectivePresentationInterfaceState.chatLocation, peerId.namespace != Namespaces.Peer.SecretChat, effectiveInputText.string.trimmingCharacters(in: .whitespacesAndNewlines) == "🎲" {
|
let trimmedInputText = effectiveInputText.string.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||||
messages.append(.message(text: "", attributes: [], mediaReference: AnyMediaReference.standalone(media: TelegramMediaDice()), replyToMessageId: self.chatPresentationInterfaceState.interfaceState.replyMessageId, localGroupingKey: nil))
|
if case let .peer(peerId) = effectivePresentationInterfaceState.chatLocation, peerId.namespace != Namespaces.Peer.SecretChat, ["🎲", "🎯"].contains(trimmedInputText) {
|
||||||
|
messages.append(.message(text: "", attributes: [], mediaReference: AnyMediaReference.standalone(media: TelegramMediaDice(emoji: trimmedInputText)), replyToMessageId: self.chatPresentationInterfaceState.interfaceState.replyMessageId, localGroupingKey: nil))
|
||||||
} else {
|
} else {
|
||||||
let inputText = convertMarkdownToAttributes(effectiveInputText)
|
let inputText = convertMarkdownToAttributes(effectiveInputText)
|
||||||
|
|
||||||
|
@ -614,8 +614,11 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
|||||||
}
|
}
|
||||||
|> distinctUntilChanged
|
|> distinctUntilChanged
|
||||||
|
|
||||||
let animatedEmojiStickers = combineLatest(loadedStickerPack(postbox: context.account.postbox, network: context.account.network, reference: .animatedEmoji, forceActualized: false), loadedStickerPack(postbox: context.account.postbox, network: context.account.network, reference: .dice, forceActualized: false))
|
|
||||||
|> map { animatedEmoji, dice -> [String: [StickerPackItem]] in
|
// loadedStickerPack(postbox: context.account.postbox, network: context.account.network, reference: .dice, forceActualized: false)
|
||||||
|
|
||||||
|
let animatedEmojiStickers = loadedStickerPack(postbox: context.account.postbox, network: context.account.network, reference: .animatedEmoji, forceActualized: false)
|
||||||
|
|> map { animatedEmoji -> [String: [StickerPackItem]] in
|
||||||
var animatedEmojiStickers: [String: [StickerPackItem]] = [:]
|
var animatedEmojiStickers: [String: [StickerPackItem]] = [:]
|
||||||
switch animatedEmoji {
|
switch animatedEmoji {
|
||||||
case let .result(_, items, _):
|
case let .result(_, items, _):
|
||||||
@ -631,23 +634,21 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
|||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
switch dice {
|
// switch dice {
|
||||||
case let .result(_, items, _):
|
// case let .result(_, items, _):
|
||||||
var diceStickers: [StickerPackItem] = []
|
// var diceStickers: [StickerPackItem] = []
|
||||||
for case let item as StickerPackItem in items {
|
// for case let item as StickerPackItem in items {
|
||||||
diceStickers.append(item)
|
// diceStickers.append(item)
|
||||||
}
|
// }
|
||||||
animatedEmojiStickers["dice"] = diceStickers
|
// animatedEmojiStickers["dice"] = diceStickers
|
||||||
default:
|
// default:
|
||||||
break
|
// break
|
||||||
}
|
// }
|
||||||
return animatedEmojiStickers
|
return animatedEmojiStickers
|
||||||
}
|
}
|
||||||
|
|
||||||
let previousHistoryAppearsCleared = Atomic<Bool?>(value: nil)
|
let previousHistoryAppearsCleared = Atomic<Bool?>(value: nil)
|
||||||
|
|
||||||
let nextTransitionVersion = Atomic<Int>(value: 0)
|
|
||||||
|
|
||||||
let updatingMedia = context.account.pendingUpdateMessageManager.updatingMessageMedia
|
let updatingMedia = context.account.pendingUpdateMessageManager.updatingMessageMedia
|
||||||
|> map { value -> [MessageId: ChatUpdatingMessageMedia] in
|
|> map { value -> [MessageId: ChatUpdatingMessageMedia] in
|
||||||
var result = value
|
var result = value
|
||||||
|
@ -256,7 +256,7 @@ func contextMenuForChatPresentationIntefaceState(chatPresentationInterfaceState:
|
|||||||
var loadStickerSaveStatus: MediaId?
|
var loadStickerSaveStatus: MediaId?
|
||||||
var loadCopyMediaResource: MediaResource?
|
var loadCopyMediaResource: MediaResource?
|
||||||
var isAction = false
|
var isAction = false
|
||||||
var isDice = false
|
var diceEmoji: String?
|
||||||
var canDiscuss = false
|
var canDiscuss = false
|
||||||
if messages.count == 1 {
|
if messages.count == 1 {
|
||||||
for media in messages[0].media {
|
for media in messages[0].media {
|
||||||
@ -272,8 +272,8 @@ func contextMenuForChatPresentationIntefaceState(chatPresentationInterfaceState:
|
|||||||
if !messages[0].containsSecretMedia {
|
if !messages[0].containsSecretMedia {
|
||||||
loadCopyMediaResource = largestImageRepresentation(image.representations)?.resource
|
loadCopyMediaResource = largestImageRepresentation(image.representations)?.resource
|
||||||
}
|
}
|
||||||
} else if let _ = media as? TelegramMediaDice {
|
} else if let dice = media as? TelegramMediaDice {
|
||||||
isDice = true
|
diceEmoji = dice.emoji
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -425,7 +425,7 @@ func contextMenuForChatPresentationIntefaceState(chatPresentationInterfaceState:
|
|||||||
resourceAvailable = false
|
resourceAvailable = false
|
||||||
}
|
}
|
||||||
|
|
||||||
if !messages[0].text.isEmpty || resourceAvailable || isDice {
|
if !messages[0].text.isEmpty || resourceAvailable || diceEmoji != nil {
|
||||||
let message = messages[0]
|
let message = messages[0]
|
||||||
var isExpired = false
|
var isExpired = false
|
||||||
for media in message.media {
|
for media in message.media {
|
||||||
@ -437,8 +437,8 @@ func contextMenuForChatPresentationIntefaceState(chatPresentationInterfaceState:
|
|||||||
actions.append(.action(ContextMenuActionItem(text: chatPresentationInterfaceState.strings.Conversation_ContextMenuCopy, icon: { theme in
|
actions.append(.action(ContextMenuActionItem(text: chatPresentationInterfaceState.strings.Conversation_ContextMenuCopy, icon: { theme in
|
||||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Copy"), color: theme.actionSheet.primaryTextColor)
|
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Copy"), color: theme.actionSheet.primaryTextColor)
|
||||||
}, action: { _, f in
|
}, action: { _, f in
|
||||||
if isDice {
|
if let diceEmoji = diceEmoji {
|
||||||
UIPasteboard.general.string = "🎲"
|
UIPasteboard.general.string = diceEmoji
|
||||||
} else {
|
} else {
|
||||||
let copyTextWithEntities = {
|
let copyTextWithEntities = {
|
||||||
var messageEntities: [MessageTextEntity]?
|
var messageEntities: [MessageTextEntity]?
|
||||||
|
@ -208,11 +208,9 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if let _ = self.telegramDice {
|
if let telegramDice = self.telegramDice {
|
||||||
if let diceEmojis = item.associatedData.animatedEmojiStickers["dice"] {
|
let animationNode = ManagedDiceAnimationNode(context: item.context, dice: telegramDice)
|
||||||
let animationNode = ManagedDiceAnimationNode(context: item.context, emojis: diceEmojis.map { $0.file })
|
self.animationNode = animationNode
|
||||||
self.animationNode = animationNode
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
let animationNode = AnimatedStickerNode()
|
let animationNode = AnimatedStickerNode()
|
||||||
animationNode.started = { [weak self] in
|
animationNode.started = { [weak self] in
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import Display
|
import Display
|
||||||
import AsyncDisplayKit
|
import AsyncDisplayKit
|
||||||
|
import Postbox
|
||||||
import SyncCore
|
import SyncCore
|
||||||
import TelegramCore
|
import TelegramCore
|
||||||
import SwiftSignalKit
|
import SwiftSignalKit
|
||||||
@ -13,16 +14,43 @@ enum ManagedDiceAnimationState: Equatable {
|
|||||||
case value(Int32, Bool)
|
case value(Int32, Bool)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func rollingAnimationItem(emoji: String) -> ManagedAnimationItem? {
|
||||||
|
switch emoji {
|
||||||
|
case "🎲":
|
||||||
|
return ManagedAnimationItem(source: .local("Dice_Rolling"), frames: ManagedAnimationFrameRange(startFrame: 0, endFrame: 60), duration: 1.0, loop: true)
|
||||||
|
case "🎯":
|
||||||
|
return ManagedAnimationItem(source: .local("Darts_Aiming"), frames: ManagedAnimationFrameRange(startFrame: 0, endFrame: 90), duration: 1.5, loop: true)
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
final class ManagedDiceAnimationNode: ManagedAnimationNode, GenericAnimatedStickerNode {
|
final class ManagedDiceAnimationNode: ManagedAnimationNode, GenericAnimatedStickerNode {
|
||||||
private let context: AccountContext
|
private let context: AccountContext
|
||||||
private let emojis: [TelegramMediaFile]
|
private let dice: TelegramMediaDice
|
||||||
|
|
||||||
private var diceState: ManagedDiceAnimationState? = nil
|
private var diceState: ManagedDiceAnimationState? = nil
|
||||||
private let disposable = MetaDisposable()
|
private let disposable = MetaDisposable()
|
||||||
|
|
||||||
init(context: AccountContext, emojis: [TelegramMediaFile]) {
|
private let emojis = Promise<[TelegramMediaFile]>()
|
||||||
|
|
||||||
|
init(context: AccountContext, dice: TelegramMediaDice) {
|
||||||
self.context = context
|
self.context = context
|
||||||
self.emojis = emojis
|
self.dice = dice
|
||||||
|
|
||||||
|
self.emojis.set(loadedStickerPack(postbox: context.account.postbox, network: context.account.network, reference: .dice(dice.emoji), forceActualized: false)
|
||||||
|
|> mapToSignal { stickerPack -> Signal<[TelegramMediaFile], NoError> in
|
||||||
|
switch stickerPack {
|
||||||
|
case let .result(_, items, _):
|
||||||
|
var emojiStickers: [TelegramMediaFile] = []
|
||||||
|
for case let item as StickerPackItem in items {
|
||||||
|
emojiStickers.append(item.file)
|
||||||
|
}
|
||||||
|
return .single(emojiStickers)
|
||||||
|
default:
|
||||||
|
return .complete()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
super.init(size: CGSize(width: 184.0, height: 184.0))
|
super.init(size: CGSize(width: 184.0, height: 184.0))
|
||||||
}
|
}
|
||||||
@ -35,98 +63,122 @@ final class ManagedDiceAnimationNode: ManagedAnimationNode, GenericAnimatedStick
|
|||||||
let previousState = self.diceState
|
let previousState = self.diceState
|
||||||
self.diceState = diceState
|
self.diceState = diceState
|
||||||
|
|
||||||
|
let frameCount: Int
|
||||||
|
let duration: Double
|
||||||
|
|
||||||
|
switch dice.emoji {
|
||||||
|
case "🎲":
|
||||||
|
frameCount = 180
|
||||||
|
duration = 3.0
|
||||||
|
case "🎯":
|
||||||
|
frameCount = 100
|
||||||
|
duration = 1.6
|
||||||
|
default:
|
||||||
|
frameCount = 180
|
||||||
|
duration = 1.6
|
||||||
|
}
|
||||||
|
|
||||||
|
let context = self.context
|
||||||
if let previousState = previousState {
|
if let previousState = previousState {
|
||||||
switch previousState {
|
switch previousState {
|
||||||
case .rolling:
|
case .rolling:
|
||||||
switch diceState {
|
switch diceState {
|
||||||
case let .value(value, _):
|
case let .value(value, _):
|
||||||
guard self.emojis.count == 6 else {
|
let animationItem: Signal<ManagedAnimationItem, NoError> = self.emojis.get()
|
||||||
return
|
|> mapToSignal { emojis -> Signal<ManagedAnimationItem, NoError> in
|
||||||
}
|
guard emojis.count > value else {
|
||||||
let file = self.emojis[Int(value) - 1]
|
return .complete()
|
||||||
let dimensions = file.dimensions ?? PixelDimensions(width: 512, height: 512)
|
|
||||||
let fittedSize = dimensions.cgSize.aspectFilled(CGSize(width: 384.0, height: 384.0))
|
|
||||||
|
|
||||||
let fetched = freeMediaFileInteractiveFetched(account: self.context.account, fileReference: .standalone(media: file))
|
|
||||||
let sticker = Signal<Void, NoError> { subscriber in
|
|
||||||
let fetchedDisposable = fetched.start()
|
|
||||||
let resourceDisposable = (chatMessageAnimationData(postbox: self.context.account.postbox, resource: file.resource, fitzModifier: nil, width: Int(fittedSize.width), height: Int(fittedSize.height), synchronousLoad: false)
|
|
||||||
|> filter { data in
|
|
||||||
return data.complete
|
|
||||||
}).start(next: { next in
|
|
||||||
subscriber.putNext(Void())
|
|
||||||
})
|
|
||||||
|
|
||||||
return ActionDisposable {
|
|
||||||
fetchedDisposable.dispose()
|
|
||||||
resourceDisposable.dispose()
|
|
||||||
}
|
}
|
||||||
}
|
let file = emojis[Int(value) - 1]
|
||||||
|
let dimensions = file.dimensions ?? PixelDimensions(width: 512, height: 512)
|
||||||
|
let fittedSize = dimensions.cgSize.aspectFilled(CGSize(width: 384.0, height: 384.0))
|
||||||
|
|
||||||
self.disposable.set((sticker |> deliverOnMainQueue).start(next: { [weak self] data in
|
let fetched = freeMediaFileInteractiveFetched(account: context.account, fileReference: .standalone(media: file))
|
||||||
|
let animationItem = Signal<ManagedAnimationItem, NoError> { subscriber in
|
||||||
|
let fetchedDisposable = fetched.start()
|
||||||
|
let resourceDisposable = (chatMessageAnimationData(postbox: context.account.postbox, resource: file.resource, fitzModifier: nil, width: Int(fittedSize.width), height: Int(fittedSize.height), synchronousLoad: false)
|
||||||
|
|> filter { data in
|
||||||
|
return data.complete
|
||||||
|
}).start(next: { next in
|
||||||
|
subscriber.putNext(ManagedAnimationItem(source: .resource(context.account.postbox.mediaBox, file.resource), frames: ManagedAnimationFrameRange(startFrame: 0, endFrame: frameCount), duration: duration))
|
||||||
|
})
|
||||||
|
|
||||||
|
return ActionDisposable {
|
||||||
|
fetchedDisposable.dispose()
|
||||||
|
resourceDisposable.dispose()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return animationItem
|
||||||
|
}
|
||||||
|
|
||||||
|
self.disposable.set((animationItem |> deliverOnMainQueue).start(next: { [weak self] item in
|
||||||
if let strongSelf = self {
|
if let strongSelf = self {
|
||||||
strongSelf.trackTo(item: ManagedAnimationItem(source: .resource(strongSelf.context.account.postbox.mediaBox, file.resource), frames: ManagedAnimationFrameRange(startFrame: 0, endFrame: 180), duration: 3.0))
|
strongSelf.trackTo(item: item)
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
case .rolling:
|
case .rolling:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case let .value(currentValue):
|
case .value:
|
||||||
switch diceState {
|
switch diceState {
|
||||||
case .rolling:
|
case .rolling:
|
||||||
self.trackTo(item: ManagedAnimationItem(source: .local("Dice_Rolling"), frames: ManagedAnimationFrameRange(startFrame: 0, endFrame: 60), duration: 1.0, loop: true))
|
if let item = rollingAnimationItem(emoji: self.dice.emoji) {
|
||||||
case let .value(value):
|
self.trackTo(item: item)
|
||||||
|
}
|
||||||
|
case .value:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
switch diceState {
|
switch diceState {
|
||||||
case let .value(value, immediate):
|
case let .value(value, immediate):
|
||||||
guard self.emojis.count == 6 else {
|
let animationItem: Signal<ManagedAnimationItem, NoError> = self.emojis.get()
|
||||||
return
|
|> mapToSignal { emojis -> Signal<ManagedAnimationItem, NoError> in
|
||||||
}
|
guard emojis.count > value else {
|
||||||
let file = self.emojis[Int(value) - 1]
|
return .complete()
|
||||||
|
|
||||||
if let _ = self.context.account.postbox.mediaBox.completedResourcePath(file.resource) {
|
|
||||||
if immediate {
|
|
||||||
self.trackTo(item: ManagedAnimationItem(source: .resource(self.context.account.postbox.mediaBox, file.resource), frames: ManagedAnimationFrameRange(startFrame: 180, endFrame: 180), duration: 0.0))
|
|
||||||
} else {
|
|
||||||
self.trackTo(item: ManagedAnimationItem(source: .resource(self.context.account.postbox.mediaBox, file.resource), frames: ManagedAnimationFrameRange(startFrame: 0, endFrame: 180), duration: 3.0))
|
|
||||||
}
|
}
|
||||||
} else {
|
let file = emojis[Int(value) - 1]
|
||||||
self.setState(.rolling)
|
|
||||||
|
|
||||||
let dimensions = file.dimensions ?? PixelDimensions(width: 512, height: 512)
|
|
||||||
let fittedSize = dimensions.cgSize.aspectFilled(CGSize(width: 384.0, height: 384.0))
|
|
||||||
|
|
||||||
let fetched = freeMediaFileInteractiveFetched(account: self.context.account, fileReference: .standalone(media: file))
|
if let _ = context.account.postbox.mediaBox.completedResourcePath(file.resource) {
|
||||||
let sticker = Signal<Void, NoError> { subscriber in
|
if immediate {
|
||||||
let fetchedDisposable = fetched.start()
|
return .single(ManagedAnimationItem(source: .resource(context.account.postbox.mediaBox, file.resource), frames: ManagedAnimationFrameRange(startFrame: frameCount, endFrame: frameCount), duration: 0.0))
|
||||||
let resourceDisposable = (chatMessageAnimationData(postbox: self.context.account.postbox, resource: file.resource, fitzModifier: nil, width: Int(fittedSize.width), height: Int(fittedSize.height), synchronousLoad: false)
|
} else {
|
||||||
|> filter { data in
|
return .single(ManagedAnimationItem(source: .resource(context.account.postbox.mediaBox, file.resource), frames: ManagedAnimationFrameRange(startFrame: 0, endFrame: frameCount), duration: duration))
|
||||||
return data.complete
|
|
||||||
}).start(next: { next in
|
|
||||||
subscriber.putNext(Void())
|
|
||||||
})
|
|
||||||
|
|
||||||
return ActionDisposable {
|
|
||||||
fetchedDisposable.dispose()
|
|
||||||
resourceDisposable.dispose()
|
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
|
self.setState(.rolling)
|
||||||
self.disposable.set((sticker |> deliverOnMainQueue).start(next: { [weak self] data in
|
|
||||||
if let strongSelf = self {
|
let dimensions = file.dimensions ?? PixelDimensions(width: 512, height: 512)
|
||||||
if immediate {
|
let fittedSize = dimensions.cgSize.aspectFilled(CGSize(width: 384.0, height: 384.0))
|
||||||
strongSelf.trackTo(item: ManagedAnimationItem(source: .resource(strongSelf.context.account.postbox.mediaBox, file.resource), frames: ManagedAnimationFrameRange(startFrame: 180, endFrame: 180), duration: 0.0))
|
|
||||||
} else {
|
let fetched = freeMediaFileInteractiveFetched(account: self.context.account, fileReference: .standalone(media: file))
|
||||||
strongSelf.trackTo(item: ManagedAnimationItem(source: .resource(strongSelf.context.account.postbox.mediaBox, file.resource), frames: ManagedAnimationFrameRange(startFrame: 0, endFrame: 180), duration: 3.0))
|
let animationItem = Signal<ManagedAnimationItem, NoError> { subscriber in
|
||||||
|
let fetchedDisposable = fetched.start()
|
||||||
|
let resourceDisposable = (chatMessageAnimationData(postbox: self.context.account.postbox, resource: file.resource, fitzModifier: nil, width: Int(fittedSize.width), height: Int(fittedSize.height), synchronousLoad: false)
|
||||||
|
|> filter { data in
|
||||||
|
return data.complete
|
||||||
|
}).start(next: { next in
|
||||||
|
subscriber.putNext(ManagedAnimationItem(source: .resource(context.account.postbox.mediaBox, file.resource), frames: ManagedAnimationFrameRange(startFrame: 0, endFrame: frameCount), duration: duration))
|
||||||
|
})
|
||||||
|
|
||||||
|
return ActionDisposable {
|
||||||
|
fetchedDisposable.dispose()
|
||||||
|
resourceDisposable.dispose()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}))
|
return animationItem
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.disposable.set((animationItem |> deliverOnMainQueue).start(next: { [weak self] item in
|
||||||
|
if let strongSelf = self {
|
||||||
|
strongSelf.trackTo(item: item)
|
||||||
|
}
|
||||||
|
}))
|
||||||
case .rolling:
|
case .rolling:
|
||||||
self.trackTo(item: ManagedAnimationItem(source: .local("Dice_Rolling"), frames: ManagedAnimationFrameRange(startFrame: 0, endFrame: 60), duration: 1.0, loop: true))
|
if let item = rollingAnimationItem(emoji: self.dice.emoji) {
|
||||||
|
self.trackTo(item: item)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user