mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-24 07:05:35 +00:00
Dice fixes
This commit is contained in:
@@ -10,7 +10,6 @@ import SwiftSignalKit
|
||||
|
||||
public final class ManagedAnimationState {
|
||||
public let item: ManagedAnimationItem
|
||||
|
||||
private let instance: LottieInstance
|
||||
|
||||
let frameCount: Int
|
||||
@@ -19,6 +18,8 @@ public final class ManagedAnimationState {
|
||||
var relativeTime: Double = 0.0
|
||||
public var frameIndex: Int?
|
||||
|
||||
public var executedCallbacks = Set<Int>()
|
||||
|
||||
private let renderContext: DrawingContext
|
||||
|
||||
public init?(displaySize: CGSize, item: ManagedAnimationItem, current: ManagedAnimationState?) {
|
||||
@@ -109,17 +110,19 @@ public enum ManagedAnimationSource: Equatable {
|
||||
}
|
||||
}
|
||||
|
||||
public struct ManagedAnimationItem: Equatable {
|
||||
public struct ManagedAnimationItem {
|
||||
public let source: ManagedAnimationSource
|
||||
var frames: ManagedAnimationFrameRange?
|
||||
var duration: Double?
|
||||
var loop: Bool
|
||||
var callbacks: [(Int, () -> Void)]
|
||||
|
||||
public init(source: ManagedAnimationSource, frames: ManagedAnimationFrameRange? = nil, duration: Double? = nil, loop: Bool = false) {
|
||||
public init(source: ManagedAnimationSource, frames: ManagedAnimationFrameRange? = nil, duration: Double? = nil, loop: Bool = false, callbacks: [(Int, () -> Void)] = []) {
|
||||
self.source = source
|
||||
self.frames = frames
|
||||
self.duration = duration
|
||||
self.loop = loop
|
||||
self.callbacks = callbacks
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,6 +243,13 @@ open class ManagedAnimationNode: ASDisplayNode {
|
||||
if let image = state.draw() {
|
||||
self.imageNode.image = image
|
||||
}
|
||||
|
||||
for (callbackFrame, callback) in state.item.callbacks {
|
||||
if !state.executedCallbacks.contains(callbackFrame) && frameIndex >= callbackFrame {
|
||||
state.executedCallbacks.insert(callbackFrame)
|
||||
callback()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var animationAdvancement: Double = 1.0 / 60.0
|
||||
|
||||
@@ -6573,8 +6573,8 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
}
|
||||
}
|
||||
if let value = value {
|
||||
self.present(UndoOverlayController(presentationData: self.presentationData, content: .dice(dice: dice, account: self.context.account, text: value, action: self.presentationData.strings.Conversation_SendDice), elevatedLayout: true, action: { [weak self] action in
|
||||
if let strongSelf = self, action == .undo {
|
||||
self.present(UndoOverlayController(presentationData: self.presentationData, content: .dice(dice: dice, account: self.context.account, text: value, action: canSendMessagesToChat(self.presentationInterfaceState) ? self.presentationData.strings.Conversation_SendDice : nil), elevatedLayout: true, action: { [weak self] action in
|
||||
if let strongSelf = self, canSendMessagesToChat(strongSelf.presentationInterfaceState), action == .undo {
|
||||
strongSelf.sendMessages([.message(text: "", attributes: [], mediaReference: AnyMediaReference.standalone(media: TelegramMediaDice(emoji: dice.emoji)), replyToMessageId: nil, localGroupingKey: nil)])
|
||||
}
|
||||
return false
|
||||
|
||||
@@ -210,6 +210,13 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
||||
|
||||
if let telegramDice = self.telegramDice {
|
||||
let animationNode = ManagedDiceAnimationNode(context: item.context, emoji: telegramDice.emoji)
|
||||
if !item.message.effectivelyIncoming(item.context.account.peerId) {
|
||||
animationNode.success = { [weak self] in
|
||||
if let strongSelf = self, let item = strongSelf.item {
|
||||
item.controllerInteraction.animateDiceSuccess()
|
||||
}
|
||||
}
|
||||
}
|
||||
self.animationNode = animationNode
|
||||
} else {
|
||||
let animationNode = AnimatedStickerNode()
|
||||
|
||||
@@ -14,19 +14,25 @@ enum ManagedDiceAnimationState: Equatable {
|
||||
case value(Int32, Bool)
|
||||
}
|
||||
|
||||
private func animationItem(account: Account, emojis: Signal<[TelegramMediaFile], NoError>, emoji: String, value: Int32?, immediate: Bool = false, roll: Bool = false, loop: Bool = false) -> Signal<ManagedAnimationItem?, NoError> {
|
||||
return emojis
|
||||
|> mapToSignal { diceEmojis -> Signal<ManagedAnimationItem?, NoError> in
|
||||
private func animationItem(account: Account, emojis: Signal<[TelegramMediaFile], NoError>, configuration: Signal<InteractiveEmojiConfiguration?, NoError> = .single(nil), emoji: String, value: Int32?, immediate: Bool = false, roll: Bool = false, loop: Bool = false, successCallback: (() -> Void)? = nil) -> Signal<ManagedAnimationItem?, NoError> {
|
||||
return combineLatest(emojis, configuration)
|
||||
|> mapToSignal { diceEmojis, configuration -> Signal<ManagedAnimationItem?, NoError> in
|
||||
if let value = value, value >= diceEmojis.count {
|
||||
return .complete()
|
||||
}
|
||||
let file = diceEmojis[Int(value ?? 0)]
|
||||
|
||||
var callbacks: [(Int, () -> Void)] = []
|
||||
|
||||
if !loop, let successCallback = successCallback, let value = value, let configuration = configuration, let success = configuration.successParameters[emoji], value == success.value {
|
||||
callbacks.append((success.frame, successCallback))
|
||||
}
|
||||
|
||||
if let _ = account.postbox.mediaBox.completedResourcePath(file.resource) {
|
||||
if immediate {
|
||||
return .single(ManagedAnimationItem(source: .resource(account.postbox.mediaBox, file.resource), frames: .still(.end), duration: 0))
|
||||
} else {
|
||||
return .single(ManagedAnimationItem(source: .resource(account.postbox.mediaBox, file.resource), loop: loop))
|
||||
return .single(ManagedAnimationItem(source: .resource(account.postbox.mediaBox, file.resource), loop: loop, callbacks: callbacks))
|
||||
}
|
||||
} else {
|
||||
let dimensions = file.dimensions ?? PixelDimensions(width: 512, height: 512)
|
||||
@@ -39,7 +45,7 @@ private func animationItem(account: Account, emojis: Signal<[TelegramMediaFile],
|
||||
|> filter { data in
|
||||
return data.complete
|
||||
}).start(next: { next in
|
||||
subscriber.putNext(ManagedAnimationItem(source: .resource(account.postbox.mediaBox, file.resource), loop: loop))
|
||||
subscriber.putNext(ManagedAnimationItem(source: .resource(account.postbox.mediaBox, file.resource), loop: loop, callbacks: callbacks))
|
||||
})
|
||||
|
||||
return ActionDisposable {
|
||||
@@ -91,7 +97,7 @@ public struct InteractiveEmojiConfiguration {
|
||||
var successParameters: [String: InteractiveEmojiSuccessParameters] = [:]
|
||||
if let success = data["emojies_send_dice_success"] as? [String: [String: Double]] {
|
||||
for (key, dict) in success {
|
||||
if let successValue = dict[""], let successFrame = dict[""] {
|
||||
if let successValue = dict["value"], let successFrame = dict["frame_start"] {
|
||||
successParameters[key] = InteractiveEmojiSuccessParameters(value: Int(successValue), frame: Int(successFrame))
|
||||
}
|
||||
}
|
||||
@@ -110,18 +116,20 @@ final class ManagedDiceAnimationNode: ManagedAnimationNode, GenericAnimatedStick
|
||||
private var diceState: ManagedDiceAnimationState? = nil
|
||||
private let disposable = MetaDisposable()
|
||||
|
||||
private let configuration = Promise<InteractiveEmojiConfiguration?>()
|
||||
private let emojis = Promise<[TelegramMediaFile]>()
|
||||
|
||||
var success: (() -> Void)?
|
||||
|
||||
init(context: AccountContext, emoji: String) {
|
||||
self.context = context
|
||||
self.emoji = emoji
|
||||
|
||||
self.context.account.postbox.preferencesView(keys: [PreferencesKeys.appConfiguration])
|
||||
|> map { preferencesView -> InteractiveEmojiConfiguration in
|
||||
self.configuration.set(self.context.account.postbox.preferencesView(keys: [PreferencesKeys.appConfiguration])
|
||||
|> map { preferencesView -> InteractiveEmojiConfiguration? in
|
||||
let appConfiguration: AppConfiguration = preferencesView.values[PreferencesKeys.appConfiguration] as? AppConfiguration ?? .defaultValue
|
||||
return InteractiveEmojiConfiguration.with(appConfiguration: appConfiguration)
|
||||
}
|
||||
|
||||
})
|
||||
self.emojis.set(loadedStickerPack(postbox: context.account.postbox, network: context.account.network, reference: .dice(emoji), forceActualized: false)
|
||||
|> mapToSignal { stickerPack -> Signal<[TelegramMediaFile], NoError> in
|
||||
switch stickerPack {
|
||||
@@ -155,7 +163,9 @@ final class ManagedDiceAnimationNode: ManagedAnimationNode, GenericAnimatedStick
|
||||
case .rolling:
|
||||
switch diceState {
|
||||
case let .value(value, _):
|
||||
item = animationItem(account: context.account, emojis: self.emojis.get(), emoji: self.emoji, value: value)
|
||||
item = animationItem(account: context.account, emojis: self.emojis.get(), configuration: self.configuration.get(), emoji: self.emoji, value: value, successCallback: { [weak self] in
|
||||
self?.success?()
|
||||
})
|
||||
case .rolling:
|
||||
break
|
||||
}
|
||||
@@ -170,7 +180,9 @@ final class ManagedDiceAnimationNode: ManagedAnimationNode, GenericAnimatedStick
|
||||
} else {
|
||||
switch diceState {
|
||||
case let .value(value, immediate):
|
||||
item = animationItem(account: context.account, emojis: self.emojis.get(), emoji: self.emoji, value: value, immediate: immediate, roll: true)
|
||||
item = animationItem(account: context.account, emojis: self.emojis.get(), configuration: self.configuration.get(), emoji: self.emoji, value: value, immediate: immediate, roll: true, successCallback: { [weak self] in
|
||||
self?.success?()
|
||||
})
|
||||
case .rolling:
|
||||
item = rollingAnimationItem(account: context.account, emojis: self.emojis.get(), emoji: self.emoji)
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ public enum UndoOverlayContent {
|
||||
case swipeToReply(title: String, text: String)
|
||||
case actionSucceeded(title: String, text: String, cancel: String)
|
||||
case stickersModified(title: String, text: String, undo: Bool, info: StickerPackCollectionInfo, topItem: ItemCollectionItem?, account: Account)
|
||||
case dice(dice: TelegramMediaDice, account: Account, text: String, action: String)
|
||||
case dice(dice: TelegramMediaDice, account: Account, text: String, action: String?)
|
||||
}
|
||||
|
||||
public enum UndoOverlayAction {
|
||||
|
||||
@@ -290,15 +290,19 @@ final class UndoOverlayControllerNode: ViewControllerTracingNode {
|
||||
let link = MarkdownAttributeSet(font: Font.regular(14.0), textColor: undoTextColor)
|
||||
let attributedText = parseMarkdownIntoAttributedString(text, attributes: MarkdownAttributes(body: body, bold: bold, link: link, linkAttribute: { _ in return nil }), textAlignment: .natural)
|
||||
self.textNode.attributedText = attributedText
|
||||
displayUndo = true
|
||||
undoText = action
|
||||
if let action = action {
|
||||
displayUndo = true
|
||||
undoText = action
|
||||
} else {
|
||||
displayUndo = false
|
||||
}
|
||||
self.originalRemainingSeconds = 5
|
||||
|
||||
self.stickerImageSize = CGSize(width: 42.0, height: 42.0)
|
||||
|
||||
switch dice.emoji {
|
||||
case "🎲":
|
||||
self.stickerOffset = CGPoint(x: 0.0, y: -8.0)
|
||||
self.stickerOffset = CGPoint(x: 0.0, y: -7.0)
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user