mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
97 lines
2.6 KiB
Swift
97 lines
2.6 KiB
Swift
import Foundation
|
|
import Display
|
|
import SwiftSignalKit
|
|
|
|
protocol EmojiHaptic {
|
|
var enabled: Bool { get set }
|
|
var active: Bool { get }
|
|
|
|
func start(time: Double)
|
|
}
|
|
|
|
final class HeartbeatHaptic: EmojiHaptic {
|
|
private var hapticFeedback = HapticFeedback()
|
|
private var timer: SwiftSignalKit.Timer?
|
|
private var time: Double = 0.0
|
|
var enabled: Bool = false {
|
|
didSet {
|
|
if !self.enabled {
|
|
self.reset()
|
|
}
|
|
}
|
|
}
|
|
|
|
var active: Bool {
|
|
return self.timer != nil
|
|
}
|
|
|
|
private func reset() {
|
|
if let timer = self.timer {
|
|
self.time = 0.0
|
|
timer.invalidate()
|
|
self.timer = nil
|
|
}
|
|
}
|
|
|
|
private func beat(time: Double) {
|
|
let epsilon = 0.1
|
|
if fabs(0.0 - time) < epsilon || fabs(1.0 - time) < epsilon || fabs(2.0 - time) < epsilon {
|
|
self.hapticFeedback.impact(.medium)
|
|
} else if fabs(0.2 - time) < epsilon || fabs(1.2 - time) < epsilon || fabs(2.2 - time) < epsilon {
|
|
self.hapticFeedback.impact(.light)
|
|
}
|
|
}
|
|
|
|
func start(time: Double) {
|
|
self.hapticFeedback.prepareImpact()
|
|
|
|
if time > 2.0 {
|
|
return
|
|
}
|
|
|
|
var startTime: Double = 0.0
|
|
var delay: Double = 0.0
|
|
|
|
if time > 0.0 {
|
|
if time <= 1.0 {
|
|
startTime = 1.0
|
|
} else if time <= 2.0 {
|
|
startTime = 2.0
|
|
}
|
|
}
|
|
|
|
delay = max(0.0, startTime - time)
|
|
|
|
let block = { [weak self] in
|
|
guard let strongSelf = self, strongSelf.enabled else {
|
|
return
|
|
}
|
|
|
|
strongSelf.time = startTime
|
|
strongSelf.beat(time: startTime)
|
|
strongSelf.timer = SwiftSignalKit.Timer(timeout: 0.2, repeat: true, completion: { [weak self] in
|
|
guard let strongSelf = self, strongSelf.enabled else {
|
|
return
|
|
}
|
|
strongSelf.time += 0.2
|
|
strongSelf.beat(time: strongSelf.time)
|
|
|
|
if strongSelf.time > 2.2 {
|
|
strongSelf.reset()
|
|
strongSelf.time = 0.0
|
|
strongSelf.timer?.invalidate()
|
|
strongSelf.timer = nil
|
|
}
|
|
|
|
}, queue: Queue.mainQueue())
|
|
strongSelf.timer?.start()
|
|
}
|
|
|
|
if delay > 0.0 {
|
|
Queue.mainQueue().after(delay, block)
|
|
} else {
|
|
block()
|
|
}
|
|
}
|
|
}
|