Skip to content

Commit f39d1ae

Browse files
committed
fixes and improvements
1 parent f013a59 commit f39d1ae

21 files changed

Lines changed: 267 additions & 137 deletions

Sources/EeveeSpotify/DataLoaderServiceHooks.x.swift

Lines changed: 35 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ class SPTDataLoaderServiceHook: ClassHook<NSObject>, SpotifySessionDelegate {
66

77
// orion:new
88
func shouldModify(_ url: URL) -> Bool {
9-
let shouldPatchPremium = PremiumPatchingGroup.isActive
10-
let shouldReplaceLyrics = LyricsGroup.isActive
9+
let shouldPatchPremium = BasePremiumPatchingGroup.isActive
10+
let shouldReplaceLyrics = BaseLyricsGroup.isActive
1111

1212
return (shouldReplaceLyrics && url.isLyrics)
1313
|| (shouldPatchPremium && (url.isCustomize || url.isPremiumPlanRow || url.isPremiumBadge || url.isPlanOverview))
@@ -33,61 +33,53 @@ class SPTDataLoaderServiceHook: ClassHook<NSObject>, SpotifySessionDelegate {
3333
return
3434
}
3535

36+
guard let buffer = URLSessionHelper.shared.obtainData(for: url) else {
37+
return
38+
}
39+
3640
do {
37-
if let buffer = URLSessionHelper.shared.obtainData(for: url) {
38-
if url.isLyrics {
39-
respondWithCustomData(
40-
try getLyricsDataForCurrentTrack(
41-
originalLyrics: try? Lyrics(serializedBytes: buffer)
42-
),
43-
task: task,
44-
session: session
45-
)
46-
47-
return
48-
}
49-
50-
if url.isPremiumPlanRow {
51-
respondWithCustomData(
52-
try getPremiumPlanRowData(
53-
originalPremiumPlanRow: try PremiumPlanRow(serializedBytes: buffer)
54-
),
55-
task: task,
56-
session: session
57-
)
58-
59-
return
60-
}
61-
62-
if url.isPremiumBadge {
63-
respondWithCustomData(try getPremiumPlanBadge(), task: task, session: session)
64-
return
65-
}
66-
41+
if url.isLyrics {
42+
respondWithCustomData(
43+
try getLyricsDataForCurrentTrack(
44+
originalLyrics: try? Lyrics(serializedBytes: buffer)
45+
),
46+
task: task,
47+
session: session
48+
)
49+
return
50+
}
51+
52+
if url.isPremiumPlanRow {
53+
respondWithCustomData(
54+
try getPremiumPlanRowData(
55+
originalPremiumPlanRow: try PremiumPlanRow(serializedBytes: buffer)
56+
),
57+
task: task,
58+
session: session
59+
)
60+
return
61+
}
62+
63+
if url.isPremiumBadge {
64+
respondWithCustomData(try getPremiumPlanBadge(), task: task, session: session)
65+
return
66+
}
67+
68+
if url.isCustomize {
6769
var customizeMessage = try CustomizeMessage(serializedBytes: buffer)
6870
modifyRemoteConfiguration(&customizeMessage.response)
69-
7071
respondWithCustomData(try customizeMessage.serializedData(), task: task, session: session)
7172
return
7273
}
7374

7475
if url.isPlanOverview {
75-
do {
76-
orig.URLSession(session, dataTask: task, didReceiveData: try getPlanOverviewData())
77-
orig.URLSession(session, task: task, didCompleteWithError: nil)
78-
}
79-
catch {
80-
orig.URLSession(session, task: task, didCompleteWithError: error)
81-
}
82-
76+
respondWithCustomData(try getPlanOverviewData(), task: task, session: session)
8377
return
8478
}
8579
}
8680
catch {
8781
orig.URLSession(session, task: task, didCompleteWithError: error)
8882
}
89-
90-
orig.URLSession(session, task: task, didCompleteWithError: error)
9183
}
9284

9385
func URLSession(

Sources/EeveeSpotify/Lyrics/CustomLyrics+AllTracksLyrics.x.swift

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,59 @@
11
import Orion
22
import UIKit
33

4+
private var shouldOverrideLocalTrackURI = false
5+
46
class SPTPlayerTrackHook: ClassHook<NSObject> {
5-
typealias Group = LyricsGroup
7+
typealias Group = BaseLyricsGroup
68
static let targetName = EeveeSpotify.hookTarget == .latest
79
? "SPTPlayerTrackImplementation"
810
: "SPTPlayerTrack"
911

1012
func metadata() -> [String: String] {
1113
var meta = orig.metadata()
12-
1314
meta["has_lyrics"] = "true"
1415
return meta
1516
}
17+
18+
func URI() -> NSURL? {
19+
let uri = orig.URI()
20+
21+
guard shouldOverrideLocalTrackURI,
22+
let absoluteString = uri?.absoluteString,
23+
absoluteString.hasPrefix("spotify:local:") else {
24+
return uri
25+
}
26+
27+
return NSURL(string: "spotify:track:")!
28+
}
1629
}
1730

1831
class LyricsScrollProviderHook: ClassHook<NSObject> {
19-
typealias Group = LyricsGroup
32+
typealias Group = BaseLyricsGroup
2033
static var targetName = HookTargetNameHelper.lyricsScrollProvider
2134

2235
func isEnabledForTrack(_ track: SPTPlayerTrack) -> Bool {
2336
return true
2437
}
2538
}
2639

40+
class NPVScrollViewControllerHook: ClassHook<NSObject> {
41+
typealias Group = ModernLyricsGroup
42+
static var targetName = "NowPlaying_ScrollImpl.NPVScrollViewController"
43+
44+
func viewWillAppear(_ animated: Bool) {
45+
shouldOverrideLocalTrackURI = true
46+
orig.viewWillAppear(animated)
47+
}
48+
49+
func viewWillDisappear(_ animated: Bool) {
50+
shouldOverrideLocalTrackURI = false
51+
orig.viewWillDisappear(animated)
52+
}
53+
}
54+
2755
class NowPlayingScrollViewControllerHook: ClassHook<NSObject> {
28-
typealias Group = LyricsGroup
56+
typealias Group = LegacyLyricsGroup
2957
static var targetName = "NowPlaying_ScrollImpl.NowPlayingScrollViewController"
3058

3159
func nowPlayingScrollViewModelWithDidLoadComponentsFor(

Sources/EeveeSpotify/Lyrics/CustomLyrics+DisableReportButton.x.swift

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@ import Orion
22
import UIKit
33

44
class LyricsFullscreenViewControllerHook: ClassHook<UIViewController> {
5-
typealias Group = LyricsGroup
5+
typealias Group = BaseLyricsGroup
66

77
static var targetName: String {
88
switch EeveeSpotify.hookTarget {
99
case .lastAvailableiOS14: return "Lyrics_CoreImpl.FullscreenViewController"
10-
default: return "Lyrics_FullscreenPageImpl.FullscreenViewController"
10+
case .lastAvailableiOS15: return "Lyrics_FullscreenPageImpl.FullscreenViewController"
11+
default: return "Lyrics_FullscreenElementPageImpl.FullscreenElementViewController"
1112
}
1213
}
1314

@@ -21,6 +22,26 @@ class LyricsFullscreenViewControllerHook: ClassHook<UIViewController> {
2122
return
2223
}
2324

25+
if EeveeSpotify.hookTarget == .latest {
26+
guard let fullscreenView = WindowHelper.shared.findFirstSubview(
27+
"Lyrics_FullscreenElementPageImpl.FullscreenView",
28+
in: target.view
29+
) else {
30+
return
31+
}
32+
33+
let controlsView = Ivars<UIView>(fullscreenView).controlsView
34+
let contextMenuButtonContainer = Ivars<UIView>(controlsView).contextMenuButtonContainer
35+
36+
if let contextButton = contextMenuButtonContainer.subviews(
37+
matching: "Encore6Button"
38+
).first as? UIControl {
39+
contextButton.isEnabled = false
40+
}
41+
42+
return
43+
}
44+
2445
let headerView = Ivars<UIView>(target.view).headerView
2546

2647
if let reportButton = headerView.subviews(matching: "EncoreButton")[1] as? UIButton {

Sources/EeveeSpotify/Lyrics/CustomLyrics+HideOnError.x.swift

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import Orion
22
import UIKit
33

44
class ErrorViewControllerHook: ClassHook<UIViewController> {
5-
typealias Group = LyricsGroup
5+
typealias Group = BaseLyricsGroup
66

77
static var targetName: String {
88
switch EeveeSpotify.hookTarget {
@@ -14,17 +14,29 @@ class ErrorViewControllerHook: ClassHook<UIViewController> {
1414
func loadView() {
1515
orig.loadView()
1616

17-
guard UserDefaults.lyricsOptions.hideOnError, let controller = nowPlayingScrollViewController else {
17+
guard UserDefaults.lyricsOptions.hideOnError else {
1818
return
1919
}
2020

21-
var providers = controller.activeProviders
22-
23-
providers.removeAll(
24-
where: { NSStringFromClass(type(of: $0)) == HookTargetNameHelper.lyricsScrollProvider }
25-
)
26-
27-
controller.activeProviders = providers
28-
controller.collectionView().reloadData()
21+
if let controller = nowPlayingScrollViewController {
22+
controller.dataSource.activeProviders.removeAll {
23+
NSStringFromClass(type(of: $0)) == HookTargetNameHelper.lyricsScrollProvider
24+
}
25+
26+
controller.collectionView().reloadData()
27+
}
28+
else if let controller = npvScrollViewController, let dataSource = scrollDataSource {
29+
let lyricsProviderIndex = dataSource.activeProviders.firstIndex {
30+
NSStringFromClass(type(of: $0)) == HookTargetNameHelper.lyricsScrollProvider
31+
}
32+
33+
let collectionView = controller.collectionView()
34+
let dataSource = Ivars<__UIDiffableDataSource>(collectionView.dataSource!)._impl
35+
36+
let itemIdentifiers = dataSource.itemIdentifiers()
37+
let lyricsProviderItemIdentifier = itemIdentifiers[lyricsProviderIndex!]
38+
39+
dataSource.deleteItemsWithIdentifiers([lyricsProviderItemIdentifier])
40+
}
2941
}
3042
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import UIKit
2+
import Orion
3+
4+
class UITableViewHook: ClassHook<UITableView> {
5+
typealias Group = BaseLyricsGroup
6+
7+
func scrollToRowAtIndexPath(
8+
_ indexPath: NSIndexPath,
9+
atScrollPosition scrollPosition: UITableView.ScrollPosition,
10+
animated: Bool
11+
) {
12+
if target.numberOfRows(inSection: indexPath.section) == 0 {
13+
return
14+
}
15+
16+
orig.scrollToRowAtIndexPath(
17+
indexPath,
18+
atScrollPosition: scrollPosition,
19+
animated: animated
20+
)
21+
}
22+
}

Sources/EeveeSpotify/Lyrics/CustomLyrics+ShowAttributes.x.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import Orion
22
import UIKit
33

44
class LyricsOnlyViewControllerHook: ClassHook<UIViewController> {
5-
typealias Group = LyricsGroup
5+
typealias Group = BaseLyricsGroup
66

77
static var targetName: String {
88
switch EeveeSpotify.hookTarget {

Sources/EeveeSpotify/Lyrics/CustomLyrics.x.swift

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@ import SwiftUI
33

44
//
55

6-
struct LyricsGroup: HookGroup { }
6+
struct BaseLyricsGroup: HookGroup { }
7+
8+
struct LegacyLyricsGroup: HookGroup { }
9+
struct ModernLyricsGroup: HookGroup { }
710

811
var lyricsState = LyricsLoadingState()
912

@@ -16,9 +19,12 @@ private let petitLyricsRepository = PetitLyricsRepository()
1619
//
1720

1821
private func loadCustomLyricsForCurrentTrack() throws -> Lyrics {
19-
guard let track = nowPlayingScrollViewController?.loadedTrack else {
20-
throw LyricsError.noCurrentTrack
21-
}
22+
guard
23+
let track = statefulPlayer?.currentTrack() ??
24+
nowPlayingScrollViewController?.loadedTrack
25+
else {
26+
throw LyricsError.noCurrentTrack
27+
}
2228

2329
let searchQuery = LyricsSearchQuery(
2430
title: track.trackTitle(),
@@ -115,9 +121,12 @@ private func loadCustomLyricsForCurrentTrack() throws -> Lyrics {
115121
}
116122

117123
func getLyricsDataForCurrentTrack(originalLyrics: Lyrics? = nil) throws -> Data {
118-
guard let track = nowPlayingScrollViewController?.loadedTrack else {
119-
throw LyricsError.noCurrentTrack
120-
}
124+
guard
125+
let track = statefulPlayer?.currentTrack() ??
126+
nowPlayingScrollViewController?.loadedTrack
127+
else {
128+
throw LyricsError.noCurrentTrack
129+
}
121130

122131
var lyrics = try loadCustomLyricsForCurrentTrack()
123132

@@ -143,7 +152,7 @@ func getLyricsDataForCurrentTrack(originalLyrics: Lyrics? = nil) throws -> Data
143152
color = Color(hex: extractedColor)
144153
.normalized(lyricsColorsSettings.normalizationFactor)
145154
}
146-
else if let uiColor = nowPlayingScrollViewController?.backgroundViewModel.color() {
155+
else if let uiColor = backgroundViewModel?.color() {
147156
color = Color(uiColor)
148157
.normalized(lyricsColorsSettings.normalizationFactor)
149158
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import Orion
2+
3+
extension NowPlayingScrollDataSourceImplementation {
4+
var activeProviders: Array<NSObject> {
5+
get {
6+
Ivars<Array<NSObject>>(self).activeProviders
7+
}
8+
set {
9+
Ivars<Array<NSObject>>(self).activeProviders = newValue
10+
}
11+
}
12+
}

Sources/EeveeSpotify/Lyrics/Models/Extensions/NowPlayingScrollViewController+Extension.swift

Lines changed: 2 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -22,37 +22,9 @@ extension NowPlayingScrollViewController {
2222
}
2323
}
2424

25-
//
26-
27-
private var dataSource: NSObject {
28-
get {
29-
Ivars<NSObject>(nowPlayingScrollViewModel).dataSource
30-
}
31-
}
32-
33-
var activeProviders: Array<NSObject> {
34-
get {
35-
Ivars<Array<NSObject>>(dataSource).activeProviders
36-
}
37-
set {
38-
Ivars<Array<NSObject>>(dataSource).activeProviders = newValue
39-
}
40-
}
41-
42-
//
43-
44-
private var backgroundViewController: NSObject {
45-
get {
46-
Ivars<NSObject>(self).backgroundViewController
47-
}
48-
}
49-
50-
var backgroundViewModel: SPTNowPlayingBackgroundViewModel {
25+
var dataSource: NowPlayingScrollDataSourceImplementation {
5126
get {
52-
let ivars = Ivars<SPTNowPlayingBackgroundViewModel>(self.backgroundViewController)
53-
return EeveeSpotify.hookTarget == .latest
54-
? ivars.artworkColorObservable
55-
: ivars.viewModel
27+
Ivars<NowPlayingScrollDataSourceImplementation>(nowPlayingScrollViewModel).dataSource
5628
}
5729
}
5830
}

0 commit comments

Comments
 (0)