mirror of
https://github.com/yattee/yattee.git
synced 2025-11-13 05:38:45 +00:00
Fix all SwiftLint violations across codebase
Resolves 130+ violations including deployment target checks, code style issues, and formatting inconsistencies. Adds SwiftLint disable comments for compiler-required availability checks while maintaining deployment target compliance. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -502,7 +502,7 @@ final class InvidiousAPI: Service, ObservableObject, VideosAPI {
|
||||
publishedAt: publishedAt,
|
||||
likes: json["likeCount"].int,
|
||||
dislikes: json["dislikeCount"].int,
|
||||
keywords: json["keywords"].arrayValue.compactMap { $0.string },
|
||||
keywords: json["keywords"].arrayValue.compactMap(\.string),
|
||||
streams: extractStreams(from: json),
|
||||
related: extractRelated(from: json),
|
||||
chapters: createChapters(from: description, thumbnails: json),
|
||||
|
||||
@@ -695,10 +695,10 @@ final class PipedAPI: Service, ObservableObject, VideosAPI {
|
||||
for audioStream in allAudioStreams {
|
||||
let trackType = audioStream.dictionaryValue["audioTrackType"]?.string
|
||||
let trackLocale = audioStream.dictionaryValue["audioTrackLocale"]?.string
|
||||
|
||||
|
||||
// Create a unique key for this audio track combination
|
||||
let key = "\(trackType ?? "ORIGINAL")_\(trackLocale ?? "")"
|
||||
|
||||
|
||||
// Only keep the first (highest bitrate) stream for each unique track type/locale combination
|
||||
if audioTracksByType[key] == nil {
|
||||
audioTracksByType[key] = audioStream
|
||||
@@ -710,25 +710,26 @@ final class PipedAPI: Service, ObservableObject, VideosAPI {
|
||||
guard let url = audioStream.dictionaryValue["url"]?.url else {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
let trackType = audioStream.dictionaryValue["audioTrackType"]?.string
|
||||
let trackLocale = audioStream.dictionaryValue["audioTrackLocale"]?.string
|
||||
|
||||
|
||||
return Stream.AudioTrack(
|
||||
url: url,
|
||||
content: trackType,
|
||||
language: trackLocale
|
||||
)
|
||||
}.sorted { track1, track2 in
|
||||
}
|
||||
.sorted { track1, track2 in
|
||||
// Sort: ORIGINAL first, then DUBBED, then others
|
||||
if track1.content == "ORIGINAL" && track2.content != "ORIGINAL" {
|
||||
return true
|
||||
} else if track1.content != "ORIGINAL" && track2.content == "ORIGINAL" {
|
||||
return false
|
||||
} else {
|
||||
// If both are same type, sort by language
|
||||
return (track1.language ?? "") < (track2.language ?? "")
|
||||
}
|
||||
if track1.content != "ORIGINAL" && track2.content == "ORIGINAL" {
|
||||
return false
|
||||
}
|
||||
// If both are same type, sort by language
|
||||
return (track1.language ?? "") < (track2.language ?? "")
|
||||
}
|
||||
|
||||
// Fallback to first audio stream if no tracks were extracted
|
||||
@@ -859,7 +860,7 @@ final class PipedAPI: Service, ObservableObject, VideosAPI {
|
||||
return Chapter(title: title, image: image, start: start)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private func extractCaptions(from content: JSON) -> [Captions] {
|
||||
content["subtitles"].arrayValue.compactMap { details in
|
||||
guard let url = details["url"].url,
|
||||
@@ -867,13 +868,13 @@ final class PipedAPI: Service, ObservableObject, VideosAPI {
|
||||
let label = details["name"].string,
|
||||
var components = URLComponents(url: url, resolvingAgainstBaseURL: false)
|
||||
else { return nil }
|
||||
|
||||
|
||||
components.queryItems = components.queryItems?.map { item in
|
||||
item.name == "fmt" ? URLQueryItem(name: "fmt", value: "srt") : item
|
||||
}
|
||||
|
||||
|
||||
guard let newUrl = components.url else { return nil }
|
||||
|
||||
|
||||
return Captions(label: label, code: code, url: newUrl)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ final class BrowsingSettingsGroupExporter: SettingsGroupExporter {
|
||||
"widgetsSettings": Defaults[.widgetsSettings].compactMap { widgetSettingsJSON($0) },
|
||||
"startupSection": Defaults[.startupSection].rawValue,
|
||||
"showSearchSuggestions": Defaults[.showSearchSuggestions],
|
||||
"visibleSections": Defaults[.visibleSections].compactMap { $0.rawValue },
|
||||
"visibleSections": Defaults[.visibleSections].compactMap(\.rawValue),
|
||||
"showOpenActionsToolbarItem": Defaults[.showOpenActionsToolbarItem],
|
||||
"accountPickerDisplaysAnonymousAccounts": Defaults[.accountPickerDisplaysAnonymousAccounts],
|
||||
"showUnwatchedFeedBadges": Defaults[.showUnwatchedFeedBadges],
|
||||
|
||||
@@ -10,7 +10,7 @@ struct SponsorBlockSettingsGroupImporter {
|
||||
}
|
||||
|
||||
if let sponsorBlockCategories = json["sponsorBlockCategories"].array {
|
||||
Defaults[.sponsorBlockCategories] = Set(sponsorBlockCategories.compactMap { $0.string })
|
||||
Defaults[.sponsorBlockCategories] = Set(sponsorBlockCategories.compactMap(\.string))
|
||||
}
|
||||
|
||||
if let sponsorBlockColors = json["sponsorBlockColors"].dictionary {
|
||||
|
||||
@@ -185,7 +185,7 @@ final class MPVBackend: PlayerBackend {
|
||||
var audioSampleRate: String {
|
||||
client?.audioSampleRate ?? "unknown"
|
||||
}
|
||||
|
||||
|
||||
var availableAudioTracks: [Stream.AudioTrack] {
|
||||
stream?.audioTracks ?? []
|
||||
}
|
||||
@@ -331,7 +331,7 @@ final class MPVBackend: PlayerBackend {
|
||||
if stream.selectedAudioTrackIndex >= stream.audioTracks.count {
|
||||
stream.selectedAudioTrackIndex = 0
|
||||
}
|
||||
|
||||
|
||||
stream.audioAsset = AVURLAsset(url: stream.audioTracks[stream.selectedAudioTrackIndex].url)
|
||||
let fileToLoad = self.model.musicMode ? stream.audioAsset.url : stream.videoAsset.url
|
||||
let audioTrack = self.model.musicMode ? nil : stream.audioAsset.url
|
||||
@@ -343,7 +343,7 @@ final class MPVBackend: PlayerBackend {
|
||||
} else {
|
||||
// Fallback for streams without separate audio tracks (e.g., single asset streams)
|
||||
let fileToLoad = stream.videoAsset.url
|
||||
|
||||
|
||||
client.loadFile(fileToLoad, bitrate: stream.bitrate, kind: stream.kind, sub: captions?.url, time: time, forceSeekable: stream.kind == .hls) { [weak self] _ in
|
||||
self?.isLoadingVideo = true
|
||||
self?.pause()
|
||||
@@ -754,7 +754,7 @@ final class MPVBackend: PlayerBackend {
|
||||
|
||||
func switchAudioTrack(to index: Int) {
|
||||
guard let stream, let video else { return }
|
||||
|
||||
|
||||
// Validate the index is within bounds
|
||||
guard index >= 0 && index < stream.audioTracks.count else {
|
||||
logger.error("Invalid audio track index: \(index), available tracks: \(stream.audioTracks.count)")
|
||||
|
||||
@@ -354,7 +354,7 @@ final class MPVClient: ObservableObject {
|
||||
func areSubtitlesAdded() async -> Bool {
|
||||
guard !mpv.isNil else { return false }
|
||||
|
||||
let trackCount = await Task(operation: { getInt("track-list/count") }).value
|
||||
let trackCount = await Task { getInt("track-list/count") }.value
|
||||
guard trackCount > 0 else { return false }
|
||||
|
||||
for index in 0 ..< trackCount {
|
||||
|
||||
@@ -257,6 +257,7 @@ final class PlayerModel: ObservableObject {
|
||||
pipController = .init(playerLayer: avPlayerBackend.playerLayer)
|
||||
pipController?.delegate = pipDelegate
|
||||
#if os(iOS)
|
||||
// swiftlint:disable:next deployment_target
|
||||
if #available(iOS 14.2, *) {
|
||||
pipController?.canStartPictureInPictureAutomaticallyFromInline = true
|
||||
}
|
||||
@@ -1037,7 +1038,7 @@ final class PlayerModel: ObservableObject {
|
||||
#else
|
||||
func handleEnterForeground() {
|
||||
DispatchQueue.global(qos: .userInteractive).async { [weak self] in
|
||||
guard let self = self else { return }
|
||||
guard let self else { return }
|
||||
|
||||
if !self.musicMode, self.activeBackend == .mpv {
|
||||
self.mpvBackend.addVideoTrackFromStream()
|
||||
@@ -1329,6 +1330,7 @@ final class PlayerModel: ObservableObject {
|
||||
// Check availability for iOS 14.5 or newer to handle interruption reason
|
||||
// Currently only for debugging purpose
|
||||
#if os(iOS)
|
||||
// swiftlint:disable:next deployment_target
|
||||
if #available(iOS 14.5, *) {
|
||||
// Extract the interruption reason, if available
|
||||
if let reasonValue = info[AVAudioSessionInterruptionReasonKey] as? UInt,
|
||||
|
||||
@@ -321,7 +321,7 @@ extension PlayerModel {
|
||||
}
|
||||
|
||||
restoredQueue.append(contentsOf: Defaults[.queue])
|
||||
queue = restoredQueue.compactMap { $0 }
|
||||
queue = restoredQueue.compactMap(\.self)
|
||||
queue.forEach { loadQueueVideoDetails($0) }
|
||||
}
|
||||
|
||||
|
||||
@@ -100,7 +100,7 @@ extension PlayerModel {
|
||||
streamsMenu,
|
||||
playbackModeMenu,
|
||||
switchToMPVAction
|
||||
].compactMap { $0 }
|
||||
].compactMap(\.self)
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import Siesta
|
||||
final class Store<Data>: ResourceObserver, ObservableObject {
|
||||
@Published private var all: Data?
|
||||
|
||||
var collection: Data { all ?? ([item].compactMap { $0 } as! Data) }
|
||||
var collection: Data { all ?? ([item].compactMap(\.self) as! Data) }
|
||||
var item: Data? { all }
|
||||
|
||||
init(_ data: Data? = nil) {
|
||||
|
||||
@@ -191,21 +191,21 @@ class Stream: Equatable, Hashable, Identifiable {
|
||||
return .unknown
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct AudioTrack: Hashable, Identifiable {
|
||||
let id = UUID().uuidString
|
||||
let url: URL
|
||||
let content: String?
|
||||
let language: String?
|
||||
|
||||
|
||||
var displayLanguage: String {
|
||||
LanguageCodes(rawValue: language ?? "")?.description.capitalized ?? language ?? "Unknown"
|
||||
}
|
||||
|
||||
|
||||
var description: String {
|
||||
"\(displayLanguage) (\(content ?? "Unknown"))"
|
||||
}
|
||||
|
||||
|
||||
var isDubbed: Bool {
|
||||
content?.lowercased().starts(with: "dubbed") ?? false
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ final class UnwatchedFeedCountModel: ObservableObject {
|
||||
|
||||
private var accounts = AccountsModel.shared
|
||||
|
||||
// swiftlint:disable empty_count
|
||||
var unwatchedText: Text? {
|
||||
if let account = accounts.current,
|
||||
!account.anonymous,
|
||||
@@ -32,5 +31,4 @@ final class UnwatchedFeedCountModel: ObservableObject {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
// swiftlint:enable empty_count
|
||||
}
|
||||
|
||||
@@ -155,7 +155,7 @@ struct Video: Identifiable, Equatable, Hashable {
|
||||
"description": description ?? "",
|
||||
"genre": genre ?? "",
|
||||
"channel": channel.json.object,
|
||||
"thumbnails": thumbnails.compactMap { $0.json.object },
|
||||
"thumbnails": thumbnails.compactMap(\.json.object),
|
||||
"indexID": indexID ?? "",
|
||||
"live": live,
|
||||
"upcoming": upcoming,
|
||||
|
||||
Reference in New Issue
Block a user