mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Slot machine animation
This commit is contained in:
parent
a1fb9f3f61
commit
7e643321cf
@ -730,6 +730,7 @@ plist_fragment(
|
||||
<string>onionhttp</string>
|
||||
<string>ucbrowser</string>
|
||||
<string>dolphin</string>
|
||||
<string>instagram-stories</string>
|
||||
</array>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
|
BIN
Telegram/Telegram-iOS/Resources/Slot_Back_Idle.tgs
Normal file
BIN
Telegram/Telegram-iOS/Resources/Slot_Back_Idle.tgs
Normal file
Binary file not shown.
BIN
Telegram/Telegram-iOS/Resources/Slot_Back_Win.tgs
Normal file
BIN
Telegram/Telegram-iOS/Resources/Slot_Back_Win.tgs
Normal file
Binary file not shown.
BIN
Telegram/Telegram-iOS/Resources/Slot_Front_Pull.tgs
Normal file
BIN
Telegram/Telegram-iOS/Resources/Slot_Front_Pull.tgs
Normal file
Binary file not shown.
BIN
Telegram/Telegram-iOS/Resources/Slot_L_7.tgs
Normal file
BIN
Telegram/Telegram-iOS/Resources/Slot_L_7.tgs
Normal file
Binary file not shown.
BIN
Telegram/Telegram-iOS/Resources/Slot_L_7_Win.tgs
Normal file
BIN
Telegram/Telegram-iOS/Resources/Slot_L_7_Win.tgs
Normal file
Binary file not shown.
BIN
Telegram/Telegram-iOS/Resources/Slot_L_Bar.tgs
Normal file
BIN
Telegram/Telegram-iOS/Resources/Slot_L_Bar.tgs
Normal file
Binary file not shown.
BIN
Telegram/Telegram-iOS/Resources/Slot_L_Berries.tgs
Normal file
BIN
Telegram/Telegram-iOS/Resources/Slot_L_Berries.tgs
Normal file
Binary file not shown.
BIN
Telegram/Telegram-iOS/Resources/Slot_L_Lemon.tgs
Normal file
BIN
Telegram/Telegram-iOS/Resources/Slot_L_Lemon.tgs
Normal file
Binary file not shown.
BIN
Telegram/Telegram-iOS/Resources/Slot_L_Spinning.tgs
Normal file
BIN
Telegram/Telegram-iOS/Resources/Slot_L_Spinning.tgs
Normal file
Binary file not shown.
BIN
Telegram/Telegram-iOS/Resources/Slot_M_7.tgs
Normal file
BIN
Telegram/Telegram-iOS/Resources/Slot_M_7.tgs
Normal file
Binary file not shown.
BIN
Telegram/Telegram-iOS/Resources/Slot_M_7_Win.tgs
Normal file
BIN
Telegram/Telegram-iOS/Resources/Slot_M_7_Win.tgs
Normal file
Binary file not shown.
BIN
Telegram/Telegram-iOS/Resources/Slot_M_Bar.tgs
Normal file
BIN
Telegram/Telegram-iOS/Resources/Slot_M_Bar.tgs
Normal file
Binary file not shown.
BIN
Telegram/Telegram-iOS/Resources/Slot_M_Berries.tgs
Normal file
BIN
Telegram/Telegram-iOS/Resources/Slot_M_Berries.tgs
Normal file
Binary file not shown.
BIN
Telegram/Telegram-iOS/Resources/Slot_M_Lemon.tgs
Normal file
BIN
Telegram/Telegram-iOS/Resources/Slot_M_Lemon.tgs
Normal file
Binary file not shown.
BIN
Telegram/Telegram-iOS/Resources/Slot_M_Spinning.tgs
Normal file
BIN
Telegram/Telegram-iOS/Resources/Slot_M_Spinning.tgs
Normal file
Binary file not shown.
BIN
Telegram/Telegram-iOS/Resources/Slot_R_7.tgs
Normal file
BIN
Telegram/Telegram-iOS/Resources/Slot_R_7.tgs
Normal file
Binary file not shown.
BIN
Telegram/Telegram-iOS/Resources/Slot_R_7_Win.tgs
Normal file
BIN
Telegram/Telegram-iOS/Resources/Slot_R_7_Win.tgs
Normal file
Binary file not shown.
BIN
Telegram/Telegram-iOS/Resources/Slot_R_Bar.tgs
Normal file
BIN
Telegram/Telegram-iOS/Resources/Slot_R_Bar.tgs
Normal file
Binary file not shown.
BIN
Telegram/Telegram-iOS/Resources/Slot_R_Berries.tgs
Normal file
BIN
Telegram/Telegram-iOS/Resources/Slot_R_Berries.tgs
Normal file
Binary file not shown.
BIN
Telegram/Telegram-iOS/Resources/Slot_R_Lemon.tgs
Normal file
BIN
Telegram/Telegram-iOS/Resources/Slot_R_Lemon.tgs
Normal file
Binary file not shown.
BIN
Telegram/Telegram-iOS/Resources/Slot_R_Spinning.tgs
Normal file
BIN
Telegram/Telegram-iOS/Resources/Slot_R_Spinning.tgs
Normal file
Binary file not shown.
@ -5735,3 +5735,5 @@ Any member of this group will be able to see messages in the channel.";
|
||||
"Call.AudioRouteMute" = "Mute Yourself";
|
||||
|
||||
"AccessDenied.VideoCallCamera" = "Telegram needs access to your camera to make video calls.\n\nPlease go to Settings > Privacy > Camera and set Telegram to ON.";
|
||||
|
||||
"Call.AccountIsLoggedOnCurrentDevice" = "Sorry, you can't call %@ because that account is logged in to Telegram on the device you're using for the call.";
|
||||
|
@ -277,7 +277,12 @@ public final class DeviceAccess {
|
||||
if status == PGCameraAuthorizationStatusRestricted {
|
||||
text = presentationData.strings.AccessDenied_CameraRestricted
|
||||
} else {
|
||||
switch cameraSubject {
|
||||
case .video:
|
||||
text = presentationData.strings.AccessDenied_Camera
|
||||
case .videoCall:
|
||||
text = presentationData.strings.AccessDenied_VideoCallCamera
|
||||
}
|
||||
}
|
||||
completion(false)
|
||||
present(standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: presentationData.strings.AccessDenied_Title, text: text, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_NotNow, action: {}), TextAlertAction(type: .genericAction, title: presentationData.strings.AccessDenied_Settings, action: {
|
||||
|
@ -1523,9 +1523,9 @@ final class CallControllerNode: ViewControllerTracingNode, CallControllerNodePro
|
||||
} else if let _ = self.keyPreviewNode {
|
||||
self.backPressed()
|
||||
} else {
|
||||
if let expandedVideoNode = self.expandedVideoNode, let minimizedVideoNode = self.minimizedVideoNode {
|
||||
if self.hasVideoNodes {
|
||||
let point = recognizer.location(in: recognizer.view)
|
||||
if minimizedVideoNode.frame.contains(point) {
|
||||
if let expandedVideoNode = self.expandedVideoNode, let minimizedVideoNode = self.minimizedVideoNode, minimizedVideoNode.frame.contains(point) {
|
||||
if !self.areUserActionsDisabledNow() {
|
||||
let copyView = minimizedVideoNode.view.snapshotView(afterScreenUpdates: false)
|
||||
copyView?.frame = minimizedVideoNode.frame
|
||||
|
@ -45,7 +45,7 @@ private func generateEmptyButtonImage(icon: UIImage?, strokeColor: UIColor?, fil
|
||||
context.fill(imageRect)
|
||||
} else {
|
||||
context.setBlendMode(.normal)
|
||||
context.draw(icon.cgImage!, in: imageRect)
|
||||
context.draw(generateTintedImage(image: icon, color: .white)!.cgImage!, in: imageRect)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@ -228,6 +228,10 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
||||
}
|
||||
|
||||
if let telegramDice = self.telegramDice {
|
||||
if telegramDice.emoji == "🎲" {
|
||||
let animationNode = SlotMachineAnimationNode(context: item.context)
|
||||
self.animationNode = animationNode
|
||||
} else {
|
||||
let animationNode = ManagedDiceAnimationNode(context: item.context, emoji: telegramDice.emoji.strippedEmoji)
|
||||
if !item.message.effectivelyIncoming(item.context.account.peerId) {
|
||||
animationNode.success = { [weak self] in
|
||||
@ -237,6 +241,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
||||
}
|
||||
}
|
||||
self.animationNode = animationNode
|
||||
}
|
||||
} else {
|
||||
let animationNode: AnimatedStickerNode
|
||||
if let (node, parentNode, listNode, greetingCompletion) = item.controllerInteraction.greetingStickerNode(), let greetingStickerNode = node as? AnimatedStickerNode {
|
||||
@ -290,7 +295,13 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
||||
|
||||
self.setupNode(item: item)
|
||||
|
||||
if let telegramDice = self.telegramDice, let diceNode = self.animationNode as? ManagedDiceAnimationNode {
|
||||
if let telegramDice = self.telegramDice, let diceNode = self.animationNode as? SlotMachineAnimationNode {
|
||||
if let value = telegramDice.value {
|
||||
diceNode.setState(value == 0 ? .rolling : .value(value, true))
|
||||
} else {
|
||||
diceNode.setState(.rolling)
|
||||
}
|
||||
} else if let telegramDice = self.telegramDice, let diceNode = self.animationNode as? ManagedDiceAnimationNode {
|
||||
if let value = telegramDice.value {
|
||||
diceNode.setState(value == 0 ? .rolling : .value(value, true))
|
||||
} else {
|
||||
|
241
submodules/TelegramUI/Sources/SlotMachineAnimationNode.swift
Normal file
241
submodules/TelegramUI/Sources/SlotMachineAnimationNode.swift
Normal file
@ -0,0 +1,241 @@
|
||||
import Foundation
|
||||
import Display
|
||||
import AsyncDisplayKit
|
||||
import Postbox
|
||||
import SyncCore
|
||||
import TelegramCore
|
||||
import SwiftSignalKit
|
||||
import AccountContext
|
||||
import StickerResources
|
||||
import ManagedAnimationNode
|
||||
|
||||
enum ReelValue {
|
||||
case rolling
|
||||
case bar
|
||||
case berries
|
||||
case lemon
|
||||
case seven
|
||||
case sevenWin
|
||||
}
|
||||
|
||||
private func leftReelAnimationItem(value: ReelValue, immediate: Bool = false) -> ManagedAnimationItem {
|
||||
let frames: ManagedAnimationFrameRange? = immediate ? .still(.end) : nil
|
||||
switch value {
|
||||
case .rolling:
|
||||
return ManagedAnimationItem(source: .local("Slot_L_Spinning"), loop: true)
|
||||
case .bar:
|
||||
return ManagedAnimationItem(source: .local("Slot_L_Bar"), frames: frames, loop: false)
|
||||
case .berries:
|
||||
return ManagedAnimationItem(source: .local("Slot_L_Berries"), frames: frames, loop: false)
|
||||
case .lemon:
|
||||
return ManagedAnimationItem(source: .local("Slot_L_Lemon"), frames: frames, loop: false)
|
||||
case .seven:
|
||||
return ManagedAnimationItem(source: .local("Slot_L_7"), frames: frames, loop: false)
|
||||
case .sevenWin:
|
||||
return ManagedAnimationItem(source: .local("Slot_L_7_Win"), frames: frames, loop: false)
|
||||
}
|
||||
}
|
||||
|
||||
private func centerReelAnimationItem(value: ReelValue, immediate: Bool = false) -> ManagedAnimationItem {
|
||||
let frames: ManagedAnimationFrameRange? = immediate ? .still(.end) : nil
|
||||
switch value {
|
||||
case .rolling:
|
||||
return ManagedAnimationItem(source: .local("Slot_M_Spinning"), frames: frames, loop: true)
|
||||
case .bar:
|
||||
return ManagedAnimationItem(source: .local("Slot_M_Bar"), frames: frames, loop: false)
|
||||
case .berries:
|
||||
return ManagedAnimationItem(source: .local("Slot_M_Berries"), frames: frames, loop: false)
|
||||
case .lemon:
|
||||
return ManagedAnimationItem(source: .local("Slot_M_Lemon"), frames: frames, loop: false)
|
||||
case .seven:
|
||||
return ManagedAnimationItem(source: .local("Slot_M_7"), frames: frames, loop: false)
|
||||
case .sevenWin:
|
||||
return ManagedAnimationItem(source: .local("Slot_M_7_Win"), frames: frames, loop: false)
|
||||
}
|
||||
}
|
||||
|
||||
private func rightReelAnimationItem(value: ReelValue, immediate: Bool = false) -> ManagedAnimationItem {
|
||||
let frames: ManagedAnimationFrameRange? = immediate ? .still(.end) : nil
|
||||
switch value {
|
||||
case .rolling:
|
||||
return ManagedAnimationItem(source: .local("Slot_R_Spinning"), frames: frames, loop: true)
|
||||
case .bar:
|
||||
return ManagedAnimationItem(source: .local("Slot_R_Bar"), frames: frames, loop: false)
|
||||
case .berries:
|
||||
return ManagedAnimationItem(source: .local("Slot_R_Berries"), frames: frames, loop: false)
|
||||
case .lemon:
|
||||
return ManagedAnimationItem(source: .local("Slot_R_Lemon"), frames: frames, loop: false)
|
||||
case .seven:
|
||||
return ManagedAnimationItem(source: .local("Slot_R_7"), frames: frames, loop: false)
|
||||
case .sevenWin:
|
||||
return ManagedAnimationItem(source: .local("Slot_R_7_Win"), frames: frames, loop: false)
|
||||
}
|
||||
}
|
||||
|
||||
final class SlotMachineAnimationNode: ASDisplayNode, GenericAnimatedStickerNode {
|
||||
private let context: AccountContext
|
||||
|
||||
private let backNode: ManagedAnimationNode
|
||||
private let leftReelNode: ManagedAnimationNode
|
||||
private let centerReelNode: ManagedAnimationNode
|
||||
private let rightReelNode: ManagedAnimationNode
|
||||
private let frontNode: ManagedAnimationNode
|
||||
|
||||
private var diceState: ManagedDiceAnimationState? = nil
|
||||
private let disposables = DisposableSet()
|
||||
|
||||
init(context: AccountContext) {
|
||||
self.context = context
|
||||
|
||||
let size = CGSize(width: 184.0, height: 184.0)
|
||||
self.backNode = ManagedAnimationNode(size: size)
|
||||
self.leftReelNode = ManagedAnimationNode(size: size)
|
||||
self.centerReelNode = ManagedAnimationNode(size: size)
|
||||
self.rightReelNode = ManagedAnimationNode(size: size)
|
||||
self.frontNode = ManagedAnimationNode(size: size)
|
||||
|
||||
super.init()
|
||||
|
||||
self.addSubnode(self.backNode)
|
||||
self.addSubnode(self.leftReelNode)
|
||||
self.addSubnode(self.centerReelNode)
|
||||
self.addSubnode(self.rightReelNode)
|
||||
self.addSubnode(self.frontNode)
|
||||
}
|
||||
|
||||
deinit {
|
||||
self.disposables.dispose()
|
||||
}
|
||||
|
||||
override func layout() {
|
||||
super.layout()
|
||||
|
||||
self.backNode.frame = self.bounds
|
||||
self.leftReelNode.frame = self.bounds
|
||||
self.centerReelNode.frame = self.bounds
|
||||
self.rightReelNode.frame = self.bounds
|
||||
self.frontNode.frame = self.bounds
|
||||
}
|
||||
|
||||
func setState(_ diceState: ManagedDiceAnimationState) {
|
||||
let previousState = self.diceState
|
||||
self.diceState = diceState
|
||||
|
||||
if let previousState = previousState {
|
||||
switch previousState {
|
||||
case .rolling:
|
||||
switch diceState {
|
||||
case let .value(value, _):
|
||||
let l: ReelValue
|
||||
let c: ReelValue
|
||||
let r: ReelValue
|
||||
switch value {
|
||||
case 1:
|
||||
l = .seven
|
||||
c = .berries
|
||||
r = .bar
|
||||
case 2:
|
||||
l = .berries
|
||||
c = .berries
|
||||
r = .bar
|
||||
case 3:
|
||||
l = .seven
|
||||
c = .berries
|
||||
r = .seven
|
||||
case 4:
|
||||
l = .bar
|
||||
c = .lemon
|
||||
r = .seven
|
||||
case 5:
|
||||
l = .berries
|
||||
c = .berries
|
||||
r = .berries
|
||||
case 6:
|
||||
l = .sevenWin
|
||||
c = .sevenWin
|
||||
r = .sevenWin
|
||||
default:
|
||||
l = .sevenWin
|
||||
c = .sevenWin
|
||||
r = .sevenWin
|
||||
}
|
||||
if value == 6 {
|
||||
Queue.mainQueue().after(1.5) {
|
||||
self.backNode.trackTo(item: ManagedAnimationItem(source: .local("Slot_Back_Win"), loop: false))
|
||||
}
|
||||
} else {
|
||||
self.backNode.trackTo(item: ManagedAnimationItem(source: .local("Slot_Back_Idle"), loop: false))
|
||||
}
|
||||
self.leftReelNode.trackTo(item: leftReelAnimationItem(value: l))
|
||||
self.centerReelNode.trackTo(item: centerReelAnimationItem(value: c))
|
||||
self.rightReelNode.trackTo(item: rightReelAnimationItem(value: r))
|
||||
self.frontNode.trackTo(item: ManagedAnimationItem(source: .local("Slot_Front_Pull"), frames: .still(.end), loop: false))
|
||||
case .rolling:
|
||||
break
|
||||
}
|
||||
case .value:
|
||||
switch diceState {
|
||||
case .rolling:
|
||||
self.backNode.trackTo(item: ManagedAnimationItem(source: .local("Slot_Back_Idle"), loop: false))
|
||||
self.leftReelNode.trackTo(item: leftReelAnimationItem(value: .rolling))
|
||||
self.centerReelNode.trackTo(item: centerReelAnimationItem(value: .rolling))
|
||||
self.rightReelNode.trackTo(item: rightReelAnimationItem(value: .rolling))
|
||||
self.frontNode.trackTo(item: ManagedAnimationItem(source: .local("Slot_Front_Pull"), loop: false))
|
||||
case .value:
|
||||
break
|
||||
}
|
||||
}
|
||||
} else {
|
||||
switch diceState {
|
||||
case let .value(value, immediate):
|
||||
self.backNode.trackTo(item: ManagedAnimationItem(source: .local("Slot_Back_Idle"), loop: false))
|
||||
|
||||
let l: ReelValue
|
||||
let c: ReelValue
|
||||
let r: ReelValue
|
||||
switch value {
|
||||
case 1:
|
||||
l = .seven
|
||||
c = .berries
|
||||
r = .bar
|
||||
case 2:
|
||||
l = .berries
|
||||
c = .berries
|
||||
r = .bar
|
||||
case 3:
|
||||
l = .seven
|
||||
c = .berries
|
||||
r = .seven
|
||||
case 4:
|
||||
l = .bar
|
||||
c = .lemon
|
||||
r = .seven
|
||||
case 5:
|
||||
l = .berries
|
||||
c = .berries
|
||||
r = .berries
|
||||
case 6:
|
||||
l = .sevenWin
|
||||
c = .sevenWin
|
||||
r = .sevenWin
|
||||
default:
|
||||
l = .sevenWin
|
||||
c = .sevenWin
|
||||
r = .sevenWin
|
||||
}
|
||||
self.leftReelNode.trackTo(item: leftReelAnimationItem(value: l, immediate: immediate))
|
||||
self.centerReelNode.trackTo(item: centerReelAnimationItem(value: c, immediate: immediate))
|
||||
self.rightReelNode.trackTo(item: rightReelAnimationItem(value: r, immediate: immediate))
|
||||
|
||||
let frames: ManagedAnimationFrameRange? = immediate ? .still(.end) : nil
|
||||
self.frontNode.trackTo(item: ManagedAnimationItem(source: .local("Slot_Front_Pull"), frames: frames, loop: false))
|
||||
case .rolling:
|
||||
self.backNode.trackTo(item: ManagedAnimationItem(source: .local("Slot_Back_Idle"), loop: false))
|
||||
self.leftReelNode.trackTo(item: leftReelAnimationItem(value: .rolling))
|
||||
self.centerReelNode.trackTo(item: centerReelAnimationItem(value: .rolling))
|
||||
self.rightReelNode.trackTo(item: rightReelAnimationItem(value: .rolling))
|
||||
self.frontNode.trackTo(item: ManagedAnimationItem(source: .local("Slot_Front_Pull"), loop: false))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user