Skip to content

Commit

Permalink
make artists row circular
Browse files Browse the repository at this point in the history
  • Loading branch information
Lee Jun Kit committed Jun 18, 2021
1 parent 3a186da commit 76d1a16
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 23 deletions.
25 changes: 15 additions & 10 deletions Spottie/Backend/SpotifyAPI.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ extension SpotifyAPI {

var req = URLRequest(url: urlComponents.url!)
req.httpMethod = "POST"
return client.run(req).print().map(\.value).eraseToAnyPublisher()
return client.run(req).map(\.value).eraseToAnyPublisher()
}

static func togglePlayPause() -> AnyPublisher<Nothing?, Error> {
Expand All @@ -49,19 +49,19 @@ extension SpotifyAPI {
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()
return client.run(req).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()
return client.run(req).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()
return client.run(req).map(\.value).eraseToAnyPublisher()
}

static func seek(posMs: Int) -> AnyPublisher<Nothing?, Error> {
Expand All @@ -71,7 +71,7 @@ extension SpotifyAPI {

var req = URLRequest(url: urlComponents.url!)
req.httpMethod = "POST"
return client.run(req).print().map(\.value).eraseToAnyPublisher()
return client.run(req).map(\.value).eraseToAnyPublisher()
}

static func setVolume(volumePercent: Float) -> AnyPublisher<Nothing?, Error> {
Expand All @@ -82,7 +82,7 @@ extension SpotifyAPI {

var req = URLRequest(url: urlComponents.url!)
req.httpMethod = "POST"
return client.run(req).print().map(\.value).eraseToAnyPublisher()
return client.run(req).map(\.value).eraseToAnyPublisher()
}

static func setShuffle(shuffle: Bool) -> AnyPublisher<Nothing?, Error> {
Expand All @@ -92,7 +92,7 @@ extension SpotifyAPI {

var req = URLRequest(url: urlComponents.url!)
req.httpMethod = "POST"
return client.run(req).print().map(\.value).eraseToAnyPublisher()
return client.run(req).map(\.value).eraseToAnyPublisher()
}

static func setRepeatMode(mode: RepeatMode) -> AnyPublisher<Nothing?, Error> {
Expand All @@ -102,12 +102,17 @@ extension SpotifyAPI {

var req = URLRequest(url: urlComponents.url!)
req.httpMethod = "POST"
return client.run(req).print().map(\.value).eraseToAnyPublisher()
return client.run(req).map(\.value).eraseToAnyPublisher()
}

static func getPersonalizedRecommendations() -> AnyPublisher<PersonalizedRecommendationsResponse?, Error> {
// get the current date
let date = Date()
let formatter = ISO8601DateFormatter()
formatter.formatOptions.insert(.withFractionalSeconds)

let queryItems = [
URLQueryItem(name: "timestamp", value: "2021-06-07T10:54:29.467Z"),
URLQueryItem(name: "timestamp", value: formatter.string(from: date)),
URLQueryItem(name: "platform", value: "web"),
URLQueryItem(name: "content_limit", value: "10"),
URLQueryItem(name: "limit", value: "20"),
Expand All @@ -129,6 +134,6 @@ extension SpotifyAPI {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase;

return client.run(req, decoder).print().map(\.value).eraseToAnyPublisher()
return client.run(req, decoder).map(\.value).eraseToAnyPublisher()
}
}
1 change: 1 addition & 0 deletions Spottie/Backend/Types/API/RecommendationGroup.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import Foundation
struct RecommendationGroup: Decodable, Hashable, Identifiable {
var id: String
var name: String
var tagline: String?
var rendering: String
var items: [RecommendationItem]

Expand Down
30 changes: 23 additions & 7 deletions Spottie/Views/Carousel/CarouselRow.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,17 @@ struct CarouselRow: View {
Text(viewModel.title)
.font(.title)
.padding(.leading)
Text(viewModel.subtitle)
.font(.body)
.foregroundColor(.secondary)
.padding(.leading)
.padding(.bottom, 8)
viewModel.subtitle.map({
Text($0)
.font(.body)
.foregroundColor(.secondary)
.padding(.leading)
.padding(.bottom, 8)
})
HStack(alignment: .top, spacing: 40) {
ForEach(viewModel.items) { item in
CarouselRowItem(viewModel: CarouselRowItem.ViewModel.init(item))
let vm = CarouselRowItem.ViewModel.init(item, artworkIsCircular: viewModel.renderMode == .circular)
CarouselRowItem(viewModel: vm)
.onTapGesture {
viewModel.onItemPressed(item.id)
}
Expand All @@ -33,16 +36,29 @@ struct CarouselRow: View {
}

extension CarouselRow {
enum RenderMode {
case circular
case normal
}

class ViewModel: ObservableObject {
@Published var renderMode: RenderMode
@Published var title: String
@Published var subtitle = "Unwind with these calming playlists."
@Published var subtitle: String?
@Published var items: [RecommendationItem]
let onItemPressed: (String) -> Void

init(_ recommendationGroup: RecommendationGroup, numberOfItemsToShow: Int, onItemPressed: @escaping (String) -> Void) {
self.onItemPressed = onItemPressed

title = recommendationGroup.name
subtitle = recommendationGroup.tagline

if (recommendationGroup.id == "home-personalized[favorite-artists]") {
renderMode = .circular
} else {
renderMode = .normal
}

let numItems = recommendationGroup.items.count
if (numItems < numberOfItemsToShow) {
Expand Down
24 changes: 18 additions & 6 deletions Spottie/Views/Carousel/CarouselRowItem.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,19 @@ struct CarouselRowItem: View {

var body: some View {
VStack(alignment: .leading) {
WebImage(url: viewModel.artworkURL)
.resizable()
.aspectRatio(1.0, contentMode: .fill)
.cornerRadius(5)
if viewModel.artworkIsCircle {
WebImage(url: viewModel.artworkURL)
.resizable()
.aspectRatio(1.0, contentMode: .fill)
.clipShape(Circle())
.overlay(Circle().stroke(Color.white, lineWidth: 4.0))
.shadow(radius: 7)
} else {
WebImage(url: viewModel.artworkURL)
.resizable()
.aspectRatio(1.0, contentMode: .fill)
.cornerRadius(5)
}
Text(viewModel.title)
.lineLimit(1)
.foregroundColor(.primary)
Expand Down Expand Up @@ -44,8 +53,11 @@ extension CarouselRowItem {
@Published var subtitle: String
@Published var artworkURL: URL
@Published var isHovering = false
@Published var artworkIsCircle = false

init(_ item: RecommendationItem) {
init(_ item: RecommendationItem, artworkIsCircular: Bool) {
artworkIsCircle = artworkIsCircular

if let data = item.data {
switch data {
case let .album(album):
Expand All @@ -54,7 +66,7 @@ extension CarouselRowItem {
self.artworkURL = album.getArtworkURL()!
case let .artist(artist):
self.title = artist.name
self.subtitle = artist.name
self.subtitle = "Artist"
self.artworkURL = URL(string: artist.images[0].url)!
case let.playlist(playlist):
self.title = playlist.name
Expand Down

0 comments on commit 76d1a16

Please sign in to comment.