add system control gestures (brightness, volume)

This commit is contained in:
PangMo5 2022-02-05 18:14:23 +09:00
parent 5609d4c3ea
commit 682f79631c
7 changed files with 133 additions and 25 deletions

View File

@ -378,6 +378,8 @@ internal enum L10n {
internal static var switchUser: String { return L10n.tr("Localizable", "switchUser") }
/// System
internal static var system: String { return L10n.tr("Localizable", "system") }
/// System Control Gestures Enabled
internal static var systemControlGesturesEnabled: String { return L10n.tr("Localizable", "systemControlGesturesEnabled") }
/// Tags
internal static var tags: String { return L10n.tr("Localizable", "tags") }
/// Too Many Redirects

View File

@ -46,6 +46,8 @@ extension Defaults.Keys {
// Video player / overlay settings
static let overlayType = Key<OverlayType>("overlayType", default: .normal, suite: SwiftfinStore.Defaults.generalSuite)
static let jumpGesturesEnabled = Key<Bool>("gesturesEnabled", default: true, suite: SwiftfinStore.Defaults.generalSuite)
static let systemControlGesturesEnabled = Key<Bool>("systemControlGesturesEnabled", default: true,
suite: SwiftfinStore.Defaults.generalSuite)
static let videoPlayerJumpForward = Key<VideoPlayerJumpLength>("videoPlayerJumpForward", default: .fifteen,
suite: SwiftfinStore.Defaults.generalSuite)
static let videoPlayerJumpBackward = Key<VideoPlayerJumpLength>("videoPlayerJumpBackward", default: .fifteen,

View File

@ -115,6 +115,7 @@ final class VideoPlayerViewModel: ViewModel {
let chapters: [ChapterInfo]
let overlayType: OverlayType
let jumpGesturesEnabled: Bool
let systemControlGesturesEnabled: Bool
let resumeOffset: Bool
let streamType: ServerStreamType
let container: String
@ -241,6 +242,7 @@ final class VideoPlayerViewModel: ViewModel {
self.jumpBackwardLength = Defaults[.videoPlayerJumpBackward]
self.jumpForwardLength = Defaults[.videoPlayerJumpForward]
self.jumpGesturesEnabled = Defaults[.jumpGesturesEnabled]
self.systemControlGesturesEnabled = Defaults[.systemControlGesturesEnabled]
self.shouldShowJumpButtonsInOverlayMenu = Defaults[.shouldShowJumpButtonsInOverlayMenu]
self.resumeOffset = Defaults[.resumeOffset]

View File

@ -38,31 +38,6 @@ struct LibraryListView: View {
self.mainCoordinator.root(\.liveTV)
}
label: {
ZStack {
HStack {
Spacer()
VStack {
Text(library.name ?? "")
.foregroundColor(.white)
.font(.title2)
.fontWeight(.semibold)
}
Spacer()
}.padding(32)
}
.frame(minWidth: 100, maxWidth: .infinity)
.frame(height: 100)
}
.cornerRadius(10)
.shadow(radius: 5)
.padding(.bottom, 5)
}
} else {
Button {
self.libraryListRouter.route(to: \.library,
(viewModel: LibraryViewModel(parentID: library.id), title: library.name ?? ""))
}
label: {
ZStack {
HStack {
Spacer()
@ -81,6 +56,31 @@ struct LibraryListView: View {
.cornerRadius(10)
.shadow(radius: 5)
.padding(.bottom, 5)
}
} else {
Button {
self.libraryListRouter.route(to: \.library,
(viewModel: LibraryViewModel(parentID: library.id), title: library.name ?? ""))
}
label: {
ZStack {
HStack {
Spacer()
VStack {
Text(library.name ?? "")
.foregroundColor(.white)
.font(.title2)
.fontWeight(.semibold)
}
Spacer()
}.padding(32)
}
.frame(minWidth: 100, maxWidth: .infinity)
.frame(height: 100)
}
.cornerRadius(10)
.shadow(radius: 5)
.padding(.bottom, 5)
}
}
} else {

View File

@ -38,6 +38,8 @@ struct SettingsView: View {
var jumpBackwardLength
@Default(.jumpGesturesEnabled)
var jumpGesturesEnabled
@Default(.systemControlGesturesEnabled)
var systemControlGesturesEnabled
@Default(.resumeOffset)
var resumeOffset
@Default(.subtitleSize)
@ -107,6 +109,8 @@ struct SettingsView: View {
Toggle(L10n.jumpGesturesEnabled, isOn: $jumpGesturesEnabled)
Toggle(L10n.systemControlGesturesEnabled, isOn: $systemControlGesturesEnabled)
Toggle(L10n.resume5SecondOffset, isOn: $resumeOffset)
Button {

View File

@ -42,12 +42,18 @@ class VLCPlayerViewController: UIViewController {
currentChapterOverlayHostingController?.view.alpha ?? 0 > 0
}
private var panBeganBrightness = CGFloat.zero
private var panBeganVolumeValue = Float.zero
private var panBeganPoint = CGPoint.zero
private lazy var videoContentView = makeVideoContentView()
private lazy var mainGestureView = makeMainGestureView()
private var currentOverlayHostingController: UIHostingController<VLCPlayerOverlayView>?
private var currentChapterOverlayHostingController: UIHostingController<VLCPlayerChapterOverlayView>?
private var systemControlOverlayLabel = UILabel()
private var currentJumpBackwardOverlayView: UIImageView?
private var currentJumpForwardOverlayView: UIImageView?
private var volumeView = MPVolumeView()
override var keyCommands: [UIKeyCommand]? {
var commands = [
@ -95,6 +101,12 @@ class VLCPlayerViewController: UIViewController {
private func setupSubviews() {
view.addSubview(videoContentView)
view.addSubview(mainGestureView)
// Setup BrightnessOverlayView
systemControlOverlayLabel.alpha = 0
systemControlOverlayLabel.translatesAutoresizingMaskIntoConstraints = false
systemControlOverlayLabel.font = .systemFont(ofSize: 48)
view.addSubview(systemControlOverlayLabel)
}
private func setupConstraints() {
@ -110,6 +122,10 @@ class VLCPlayerViewController: UIViewController {
mainGestureView.leftAnchor.constraint(equalTo: videoContentView.leftAnchor),
mainGestureView.rightAnchor.constraint(equalTo: videoContentView.rightAnchor),
])
NSLayoutConstraint.activate([
systemControlOverlayLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor),
systemControlOverlayLabel.centerYAnchor.constraint(equalTo: view.centerYAnchor),
])
}
// MARK: viewWillDisappear
@ -202,6 +218,8 @@ class VLCPlayerViewController: UIViewController {
let pinchGesture = UIPinchGestureRecognizer(target: self, action: #selector(didPinch(_:)))
let panGesture = UIPanGestureRecognizer(target: self, action: #selector(didPan(_:)))
view.addGestureRecognizer(singleTapGesture)
view.addGestureRecognizer(pinchGesture)
@ -210,6 +228,10 @@ class VLCPlayerViewController: UIViewController {
view.addGestureRecognizer(leftSwipeGesture)
}
if viewModel.systemControlGesturesEnabled {
view.addGestureRecognizer(panGesture)
}
return view
}
@ -243,6 +265,35 @@ class VLCPlayerViewController: UIViewController {
}
}
@objc
private func didPan(_ gestureRecognizer: UIPanGestureRecognizer) {
switch gestureRecognizer.state {
case .began:
panBeganBrightness = UIScreen.main.brightness
if let view = volumeView.subviews.first as? UISlider {
panBeganVolumeValue = view.value
}
panBeganPoint = gestureRecognizer.location(in: mainGestureView)
case .changed:
let mainGestureViewHalfWidth = mainGestureView.frame.width * 0.5
let mainGestureViewHalfHeight = mainGestureView.frame.height * 0.5
let pos = gestureRecognizer.location(in: mainGestureView)
let moveDelta = pos.y - panBeganPoint.y
let changedValue = moveDelta / mainGestureViewHalfHeight
if panBeganPoint.x < mainGestureViewHalfWidth {
UIScreen.main.brightness = panBeganBrightness - changedValue
flashBrightnessOverlay()
} else if let view = volumeView.subviews.first as? UISlider {
view.value = panBeganVolumeValue - Float(changedValue)
flashVolumeOverlay()
}
default:
hideSystemControlOverlay()
}
}
// MARK: setupOverlayHostingController
private func setupOverlayHostingController(viewModel: VideoPlayerViewModel) {
@ -560,6 +611,53 @@ extension VLCPlayerViewController {
}
}
// MARK: Show/Hide System Control
extension VLCPlayerViewController {
private func flashBrightnessOverlay() {
guard !displayingOverlay else { return }
let imageAttachment = NSTextAttachment()
imageAttachment.image = UIImage(systemName: "sun.max", withConfiguration: UIImage.SymbolConfiguration(pointSize: 48))?
.withTintColor(.white)
let attributedString = NSMutableAttributedString()
attributedString.append(.init(attachment: imageAttachment))
attributedString.append(.init(string: " \(String(format: "%.0f", UIScreen.main.brightness * 100))%"))
systemControlOverlayLabel.attributedText = attributedString
systemControlOverlayLabel.layer.removeAllAnimations()
UIView.animate(withDuration: 0.1) {
self.systemControlOverlayLabel.alpha = 1
}
}
private func flashVolumeOverlay() {
guard !displayingOverlay,
let value = (volumeView.subviews.first as? UISlider)?.value else { return }
let imageAttachment = NSTextAttachment()
imageAttachment.image = UIImage(systemName: "speaker.wave.2", withConfiguration: UIImage.SymbolConfiguration(pointSize: 48))?
.withTintColor(.white)
let attributedString = NSMutableAttributedString()
attributedString.append(.init(attachment: imageAttachment))
attributedString.append(.init(string: " \(String(format: "%.0f", value * 100))%"))
systemControlOverlayLabel.attributedText = attributedString
systemControlOverlayLabel.layer.removeAllAnimations()
UIView.animate(withDuration: 0.1) {
self.systemControlOverlayLabel.alpha = 1
}
}
private func hideSystemControlOverlay() {
UIView.animate(withDuration: 0.75) {
self.systemControlOverlayLabel.alpha = 0
}
}
}
// MARK: Show/Hide Jump
extension VLCPlayerViewController {