From e76b62edbc2491fe956031ad9f2f3d4dcfb2e844 Mon Sep 17 00:00:00 2001 From: eevee Date: Wed, 9 Oct 2024 21:38:29 +0300 Subject: [PATCH] v5.5 --- Sources/EeveeSpotify/DarkPopUps.x.swift | 17 +-- .../EeveeSpotify/Helpers/PopUpHelper.swift | 5 +- .../Helpers/URLSessionHelper.swift | 1 - .../EeveeSpotify/Helpers/WindowHelper.swift | 8 +- .../EeveeSpotify/Lyrics/CustomLyrics.x.swift | 4 +- .../Repositories/GeniusLyricsRepository.swift | 1 - .../MusixmatchLyricsRepository.swift | 3 - .../Models/Extensions/String+Extension.swift | 6 + Sources/EeveeSpotify/OpenSpotify.x.swift | 2 - .../DynamicPremium+ModifyBootstrap.x.swift | 2 +- .../Premium/ServerSidedReminder.x.swift | 14 +- .../Settings/EeveeSettings.x.swift | 5 - .../Settings/Helpers/GitHubHelper.swift | 43 ++++++ .../Settings/Models/EeveeContributor.swift | 4 + .../Models/EeveeContributorSection.swift | 5 + .../Settings/Models/GitHubRelease.swift | 3 + .../Settings/Models/GitHubReleaseInfo.swift | 5 - .../Settings/Models/GitHubUser.swift | 5 + .../Settings/ViewModels/ImageViewModel.swift | 51 +++++++ .../Contributors/EeveeContributorView.swift | 33 +++++ .../EeveeContributorsSheetView.swift | 57 ++++++++ .../Views/EeveeSettingsVersionView.swift | 55 +++++++ .../EeveeSettingsView+VersionSection.swift | 45 ------ .../Settings/Views/EeveeSettingsView.swift | 17 ++- .../EeveeLyricsSettingsView+Extension.swift | 7 +- .../Sections/EeveeLyricsSettingsView.swift | 1 - .../Views/Sections/EeveeUISettingsView.swift | 2 +- .../Views/Shared/ChevronRightView.swift | 9 ++ .../Views/Shared/CommonIssuesTipView.swift | 5 +- .../Settings/Views/Shared/ImageView.swift | 14 ++ .../Views/Shared/NavigationSectionView.swift | 5 +- Sources/EeveeSpotify/Tweak.x.swift | 3 +- contributors.json | 136 ++++++++++++++++++ control | 2 +- .../az.lproj/Localizable.strings | 3 - .../bg.lproj/Localizable.strings | 3 - .../da.lproj/Localizable.strings | 3 - .../de-CH.lproj/Localizable.strings | 3 - .../de.lproj/Localizable.strings | 3 - .../en.lproj/Localizable.strings | 5 +- .../es.lproj/Localizable.strings | 3 - .../fa.lproj/Localizable.strings | 3 - .../fr.lproj/Localizable.strings | 3 - .../it.lproj/Localizable.strings | 3 - .../ko.lproj/Localizable.strings | 5 +- .../np.lproj/Localizable.strings | 3 - .../pl.lproj/Localizable.strings | 3 - .../pt-BR.lproj/Localizable.strings | 3 - .../ru.lproj/Localizable.strings | 5 +- .../tr.lproj/Localizable.strings | 3 - .../uk.lproj/Localizable.strings | 3 - .../vi.lproj/Localizable.strings | 3 - .../zh-CN.lproj/Localizable.strings | 3 - .../zh-TW.lproj/Localizable.strings | 3 - 54 files changed, 470 insertions(+), 171 deletions(-) create mode 100644 Sources/EeveeSpotify/Settings/Helpers/GitHubHelper.swift create mode 100644 Sources/EeveeSpotify/Settings/Models/EeveeContributor.swift create mode 100644 Sources/EeveeSpotify/Settings/Models/EeveeContributorSection.swift create mode 100644 Sources/EeveeSpotify/Settings/Models/GitHubRelease.swift delete mode 100644 Sources/EeveeSpotify/Settings/Models/GitHubReleaseInfo.swift create mode 100644 Sources/EeveeSpotify/Settings/Models/GitHubUser.swift create mode 100644 Sources/EeveeSpotify/Settings/ViewModels/ImageViewModel.swift create mode 100644 Sources/EeveeSpotify/Settings/Views/Contributors/EeveeContributorView.swift create mode 100644 Sources/EeveeSpotify/Settings/Views/Contributors/EeveeContributorsSheetView.swift create mode 100644 Sources/EeveeSpotify/Settings/Views/EeveeSettingsVersionView.swift delete mode 100644 Sources/EeveeSpotify/Settings/Views/EeveeSettingsView+VersionSection.swift create mode 100644 Sources/EeveeSpotify/Settings/Views/Shared/ChevronRightView.swift create mode 100644 Sources/EeveeSpotify/Settings/Views/Shared/ImageView.swift create mode 100644 contributors.json diff --git a/Sources/EeveeSpotify/DarkPopUps.x.swift b/Sources/EeveeSpotify/DarkPopUps.x.swift index d356645..ab7703e 100644 --- a/Sources/EeveeSpotify/DarkPopUps.x.swift +++ b/Sources/EeveeSpotify/DarkPopUps.x.swift @@ -5,21 +5,17 @@ import SwiftUI struct DarkPopUps: HookGroup { } class EncoreLabelHook: ClassHook { - typealias Group = DarkPopUps static let targetName = "SPTEncoreLabel" func intrinsicContentSize() -> CGSize { + if let viewController = WindowHelper.shared.viewController(for: target), + NSStringFromClass(type(of: viewController)) == "SPTEncorePopUpContainer" + { + let label = Dynamic.convert(target.subviews.first!, to: UILabel.self) - if let viewController = WindowHelper.shared.viewController(for: target) { - - if NSStringFromClass(type(of: viewController)) == "SPTEncorePopUpContainer" { - - let label = Dynamic.convert(target.subviews.first!, to: UILabel.self) - - if !label.hasParent(matching: "Primary") { - label.textColor = .white - } + if !label.hasParent(matching: "Primary") { + label.textColor = .white } } @@ -28,7 +24,6 @@ class EncoreLabelHook: ClassHook { } class SPTEncorePopUpContainerHook: ClassHook { - typealias Group = DarkPopUps static let targetName = "SPTEncorePopUpContainer" diff --git a/Sources/EeveeSpotify/Helpers/PopUpHelper.swift b/Sources/EeveeSpotify/Helpers/PopUpHelper.swift index a343b9f..c587858 100644 --- a/Sources/EeveeSpotify/Helpers/PopUpHelper.swift +++ b/Sources/EeveeSpotify/Helpers/PopUpHelper.swift @@ -1,8 +1,7 @@ import UIKit import Orion -class PopUpHelper { - +struct PopUpHelper { private static var isPopUpShowing = false static let sharedPresenter = type( @@ -19,9 +18,7 @@ class PopUpHelper { onPrimaryClick: (() -> Void)? = nil, onSecondaryClick: (() -> Void)? = nil ) { - DispatchQueue.main.asyncAfter(deadline: delayed ? .now() + 3.0 : .now()) { - if isPopUpShowing { return } diff --git a/Sources/EeveeSpotify/Helpers/URLSessionHelper.swift b/Sources/EeveeSpotify/Helpers/URLSessionHelper.swift index 86365f6..dadbb88 100644 --- a/Sources/EeveeSpotify/Helpers/URLSessionHelper.swift +++ b/Sources/EeveeSpotify/Helpers/URLSessionHelper.swift @@ -1,7 +1,6 @@ import UIKit class URLSessionHelper { - static let shared = URLSessionHelper() private var requestsMap: [URL:Data] diff --git a/Sources/EeveeSpotify/Helpers/WindowHelper.swift b/Sources/EeveeSpotify/Helpers/WindowHelper.swift index 5aa8e6d..28f327a 100644 --- a/Sources/EeveeSpotify/Helpers/WindowHelper.swift +++ b/Sources/EeveeSpotify/Helpers/WindowHelper.swift @@ -1,7 +1,6 @@ import UIKit -class WindowHelper { - +struct WindowHelper { static let shared = WindowHelper() let window: UIWindow @@ -17,7 +16,6 @@ class WindowHelper { } func findFirstViewController(_ regex: String) -> UIViewController? { - let rootView = self.rootViewController.view! var result: UIViewController? @@ -37,6 +35,10 @@ class WindowHelper { searchViews(rootView) return result } + + func dismissCurrentViewController() { + rootViewController.dismiss(animated: true) + } func overrideUserInterfaceStyle(_ style: UIUserInterfaceStyle) { window.overrideUserInterfaceStyle = style diff --git a/Sources/EeveeSpotify/Lyrics/CustomLyrics.x.swift b/Sources/EeveeSpotify/Lyrics/CustomLyrics.x.swift index d3d9db8..731cad7 100644 --- a/Sources/EeveeSpotify/Lyrics/CustomLyrics.x.swift +++ b/Sources/EeveeSpotify/Lyrics/CustomLyrics.x.swift @@ -185,7 +185,7 @@ private func loadLyricsForCurrentTrack() throws { PopUpHelper.showPopUp( delayed: false, message: "musixmatch_unauthorized_popup".localized, - buttonText: "OK" + buttonText: "OK".uiKitLocalized ) hasShownUnauthorizedPopUp.toggle() @@ -197,7 +197,7 @@ private func loadLyricsForCurrentTrack() throws { PopUpHelper.showPopUp( delayed: false, message: "musixmatch_restricted_popup".localized, - buttonText: "OK" + buttonText: "OK".uiKitLocalized ) hasShownRestrictedPopUp.toggle() diff --git a/Sources/EeveeSpotify/Lyrics/Repositories/GeniusLyricsRepository.swift b/Sources/EeveeSpotify/Lyrics/Repositories/GeniusLyricsRepository.swift index 73ff274..3d88a68 100644 --- a/Sources/EeveeSpotify/Lyrics/Repositories/GeniusLyricsRepository.swift +++ b/Sources/EeveeSpotify/Lyrics/Repositories/GeniusLyricsRepository.swift @@ -1,7 +1,6 @@ import Foundation struct GeniusLyricsRepository: LyricsRepository { - private let jsonDecoder: JSONDecoder private let apiUrl = "https://api.genius.com" private let session: URLSession diff --git a/Sources/EeveeSpotify/Lyrics/Repositories/MusixmatchLyricsRepository.swift b/Sources/EeveeSpotify/Lyrics/Repositories/MusixmatchLyricsRepository.swift index 8e2ad80..8bbc941 100644 --- a/Sources/EeveeSpotify/Lyrics/Repositories/MusixmatchLyricsRepository.swift +++ b/Sources/EeveeSpotify/Lyrics/Repositories/MusixmatchLyricsRepository.swift @@ -2,7 +2,6 @@ import Foundation import UIKit class MusixmatchLyricsRepository: LyricsRepository { - private let apiUrl = "https://apic.musixmatch.com" var selectedLanguage: String @@ -19,9 +18,7 @@ class MusixmatchLyricsRepository: LyricsRepository { _ path: String, query: [String: Any] = [:] ) throws -> Data { - var stringUrl = "\(apiUrl)\(path)" - var finalQuery = query finalQuery["usertoken"] = UserDefaults.musixmatchToken diff --git a/Sources/EeveeSpotify/Models/Extensions/String+Extension.swift b/Sources/EeveeSpotify/Models/Extensions/String+Extension.swift index 2179160..0e066f3 100644 --- a/Sources/EeveeSpotify/Models/Extensions/String+Extension.swift +++ b/Sources/EeveeSpotify/Models/Extensions/String+Extension.swift @@ -1,4 +1,5 @@ import Foundation +import UIKit import NaturalLanguage extension String { @@ -10,6 +11,11 @@ extension String { BundleHelper.shared.localizedString(self) } + var uiKitLocalized: String { + let bundle = Bundle(for: UIApplication.self) + return bundle.localizedString(forKey: self, value: nil, table: nil) + } + func localizeWithFormat(_ arguments: CVarArg...) -> String{ String(format: self.localized, arguments: arguments) } diff --git a/Sources/EeveeSpotify/OpenSpotify.x.swift b/Sources/EeveeSpotify/OpenSpotify.x.swift index 83e1b5e..38f1949 100644 --- a/Sources/EeveeSpotify/OpenSpotify.x.swift +++ b/Sources/EeveeSpotify/OpenSpotify.x.swift @@ -2,9 +2,7 @@ import Orion import UIKit class UIOpenURLContextHook: ClassHook { - func URL() -> URL { - let url = orig.URL() if url.isOpenSpotifySafariExtension { diff --git a/Sources/EeveeSpotify/Premium/DynamicPremium+ModifyBootstrap.x.swift b/Sources/EeveeSpotify/Premium/DynamicPremium+ModifyBootstrap.x.swift index cf447bb..22c1655 100644 --- a/Sources/EeveeSpotify/Premium/DynamicPremium+ModifyBootstrap.x.swift +++ b/Sources/EeveeSpotify/Premium/DynamicPremium+ModifyBootstrap.x.swift @@ -4,7 +4,7 @@ private func showHavePremiumPopUp() { PopUpHelper.showPopUp( delayed: true, message: "have_premium_popup".localized, - buttonText: "ok".localized + buttonText: "OK".uiKitLocalized ) } diff --git a/Sources/EeveeSpotify/Premium/ServerSidedReminder.x.swift b/Sources/EeveeSpotify/Premium/ServerSidedReminder.x.swift index 5cb0714..92922d0 100644 --- a/Sources/EeveeSpotify/Premium/ServerSidedReminder.x.swift +++ b/Sources/EeveeSpotify/Premium/ServerSidedReminder.x.swift @@ -8,7 +8,7 @@ class StreamQualitySettingsSectionHook: ClassHook { func shouldResetSelection() -> Bool { PopUpHelper.showPopUp( message: "high_audio_quality_popup".localized, - buttonText: "ok".localized + buttonText: "OK".uiKitLocalized ) return true @@ -20,7 +20,7 @@ class StreamQualitySettingsSectionHook: ClassHook { private func showOfflineModePopUp() { PopUpHelper.showPopUp( message: "playlist_downloading_popup".localized, - buttonText: "ok".localized + buttonText: "OK".uiKitLocalized ) } @@ -35,6 +35,16 @@ class ContentOffliningUIHelperImplementationHook: ClassHook { pageIdentifier: String, pageURI: URL ) -> String { + if pageIdentifier == "spotify:local-files" { + return orig.downloadToggledWithCurrentAvailability( + availability, + addAction: addAction, + removeAction: removeAction, + pageIdentifier: pageIdentifier, + pageURI: pageURI + ) + } + showOfflineModePopUp() return pageIdentifier } diff --git a/Sources/EeveeSpotify/Settings/EeveeSettings.x.swift b/Sources/EeveeSpotify/Settings/EeveeSettings.x.swift index 5c17c14..588e9e3 100644 --- a/Sources/EeveeSpotify/Settings/EeveeSettings.x.swift +++ b/Sources/EeveeSpotify/Settings/EeveeSettings.x.swift @@ -3,7 +3,6 @@ import SwiftUI import UIKit class ProfileSettingsSectionHook: ClassHook { - static let targetName = "ProfileSettingsSection" func numberOfRows() -> Int { @@ -11,9 +10,7 @@ class ProfileSettingsSectionHook: ClassHook { } func didSelectRow(_ row: Int) { - if row == 1 { - let rootSettingsController = WindowHelper.shared.findFirstViewController( "RootSettingsViewController" )! @@ -62,9 +59,7 @@ class ProfileSettingsSectionHook: ClassHook { } func cellForRow(_ row: Int) -> UITableViewCell { - if row == 1 { - let settingsTableCell = Dynamic.SPTSettingsTableViewCell .alloc(interface: SPTSettingsTableViewCell.self) .initWithStyle(3, reuseIdentifier: "EeveeSpotify") diff --git a/Sources/EeveeSpotify/Settings/Helpers/GitHubHelper.swift b/Sources/EeveeSpotify/Settings/Helpers/GitHubHelper.swift new file mode 100644 index 0000000..0b679dc --- /dev/null +++ b/Sources/EeveeSpotify/Settings/Helpers/GitHubHelper.swift @@ -0,0 +1,43 @@ +import Foundation + +struct GitHubHelper { + private let apiUrl = "https://api.github.com" + private let decoder = JSONDecoder() + + static let shared = GitHubHelper() + + init() { + decoder.keyDecodingStrategy = .convertFromSnakeCase + } + + private func perform(_ path: String) async throws -> Data { + let url = URL(string: "\(apiUrl)\(path)")! + let (data, _) = try await URLSession.shared.data(from: url) + + return data + } + + func getLatestRelease() async throws -> GitHubRelease { + let data = try await perform("/repos/whoeevee/EeveeSpotify/releases/latest") + return try decoder.decode(GitHubRelease.self, from: data) + } + + func getUser(_ username: String) async throws -> GitHubUser { + let data = try await perform("/users/\(username)") + return try decoder.decode(GitHubUser.self, from: data) + } + + func getContributors() async throws -> [GitHubUser] { + let data = try await perform("/repos/whoeevee/EeveeSpotify/contributors") + return try decoder.decode([GitHubUser].self, from: data) + } + + func getEeveeContributorSections() async throws -> [EeveeContributorSection] { + let (data, _) = try await URLSession.shared.data( + from: URL( + string: "https://raw.githubusercontent.com/whoeevee/EeveeSpotify/swift/repo.altsource.json" + )! + ) + return try decoder.decode([EeveeContributorSection].self, from: data) + } +} diff --git a/Sources/EeveeSpotify/Settings/Models/EeveeContributor.swift b/Sources/EeveeSpotify/Settings/Models/EeveeContributor.swift new file mode 100644 index 0000000..818d1e4 --- /dev/null +++ b/Sources/EeveeSpotify/Settings/Models/EeveeContributor.swift @@ -0,0 +1,4 @@ +struct EeveeContributor: Decodable, Equatable { + var username: String + var roles: [String] +} diff --git a/Sources/EeveeSpotify/Settings/Models/EeveeContributorSection.swift b/Sources/EeveeSpotify/Settings/Models/EeveeContributorSection.swift new file mode 100644 index 0000000..22dfff0 --- /dev/null +++ b/Sources/EeveeSpotify/Settings/Models/EeveeContributorSection.swift @@ -0,0 +1,5 @@ +struct EeveeContributorSection: Decodable, Equatable { + var title: String + var shuffled: Bool + var contributors: [EeveeContributor] +} diff --git a/Sources/EeveeSpotify/Settings/Models/GitHubRelease.swift b/Sources/EeveeSpotify/Settings/Models/GitHubRelease.swift new file mode 100644 index 0000000..2a1a0c7 --- /dev/null +++ b/Sources/EeveeSpotify/Settings/Models/GitHubRelease.swift @@ -0,0 +1,3 @@ +struct GitHubRelease: Decodable { + var tagName: String +} diff --git a/Sources/EeveeSpotify/Settings/Models/GitHubReleaseInfo.swift b/Sources/EeveeSpotify/Settings/Models/GitHubReleaseInfo.swift deleted file mode 100644 index 91c6d52..0000000 --- a/Sources/EeveeSpotify/Settings/Models/GitHubReleaseInfo.swift +++ /dev/null @@ -1,5 +0,0 @@ -import Foundation - -struct GitHubReleaseInfo: Decodable { - var tag_name: String -} diff --git a/Sources/EeveeSpotify/Settings/Models/GitHubUser.swift b/Sources/EeveeSpotify/Settings/Models/GitHubUser.swift new file mode 100644 index 0000000..7a9ebfb --- /dev/null +++ b/Sources/EeveeSpotify/Settings/Models/GitHubUser.swift @@ -0,0 +1,5 @@ +struct GitHubUser: Decodable, Equatable { + var avatarUrl: String + var htmlUrl: String + var login: String +} diff --git a/Sources/EeveeSpotify/Settings/ViewModels/ImageViewModel.swift b/Sources/EeveeSpotify/Settings/ViewModels/ImageViewModel.swift new file mode 100644 index 0000000..9442dda --- /dev/null +++ b/Sources/EeveeSpotify/Settings/ViewModels/ImageViewModel.swift @@ -0,0 +1,51 @@ +import SwiftUI +import UIKit + +class ImageViewModel: ObservableObject { + @Published var image: UIImage? + + private var imageCache: NSCache? + + init(urlString: String?) { + loadImage(urlString: urlString) + } + + private func loadImage(urlString: String?) { + guard let urlString = urlString else { return } + + if let imageFromCache = getImageFromCache(from: urlString) { + self.image = imageFromCache + return + } + + loadImageFromURL(urlString: urlString) + } + + private func loadImageFromURL(urlString: String) { + guard let url = URL(string: urlString) else { return } + + URLSession.shared.dataTask(with: url) { data, response, error in + guard error == nil else { + return + } + + guard let data = data else { + return + } + + DispatchQueue.main.async { [weak self] in + guard let loadedImage = UIImage(data: data) else { return } + self?.image = loadedImage + self?.setImageCache(image: loadedImage, key: urlString) + } + }.resume() + } + + private func setImageCache(image: UIImage, key: String) { + imageCache?.setObject(image, forKey: key as NSString) + } + + private func getImageFromCache(from key: String) -> UIImage? { + return imageCache?.object(forKey: key as NSString) as? UIImage + } +} diff --git a/Sources/EeveeSpotify/Settings/Views/Contributors/EeveeContributorView.swift b/Sources/EeveeSpotify/Settings/Views/Contributors/EeveeContributorView.swift new file mode 100644 index 0000000..0176070 --- /dev/null +++ b/Sources/EeveeSpotify/Settings/Views/Contributors/EeveeContributorView.swift @@ -0,0 +1,33 @@ +import SwiftUI + +struct EeveeContributorView: View { + var contributor: EeveeContributor + var githubUser: GitHubUser + + var body: some View { + VStack { + Link(destination: URL(string: githubUser.htmlUrl)!) { + HStack(spacing: 10) { + ImageView(urlString: githubUser.avatarUrl) + .frame(width: 48, height: 48) + .clipShape(Circle()) + + VStack(alignment: .leading, spacing: 0) { + Text(contributor.username) + .foregroundColor(.white) + .font(.headline) + + ForEach(contributor.roles, id: \.self) { role in + Text(role) + } + .foregroundColor(.gray) + } + + Spacer() + + ChevronRightView() + } + } + } + } +} diff --git a/Sources/EeveeSpotify/Settings/Views/Contributors/EeveeContributorsSheetView.swift b/Sources/EeveeSpotify/Settings/Views/Contributors/EeveeContributorsSheetView.swift new file mode 100644 index 0000000..fb35fd5 --- /dev/null +++ b/Sources/EeveeSpotify/Settings/Views/Contributors/EeveeContributorsSheetView.swift @@ -0,0 +1,57 @@ +import SwiftUI + +struct EeveeContributorsSheetView: View { + @State private var users: [GitHubUser] = [] + @State private var sections: [EeveeContributorSection] = [] + + var body: some View { + NavigationView { + VStack { + if users.isEmpty && sections.isEmpty { + ProgressView("Loading".uiKitLocalized) + } + else { + List { + ForEach(sections, id: \.title) { section in + Section { + ForEach( + section.shuffled + ? section.contributors.shuffled() + : section.contributors, + id: \.username + ) { contributor in + if let user = users.first(where: { $0.login == contributor.username }) { + EeveeContributorView(contributor: contributor, githubUser: user) + } + } + } header: { + Text(section.title) + } + } + } + } + } + .navigationTitle("contributors".localized) + .navigationBarTitleDisplayMode(.inline) + + .toolbar { + Button { + WindowHelper.shared.dismissCurrentViewController() + } label: { + Text("Done".uiKitLocalized) + .font(.headline) + } + } + + .animation(.default, value: users) + .animation(.default, value: sections) + + .onAppear { + Task { + users = try await GitHubHelper.shared.getContributors() + sections = try await GitHubHelper.shared.getEeveeContributorSections() + } + } + } + } +} diff --git a/Sources/EeveeSpotify/Settings/Views/EeveeSettingsVersionView.swift b/Sources/EeveeSpotify/Settings/Views/EeveeSettingsVersionView.swift new file mode 100644 index 0000000..2f900e1 --- /dev/null +++ b/Sources/EeveeSpotify/Settings/Views/EeveeSettingsVersionView.swift @@ -0,0 +1,55 @@ +import SwiftUI + +struct EeveeSettingsVersionView: View { + @State private var latestVersion: String? + @State private var isPresentingContributorsSheet = false + + private func loadVersion() async throws { + let release = try await GitHubHelper.shared.getLatestRelease() + latestVersion = String(release.tagName.dropFirst(5)) // swiftX.X + } + + private var isUpdateAvailable: Bool { + latestVersion != nil && latestVersion != EeveeSpotify.version + } + + var body: some View { + Section { + if isUpdateAvailable { + Link( + "update_available".localized, + destination: URL(string: "https://github.com/whoeevee/EeveeSpotify/releases")! + ) + } + } footer: { + VStack(alignment: .leading) { + Text("v\(EeveeSpotify.version)") + + if latestVersion == nil { + HStack(spacing: 10) { + ProgressView() + Text("checking_for_update".localized) + } + } + else { + Button("\("contributors".localized)...") { + isPresentingContributorsSheet = true + } + .foregroundColor(.gray) + .font(.subheadline.weight(.semibold)) + } + } + } + .sheet(isPresented: $isPresentingContributorsSheet) { + EeveeContributorsSheetView() + } + + .animation(.default, value: latestVersion) + + .onAppear { + Task { + try await loadVersion() + } + } + } +} diff --git a/Sources/EeveeSpotify/Settings/Views/EeveeSettingsView+VersionSection.swift b/Sources/EeveeSpotify/Settings/Views/EeveeSettingsView+VersionSection.swift deleted file mode 100644 index 09eb0fb..0000000 --- a/Sources/EeveeSpotify/Settings/Views/EeveeSettingsView+VersionSection.swift +++ /dev/null @@ -1,45 +0,0 @@ -import SwiftUI - -extension EeveeSettingsView { - func loadVersion() async throws { - let (data, _) = try await URLSession.shared.data( - from: URL(string: "https://api.github.com/repos/whoeevee/EeveeSpotify/releases/latest")! - ) - - let tag = try JSONDecoder().decode(GitHubReleaseInfo.self, from: data).tag_name - latestVersion = String(tag.dropFirst(5)) - } - - private var isUpdateAvailable: Bool { - guard - let latest = Double(latestVersion), - let current = Double(EeveeSpotify.version) - else { - return false - } - - return latest > current - } - - @ViewBuilder func VersionSection() -> some View { - Section { - if isUpdateAvailable { - Link( - "update_available".localized, - destination: URL(string: "https://github.com/whoeevee/EeveeSpotify/releases")! - ) - } - } footer: { - VStack(alignment: .leading) { - Text("v\(EeveeSpotify.version)") - - if latestVersion.isEmpty { - HStack(spacing: 10) { - ProgressView() - Text("checking_for_update".localized) - } - } - } - } - } -} diff --git a/Sources/EeveeSpotify/Settings/Views/EeveeSettingsView.swift b/Sources/EeveeSpotify/Settings/Views/EeveeSettingsView.swift index 50f8780..529f325 100644 --- a/Sources/EeveeSpotify/Settings/Views/EeveeSettingsView.swift +++ b/Sources/EeveeSpotify/Settings/Views/EeveeSettingsView.swift @@ -4,8 +4,6 @@ import UIKit struct EeveeSettingsView: View { let navigationController: UINavigationController - @State var latestVersion = "" - @State private var hasShownCommonIssuesTip = UserDefaults.hasShownCommonIssuesTip @State private var isClearingData = false @@ -17,10 +15,17 @@ struct EeveeSettingsView: View { ) navigationController.pushViewController(viewController, animated: true) } + + init(navigationController: UINavigationController) { + self.navigationController = navigationController + + let spotifyAccentColor = UIColor(Color(hex: "#1ed760")) + UIView.appearance().tintColor = spotifyAccentColor + } var body: some View { List { - VersionSection() + EeveeSettingsVersionView() if !hasShownCommonIssuesTip { CommonIssuesTipView( @@ -95,19 +100,13 @@ struct EeveeSettingsView: View { } } } - .listStyle(GroupedListStyle()) .animation(.default, value: isClearingData) - .animation(.default, value: latestVersion) .animation(.default, value: hasShownCommonIssuesTip) .onAppear { WindowHelper.shared.overrideUserInterfaceStyle(.dark) - - Task { - try await loadVersion() - } } } } diff --git a/Sources/EeveeSpotify/Settings/Views/Sections/EeveeLyricsSettingsView+Extension.swift b/Sources/EeveeSpotify/Settings/Views/Sections/EeveeLyricsSettingsView+Extension.swift index 5825c88..dcc2349 100644 --- a/Sources/EeveeSpotify/Settings/Views/Sections/EeveeLyricsSettingsView+Extension.swift +++ b/Sources/EeveeSpotify/Settings/Views/Sections/EeveeLyricsSettingsView+Extension.swift @@ -1,7 +1,6 @@ import SwiftUI extension EeveeLyricsSettingsView { - func getMusixmatchToken(_ input: String) -> String? { if let match = input.firstMatch("\\[UserToken\\]: ([a-f0-9]+)"), let tokenRange = Range(match.range(at: 1), in: input) { @@ -21,17 +20,15 @@ extension EeveeLyricsSettingsView { preferredStyle: .alert ) - alert.view.tintColor = UIColor(Color(hex: "#1ed760")) - alert.addTextField() { textField in textField.placeholder = "---- Debug Info ---- [Device]: iPhone" } - alert.addAction(UIAlertAction(title: "cancel".localized, style: .cancel) { _ in + alert.addAction(UIAlertAction(title: "Cancel".uiKitLocalized, style: .cancel) { _ in lyricsSource = oldSource }) - alert.addAction(UIAlertAction(title: "ok".localized, style: .default) { _ in + alert.addAction(UIAlertAction(title: "OK".uiKitLocalized, style: .default) { _ in let text = alert.textFields!.first!.text! guard let token = getMusixmatchToken(text) else { diff --git a/Sources/EeveeSpotify/Settings/Views/Sections/EeveeLyricsSettingsView.swift b/Sources/EeveeSpotify/Settings/Views/Sections/EeveeLyricsSettingsView.swift index 406ca18..3bc0b87 100644 --- a/Sources/EeveeSpotify/Settings/Views/Sections/EeveeLyricsSettingsView.swift +++ b/Sources/EeveeSpotify/Settings/Views/Sections/EeveeLyricsSettingsView.swift @@ -1,7 +1,6 @@ import SwiftUI struct EeveeLyricsSettingsView: View { - @State var musixmatchToken = UserDefaults.musixmatchToken @State var lyricsSource = UserDefaults.lyricsSource @State var geniusFallback = UserDefaults.geniusFallback diff --git a/Sources/EeveeSpotify/Settings/Views/Sections/EeveeUISettingsView.swift b/Sources/EeveeSpotify/Settings/Views/Sections/EeveeUISettingsView.swift index f5cc294..78c06bd 100644 --- a/Sources/EeveeSpotify/Settings/Views/Sections/EeveeUISettingsView.swift +++ b/Sources/EeveeSpotify/Settings/Views/Sections/EeveeUISettingsView.swift @@ -63,8 +63,8 @@ struct EeveeUISettingsView: View { .modifier(ListRowSeparatorHidden()) } } - .listStyle(GroupedListStyle()) + .listStyle(GroupedListStyle()) .animation(.default, value: lyricsColors) } } diff --git a/Sources/EeveeSpotify/Settings/Views/Shared/ChevronRightView.swift b/Sources/EeveeSpotify/Settings/Views/Shared/ChevronRightView.swift new file mode 100644 index 0000000..56089b9 --- /dev/null +++ b/Sources/EeveeSpotify/Settings/Views/Shared/ChevronRightView.swift @@ -0,0 +1,9 @@ +import SwiftUI + +struct ChevronRightView: View { + var body: some View { + Image(systemName: "chevron.right") + .font(.subheadline.weight(.semibold)) + .foregroundColor(Color(UIColor.systemGray2)) + } +} diff --git a/Sources/EeveeSpotify/Settings/Views/Shared/CommonIssuesTipView.swift b/Sources/EeveeSpotify/Settings/Views/Shared/CommonIssuesTipView.swift index a3a58e6..720b14c 100644 --- a/Sources/EeveeSpotify/Settings/Views/Shared/CommonIssuesTipView.swift +++ b/Sources/EeveeSpotify/Settings/Views/Shared/CommonIssuesTipView.swift @@ -1,7 +1,6 @@ import SwiftUI struct CommonIssuesTipView: View { - var onDismiss: () -> Void var body: some View { @@ -18,7 +17,9 @@ struct CommonIssuesTipView: View { } Link( - destination: URL(string: "https://github.com/whoeevee/EeveeSpotify/blob/swift/common_issues.md")!, + destination: URL( + string: "https://github.com/whoeevee/EeveeSpotify/blob/swift/common_issues.md" + )!, label: { VStack { Text("\("common_issues_tip_message".localized) ") diff --git a/Sources/EeveeSpotify/Settings/Views/Shared/ImageView.swift b/Sources/EeveeSpotify/Settings/Views/Shared/ImageView.swift new file mode 100644 index 0000000..b757fb4 --- /dev/null +++ b/Sources/EeveeSpotify/Settings/Views/Shared/ImageView.swift @@ -0,0 +1,14 @@ +import SwiftUI + +struct ImageView: View { + @ObservedObject private var imageViewModel: ImageViewModel + + init(urlString: String?) { + imageViewModel = ImageViewModel(urlString: urlString) + } + + var body: some View { + Image(uiImage: imageViewModel.image ?? UIImage()) + .resizable() + } +} diff --git a/Sources/EeveeSpotify/Settings/Views/Shared/NavigationSectionView.swift b/Sources/EeveeSpotify/Settings/Views/Shared/NavigationSectionView.swift index d679cd3..fbc2426 100644 --- a/Sources/EeveeSpotify/Settings/Views/Shared/NavigationSectionView.swift +++ b/Sources/EeveeSpotify/Settings/Views/Shared/NavigationSectionView.swift @@ -1,7 +1,6 @@ import SwiftUI struct NavigationSectionView: View { - var color: Color var title: String var imageSystemName: String @@ -23,9 +22,7 @@ struct NavigationSectionView: View { Spacer() - Image(systemName: "chevron.right") - .foregroundColor(Color(UIColor.systemGray2)) - .font(.subheadline.bold()) + ChevronRightView() } } } diff --git a/Sources/EeveeSpotify/Tweak.x.swift b/Sources/EeveeSpotify/Tweak.x.swift index b0faede..5393d36 100644 --- a/Sources/EeveeSpotify/Tweak.x.swift +++ b/Sources/EeveeSpotify/Tweak.x.swift @@ -11,8 +11,7 @@ func exitApplication() { struct PremiumPatching: HookGroup { } struct EeveeSpotify: Tweak { - - static let version = "5.4" + static let version = "5.5" static let isOldSpotifyVersion = NSClassFromString("Lyrics_NPVCommunicatorImpl.LyricsOnlyViewController") == nil init() { diff --git a/contributors.json b/contributors.json new file mode 100644 index 0000000..b9d7c01 --- /dev/null +++ b/contributors.json @@ -0,0 +1,136 @@ +[ + { + "title": "Developement", + "shuffled": false, + "contributors": [ + { + "username": "whoeevee", + "roles": [ + "Owner", + "Main Developer" + ] + }, + { + "username": "asdfzxcvbn", + "roles": [ + "Collaborator", + "EeveeRepoUpdater" + ] + } + ] + }, + { + "title": "Localization", + "shuffled": true, + "contributors": [ + { + "username": "longopy", + "roles": [ + "Spanish" + ] + }, + { + "username": "xiangfeidexiaohuo", + "roles": [ + "Simplified Chinese" + ] + }, + { + "username": "LivioZ", + "roles": [ + "Italian" + ] + }, + { + "username": "LIKVIDATOR1337", + "roles": [ + "Ukrainian" + ] + }, + { + "username": "gototheskinny", + "roles": [ + "Turkish" + ] + }, + { + "username": "ElliotCHEN37", + "roles": [ + "Traditional Chinese" + ] + }, + { + "username": "schweppes-0x", + "roles": [ + "Bulgarian" + ] + }, + { + "username": "speedyfriend433", + "roles": [ + "Korean" + ] + }, + { + "username": "Richard-NDC", + "roles": [ + "Vietnamese" + ] + }, + { + "username": "wlxxd", + "roles": [ + "German" + ] + }, + { + "username": "Incognito-Coder", + "roles": [ + "Persian" + ] + }, + { + "username": "UnexcitingDean", + "roles": [ + "Danish" + ] + }, + { + "username": "An0n-00", + "roles": [ + "Swiss German" + ] + }, + { + "username": "CukierDev", + "roles": [ + "Polish" + ] + }, + { + "username": "3xynos7", + "roles": [ + "Nepalese" + ] + }, + { + "username": "by3lish", + "roles": [ + "Azerbaijani" + ] + }, + { + "username": "5jd", + "roles": [ + "French" + ] + }, + { + "username": "emal0n", + "roles": [ + "Brazil" + ] + } + ] + } +] diff --git a/control b/control index c6004e5..1b10bbe 100644 --- a/control +++ b/control @@ -1,6 +1,6 @@ Package: com.eevee.spotify Name: EeveeSpotify -Version: 5.4 +Version: 5.5 Architecture: iphoneos-arm Description: A tweak to get Spotify Premium for free, just like Spotilife Maintainer: Eevee diff --git a/layout/Library/Application Support/EeveeSpotify.bundle/az.lproj/Localizable.strings b/layout/Library/Application Support/EeveeSpotify.bundle/az.lproj/Localizable.strings index b5145b3..4a2bca1 100644 --- a/layout/Library/Application Support/EeveeSpotify.bundle/az.lproj/Localizable.strings +++ b/layout/Library/Application Support/EeveeSpotify.bundle/az.lproj/Localizable.strings @@ -15,9 +15,6 @@ reset_data_description = "Keş yaddaşını təmizləyin və tətbiqi yenidən b checking_for_update = "Yeniləmələr yoxlanılır..."; update_available = "Yeniləmə Mövcuddur"; -cancel = "Ləğv et"; -ok = "OK"; - // Patching do_not_patch_premium = "Premium üçün yamaqlama"; diff --git a/layout/Library/Application Support/EeveeSpotify.bundle/bg.lproj/Localizable.strings b/layout/Library/Application Support/EeveeSpotify.bundle/bg.lproj/Localizable.strings index e189761..0e936df 100644 --- a/layout/Library/Application Support/EeveeSpotify.bundle/bg.lproj/Localizable.strings +++ b/layout/Library/Application Support/EeveeSpotify.bundle/bg.lproj/Localizable.strings @@ -15,9 +15,6 @@ reset_data_description = "Изчистете кешираните данни и checking_for_update = "Проверка за актуализация..."; update_available = "Налична е актуализация"; -cancel = "Отказ"; -ok = "ОК"; - // Patching do_not_patch_premium = "Не пачвай Premium"; diff --git a/layout/Library/Application Support/EeveeSpotify.bundle/da.lproj/Localizable.strings b/layout/Library/Application Support/EeveeSpotify.bundle/da.lproj/Localizable.strings index 8b38044..653647f 100644 --- a/layout/Library/Application Support/EeveeSpotify.bundle/da.lproj/Localizable.strings +++ b/layout/Library/Application Support/EeveeSpotify.bundle/da.lproj/Localizable.strings @@ -15,9 +15,6 @@ reset_data_description = "Ryd cachelagrede data og genstart appen."; checking_for_update = "Tjekker for opdateringer..."; update_available = "Opdatering tilgængelig"; -cancel = "Annuller"; -ok = "OK"; - // Patching do_not_patch_premium = "Patch ikke Premium"; diff --git a/layout/Library/Application Support/EeveeSpotify.bundle/de-CH.lproj/Localizable.strings b/layout/Library/Application Support/EeveeSpotify.bundle/de-CH.lproj/Localizable.strings index 9e98b78..3277daf 100644 --- a/layout/Library/Application Support/EeveeSpotify.bundle/de-CH.lproj/Localizable.strings +++ b/layout/Library/Application Support/EeveeSpotify.bundle/de-CH.lproj/Localizable.strings @@ -15,9 +15,6 @@ reset_data_description = "Lösch zwischegspeicherti Date und starte d'App neu."; checking_for_update = "lueg nachemene Update..."; update_available = "Es het es Update verfüegbar!"; -cancel = "Abbräche"; -ok = "OK"; - // Patching do_not_patch_premium = "Duen Premium nid pätche"; diff --git a/layout/Library/Application Support/EeveeSpotify.bundle/de.lproj/Localizable.strings b/layout/Library/Application Support/EeveeSpotify.bundle/de.lproj/Localizable.strings index 47428b4..64a6d2c 100644 --- a/layout/Library/Application Support/EeveeSpotify.bundle/de.lproj/Localizable.strings +++ b/layout/Library/Application Support/EeveeSpotify.bundle/de.lproj/Localizable.strings @@ -15,9 +15,6 @@ reset_data_description = "Zwischengespeicherte Daten (Cache) löschen und App ne checking_for_update = "Suche nach Updates..."; update_available = "Update verfügbar"; -cancel = "Abbrechen"; -ok = "OK"; - // Patching do_not_patch_premium = "Premium nicht patchen"; diff --git a/layout/Library/Application Support/EeveeSpotify.bundle/en.lproj/Localizable.strings b/layout/Library/Application Support/EeveeSpotify.bundle/en.lproj/Localizable.strings index 513a3cb..681c5d6 100644 --- a/layout/Library/Application Support/EeveeSpotify.bundle/en.lproj/Localizable.strings +++ b/layout/Library/Application Support/EeveeSpotify.bundle/en.lproj/Localizable.strings @@ -15,9 +15,6 @@ reset_data_description = "Clear cached data and restart the app."; checking_for_update = "Checking for Update..."; update_available = "Update Available"; -cancel = "Cancel"; -ok = "OK"; - // Patching do_not_patch_premium = "Do Not Patch Premium"; @@ -105,3 +102,5 @@ let_the_music_play = "Let the music play..."; // liked songs title, should match official spotify loc liked_songs = "Liked songs"; + +contributors = "Contributors"; diff --git a/layout/Library/Application Support/EeveeSpotify.bundle/es.lproj/Localizable.strings b/layout/Library/Application Support/EeveeSpotify.bundle/es.lproj/Localizable.strings index 92e5482..6b35f2b 100644 --- a/layout/Library/Application Support/EeveeSpotify.bundle/es.lproj/Localizable.strings +++ b/layout/Library/Application Support/EeveeSpotify.bundle/es.lproj/Localizable.strings @@ -15,9 +15,6 @@ reset_data_description = "Borra los datos almacenados en caché y reinicia la ap checking_for_update = "Comprobando Actualizaciones..."; update_available = "Actualización Disponible"; -cancel = "Cancelar"; -ok = "Confirmar"; - // Patching do_not_patch_premium = "No Parchear Premium"; diff --git a/layout/Library/Application Support/EeveeSpotify.bundle/fa.lproj/Localizable.strings b/layout/Library/Application Support/EeveeSpotify.bundle/fa.lproj/Localizable.strings index a99ce9d..06373a5 100644 --- a/layout/Library/Application Support/EeveeSpotify.bundle/fa.lproj/Localizable.strings +++ b/layout/Library/Application Support/EeveeSpotify.bundle/fa.lproj/Localizable.strings @@ -15,9 +15,6 @@ reset_data_description = "پاک کردن کش و راه اندازی مجدد"; checking_for_update = "درحال بررسی بروزرسانی..."; update_available = "آپدیت موجود است"; -cancel = "لغو"; -ok = "باشه"; - // Patching do_not_patch_premium = "پچ نکردن حالت ویژه"; diff --git a/layout/Library/Application Support/EeveeSpotify.bundle/fr.lproj/Localizable.strings b/layout/Library/Application Support/EeveeSpotify.bundle/fr.lproj/Localizable.strings index 14f04b1..c4b919f 100644 --- a/layout/Library/Application Support/EeveeSpotify.bundle/fr.lproj/Localizable.strings +++ b/layout/Library/Application Support/EeveeSpotify.bundle/fr.lproj/Localizable.strings @@ -15,9 +15,6 @@ reset_data_description = "Effacez les données en cache et redémarrez l'applica checking_for_update = "Vérification des mises à jour..."; update_available = "Mise à jour disponible"; -cancel = "Annuler"; -ok = "OK"; - // Patching do_not_patch_premium = "Ne pas patcher Premium"; diff --git a/layout/Library/Application Support/EeveeSpotify.bundle/it.lproj/Localizable.strings b/layout/Library/Application Support/EeveeSpotify.bundle/it.lproj/Localizable.strings index 0845b8b..10451d0 100644 --- a/layout/Library/Application Support/EeveeSpotify.bundle/it.lproj/Localizable.strings +++ b/layout/Library/Application Support/EeveeSpotify.bundle/it.lproj/Localizable.strings @@ -15,9 +15,6 @@ reset_data_description = "Cancella i dati memorizzati nella cache e riavvia l'ap checking_for_update = "Verifica aggiornamenti..."; update_available = "Aggiornamento disponibile"; -cancel = "Annulla"; -ok = "OK"; - // Patching do_not_patch_premium = "Non patchare Premium"; diff --git a/layout/Library/Application Support/EeveeSpotify.bundle/ko.lproj/Localizable.strings b/layout/Library/Application Support/EeveeSpotify.bundle/ko.lproj/Localizable.strings index 6680aa5..285fe01 100644 --- a/layout/Library/Application Support/EeveeSpotify.bundle/ko.lproj/Localizable.strings +++ b/layout/Library/Application Support/EeveeSpotify.bundle/ko.lproj/Localizable.strings @@ -15,9 +15,6 @@ reset_data_description = "캐시된 데이터를 지우고 앱을 다시 시작 checking_for_update = "업데이트 확인 중..."; update_available = "업데이트 가능"; -cancel = "취소"; -ok = "확인"; - // Patching do_not_patch_premium = "프리미엄으로 패치 안 함"; @@ -100,4 +97,4 @@ unknown_error = "알 수 없는 오류"; // Instrumental Titles song_is_instrumental = "이 노래는 악기전용 노래입니다."; -let_the_music_play = "음악이 재생되게 놔두세요..."; \ No newline at end of file +let_the_music_play = "음악이 재생되게 놔두세요..."; diff --git a/layout/Library/Application Support/EeveeSpotify.bundle/np.lproj/Localizable.strings b/layout/Library/Application Support/EeveeSpotify.bundle/np.lproj/Localizable.strings index 3fd04ad..b188ed3 100644 --- a/layout/Library/Application Support/EeveeSpotify.bundle/np.lproj/Localizable.strings +++ b/layout/Library/Application Support/EeveeSpotify.bundle/np.lproj/Localizable.strings @@ -15,9 +15,6 @@ reset_data_description = "क्यास डाटा खाली गर्न checking_for_update = "अपडेटको लागि जाँच गर्दै..."; update_available = "अपडेट उपलब्ध छ"; -cancel = "रद्द गर्नुहोस्"; -ok = "ठीक छ"; - // Patching do_not_patch_premium = "प्रिमियम प्याच नगर्नुहोस्"; diff --git a/layout/Library/Application Support/EeveeSpotify.bundle/pl.lproj/Localizable.strings b/layout/Library/Application Support/EeveeSpotify.bundle/pl.lproj/Localizable.strings index 2731e8c..529c816 100644 --- a/layout/Library/Application Support/EeveeSpotify.bundle/pl.lproj/Localizable.strings +++ b/layout/Library/Application Support/EeveeSpotify.bundle/pl.lproj/Localizable.strings @@ -15,9 +15,6 @@ reset_data_description = "Wyczyść dane cache i zrestartuj aplikacje."; checking_for_update = "Sprawdzanie aktualizacji..."; update_available = "Aktualizacja Dostępna"; -cancel = "Anuluj"; -ok = "OK"; - // Patching do_not_patch_premium = "Nie używaj łatki premium"; diff --git a/layout/Library/Application Support/EeveeSpotify.bundle/pt-BR.lproj/Localizable.strings b/layout/Library/Application Support/EeveeSpotify.bundle/pt-BR.lproj/Localizable.strings index 8355aa8..7e1bf42 100644 --- a/layout/Library/Application Support/EeveeSpotify.bundle/pt-BR.lproj/Localizable.strings +++ b/layout/Library/Application Support/EeveeSpotify.bundle/pt-BR.lproj/Localizable.strings @@ -15,9 +15,6 @@ reset_data_description = "Esta função limpará os Dados em cache e reiniciará checking_for_update = "Procurando atualizações..."; update_available = "Atualização disponivel"; -cancel = "Cancelar"; -ok = "Confirmar"; - // Patching do_not_patch_premium = "Não aplicar correção ao premium"; diff --git a/layout/Library/Application Support/EeveeSpotify.bundle/ru.lproj/Localizable.strings b/layout/Library/Application Support/EeveeSpotify.bundle/ru.lproj/Localizable.strings index efb3194..7cc8adf 100644 --- a/layout/Library/Application Support/EeveeSpotify.bundle/ru.lproj/Localizable.strings +++ b/layout/Library/Application Support/EeveeSpotify.bundle/ru.lproj/Localizable.strings @@ -15,9 +15,6 @@ reset_data_description = "Очистить кэшированные данные checking_for_update = "Проверка наличия обновления..."; update_available = "Доступно обновление"; -cancel = "Отменить"; -ok = "OK"; - // Patching do_not_patch_premium = "Не патчить Premium"; @@ -103,3 +100,5 @@ let_the_music_play = "Пусть заиграет музыка..."; // liked songs title, should match official spotify loc liked_songs = "Тебе понравилось"; + +contributors = "Участники"; diff --git a/layout/Library/Application Support/EeveeSpotify.bundle/tr.lproj/Localizable.strings b/layout/Library/Application Support/EeveeSpotify.bundle/tr.lproj/Localizable.strings index 233fd9a..0f99456 100644 --- a/layout/Library/Application Support/EeveeSpotify.bundle/tr.lproj/Localizable.strings +++ b/layout/Library/Application Support/EeveeSpotify.bundle/tr.lproj/Localizable.strings @@ -15,9 +15,6 @@ reset_data_description = "Önbelleğe alınan verileri temizleyin ve uygulamayı checking_for_update = "Güncelleme Kontrol Ediliyor..."; update_available = "Güncelleme Mevcut"; -cancel = "İptal"; -ok = "Tamam"; - // Patching do_not_patch_premium = "Premium için olan Yamayı Yapma"; diff --git a/layout/Library/Application Support/EeveeSpotify.bundle/uk.lproj/Localizable.strings b/layout/Library/Application Support/EeveeSpotify.bundle/uk.lproj/Localizable.strings index ca8d957..61dcf60 100644 --- a/layout/Library/Application Support/EeveeSpotify.bundle/uk.lproj/Localizable.strings +++ b/layout/Library/Application Support/EeveeSpotify.bundle/uk.lproj/Localizable.strings @@ -15,9 +15,6 @@ reset_data_description = "Очистити кешовані дані та пер checking_for_update = "Перевірка наявності оновлень..."; update_available = "Доступне оновлення"; -cancel = "Скасувати"; -ok = "ОК"; - // Patching do_not_patch_premium = "Не патчити Premium"; diff --git a/layout/Library/Application Support/EeveeSpotify.bundle/vi.lproj/Localizable.strings b/layout/Library/Application Support/EeveeSpotify.bundle/vi.lproj/Localizable.strings index 88b58a7..2d0049d 100644 --- a/layout/Library/Application Support/EeveeSpotify.bundle/vi.lproj/Localizable.strings +++ b/layout/Library/Application Support/EeveeSpotify.bundle/vi.lproj/Localizable.strings @@ -15,9 +15,6 @@ reset_data_description = "Xóa cache và khởi động lại app."; checking_for_update = "Đang kiểm tra bản cập nhật..."; update_available = "Đã có bản cập nhật mới"; -cancel = "Hủy"; -ok = "OK"; - // Patching do_not_patch_premium = "Không vá Premium"; diff --git a/layout/Library/Application Support/EeveeSpotify.bundle/zh-CN.lproj/Localizable.strings b/layout/Library/Application Support/EeveeSpotify.bundle/zh-CN.lproj/Localizable.strings index 6678234..585cac4 100644 --- a/layout/Library/Application Support/EeveeSpotify.bundle/zh-CN.lproj/Localizable.strings +++ b/layout/Library/Application Support/EeveeSpotify.bundle/zh-CN.lproj/Localizable.strings @@ -15,9 +15,6 @@ reset_data_description = "清除缓存数据并重新启动应用程序。"; checking_for_update = "正在检查更新..."; update_available = "发现可用更新"; -cancel = "取消"; -ok = "好的"; - // Patching do_not_patch_premium = "不启用 Premium 补丁"; diff --git a/layout/Library/Application Support/EeveeSpotify.bundle/zh-TW.lproj/Localizable.strings b/layout/Library/Application Support/EeveeSpotify.bundle/zh-TW.lproj/Localizable.strings index 3f38a73..9e218e3 100644 --- a/layout/Library/Application Support/EeveeSpotify.bundle/zh-TW.lproj/Localizable.strings +++ b/layout/Library/Application Support/EeveeSpotify.bundle/zh-TW.lproj/Localizable.strings @@ -15,9 +15,6 @@ reset_data_description = "清除快取並重新啟動Spotify."; checking_for_update = "正在檢查更新..."; update_available = "有可用的更新"; -cancel = "取消"; -ok = "確定"; - // 修補方案 do_not_patch_premium = "不修補Premium";