diff --git a/App/Milkshake.dmg b/App/Milkshake.dmg index cf20b28..da878e1 100644 Binary files a/App/Milkshake.dmg and b/App/Milkshake.dmg differ diff --git a/Milkshake.xcodeproj/project.pbxproj b/Milkshake.xcodeproj/project.pbxproj index ec3c987..4b6dda0 100644 --- a/Milkshake.xcodeproj/project.pbxproj +++ b/Milkshake.xcodeproj/project.pbxproj @@ -59,6 +59,7 @@ 05D3421028A34D620039D620 /* Crypt.m in Sources */ = {isa = PBXBuildFile; fileRef = 05D3420F28A34D620039D620 /* Crypt.m */; }; 05D4F5EE217CEC4A00283085 /* milkshake.icns in Resources */ = {isa = PBXBuildFile; fileRef = 05D4F5ED217CEC4900283085 /* milkshake.icns */; }; 05D4F5F0217CEE5100283085 /* milkshake_512x512.png in Resources */ = {isa = PBXBuildFile; fileRef = 05D4F5EF217CEE5100283085 /* milkshake_512x512.png */; }; + 05E1929928A71DCE00E81970 /* VolumeSliderCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05E1929828A71DCE00E81970 /* VolumeSliderCell.swift */; }; 05ED20D51FCCFA4F00123317 /* API.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05ED20D41FCCFA4F00123317 /* API.swift */; }; 05ED20DF1FCD10B000123317 /* playing.gif in Resources */ = {isa = PBXBuildFile; fileRef = 05ED20DC1FCD10B000123317 /* playing.gif */; }; 05ED20E21FCD125C00123317 /* ResultsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05ED20E01FCD125C00123317 /* ResultsViewController.swift */; }; @@ -145,6 +146,7 @@ 05D3421128A34D840039D620 /* Crypt.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Crypt.h; sourceTree = ""; }; 05D4F5ED217CEC4900283085 /* milkshake.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = milkshake.icns; sourceTree = ""; }; 05D4F5EF217CEE5100283085 /* milkshake_512x512.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = milkshake_512x512.png; sourceTree = ""; }; + 05E1929828A71DCE00E81970 /* VolumeSliderCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VolumeSliderCell.swift; sourceTree = ""; }; 05ED20D41FCCFA4F00123317 /* API.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = API.swift; sourceTree = ""; }; 05ED20DC1FCD10B000123317 /* playing.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = playing.gif; sourceTree = ""; }; 05ED20E01FCD125C00123317 /* ResultsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultsViewController.swift; sourceTree = ""; }; @@ -323,6 +325,7 @@ 05ED20E61FCD2FBD00123317 /* SearchTableCellView.swift */, 05ED20E81FCD2FE200123317 /* SearchTableCellView.xib */, 059A061F200DC7ED003C81F1 /* SpectrumAnalyzerView.swift */, + 05E1929828A71DCE00E81970 /* VolumeSliderCell.swift */, ); name = views; sourceTree = ""; @@ -395,7 +398,7 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0810; - LastUpgradeCheck = 0910; + LastUpgradeCheck = 1250; ORGANIZATIONNAME = "Dean Liu"; TargetAttributes = { 48F749421FCCEBD000F0A853 = { @@ -545,6 +548,7 @@ 054A31171FF5D5B10022D06E /* HeaderTableCellView.swift in Sources */, 05ED21131FD6ED8F00123317 /* MusicItem.swift in Sources */, 05A57E692010E90F00B8FBCB /* NSBezierPath+CGPath.swift in Sources */, + 05E1929928A71DCE00E81970 /* VolumeSliderCell.swift in Sources */, 48F749491FCCEBD000F0A853 /* MainViewController.swift in Sources */, 054130351FE01EBA0067DCFE /* PlayerButton.swift in Sources */, 48F749581FCCECBD00F0A853 /* RoundView.swift in Sources */, @@ -605,6 +609,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; @@ -614,6 +619,7 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; @@ -621,8 +627,10 @@ CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -661,6 +669,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; @@ -670,6 +679,7 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; @@ -677,8 +687,10 @@ CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -715,7 +727,7 @@ CODE_SIGN_IDENTITY = "Mac Developer"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - DEVELOPMENT_TEAM = ""; + DEVELOPMENT_TEAM = S9FKV88H43; ENABLE_HARDENED_RUNTIME = YES; INFOPLIST_FILE = Milkshake/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; @@ -739,7 +751,7 @@ CODE_SIGN_IDENTITY = "Mac Developer"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - DEVELOPMENT_TEAM = ""; + DEVELOPMENT_TEAM = S9FKV88H43; ENABLE_HARDENED_RUNTIME = YES; INFOPLIST_FILE = Milkshake/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; diff --git a/Milkshake.xcodeproj/xcuserdata/dean.xcuserdatad/xcschemes/Milkshake.xcscheme b/Milkshake.xcodeproj/xcuserdata/dean.xcuserdatad/xcschemes/Milkshake.xcscheme index d865996..0c8b13e 100644 --- a/Milkshake.xcodeproj/xcuserdata/dean.xcuserdatad/xcschemes/Milkshake.xcscheme +++ b/Milkshake.xcodeproj/xcuserdata/dean.xcuserdatad/xcschemes/Milkshake.xcscheme @@ -1,6 +1,6 @@ + BreakpointExtensionID = "Xcode.Breakpoint.RuntimeIssueBreakpoint"> + breakpointStackSelectionBehavior = "1" + type = "4"> - - - - diff --git a/Milkshake/API.swift b/Milkshake/API.swift index ee63047..1652f54 100644 --- a/Milkshake/API.swift +++ b/Milkshake/API.swift @@ -88,15 +88,17 @@ class API: NSObject { } let rv = responseValue as! [String: AnyObject] - if (rv["errorCode"] as? Int) == 1001 { + if (rv["errorCode"] as? Int ?? 0) == 1001 { print("Token needs to be refreshed!!") self.X_AuthToken = "" if let dictionary = Locksmith.loadDataForUserAccount(userAccount: "Milkshake") { let username = dictionary["username"] as! String let password = dictionary["password"] as! String - self.auth(username: username, pass: password) { responseDict in - self.X_AuthToken = responseDict["authToken"] as? String; + + self.authPartnerAndUser(username: username, password: password) { responseDict in + self.X_AuthToken = responseDict["result"]!["userAuthToken"] as? String; + // Clear the station queues because they're all expired if url.hasSuffix("annotateObjectsSimple") { print("Clearing out... trying again") @@ -141,30 +143,19 @@ class API: NSObject { print(self.cookies) } - - func auth(username:String, pass:String, callbackHandler:@escaping(_ Dictionary:[String:AnyObject]) -> ()) { - let parameters: [String: Any] = [ - "existingAuthToken": "", - "username": username, - "password": pass, - "keepLoggedIn": NSNumber(value: true) - ] - let url: String = "\(Constants.pandoraApiUrlV1)/auth/login" - self.request(url, params: parameters, callbackHandler: callbackHandler) - } - - func auth(username:String, token:String, callbackHandler:@escaping(_ Dictionary:[String:AnyObject]) -> ()) { - let params: [String: Any] = [ - "existingAuthToken": token, - "username": username, - "password": "", - "keepLoggedIn": true - ] - let url: String = "\(Constants.pandoraApiUrlV1)/auth/login" - self.request(url, params: params, callbackHandler: callbackHandler) + func authPartnerAndUser(username:String, password:String, callbackHandler:@escaping(_ Dictionary:[String:AnyObject]) ->()){ + + self._partnerAuthPartnerLogin() { responseDict in + let partnerAuthToken = responseDict["result"]!["partnerAuthToken"] as! String + let partnerId = responseDict["result"]!["partnerId"] as! String + let syncTimeEnc = responseDict["result"]!["syncTime"] as! String + let syncTime = PandoraDecryptTime(syncTimeEnc, Constants.decryptPassword) + + self._partnerAuthUserLogin(username: username, password: password, partnerAuthToken: partnerAuthToken, partnerId: partnerId, syncTime: syncTime, callbackHandler: callbackHandler) + } } - func partnerAuthPartnerLogin(callbackHandler:@escaping(_ Dictionary:[String:AnyObject]) ->()){ + func _partnerAuthPartnerLogin(callbackHandler:@escaping(_ Dictionary:[String:AnyObject]) ->()){ let params: [String: String] = [ "username": Constants.username, "password": Constants.password, @@ -176,7 +167,7 @@ class API: NSObject { self.requestTuner(url, params: params, encrypted: false, callbackHandler: callbackHandler) } - func partnerAuthUserLogin(username:String, password:String, partnerAuthToken:String, partnerId:String, syncTime:Int, callbackHandler:@escaping(_ Dictionary:[String:AnyObject]) ->()){ + func _partnerAuthUserLogin(username:String, password:String, partnerAuthToken:String, partnerId:String, syncTime:Int, callbackHandler:@escaping(_ Dictionary:[String:AnyObject]) ->()){ let params: [String: Any] = [ "loginType": "user", "username": username, @@ -194,6 +185,12 @@ class API: NSObject { self.requestTuner(urlParams.url!.absoluteString, params: params, encrypted: true, callbackHandler: callbackHandler) } + func billingInfo(callbackHandler:@escaping(_ Dictionary:[String:AnyObject]) -> ()) { + let url: String = "\(Constants.pandoraApiUrlV1)/billing/infoV2" + let params: [String: Any] = [:] + self.request(url, params: params, callbackHandler: callbackHandler) + } + func playbackResumed(forceActive:Bool, callbackHandler:@escaping(_ Dictionary:[String:AnyObject]) -> ()) { let params: [String: Any] = [ "forceActive": true diff --git a/Milkshake/AppDelegate.swift b/Milkshake/AppDelegate.swift index b6e5c30..aa4405d 100644 --- a/Milkshake/AppDelegate.swift +++ b/Milkshake/AppDelegate.swift @@ -244,20 +244,20 @@ class AppDelegate: NSObject, NSApplicationDelegate, LoginProtocol { func handleSuccessLogin(results: Dictionary) { let authToken = results["userAuthToken"] as! String self.listenerId = results["userId"] as! String -// self.isPremium = (config["branding"] as! String).lowercased() == "pandorapremium" -// self.listenerId = results["listenerId"] as! String - - if self.isPremium == false { - self.menuArtists.isHidden = true - self.menuPlaylist.isHidden = true - } - // Setting + let defaults = UserDefaults.standard defaults.set(authToken, forKey: "authToken") self.api.X_AuthToken = authToken - print ("x auth token....") - print(self.api.X_AuthToken!) - self.launchMain() + + self.api.billingInfo() { results in + self.isPremium = ((results["activeProduct"]?["productTier"] as? String) ?? "").lowercased() == "pandora_premium" + if self.isPremium == false { + self.menuArtists.isHidden = true + self.menuPlaylist.isHidden = true + self.menuShuffle.isHidden = true + } + self.launchMain() + } } func isRadio() -> Bool { diff --git a/Milkshake/Base.lproj/Main.storyboard b/Milkshake/Base.lproj/Main.storyboard index 53b608c..ee0ed2e 100644 --- a/Milkshake/Base.lproj/Main.storyboard +++ b/Milkshake/Base.lproj/Main.storyboard @@ -1,8 +1,8 @@ - + - + @@ -652,7 +652,7 @@