Skip to content

Commit

Permalink
wip: player bottom bar, mock working progress slider
Browse files Browse the repository at this point in the history
  • Loading branch information
Lee Jun Kit committed May 27, 2021
1 parent b1e3ed6 commit 36cce78
Show file tree
Hide file tree
Showing 46 changed files with 906 additions and 73 deletions.
267 changes: 265 additions & 2 deletions Spottie.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"object": {
"pins": [
{
"package": "SDWebImage",
"repositoryURL": "https://github.com/SDWebImage/SDWebImage.git",
"state": {
"branch": null,
"revision": "76dd4b49110b8624317fc128e7fa0d8a252018bc",
"version": "5.11.1"
}
},
{
"package": "SDWebImageSwiftUI",
"repositoryURL": "https://github.com/SDWebImage/SDWebImageSwiftUI",
"state": {
"branch": null,
"revision": "cd8625b7cf11a97698e180d28bb7d5d357196678",
"version": "2.0.2"
}
}
]
},
"version": 1
}
28 changes: 28 additions & 0 deletions Spottie/Backend/EventBroker.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,31 @@
//

import Foundation
import Combine

class EventBroker : ObservableObject {
private let websocketClient = WebsocketClient(url: URL(string: "ws://localhost:24879/events")!)
private var cancellables = [AnyCancellable]()
private let decoder = JSONDecoder()

let onEventReceived = PassthroughSubject<SpotifyEvent, Never>()

init() {
websocketClient
.onMessageReceived
.receive(on: DispatchQueue.main)
.print()
.sink { [weak self] message in
do {
guard let self = self else {
return;
}
let data = message.data(using: .utf8)!
let event = try self.decoder.decode(SpotifyEvent.self, from: data)
self.onEventReceived.send(event)
} catch let error {
print(error)
}
}.store(in: &cancellables)
}
}
31 changes: 30 additions & 1 deletion Spottie/Backend/HTTPClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,35 @@
// Spottie
//
// Created by Lee Jun Kit on 20/5/21.
//
// https://www.vadimbulavin.com/modern-networking-in-swift-5-with-urlsession-combine-framework-and-codable/

import Foundation
import Combine

struct HTTPClient {
struct Response<T> {
let value: T?
let response: URLResponse
}

func run<T: Decodable>(_ request: URLRequest, _ decoder: JSONDecoder = JSONDecoder()) -> AnyPublisher<Response<T>, Error> {
return URLSession.shared
.dataTaskPublisher(for: request)
.tryMap { result -> Response<T> in
let response = result.response as! HTTPURLResponse
let contentType = response.allHeaderFields["Content-Type"] as? String
print(response.allHeaderFields)

if let contentType = contentType {
if contentType.contains("application/json") {
let value = try decoder.decode(T.self, from: result.data)
return Response(value: value, response: result.response)
}
}

return Response(value: nil, response: result.response)
}
.receive(on: DispatchQueue.main)
.eraseToAnyPublisher()
}
}
39 changes: 39 additions & 0 deletions Spottie/Backend/SpotifyAPI.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,42 @@
//

import Foundation
import Combine

enum SpotifyAPI {
static let client = HTTPClient()
static let base = URL(string: "http://localhost:24879")!
}

extension SpotifyAPI {
static func currentPlayerState() -> AnyPublisher<CurrentlyPlayingContextObject?, Error> {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase;
let req = URLRequest(url: base.appendingPathComponent("/web-api/v1/me/player"))
return client.run(req, decoder).map(\.value).eraseToAnyPublisher()
}

static func pause() -> AnyPublisher<Nothing?, Error> {
var req = URLRequest(url: base.appendingPathComponent("/player/pause"))
req.httpMethod = "POST"
return client.run(req).map(\.value).eraseToAnyPublisher()
}

static func resume() -> AnyPublisher<Nothing?, Error> {
var req = URLRequest(url: base.appendingPathComponent("/player/resume"))
req.httpMethod = "POST"
return client.run(req).print().map(\.value).eraseToAnyPublisher()
}

static func previousTrack() -> AnyPublisher<Nothing?, Error> {
var req = URLRequest(url: base.appendingPathComponent("/player/prev"))
req.httpMethod = "POST"
return client.run(req).print().map(\.value).eraseToAnyPublisher()
}

static func nextTrack() -> AnyPublisher<Nothing?, Error> {
var req = URLRequest(url: base.appendingPathComponent("/player/next"))
req.httpMethod = "POST"
return client.run(req).print().map(\.value).eraseToAnyPublisher()
}
}
12 changes: 10 additions & 2 deletions Spottie/Backend/Types/API/CurrentlyPlayingContextObject.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,16 @@
// Created by Lee Jun Kit on 23/5/21.
//

struct CurrentPlayerStateResponse: Codable {
enum RepeatState: String, Codable {
case off
case track
case context
}

struct CurrentlyPlayingContextObject: Codable {
var isPlaying: Bool
var shuffleState: Bool

var repeatState: RepeatState
var progressMs: Int
var item: WebAPITrackObject
}
2 changes: 1 addition & 1 deletion Spottie/Backend/Types/Base/AlbumObject.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
struct AlbumObject: Codable {
var gid: String
var name: String
var artist: ArtistObject
var artist: [ArtistObject]
var label: String
var date: DateObject
var coverGroup: CoverGroupObject
Expand Down
5 changes: 5 additions & 0 deletions Spottie/Backend/Types/Base/CoverGroupObject.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@
//
// Created by Lee Jun Kit on 22/5/21.
//
import Foundation

struct CoverGroupObject: Codable {
var image: [ImageObject]
func getArtworkURL() -> URL? {
let fileId = self.image[0].fileId.lowercased()
return URL(string: "https://i.scdn.co/image/\(fileId)")
}
}
4 changes: 2 additions & 2 deletions Spottie/Backend/Types/Base/TrackObject.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ struct TrackObject: Codable {
var gid: String
var name: String
var album: AlbumObject
var artist: ArtistObject
var artist: [ArtistObject]
var number: Int
var discNumber: Int
var duration: Int
var popularity: Int
var popularity: Int
}
8 changes: 7 additions & 1 deletion Spottie/Backend/Types/Base/WebAPIArtistObject.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,10 @@
// Created by Lee Jun Kit on 24/5/21.
//

import Foundation
struct WebAPIArtistObject: Codable {
var id: String
var uri: String
var name: String
var images: [WebAPIImageObject]
var popularity: Int
}
6 changes: 5 additions & 1 deletion Spottie/Backend/Types/Base/WebAPIImageObject.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,8 @@
// Created by Lee Jun Kit on 24/5/21.
//

import Foundation
struct WebAPIImageObject: Codable {
var url: String
var width: Int?
var height: Int?
}
28 changes: 27 additions & 1 deletion Spottie/Backend/Types/Base/WebAPISimplifiedAlbumObject.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,32 @@
// Created by Lee Jun Kit on 24/5/21.
//

struct WebAPISimplifiedArtistObject: Codable {
import Foundation

enum AlbumType: String, Codable {
case album
case single
case compilation
}

enum ReleaseDatePrecision: String, Codable {
case year
case month
case day
}

struct WebAPISimplifiedAlbumObject: Codable {
var id: String
var uri: String
var albumType: AlbumType
var artists: [WebAPISimplifiedArtistObject]
var images: [WebAPIImageObject]
var name: String
var releaseDate: String
var releaseDatePrecision: ReleaseDatePrecision
var totalTracks: Int

func getArtworkURL() -> URL? {
return URL(string: self.images[0].url)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,8 @@
// Created by Lee Jun Kit on 24/5/21.
//

import Foundation
struct WebAPISimplifiedArtistObject: Codable {
var id: String
var uri: String
var name: String
}
13 changes: 12 additions & 1 deletion Spottie/Backend/Types/Base/WebAPITrackObject.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,15 @@
// Created by Lee Jun Kit on 24/5/21.
//

import Foundation
struct WebAPITrackObject: Codable {
var id: String
var uri: String
var album: WebAPISimplifiedAlbumObject
var artists: [WebAPISimplifiedArtistObject]
var durationMs: Int
var explicit: Bool
var name: String
var popularity: Int
var discNumber: Int
var trackNumber: Int
}
4 changes: 3 additions & 1 deletion Spottie/Backend/Types/Events/ContextChangedEvent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@
// Created by Lee Jun Kit on 22/5/21.
//

import Foundation
struct ContextChangedEvent: Codable {
var uri: String
}
4 changes: 3 additions & 1 deletion Spottie/Backend/Types/Events/InactiveSessionEvent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@
// Created by Lee Jun Kit on 22/5/21.
//

import Foundation
struct InactiveSessionEvent: Codable {
var timeout: Bool
}
4 changes: 3 additions & 1 deletion Spottie/Backend/Types/Events/MetadataAvailableEvent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@
// Created by Lee Jun Kit on 22/5/21.
//

import Foundation
struct MetadataAvailableEvent: Codable {
var track: TrackObject
}
4 changes: 3 additions & 1 deletion Spottie/Backend/Types/Events/PlaybackPausedEvent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@
// Created by Lee Jun Kit on 22/5/21.
//

import Foundation
struct PlaybackPausedEvent: Codable {
var trackTime: Int
}
4 changes: 3 additions & 1 deletion Spottie/Backend/Types/Events/PlaybackResumedEvent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@
// Created by Lee Jun Kit on 22/5/21.
//

import Foundation
struct PlaybackResumedEvent: Codable {
var trackTime: Int
}
5 changes: 4 additions & 1 deletion Spottie/Backend/Types/Events/TrackChangedEvent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,7 @@
// Created by Lee Jun Kit on 22/5/21.
//

import Foundation
struct TrackChangedEvent: Codable {
var uri: String
var track: TrackObject?
}
4 changes: 3 additions & 1 deletion Spottie/Backend/Types/Events/TrackSeekedEvent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@
// Created by Lee Jun Kit on 22/5/21.
//

import Foundation
struct TrackSeekedEvent: Codable {
var trackTime: Int
}
4 changes: 3 additions & 1 deletion Spottie/Backend/Types/Events/VolumeChangedEvent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@
// Created by Lee Jun Kit on 22/5/21.
//

import Foundation
struct VolumeChangedEvent: Codable {
var value: Float
}
4 changes: 3 additions & 1 deletion Spottie/Backend/Types/Nothing.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@
// Created by Lee Jun Kit on 20/5/21.
//

import Foundation
struct Nothing: Codable {

}
Loading

0 comments on commit 36cce78

Please sign in to comment.