Use Swift 5.7 if-let style

This commit is contained in:
Arkadiusz Fal 2022-09-28 16:27:01 +02:00
parent 8f96a7c5e0
commit a086a0f440
50 changed files with 114 additions and 114 deletions

View File

@ -76,7 +76,7 @@ import SwiftUI
let blurEffect = UIBlurEffect(style: blurStyle) let blurEffect = UIBlurEffect(style: blurStyle)
blurView.effect = blurEffect blurView.effect = blurEffect
if let vibrancyStyle = vibrancyStyle { if let vibrancyStyle {
vibrancyView.effect = UIVibrancyEffect(blurEffect: blurEffect, style: vibrancyStyle) vibrancyView.effect = UIVibrancyEffect(blurEffect: blurEffect, style: vibrancyStyle)
} else { } else {
vibrancyView.effect = nil vibrancyView.effect = nil

View File

@ -59,7 +59,7 @@ struct Account: Defaults.Serializable, Hashable, Identifiable {
var shortUsername: String { var shortUsername: String {
let (username, _) = credentials let (username, _) = credentials
guard let username = username, guard let username,
username.count > 10 username.count > 10
else { else {
return username ?? "" return username ?? ""
@ -70,7 +70,7 @@ struct Account: Defaults.Serializable, Hashable, Identifiable {
} }
var description: String { var description: String {
guard let name = name, !name.isEmpty else { guard let name, !name.isEmpty else {
return shortUsername return shortUsername
} }

View File

@ -6,7 +6,7 @@ struct AccountsBridge: Defaults.Bridge {
typealias Serializable = [String: String] typealias Serializable = [String: String]
func serialize(_ value: Value?) -> Serializable? { func serialize(_ value: Value?) -> Serializable? {
guard let value = value else { guard let value else {
return nil return nil
} }
@ -22,7 +22,7 @@ struct AccountsBridge: Defaults.Bridge {
func deserialize(_ object: Serializable?) -> Value? { func deserialize(_ object: Serializable?) -> Value? {
guard guard
let object = object, let object,
let id = object["id"], let id = object["id"],
let instanceID = object["instanceID"], let instanceID = object["instanceID"],
let url = object["apiURL"], let url = object["apiURL"],

View File

@ -6,7 +6,7 @@ struct InstancesBridge: Defaults.Bridge {
typealias Serializable = [String: String] typealias Serializable = [String: String]
func serialize(_ value: Value?) -> Serializable? { func serialize(_ value: Value?) -> Serializable? {
guard let value = value else { guard let value else {
return nil return nil
} }
@ -22,7 +22,7 @@ struct InstancesBridge: Defaults.Bridge {
func deserialize(_ object: Serializable?) -> Value? { func deserialize(_ object: Serializable?) -> Value? {
guard guard
let object = object, let object,
let app = VideosApp(rawValue: object["app"] ?? ""), let app = VideosApp(rawValue: object["app"] ?? ""),
let id = object["id"], let id = object["id"],
let apiURL = object["apiURL"] let apiURL = object["apiURL"]

View File

@ -13,7 +13,7 @@ final class InvidiousAPI: Service, ObservableObject, VideosAPI {
@Published var validInstance = true @Published var validInstance = true
var signedIn: Bool { var signedIn: Bool {
guard let account = account else { return false } guard let account else { return false }
return !account.anonymous && !(account.token?.isEmpty ?? true) return !account.anonymous && !(account.token?.isEmpty ?? true)
} }
@ -182,8 +182,8 @@ final class InvidiousAPI: Service, ObservableObject, VideosAPI {
return return
} }
guard let username = username, guard let username,
let password = password, let password,
!username.isEmpty, !username.isEmpty,
!password.isEmpty !password.isEmpty
else { else {
@ -406,7 +406,7 @@ final class InvidiousAPI: Service, ObservableObject, VideosAPI {
resource = resource.withParam("duration", duration.rawValue) resource = resource.withParam("duration", duration.rawValue)
} }
if let page = page { if let page {
resource = resource.withParam("page", page) resource = resource.withParam("page", page)
} }
@ -420,7 +420,7 @@ final class InvidiousAPI: Service, ObservableObject, VideosAPI {
func comments(_ id: Video.ID, page: String?) -> Resource? { func comments(_ id: Video.ID, page: String?) -> Resource? {
let resource = resource(baseURL: account.url, path: basePathAppending("comments/\(id)")) let resource = resource(baseURL: account.url, path: basePathAppending("comments/\(id)"))
guard let page = page else { return resource } guard let page else { return resource }
return resource.withParam("continuation", page) return resource.withParam("continuation", page)
} }

View File

@ -112,8 +112,8 @@ final class PipedAPI: Service, ObservableObject, VideosAPI {
let (username, password) = AccountsModel.getCredentials(account) let (username, password) = AccountsModel.getCredentials(account)
guard !account.anonymous, guard !account.anonymous,
let username = username, let username,
let password = password let password
else { else {
return return
} }
@ -196,7 +196,7 @@ final class PipedAPI: Service, ObservableObject, VideosAPI {
} }
var signedIn: Bool { var signedIn: Bool {
guard let account = account else { guard let account else {
return false return false
} }

View File

@ -167,11 +167,11 @@ extension VideosAPI {
guard var startSeconds = seconds else { return nil } guard var startSeconds = seconds else { return nil }
if let minutes = minutes { if let minutes {
startSeconds += 60 * minutes startSeconds += 60 * minutes
} }
if let hours = hours { if let hours {
startSeconds += 60 * 60 * hours startSeconds += 60 * 60 * hours
} }

View File

@ -38,7 +38,7 @@ extension PlayerModel {
let results = try? backgroundContext.fetch(watchFetchRequest) let results = try? backgroundContext.fetch(watchFetchRequest)
backgroundContext.perform { [weak self] in backgroundContext.perform { [weak self] in
guard let self = self else { guard let self else {
return return
} }

View File

@ -28,7 +28,7 @@ final class InstancesManifest: Service, ObservableObject {
} }
func setPublicAccount(_ country: String?, accounts: AccountsModel, asCurrent: Bool = true) { func setPublicAccount(_ country: String?, accounts: AccountsModel, asCurrent: Bool = true) {
guard let country = country else { guard let country else {
accounts.publicAccount = nil accounts.publicAccount = nil
if asCurrent { if asCurrent {
accounts.configureAccount() accounts.configureAccount()
@ -68,7 +68,7 @@ final class InstancesManifest: Service, ObservableObject {
instance = countryInstances.randomElement() ?? regionInstances.randomElement() instance = countryInstances.randomElement() ?? regionInstances.randomElement()
} }
guard let instance = instance else { guard let instance else {
settings.presentAlert(title: "Could not change location", message: "No locations available at the moment") settings.presentAlert(title: "Could not change location", message: "No locations available at the moment")
return return
} }

View File

@ -180,7 +180,7 @@ final class NavigationModel: ObservableObject {
let presentingPlayer = player.presentingPlayer let presentingPlayer = player.presentingPlayer
player.hide() player.hide()
if let searchQuery = searchQuery { if let searchQuery {
let recent = RecentItem(from: searchQuery) let recent = RecentItem(from: searchQuery)
recents.add(recent) recents.add(recent)

View File

@ -11,13 +11,13 @@ final class NetworkStateModel: ObservableObject {
private let controlsOverlayModel = ControlOverlaysModel.shared private let controlsOverlayModel = ControlOverlaysModel.shared
var osdVisible: Bool { var osdVisible: Bool {
guard let player = player else { return false } guard let player else { return false }
return player.isPlaying && ((player.activeBackend == .mpv && pausedForCache) || player.isSeeking) && bufferingState < 100.0 return player.isPlaying && ((player.activeBackend == .mpv && pausedForCache) || player.isSeeking) && bufferingState < 100.0
} }
var fullStateText: String? { var fullStateText: String? {
guard let bufferingStateText = bufferingStateText, guard let bufferingStateText,
let cacheDurationText = cacheDurationText let cacheDurationText
else { else {
return nil return nil
} }
@ -36,12 +36,12 @@ final class NetworkStateModel: ObservableObject {
} }
var detailsAvailable: Bool { var detailsAvailable: Bool {
guard let player = player else { return false } guard let player else { return false }
return player.activeBackend.supportsNetworkStateBufferingDetails return player.activeBackend.supportsNetworkStateBufferingDetails
} }
var needsUpdates: Bool { var needsUpdates: Bool {
if let player = player { if let player {
return !player.currentItem.isNil && (pausedForCache || player.isSeeking || player.isLoadingVideo || controlsOverlayModel.presenting) return !player.currentItem.isNil && (pausedForCache || player.isSeeking || player.isLoadingVideo || controlsOverlayModel.presenting)
} }

View File

@ -211,7 +211,7 @@ final class AVPlayerBackend: PlayerBackend {
model: PlayerModel model: PlayerModel
) { ) {
asset.loadValuesAsynchronously(forKeys: Self.assetKeysToLoad) { [weak self] in asset.loadValuesAsynchronously(forKeys: Self.assetKeysToLoad) { [weak self] in
guard let self = self else { guard let self else {
return return
} }
model.logger.info("loading \(type.rawValue) track") model.logger.info("loading \(type.rawValue) track")
@ -285,7 +285,7 @@ final class AVPlayerBackend: PlayerBackend {
guard let item = self.model.playerItem, self.isAutoplaying(item) else { return } guard let item = self.model.playerItem, self.isAutoplaying(item) else { return }
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { [weak self] in DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { [weak self] in
guard let self = self else { guard let self else {
return return
} }
@ -361,7 +361,7 @@ final class AVPlayerBackend: PlayerBackend {
} }
private func playerItem(_: Stream) -> AVPlayerItem? { private func playerItem(_: Stream) -> AVPlayerItem? {
if let asset = asset { if let asset {
return AVPlayerItem(asset: asset) return AVPlayerItem(asset: asset)
} else { } else {
return AVPlayerItem(asset: composition) return AVPlayerItem(asset: composition)
@ -380,7 +380,7 @@ final class AVPlayerBackend: PlayerBackend {
if let thumbnailURL = video.thumbnailURL(quality: .medium) { if let thumbnailURL = video.thumbnailURL(quality: .medium) {
let task = URLSession.shared.dataTask(with: thumbnailURL) { [weak self] thumbnailData, _, _ in let task = URLSession.shared.dataTask(with: thumbnailURL) { [weak self] thumbnailData, _, _ in
guard let thumbnailData = thumbnailData else { return } guard let thumbnailData else { return }
let image = UIImage(data: thumbnailData) let image = UIImage(data: thumbnailData)
if let pngData = image?.pngData() { if let pngData = image?.pngData() {
@ -425,7 +425,7 @@ final class AVPlayerBackend: PlayerBackend {
private func observePlayerItemStatus(_ item: AVPlayerItem) { private func observePlayerItemStatus(_ item: AVPlayerItem) {
statusObservation?.invalidate() statusObservation?.invalidate()
statusObservation = item.observe(\.status, options: [.old, .new]) { [weak self] playerItem, _ in statusObservation = item.observe(\.status, options: [.old, .new]) { [weak self] playerItem, _ in
guard let self = self else { guard let self else {
return return
} }
@ -507,7 +507,7 @@ final class AVPlayerBackend: PlayerBackend {
forInterval: interval, forInterval: interval,
queue: .main queue: .main
) { [weak self] _ in ) { [weak self] _ in
guard let self = self, self.model.activeBackend == .appleAVPlayer else { guard let self, self.model.activeBackend == .appleAVPlayer else {
return return
} }
@ -551,7 +551,7 @@ final class AVPlayerBackend: PlayerBackend {
forInterval: interval, forInterval: interval,
queue: .main queue: .main
) { [weak self] _ in ) { [weak self] _ in
guard let self = self else { guard let self else {
return return
} }
@ -567,7 +567,7 @@ final class AVPlayerBackend: PlayerBackend {
private func addPlayerTimeControlStatusObserver() { private func addPlayerTimeControlStatusObserver() {
playerTimeControlStatusObserver = avPlayer.observe(\.timeControlStatus) { [weak self] player, _ in playerTimeControlStatusObserver = avPlayer.observe(\.timeControlStatus) { [weak self] player, _ in
guard let self = self, guard let self,
self.avPlayer == player, self.avPlayer == player,
self.model.activeBackend == .appleAVPlayer self.model.activeBackend == .appleAVPlayer
else { else {

View File

@ -22,7 +22,7 @@ final class MPVBackend: PlayerBackend {
var stream: Stream? var stream: Stream?
var video: Video? var video: Video?
var captions: Captions? { didSet { var captions: Captions? { didSet {
guard let captions = captions else { guard let captions else {
client.removeSubs() client.removeSubs()
return return
} }
@ -33,7 +33,7 @@ final class MPVBackend: PlayerBackend {
var loadedVideo = false var loadedVideo = false
var isLoadingVideo = true { didSet { var isLoadingVideo = true { didSet {
DispatchQueue.main.async { [weak self] in DispatchQueue.main.async { [weak self] in
guard let self = self else { guard let self else {
return return
} }
@ -71,7 +71,7 @@ final class MPVBackend: PlayerBackend {
var isSeeking = false { var isSeeking = false {
didSet { didSet {
DispatchQueue.main.async { [weak self] in DispatchQueue.main.async { [weak self] in
guard let self = self else { return } guard let self else { return }
self.model.isSeeking = self.isSeeking self.model.isSeeking = self.isSeeking
} }
} }
@ -187,7 +187,7 @@ final class MPVBackend: PlayerBackend {
#endif #endif
DispatchQueue.main.async { [weak self] in DispatchQueue.main.async { [weak self] in
guard let self = self else { guard let self else {
return return
} }
@ -213,14 +213,14 @@ final class MPVBackend: PlayerBackend {
} }
let replaceItem: (CMTime?) -> Void = { [weak self] time in let replaceItem: (CMTime?) -> Void = { [weak self] time in
guard let self = self else { guard let self else {
return return
} }
self.stop() self.stop()
DispatchQueue.main.async { [weak self] in DispatchQueue.main.async { [weak self] in
guard let self = self else { guard let self else {
return return
} }
@ -345,7 +345,7 @@ final class MPVBackend: PlayerBackend {
model.updateNowPlayingInfo() model.updateNowPlayingInfo()
handleSegmentsThrottle.execute { handleSegmentsThrottle.execute {
if let currentTime = currentTime { if let currentTime {
model.handleSegments(at: currentTime) model.handleSegments(at: currentTime)
} }
} }
@ -453,7 +453,7 @@ final class MPVBackend: PlayerBackend {
} }
func updateNetworkState() { func updateNetworkState() {
guard let client = client, let networkState = networkState else { guard let client, let networkState else {
return return
} }

View File

@ -29,7 +29,7 @@ final class MPVClient: ObservableObject {
func create(frame: CGRect? = nil) { func create(frame: CGRect? = nil) {
#if !os(macOS) #if !os(macOS)
if let frame = frame { if let frame {
glView = MPVOGLView(frame: frame) glView = MPVOGLView(frame: frame)
} }
#endif #endif
@ -134,7 +134,7 @@ final class MPVClient: ObservableObject {
var args = [url.absoluteString] var args = [url.absoluteString]
var options = [String]() var options = [String]()
if let time = time { if let time {
args.append("replace") args.append("replace")
options.append("start=\(Int(time.seconds))") options.append("start=\(Int(time.seconds))")
} }
@ -268,7 +268,7 @@ final class MPVClient: ObservableObject {
} }
DispatchQueue.main.async { [weak self] in DispatchQueue.main.async { [weak self] in
guard let self = self, let model = self.backend.model else { return } guard let self, let model = self.backend.model else { return }
UIView.animate(withDuration: 0.2, animations: { UIView.animate(withDuration: 0.2, animations: {
let aspectRatio = self.aspectRatio > 0 && self.aspectRatio < VideoPlayerView.defaultAspectRatio ? self.aspectRatio : VideoPlayerView.defaultAspectRatio let aspectRatio = self.aspectRatio > 0 && self.aspectRatio < VideoPlayerView.defaultAspectRatio ? self.aspectRatio : VideoPlayerView.defaultAspectRatio
let height = [model.playerSize.height, model.playerSize.width / aspectRatio].min()! let height = [model.playerSize.height, model.playerSize.width / aspectRatio].min()!

View File

@ -79,7 +79,7 @@ extension PlayerBackend {
} }
func seek(relative time: CMTime, seekType: SeekType, completionHandler: ((Bool) -> Void)? = nil) { func seek(relative time: CMTime, seekType: SeekType, completionHandler: ((Bool) -> Void)? = nil) {
if let currentTime = currentTime, let duration = playerItemDuration { if let currentTime, let duration = playerItemDuration {
let seekTime = min(max(0, currentTime.seconds + time.seconds), duration.seconds) let seekTime = min(max(0, currentTime.seconds + time.seconds), duration.seconds)
model.seek.registerSeek(at: .secondsInDefaultTimescale(seekTime), type: seekType, restore: currentTime) model.seek.registerSeek(at: .secondsInDefaultTimescale(seekTime), type: seekType, restore: currentTime)
seek(to: seekTime, seekType: seekType, completionHandler: completionHandler) seek(to: seekTime, seekType: seekType, completionHandler: completionHandler)

View File

@ -15,7 +15,7 @@ final class ControlOverlaysModel: ObservableObject {
} }
private func handlePresentationChange() { private func handlePresentationChange() {
guard let player = player else { return } guard let player else { return }
player.backend.setNeedsNetworkStateUpdates(presenting && Defaults[.showMPVPlaybackStats]) player.backend.setNeedsNetworkStateUpdates(presenting && Defaults[.showMPVPlaybackStats])
} }
} }

View File

@ -16,7 +16,7 @@ final class PiPDelegate: NSObject, AVPictureInPictureControllerDelegate {
func pictureInPictureControllerWillStartPictureInPicture(_: AVPictureInPictureController) {} func pictureInPictureControllerWillStartPictureInPicture(_: AVPictureInPictureController) {}
func pictureInPictureControllerDidStartPictureInPicture(_: AVPictureInPictureController) { func pictureInPictureControllerDidStartPictureInPicture(_: AVPictureInPictureController) {
guard let player = player else { return } guard let player else { return }
player.playingInPictureInPicture = true player.playingInPictureInPicture = true
player.avPlayerBackend.startPictureInPictureOnPlay = false player.avPlayerBackend.startPictureInPictureOnPlay = false
@ -27,7 +27,7 @@ final class PiPDelegate: NSObject, AVPictureInPictureControllerDelegate {
} }
func pictureInPictureControllerDidStopPictureInPicture(_: AVPictureInPictureController) { func pictureInPictureControllerDidStopPictureInPicture(_: AVPictureInPictureController) {
guard let player = player else { return } guard let player else { return }
player.playingInPictureInPicture = false player.playingInPictureInPicture = false
player.controls.objectWillChange.send() player.controls.objectWillChange.send()

View File

@ -35,7 +35,7 @@ final class PlayerControlsModel: ObservableObject {
} }
func handlePresentationChange() { func handlePresentationChange() {
guard let player = player else { return } guard let player else { return }
if presentingControls { if presentingControls {
DispatchQueue.main.async(qos: .userInteractive) { [weak self] in DispatchQueue.main.async(qos: .userInteractive) { [weak self] in
player.backend.startControlsUpdates() player.backend.startControlsUpdates()
@ -82,7 +82,7 @@ final class PlayerControlsModel: ObservableObject {
} }
func hide() { func hide() {
guard let player = player, guard let player,
!player.musicMode !player.musicMode
else { else {
return return
@ -109,7 +109,7 @@ final class PlayerControlsModel: ObservableObject {
func resetTimer() { func resetTimer() {
removeTimer() removeTimer()
guard let player = player, !player.musicMode else { guard let player, !player.musicMode else {
return return
} }

View File

@ -304,7 +304,7 @@ final class PlayerModel: ObservableObject {
var playingLive: Bool { var playingLive: Bool {
guard live, guard live,
let videoDuration = videoDuration, let videoDuration,
let time = backend.currentTime?.seconds else { return false } let time = backend.currentTime?.seconds else { return false }
return videoDuration - time < 30 return videoDuration - time < 30
@ -337,7 +337,7 @@ final class PlayerModel: ObservableObject {
backend == .appleAVPlayer || !avPlayerBackend.startPictureInPictureOnPlay backend == .appleAVPlayer || !avPlayerBackend.startPictureInPictureOnPlay
{ {
changeBackendHandler = { [weak self] in changeBackendHandler = { [weak self] in
guard let self = self else { return } guard let self else { return }
self.changeActiveBackend(from: self.activeBackend, to: backend) self.changeActiveBackend(from: self.activeBackend, to: backend)
} }
} }
@ -499,7 +499,7 @@ final class PlayerModel: ObservableObject {
fromBackend.pause() fromBackend.pause()
} }
guard var stream = stream, changingStream else { guard var stream, changingStream else {
return return
} }
@ -529,7 +529,7 @@ final class PlayerModel: ObservableObject {
} }
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { [weak self] in DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { [weak self] in
guard let self = self else { guard let self else {
return return
} }
self.upgradeToStream(stream, force: true) self.upgradeToStream(stream, force: true)
@ -610,7 +610,7 @@ final class PlayerModel: ObservableObject {
var pipPossible: Bool { var pipPossible: Bool {
guard activeBackend == .appleAVPlayer else { return !transitioningToPiP } guard activeBackend == .appleAVPlayer else { return !transitioningToPiP }
guard let pipController = pipController else { return false } guard let pipController else { return false }
guard !pipController.isPictureInPictureActive else { return true } guard !pipController.isPictureInPictureActive else { return true }
return pipController.isPictureInPicturePossible && !transitioningToPiP return pipController.isPictureInPicturePossible && !transitioningToPiP
@ -644,7 +644,7 @@ final class PlayerModel: ObservableObject {
#endif #endif
DispatchQueue.main.async(qos: .background) { [weak self] in DispatchQueue.main.async(qos: .background) { [weak self] in
guard let self = self else { return } guard let self else { return }
if self.saveLastPlayed { if self.saveLastPlayed {
self.lastPlayed = self.currentItem self.lastPlayed = self.currentItem
} }
@ -680,8 +680,8 @@ final class PlayerModel: ObservableObject {
let results = try? context.fetch(watchFetchRequest) let results = try? context.fetch(watchFetchRequest)
context.perform { [weak self] in context.perform { [weak self] in
guard let self = self, guard let self,
let results = results else { return } let results else { return }
let resultsIds = results.map(\.videoID) let resultsIds = results.map(\.videoID)
guard let autoplayVideo = related.filter({ !resultsIds.contains($0.videoID) }).randomElement() else { guard let autoplayVideo = related.filter({ !resultsIds.contains($0.videoID) }).randomElement() else {
@ -693,7 +693,7 @@ final class PlayerModel: ObservableObject {
self.autoplayItemSource = video self.autoplayItemSource = video
DispatchQueue.main.asyncAfter(deadline: .now() + 3) { [weak self] in DispatchQueue.main.asyncAfter(deadline: .now() + 3) { [weak self] in
guard let self = self else { return } guard let self else { return }
self.playerAPI.loadDetails(item, completionHandler: { newItem in self.playerAPI.loadDetails(item, completionHandler: { newItem in
guard newItem.videoID == self.autoplayItem?.videoID else { return } guard newItem.videoID == self.autoplayItem?.videoID else { return }
self.autoplayItem = newItem self.autoplayItem = newItem
@ -875,7 +875,7 @@ final class PlayerModel: ObservableObject {
} }
let task = URLSession.shared.dataTask(with: thumbnailURL) { [weak self] thumbnailData, _, _ in let task = URLSession.shared.dataTask(with: thumbnailURL) { [weak self] thumbnailData, _, _ in
guard let thumbnailData = thumbnailData else { guard let thumbnailData else {
return return
} }
@ -947,7 +947,7 @@ final class PlayerModel: ObservableObject {
guard aspectRatio != backend.aspectRatio else { return } guard aspectRatio != backend.aspectRatio else { return }
DispatchQueue.main.async { [weak self] in DispatchQueue.main.async { [weak self] in
guard let self = self else { return } guard let self else { return }
self.aspectRatio = self.backend.aspectRatio self.aspectRatio = self.backend.aspectRatio
} }
#endif #endif

View File

@ -58,7 +58,7 @@ extension PlayerModel {
preservedTime = currentItem.playbackTime preservedTime = currentItem.playbackTime
DispatchQueue.main.async { [weak self] in DispatchQueue.main.async { [weak self] in
guard let self = self else { return } guard let self else { return }
guard let video = self.currentVideo else { guard let video = self.currentVideo else {
return return
} }
@ -122,7 +122,7 @@ extension PlayerModel {
resetAutoplay() resetAutoplay()
if let nextItem = nextItem { if let nextItem {
advanceToItem(nextItem) advanceToItem(nextItem)
} else { } else {
advancing = false advancing = false
@ -164,7 +164,7 @@ extension PlayerModel {
func resetQueue() { func resetQueue() {
DispatchQueue.main.async { [weak self] in DispatchQueue.main.async { [weak self] in
guard let self = self else { guard let self else {
return return
} }
@ -193,7 +193,7 @@ extension PlayerModel {
if loadDetails { if loadDetails {
playerAPI.loadDetails(item, failureHandler: videoLoadFailureHandler) { [weak self] newItem in playerAPI.loadDetails(item, failureHandler: videoLoadFailureHandler) { [weak self] newItem in
guard let self = self else { return } guard let self else { return }
videoDetailsLoadHandler(newItem.video, newItem) videoDetailsLoadHandler(newItem.video, newItem)
if play { if play {
@ -239,7 +239,7 @@ extension PlayerModel {
func restoreQueue() { func restoreQueue() {
var restoredQueue = [PlayerQueueItem?]() var restoredQueue = [PlayerQueueItem?]()
if let lastPlayed = lastPlayed, if let lastPlayed,
!Defaults[.queue].contains(where: { $0.videoID == lastPlayed.videoID }) !Defaults[.queue].contains(where: { $0.videoID == lastPlayed.videoID })
{ {
restoredQueue.append(lastPlayed) restoredQueue.append(lastPlayed)

View File

@ -7,7 +7,7 @@ struct PlayerQueueItemBridge: Defaults.Bridge {
typealias Serializable = [String: String] typealias Serializable = [String: String]
func serialize(_ value: Value?) -> Serializable? { func serialize(_ value: Value?) -> Serializable? {
guard let value = value else { guard let value else {
return nil return nil
} }
@ -34,7 +34,7 @@ struct PlayerQueueItemBridge: Defaults.Bridge {
func deserialize(_ object: Serializable?) -> Value? { func deserialize(_ object: Serializable?) -> Value? {
guard guard
let object = object, let object,
let videoID = object["videoID"] let videoID = object["videoID"]
else { else {
return nil return nil

View File

@ -37,7 +37,7 @@ extension PlayerModel {
logger.error("segment end time is: \(segment.end) when player item duration is: \(duration.seconds)") logger.error("segment end time is: \(segment.end) when player item duration is: \(duration.seconds)")
DispatchQueue.main.async { [weak self] in DispatchQueue.main.async { [weak self] in
guard let self = self else { guard let self else {
return return
} }

View File

@ -18,7 +18,7 @@ extension PlayerModel {
func loadAvailableStreams(_ video: Video) { func loadAvailableStreams(_ video: Video) {
availableStreams = [] availableStreams = []
guard let playerInstance = playerInstance else { return } guard let playerInstance else { return }
logger.info("loading streams from \(playerInstance.description)") logger.info("loading streams from \(playerInstance.description)")
fetchStreams(playerAPI.video(video.videoID), instance: playerInstance, video: video) fetchStreams(playerAPI.video(video.videoID), instance: playerInstance, video: video)

View File

@ -55,7 +55,7 @@ struct QualityProfile: Hashable, Identifiable, Defaults.Serializable {
var formats: [Format] var formats: [Format]
var description: String { var description: String {
if let name = name, !name.isEmpty { return name } if let name, !name.isEmpty { return name }
return "\(backend.label) - \(resolution.description) - \(formatsDescription)" return "\(backend.label) - \(resolution.description) - \(formatsDescription)"
} }
@ -93,7 +93,7 @@ struct QualityProfileBridge: Defaults.Bridge {
typealias Serializable = [String: String] typealias Serializable = [String: String]
func serialize(_ value: Value?) -> Serializable? { func serialize(_ value: Value?) -> Serializable? {
guard let value = value else { return nil } guard let value else { return nil }
return [ return [
"id": value.id, "id": value.id,
@ -105,7 +105,7 @@ struct QualityProfileBridge: Defaults.Bridge {
} }
func deserialize(_ object: Serializable?) -> Value? { func deserialize(_ object: Serializable?) -> Value? {
guard let object = object, guard let object,
let id = object["id"], let id = object["id"],
let backend = PlayerBackendType(rawValue: object["backend"] ?? ""), let backend = PlayerBackendType(rawValue: object["backend"] ?? ""),
let resolution = ResolutionSetting(rawValue: object["resolution"] ?? "") let resolution = ResolutionSetting(rawValue: object["resolution"] ?? "")

View File

@ -99,7 +99,7 @@ struct QualityProfilesModel {
id = Defaults[.chargingNonCellularProfile] id = Defaults[.chargingNonCellularProfile]
#endif #endif
guard let id = id else { return nil } guard let id else { return nil }
return find(id) return find(id)
} }

View File

@ -137,7 +137,7 @@ struct RecentItemBridge: Defaults.Bridge {
typealias Serializable = [String: String] typealias Serializable = [String: String]
func serialize(_ value: Value?) -> Serializable? { func serialize(_ value: Value?) -> Serializable? {
guard let value = value else { guard let value else {
return nil return nil
} }
@ -150,7 +150,7 @@ struct RecentItemBridge: Defaults.Bridge {
func deserialize(_ object: Serializable?) -> Value? { func deserialize(_ object: Serializable?) -> Value? {
guard guard
let object = object, let object,
let type = object["type"], let type = object["type"],
let identifier = object["identifier"], let identifier = object["identifier"],
let title = object["title"] let title = object["title"]

View File

@ -25,7 +25,7 @@ final class ReturnYouTubeDislikeAPI: ObservableObject {
private func requestDislikes(completionHandler: @escaping (Int) -> Void = { _ in }) { private func requestDislikes(completionHandler: @escaping (Int) -> Void = { _ in }) {
AF.request(votesURL).responseDecodable(of: JSON.self) { [weak self] response in AF.request(votesURL).responseDecodable(of: JSON.self) { [weak self] response in
guard let self = self else { guard let self else {
return return
} }

View File

@ -51,7 +51,7 @@ final class SeekModel: ObservableObject {
} }
var gestureSeekDestinationTime: Double { var gestureSeekDestinationTime: Double {
guard let gestureSeek = gestureSeek, let gestureStart = gestureStart else { return -1 } guard let gestureSeek, let gestureStart else { return -1 }
return min(duration.seconds, max(0, gestureStart + gestureSeek)) return min(duration.seconds, max(0, gestureStart + gestureSeek))
} }

View File

@ -86,7 +86,7 @@ final class SponsorBlockAPI: ObservableObject {
} }
AF.request(url, parameters: parameters(categories: categories)).responseDecodable(of: JSON.self) { [weak self] response in AF.request(url, parameters: parameters(categories: categories)).responseDecodable(of: JSON.self) { [weak self] response in
guard let self = self else { guard let self else {
return return
} }

View File

@ -30,7 +30,7 @@ extension Watch {
watch = results?.first watch = results?.first
} }
guard let watch = watch else { return } guard let watch else { return }
watch.videoDuration = duration watch.videoDuration = duration
watch.stoppedAt = duration watch.stoppedAt = duration
@ -65,7 +65,7 @@ extension Watch {
} }
var watchedAtString: String? { var watchedAtString: String? {
guard let watchedAt = watchedAt else { guard let watchedAt else {
return nil return nil
} }

View File

@ -11,14 +11,14 @@ struct DropFavorite: DropDelegate {
return return
} }
guard let current = current else { guard let current else {
return return
} }
let from = favorites.firstIndex(of: current) let from = favorites.firstIndex(of: current)
let to = favorites.firstIndex(of: item) let to = favorites.firstIndex(of: item)
guard let from = from, let to = to else { guard let from, let to else {
return return
} }

View File

@ -32,7 +32,7 @@ struct Buffering: View {
Text(reason) Text(reason)
.font(.system(size: playerControlsLayout.timeFontSize)) .font(.system(size: playerControlsLayout.timeFontSize))
if let state = state { if let state {
Text(state) Text(state)
.font(.system(size: playerControlsLayout.bufferingStateFontSize).monospacedDigit()) .font(.system(size: playerControlsLayout.bufferingStateFontSize).monospacedDigit())
} }

View File

@ -206,12 +206,12 @@ struct PlayerControls: View {
} }
var detailsWidth: Double { var detailsWidth: Double {
guard let player = player, player.playerSize.width.isFinite else { return 200 } guard let player, player.playerSize.width.isFinite else { return 200 }
return [player.playerSize.width, 600].min()! return [player.playerSize.width, 600].min()!
} }
var detailsHeight: Double { var detailsHeight: Double {
guard let player = player, player.playerSize.height.isFinite else { return 200 } guard let player, player.playerSize.height.isFinite else { return 200 }
return [player.playerSize.height, 500].min()! return [player.playerSize.height, 500].min()!
} }

View File

@ -36,7 +36,7 @@ final class MPVOGLView: GLKView {
} }
override func draw(_: CGRect) { override func draw(_: CGRect) {
guard needsDrawing, let mpvGL = mpvGL else { guard needsDrawing, let mpvGL else {
return return
} }

View File

@ -53,7 +53,7 @@ struct StreamControl: View {
} }
.transaction { t in t.animation = .none } .transaction { t in t.animation = .none }
.onChange(of: player.streamSelection) { selection in .onChange(of: player.streamSelection) { selection in
guard let selection = selection else { return } guard let selection else { return }
player.upgradeToStream(selection) player.upgradeToStream(selection)
player.controls.hideOverlays() player.controls.hideOverlays()
} }

View File

@ -143,7 +143,7 @@ struct VideoDetails: View {
var publishedDateSection: some View { var publishedDateSection: some View {
Group { Group {
if let video = video { if let video {
HStack(spacing: 4) { HStack(spacing: 4) {
if let published = video.publishedDate { if let published = video.publishedDate {
Text(published) Text(published)
@ -227,7 +227,7 @@ struct VideoDetails: View {
var detailsPage: some View { var detailsPage: some View {
VStack(alignment: .leading, spacing: 0) { VStack(alignment: .leading, spacing: 0) {
if let video = video { if let video {
VStack(spacing: 6) { VStack(spacing: 6) {
videoProperties videoProperties

View File

@ -33,7 +33,7 @@ struct VideoPlayerSizeModifier: ViewModifier {
} }
var usedAspectRatio: Double { var usedAspectRatio: Double {
guard let aspectRatio = aspectRatio, aspectRatio > 0, aspectRatio < VideoPlayerView.defaultAspectRatio else { guard let aspectRatio, aspectRatio > 0, aspectRatio < VideoPlayerView.defaultAspectRatio else {
return VideoPlayerView.defaultAspectRatio return VideoPlayerView.defaultAspectRatio
} }

View File

@ -46,7 +46,7 @@ struct SearchTextField: View {
.padding(.trailing, 15) .padding(.trailing, 15)
#endif #endif
if let favoriteItem = favoriteItem { if let favoriteItem {
#if os(iOS) #if os(iOS)
FavoriteButton(item: favoriteItem) FavoriteButton(item: favoriteItem)
.id(favoriteItem.id) .id(favoriteItem.id)

View File

@ -117,7 +117,7 @@ struct SearchView: View {
#endif #endif
} }
.onAppear { .onAppear {
if let query = query { if let query {
state.queryText = query.query state.queryText = query.query
state.resetQuery(query) state.resetQuery(query)
updateFavoriteItem() updateFavoriteItem()

View File

@ -18,7 +18,7 @@ struct AccountValidationStatus: View {
VStack(alignment: .leading) { VStack(alignment: .leading) {
Text(isValid ? "Connected successfully (\(app?.name ?? "Unknown"))" : "Connection failed") Text(isValid ? "Connected successfully (\(app?.name ?? "Unknown"))" : "Connection failed")
if let error = error, !isValid { if let error, !isValid {
Text(error) Text(error)
.font(.caption2) .font(.caption2)
.foregroundColor(.secondary) .foregroundColor(.secondary)

View File

@ -134,7 +134,7 @@ struct InstanceForm: View {
} }
func submitForm() { func submitForm() {
guard isValid, let app = app else { guard isValid, let app else {
return return
} }

View File

@ -49,7 +49,7 @@ struct TrendingView: View {
Spacer() Spacer()
} }
if let favoriteItem = favoriteItem { if let favoriteItem {
FavoriteButton(item: favoriteItem, labelPadding: true) FavoriteButton(item: favoriteItem, labelPadding: true)
.id(favoriteItem.id) .id(favoriteItem.id)
.labelStyle(.iconOnly) .labelStyle(.iconOnly)
@ -85,7 +85,7 @@ struct TrendingView: View {
.toolbar { .toolbar {
#if os(macOS) #if os(macOS)
ToolbarItemGroup { ToolbarItemGroup {
if let favoriteItem = favoriteItem { if let favoriteItem {
FavoriteButton(item: favoriteItem) FavoriteButton(item: favoriteItem)
.id(favoriteItem.id) .id(favoriteItem.id)
} }
@ -179,7 +179,7 @@ struct TrendingView: View {
} }
#if os(tvOS) #if os(tvOS)
if let favoriteItem = favoriteItem { if let favoriteItem {
FavoriteButton(item: favoriteItem) FavoriteButton(item: favoriteItem)
.id(favoriteItem.id) .id(favoriteItem.id)
.labelStyle(.iconOnly) .labelStyle(.iconOnly)

View File

@ -55,7 +55,7 @@ struct URLParser {
} }
var isYoutubeHost: Bool { var isYoutubeHost: Bool {
guard let urlComponents = urlComponents else { return false } guard let urlComponents else { return false }
return urlComponents.host == "youtube.com" || urlComponents.host == "www.youtube.com" return urlComponents.host == "youtube.com" || urlComponents.host == "www.youtube.com"
} }
@ -132,7 +132,7 @@ struct URLParser {
} }
private var pathWithoutForwardSlash: String { private var pathWithoutForwardSlash: String {
guard let urlComponents = urlComponents else { return "" } guard let urlComponents else { return "" }
return String(urlComponents.path.dropFirst()) return String(urlComponents.path.dropFirst())
} }

View File

@ -280,7 +280,7 @@ struct VideoCell: View {
} }
} }
if let time = time, !timeOnThumbnail { if let time, !timeOnThumbnail {
Spacer() Spacer()
HStack(spacing: 2) { HStack(spacing: 2) {
@ -403,7 +403,7 @@ struct VideoCell: View {
if timeOnThumbnail, if timeOnThumbnail,
!video.live, !video.live,
let time = time let time
{ {
DetailBadge(text: time, style: .prominent) DetailBadge(text: time, style: .prominent)
} }
@ -429,7 +429,7 @@ struct VideoCell: View {
} }
.retryOnAppear(true) .retryOnAppear(true)
.onFailure { _ in .onFailure { _ in
guard let url = url else { return } guard let url else { return }
thumbnails.insertUnloadable(url) thumbnails.insertUnloadable(url)
} }

View File

@ -48,7 +48,7 @@ struct ControlsBar: View {
#if os(iOS) #if os(iOS)
.background( .background(
EmptyView().sheet(isPresented: $presentingShareSheet) { EmptyView().sheet(isPresented: $presentingShareSheet) {
if let shareURL = shareURL { if let shareURL {
ShareSheet(activityItems: [shareURL]) ShareSheet(activityItems: [shareURL])
} }
} }

View File

@ -39,7 +39,7 @@ struct VideoContextMenuView: View {
@ViewBuilder var contextMenu: some View { @ViewBuilder var contextMenu: some View {
if saveHistory { if saveHistory {
Section { Section {
if let watchedAtString = watchedAtString { if let watchedAtString {
Text(watchedAtString) Text(watchedAtString)
} }
@ -115,7 +115,7 @@ struct VideoContextMenuView: View {
return "Watching now".localized() return "Watching now".localized()
} }
if let watch = watch, let watchedAtString = watch.watchedAtString { if let watch, let watchedAtString = watch.watchedAtString {
if watchedAtString == "in 0 seconds" { if watchedAtString == "in 0 seconds" {
return "Just watched".localized() return "Just watched".localized()
} }
@ -144,7 +144,7 @@ struct VideoContextMenuView: View {
var removeFromHistoryButton: some View { var removeFromHistoryButton: some View {
Button { Button {
guard let watch = watch else { guard let watch else {
return return
} }

View File

@ -11,7 +11,7 @@ import UIKit
extension UIView { extension UIView {
/// Returs frame in screen coordinates. /// Returs frame in screen coordinates.
var globalFrame: CGRect { var globalFrame: CGRect {
if let window = window { if let window {
return convert(bounds, to: window.screen.coordinateSpace) return convert(bounds, to: window.screen.coordinateSpace)
} else { } else {
return .zero return .zero

View File

@ -31,7 +31,7 @@ final class ScrollViewMatcherViewController: UIViewController {
private var scrollView: UIScrollView? { private var scrollView: UIScrollView? {
didSet { didSet {
if oldValue != scrollView, if oldValue != scrollView,
let scrollView = scrollView let scrollView
{ {
onMatch(scrollView) onMatch(scrollView)
} }
@ -70,7 +70,7 @@ final class ScrollViewMatcherViewController: UIViewController {
} }
func matchUsingGeometry() { func matchUsingGeometry() {
if let parent = parent { if let parent {
if let scrollViewsInHierarchy: [UIScrollView] = parent.view.viewsInHierarchy() { if let scrollViewsInHierarchy: [UIScrollView] = parent.view.viewsInHierarchy() {
// Return first match if only a single scroll view is found in the hierarchy. // Return first match if only a single scroll view is found in the hierarchy.
if scrollViewsInHierarchy.count == 1, if scrollViewsInHierarchy.count == 1,

View File

@ -21,7 +21,7 @@ struct Orientation {
static func lockOrientation(_ orientation: UIInterfaceOrientationMask, andRotateTo rotateOrientation: UIInterfaceOrientation? = nil) { static func lockOrientation(_ orientation: UIInterfaceOrientationMask, andRotateTo rotateOrientation: UIInterfaceOrientation? = nil) {
lockOrientation(orientation) lockOrientation(orientation)
guard let rotateOrientation = rotateOrientation else { guard let rotateOrientation else {
return return
} }

View File

@ -59,7 +59,7 @@ public class OrientationTracker {
public func startDeviceOrientationTracking() { public func startDeviceOrientationTracking() {
motionManager.startAccelerometerUpdates(to: queue) { accelerometerData, error in motionManager.startAccelerometerUpdates(to: queue) { accelerometerData, error in
guard error == nil else { return } guard error == nil else { return }
guard let accelerometerData = accelerometerData else { return } guard let accelerometerData else { return }
let newDeviceOrientation = self.deviceOrientation(forAccelerometerData: accelerometerData) let newDeviceOrientation = self.deviceOrientation(forAccelerometerData: accelerometerData)
guard newDeviceOrientation != self.currentDeviceOrientation else { return } guard newDeviceOrientation != self.currentDeviceOrientation else { return }