element-ios/Riot/Modules/Room/Views/RemoveJitsiWidget/RemoveJitsiWidgetView.swift

195 lines
5.9 KiB
Swift
Raw Normal View History

2021-04-23 14:54:03 +00:00
//
// Copyright 2021 New Vector Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
import Foundation
import Reusable
@objcMembers
class RemoveJitsiWidgetView: UIView {
private enum Constants {
static let activationThreshold: CGFloat = 0.5
}
private enum State: Equatable {
case notStarted
case sliding(percentage: CGFloat)
case completed
static func == (lhs: State, rhs: State) -> Bool {
switch (lhs, rhs) {
case (.notStarted, .notStarted):
return true
case (let .sliding(percentage1), let .sliding(percentage2)):
return percentage1 == percentage2
case (.completed, .completed):
return true
default:
return false
}
}
}
@IBOutlet private weak var slidingViewLeadingConstraint: NSLayoutConstraint!
@IBOutlet private weak var slidingView: UIView!
@IBOutlet private weak var slidingViewLabel: UILabel! {
didSet {
slidingViewLabel.text = VectorL10n.roomSlideToEndGroupCall
}
}
@IBOutlet private weak var arrowsView: ArrowsAnimationView!
@IBOutlet private weak var hangupView: UIView!
@IBOutlet private weak var hangupImage: UIImageView!
@IBOutlet private weak var topSeparatorView: UIView!
@IBOutlet private weak var bottomSeparatorView: UIView!
private var state: State = .notStarted
private var theme: Theme = ThemeService.shared().theme
// MARK - Private
private func configure(withState state: State) {
switch state {
case .notStarted:
arrowsView.isAnimating = false
hangupView.backgroundColor = .clear
hangupImage.tintColor = theme.noticeColor
slidingViewLeadingConstraint.constant = 0
case .sliding(let percentage):
arrowsView.isAnimating = true
if percentage < Constants.activationThreshold {
hangupView.backgroundColor = .clear
hangupImage.tintColor = theme.noticeColor
} else {
hangupView.backgroundColor = theme.noticeColor
2021-04-29 11:58:45 +00:00
hangupImage.tintColor = theme.callScreenButtonTintColor
2021-04-23 14:54:03 +00:00
}
slidingViewLeadingConstraint.constant = percentage * slidingView.frame.width
case .completed:
arrowsView.isAnimating = false
hangupView.backgroundColor = theme.noticeColor
2021-04-29 11:58:45 +00:00
hangupImage.tintColor = theme.callScreenButtonTintColor
2021-04-23 14:54:03 +00:00
}
}
private func updateState(to newState: State) {
guard newState != state else {
return
}
configure(withState: newState)
state = newState
if state == .completed {
delegate?.removeJitsiWidgetViewDidCompleteSliding(self)
}
}
// MARK: - Touch Handling
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
if state == .notStarted {
updateState(to: .sliding(percentage: 0))
}
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesMoved(touches, with: event)
switch state {
case .sliding:
if let touch = touches.first {
let touchLocation = touch.location(in: self)
if frame.contains(touchLocation) {
let percentage = touchLocation.x / frame.width
updateState(to: .sliding(percentage: percentage))
}
}
default:
break
}
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesEnded(touches, with: event)
switch state {
case .sliding(let percentage):
if percentage < Constants.activationThreshold {
updateState(to: .notStarted)
} else {
updateState(to: .completed)
}
default:
break
}
}
override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesCancelled(touches, with: event)
switch state {
case .sliding(let percentage):
if percentage < Constants.activationThreshold {
updateState(to: .notStarted)
} else {
updateState(to: .completed)
}
default:
break
}
}
// MARK: - API
weak var delegate: RemoveJitsiWidgetViewDelegate?
static func instantiate() -> RemoveJitsiWidgetView {
let view = RemoveJitsiWidgetView.loadFromNib()
view.update(theme: ThemeService.shared().theme)
return view
}
func reset() {
updateState(to: .notStarted)
}
}
// MARK: - NibLoadable
extension RemoveJitsiWidgetView: NibLoadable { }
// MARK: - Themable
extension RemoveJitsiWidgetView: Themable {
func update(theme: Theme) {
self.theme = theme
self.backgroundColor = theme.headerBackgroundColor
slidingViewLabel.textColor = theme.textPrimaryColor
arrowsView.update(theme: theme)
topSeparatorView.backgroundColor = theme.lineBreakColor
bottomSeparatorView.backgroundColor = theme.lineBreakColor
configure(withState: state)
}
}