Skip to content

Commit

Permalink
wip search
Browse files Browse the repository at this point in the history
  • Loading branch information
Lee Jun Kit committed Jun 23, 2021
1 parent da11e3a commit 55dd838
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 15 deletions.
2 changes: 1 addition & 1 deletion Spottie/Backend/Types/API/SearchResultsResponse.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import Foundation

struct SearchResultsResponse: Decodable {
let albums: WebAPIPagingObject<WebAPISimplifiedAlbumObject>
let artists: WebAPIPagingObject<WebAPISimplifiedArtistObject>
let artists: WebAPIPagingObject<WebAPIArtistObject>
let tracks: WebAPIPagingObject<WebAPITrackObject>
let playlists: WebAPIPagingObject<WebAPIPlaylistObject>
}
10 changes: 10 additions & 0 deletions Spottie/Backend/Types/WebAPI/WebAPIArtistObject.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,20 @@
// 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

func getArtworkURL() -> URL {
if (self.images.isEmpty) {
return URL(string: "https://misc.scdn.co/liked-songs/liked-songs-640.png")!
}

return URL(string: self.images[0].url)!
}
}
8 changes: 8 additions & 0 deletions Spottie/Backend/Types/WebAPI/WebAPIPlaylistObject.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,12 @@ struct WebAPIPlaylistObject: Decodable {
var description: String?
var images: [WebAPIImageObject]
var tracks: WebAPIPlaylistTracksRefObject

func getArtworkURL() -> URL {
if (self.images.isEmpty) {
return URL(string: "https://misc.scdn.co/liked-songs/liked-songs-640.png")!
}

return URL(string: self.images[0].url)!
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,11 @@ struct WebAPISimplifiedAlbumObject: Codable {
var releaseDatePrecision: ReleaseDatePrecision
var totalTracks: Int

func getArtworkURL() -> URL? {
return URL(string: self.images[0].url)
func getArtworkURL() -> URL {
if (self.images.isEmpty) {
return URL(string: "https://misc.scdn.co/liked-songs/liked-songs-640.png")!
}

return URL(string: self.images[0].url)!
}
}
14 changes: 9 additions & 5 deletions Spottie/Views/Home.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ struct Home: View {

var body: some View {
GeometryReader { reader in
let numItemsToShow = numberOfItemsToShowInRow(reader)

ScrollView(.vertical) {
if searchText.isEmpty {
LazyVStack(alignment: .leading) {
Expand All @@ -35,7 +37,6 @@ struct Home: View {
)
.padding()
} else if vm.items.count > 0 {
let numItemsToShow = numberOfItemsToShowInRow(reader)
CarouselRow(
viewModel: vm,
onItemPressed: viewModel.load,
Expand All @@ -46,7 +47,10 @@ struct Home: View {
}
}
} else {
Search(viewModel: Search.ViewModel(searchTermPublisher: debouncedPublisher))
Search(
viewModel: Search.ViewModel(searchTermPublisher: debouncedPublisher),
numItemsPerRow: numItemsToShow
)
}
}
}
Expand Down Expand Up @@ -100,16 +104,16 @@ extension Home {
case let .album(album):
title = album.name
subtitle = album.artists[0].name
artworkURL = album.getArtworkURL()!
artworkURL = album.getArtworkURL()
case let .artist(artist):
title = artist.name
subtitle = "Artist"
artworkURL = URL(string: artist.images[0].url)!
artworkURL = artist.getArtworkURL()
artworkIsCircle = true
case let .playlist(playlist):
title = playlist.name
subtitle = playlist.description ?? ""
artworkURL = URL(string: playlist.images[0].url)!
artworkURL = playlist.getArtworkURL()
case let .link(link):
title = link.name
subtitle = ""
Expand Down
74 changes: 67 additions & 7 deletions Spottie/Views/Search.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,14 @@ import Combine

struct Search: View {
@StateObject var viewModel: ViewModel
var numItemsPerRow: Int

var body: some View {
ScrollView {
LazyVStack(alignment: .leading) {

LazyVStack(alignment: .leading) {
ForEach(viewModel.results) { vm in
CarouselRow(viewModel: vm, onItemPressed: { id in

}, numItemsToShow: numItemsPerRow)
}
}
}
Expand All @@ -24,7 +28,8 @@ extension Search {
// is to create a publisher from onChange of searchText
// https://rhonabwy.com/2021/02/07/integrating-swiftui-bindings-and-combine/
class ViewModel: ObservableObject {
@Published var results: SearchResultsResponse?
@Published var results: [CarouselRow.ViewModel] = []
private var cancellables = [AnyCancellable]()

init(searchTermPublisher: AnyPublisher<String, Never>) {
searchTermPublisher
Expand All @@ -35,15 +40,70 @@ extension Search {
}
.switchToLatest()
.receive(on: DispatchQueue.main)

.assign(to: &$results)
.sink { response in
if let r = response {
let artistsRow = CarouselRow.ViewModel(
id: "artists",
title: "Artists",
subtitle: nil,
items: r.artists.items.map { artist in
let id = artist.id
let title = artist.name
let artworkURL = artist.getArtworkURL()
return CarouselRowItem.ViewModel(
id: id,
title: title,
subtitle: "Artist",
artworkURL: artworkURL,
artworkIsCircle: true
)
})

let albumsRow = CarouselRow.ViewModel(
id: "albums",
title: "Albums",
subtitle: nil,
items: r.albums.items.map { album in
let id = album.id
let title = album.name
let subtitle = album.artists[0].name
let artworkURL = album.getArtworkURL()
return CarouselRowItem.ViewModel(
id: id,
title: title,
subtitle: subtitle,
artworkURL: artworkURL
)
})

let playlistsRow = CarouselRow.ViewModel(
id: "playlists",
title: "Playlists",
subtitle: nil,
items: r.playlists.items.map { playlist in
let id = playlist.id
let title = playlist.name
let subtitle = "\(playlist.tracks.total) tracks, by \(playlist.owner.displayName ?? "an unnamed user")"
let artworkURL = playlist.getArtworkURL()
return CarouselRowItem.ViewModel(
id: id,
title: title,
subtitle: subtitle,
artworkURL: artworkURL
)
})

self.results = [artistsRow, albumsRow, playlistsRow]
}
}
.store(in: &cancellables)
}
}
}

struct Search_Previews: PreviewProvider {
static let vm = Search.ViewModel(searchTermPublisher: Just("Hello").eraseToAnyPublisher())
static var previews: some View {
Search(viewModel: vm)
Search(viewModel: vm, numItemsPerRow: 4)
}
}

0 comments on commit 55dd838

Please sign in to comment.