fallback reasons

This commit is contained in:
eevee
2024-06-22 00:36:51 +03:00
parent 0f380f07e2
commit afbc8d597e
10 changed files with 164 additions and 37 deletions

View File

@@ -28,7 +28,64 @@ class EncoreButtonHook: ClassHook<UIButton> {
}
}
//
private var lastLyricsError: LyricsError? = nil
private var hasShownRestrictedPopUp = false
private var hasShownUnauthorizedPopUp = false
//
class LyricsOnlyViewControllerHook: ClassHook<UIViewController> {
static let targetName = "Lyrics_NPVCommunicatorImpl.LyricsOnlyViewController"
func viewDidLoad() {
orig.viewDidLoad()
if !UserDefaults.fallbackReasons {
return
}
guard
let lyricsHeaderViewController = target.parent?.children.first,
let lyricsLabel = lyricsHeaderViewController.view.subviews.first
else {
return
}
let encoreLabel = Dynamic.convert(lyricsLabel, to: SPTEncoreLabel.self)
let attributedString = Dynamic.convert(
encoreLabel.text().firstObject as AnyObject,
to: SPTEncoreAttributedString.self
)
var text = [attributedString]
if let description = lastLyricsError?.description {
let attributes = Dynamic.SPTEncoreAttributes
.alloc(interface: SPTEncoreAttributes.self)
.`init`({ attributes in
attributes.setForegroundColor(.white.withAlphaComponent(0.5))
})
text.append(
Dynamic.SPTEncoreAttributedString.alloc(interface: SPTEncoreAttributedString.self)
.initWithString(
"\nFallback: \(description)",
typeStyle: attributedString.typeStyle(),
attributes: attributes
)
)
}
encoreLabel.setText(text as NSArray)
}
}
func getCurrentTrackLyricsData(originalLyrics: Lyrics? = nil) throws -> Data {
@@ -47,20 +104,28 @@ func getCurrentTrackLyricsData(originalLyrics: Lyrics? = nil) throws -> Data {
spotifyTrackId: track.URI().spt_trackIdentifier(),
source: source
)
lastLyricsError = nil
}
catch let error as LyricsError {
lastLyricsError = error
switch error {
case .InvalidMusixmatchToken:
PopUpHelper.showPopUp(
delayed: false,
message: "The tweak is unable to load lyrics from Musixmatch due to Unauthorized error. Please check or update your Musixmatch token. If you use an iPad, you should get the token from the Musixmatch app for iPad.",
buttonText: "OK"
)
break
if !hasShownUnauthorizedPopUp {
PopUpHelper.showPopUp(
delayed: false,
message: "The tweak is unable to load lyrics from Musixmatch due to Unauthorized error. Please check or update your Musixmatch token. If you use an iPad, you should get the token from the Musixmatch app for iPad.",
buttonText: "OK"
)
hasShownUnauthorizedPopUp.toggle()
}
case .MusixmatchRestricted:
@@ -75,8 +140,6 @@ func getCurrentTrackLyricsData(originalLyrics: Lyrics? = nil) throws -> Data {
hasShownRestrictedPopUp.toggle()
}
break
default:
break
}

View File

@@ -68,42 +68,57 @@ struct MusixmatchLyricsDataSource {
else {
throw LyricsError.DecodingError
}
if let header = message["header"] as? [String: Any],
header["status_code"] as? Int == 401 {
if let header = message["header"] as? [String: Any],
header["status_code"] as? Int == 401 {
throw LyricsError.InvalidMusixmatchToken
}
if let trackSubtitlesGet = macroCalls["track.subtitles.get"] as? [String: Any],
let subtitlesMessage = trackSubtitlesGet["message"] as? [String: Any],
let subtitlesBody = subtitlesMessage["body"] as? [String: Any],
let subtitlesList = subtitlesBody["subtitle_list"] as? [Any],
let firstSubtitle = subtitlesList.first as? [String: Any],
let subtitle = firstSubtitle["subtitle"] as? [String: Any] {
if let restricted = subtitle["restricted"] as? Bool, restricted {
throw LyricsError.MusixmatchRestricted
let subtitlesMessage = trackSubtitlesGet["message"] as? [String: Any],
let subtitlesHeader = subtitlesMessage["header"] as? [String: Any],
let subtitlesStatusCode = subtitlesHeader["status_code"] as? Int {
if subtitlesStatusCode == 404 {
throw LyricsError.NoSuchSong
}
if let subtitleBody = subtitle["subtitle_body"] as? String {
return PlainLyrics(content: subtitleBody, timeSynced: true)
if let subtitlesBody = subtitlesMessage["body"] as? [String: Any],
let subtitleList = subtitlesBody["subtitle_list"] as? [[String: Any]],
let firstSubtitle = subtitleList.first,
let subtitle = firstSubtitle["subtitle"] as? [String: Any] {
if let restricted = subtitle["restricted"] as? Bool, restricted {
throw LyricsError.MusixmatchRestricted
}
if let subtitleBody = subtitle["subtitle_body"] as? String {
return PlainLyrics(content: subtitleBody, timeSynced: true)
}
}
}
guard
let trackLyricsGet = macroCalls["track.lyrics.get"] as? [String: Any],
let lyricsMessage = trackLyricsGet["message"] as? [String: Any],
let lyricsBody = lyricsMessage["body"] as? [String: Any],
let lyrics = lyricsBody["lyrics"] as? [String: Any],
let plainLyrics = lyrics["lyrics_body"] as? String
else {
throw LyricsError.DecodingError
}
if let restricted = lyrics["restricted"] as? Bool, restricted {
throw LyricsError.MusixmatchRestricted
if let trackLyricsGet = macroCalls["track.lyrics.get"] as? [String: Any],
let lyricsMessage = trackLyricsGet["message"] as? [String: Any],
let lyricsHeader = lyricsMessage["header"] as? [String: Any],
let lyricsStatusCode = lyricsHeader["status_code"] as? Int {
if lyricsStatusCode == 404 {
throw LyricsError.NoSuchSong
}
if let lyricsBody = lyricsMessage["body"] as? [String: Any],
let lyrics = lyricsBody["lyrics"] as? [String: Any],
let plainLyrics = lyrics["lyrics_body"] as? String {
if let restricted = lyrics["restricted"] as? Bool, restricted {
throw LyricsError.MusixmatchRestricted
}
return PlainLyrics(content: plainLyrics, timeSynced: false)
}
}
return PlainLyrics(content: plainLyrics, timeSynced: false)
throw LyricsError.DecodingError
}
}

View File

@@ -1,9 +1,19 @@
import Foundation
enum LyricsError: Error {
enum LyricsError: Error, CustomStringConvertible {
case NoCurrentTrack
case MusixmatchRestricted
case InvalidMusixmatchToken
case DecodingError
case NoSuchSong
var description: String {
switch self {
case .NoSuchSong: "No Song Found"
case .MusixmatchRestricted: "Restricted"
case .InvalidMusixmatchToken: "Unauthorized"
case .DecodingError: "Decoding Error"
case .NoCurrentTrack: "No Track Instance"
}
}
}

View File

@@ -7,6 +7,7 @@ extension UserDefaults {
private static let lyricsSourceKey = "lyricsSource"
private static let musixmatchTokenKey = "musixmatchToken"
private static let geniusFallbackKey = "geniusFallback"
private static let fallbackReasonsKey = "fallbackReasons"
private static let darkPopUpsKey = "darkPopUps"
private static let patchTypeKey = "patchType"
private static let overwriteConfigurationKey = "overwriteConfiguration"
@@ -42,6 +43,15 @@ extension UserDefaults {
defaults.set(fallback, forKey: geniusFallbackKey)
}
}
static var fallbackReasons: Bool {
get {
defaults.object(forKey: fallbackReasonsKey) as? Bool ?? true
}
set (reasons) {
defaults.set(reasons, forKey: fallbackReasonsKey)
}
}
static var darkPopUps: Bool {
get {

View File

@@ -0,0 +1,8 @@
import Foundation
@objc protocol SPTEncoreAttributedString {
func initWithString(_ string: String, typeStyle: Any, attributes: Any) -> SPTEncoreAttributedString
func text() -> String
func typeStyle() -> Any
func attributes() -> SPTEncoreAttributes
}

View File

@@ -0,0 +1,7 @@
import UIKit
@objc protocol SPTEncoreAttributes {
func `init`(_: (SPTEncoreAttributes) -> Void) -> SPTEncoreAttributes
func foregroundColor() -> UIColor
func setForegroundColor(_ color: UIColor)
}

View File

@@ -0,0 +1,6 @@
import Foundation
@objc protocol SPTEncoreLabel {
func text() -> NSArray
func setText(_ text: NSArray)
}

View File

@@ -9,4 +9,4 @@ import Foundation
@objc enum ClickState: Int {
case primary
case secondary
}
}

View File

@@ -4,4 +4,4 @@ import Foundation
static func shared() -> SPTEncorePopUpPresenter
func presentPopUp(_ popUp: SPTEncorePopUpDialog)
func dismissPopupWithAnimate(_ animate: Bool, clearQueue: Bool, completion: Any?)
}
}

View File

@@ -116,6 +116,14 @@ If the tweak is unable to find a song or process the lyrics, you'll see a "Could
set: { UserDefaults.geniusFallback = $0 }
)
)
Toggle(
"Show Fallback Reasons",
isOn: Binding<Bool>(
get: { UserDefaults.fallbackReasons },
set: { UserDefaults.fallbackReasons = $0 }
)
)
}
}
}