Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#162 - Handle favoriting an artist from search results #167

Merged
merged 1 commit into from
Mar 15, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
//
// ArtistsSearchResultsViewController.swift
// Relisten
//
// Created by Chris Paine on 3/14/19.
// Copyright © 2019 Alec Gorge. All rights reserved.
//

import UIKit
import RelistenShared

import AsyncDisplayKit

class ArtistsSearchResultsViewController: RelistenTableViewController<Any> {
public var favoriteArtists: [UUID]!
public var filteredArtists: [ArtistWithCounts] = [] {
didSet {
DispatchQueue.main.async {
self.tableNode.reloadData()
}
}
}

// MARK: UITableViewDataSource

override func numberOfSections(in tableNode: ASTableNode) -> Int {
return filteredArtists.isEmpty ? 0 : 1
}

override func tableNode(_ tableNode: ASTableNode, numberOfRowsInSection section: Int) -> Int {
return filteredArtists.count
}

func tableNode(_ tableNode: ASTableNode, nodeBlockForRowAt indexPath: IndexPath) -> ASCellNodeBlock {
if let artist = filteredArtists.objectAtIndexIfInBounds(indexPath.row) {
return { ArtistCellNode(artist: artist, withFavoritedArtists: self.favoriteArtists) }
} else {
fatalError("Couldn't get an artist at \(indexPath)")
}
}
}
256 changes: 110 additions & 146 deletions Apps/Relisten/View Controllers/ArtistsViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,9 @@ class ArtistsViewController: RelistenTableViewController<[ArtistWithCounts]>, AS
public var resourceRecentlyPerformed: Resource? = nil
public let resourceRecentlyUpdated: Resource

public var filteredArtists: [ArtistWithCounts] = []
let searchController: UISearchController = UISearchController(searchResultsController: nil)
let searchController: UISearchController!
private let resultsViewController: ArtistsSearchResultsViewController = ArtistsSearchResultsViewController(useCache: true, refreshOnAppear: true)

private let tableUpdateQueue = DispatchQueue(label: "net.relisten.groupedViewController.queue")

public init() {
Expand All @@ -59,6 +60,8 @@ class ArtistsViewController: RelistenTableViewController<[ArtistWithCounts]>, AS

resourceRecentlyUpdated = RelistenApi.recentlyUpdated()

searchController = UISearchController(searchResultsController: resultsViewController)

super.init(useCache: true, refreshOnAppear: true)

recentShowsNode.collectionNode.delegate = self
Expand All @@ -84,6 +87,8 @@ class ArtistsViewController: RelistenTableViewController<[ArtistWithCounts]>, AS
searchController.searchBar.barTintColor = AppColors.textOnPrimary
searchController.searchBar.tintColor = AppColors.textOnPrimary

resultsViewController.tableNode.delegate = self

navigationItem.searchController = searchController
definesPresentationContext = true
}
Expand Down Expand Up @@ -174,9 +179,7 @@ class ArtistsViewController: RelistenTableViewController<[ArtistWithCounts]>, AS
DispatchQueue.main.async {
self.offlineShows = shows
self.offlineShowsNode.shows = self.offlineShows.map({ ($0.show, $0.artist, $0.source) })
if self.isFiltering() == false {
self.tableNode.reloadSections([ Sections.availableOffline.rawValue ], with: .automatic)
}
self.tableNode.reloadSections([ Sections.availableOffline.rawValue ], with: .automatic)
}
}
}
Expand All @@ -186,9 +189,7 @@ class ArtistsViewController: RelistenTableViewController<[ArtistWithCounts]>, AS
DispatchQueue.main.async {
self.favoriteShows = shows
self.favoritedSourcesNode.shows = self.favoriteShows.map({ ($0.show, $0.artist, $0.source) })
if self.isFiltering() == false {
self.tableNode.reloadSections([ Sections.favoritedShows.rawValue ], with: .automatic)
}
self.tableNode.reloadSections([ Sections.favoritedShows.rawValue ], with: .automatic)
}
}
}
Expand All @@ -199,9 +200,7 @@ class ArtistsViewController: RelistenTableViewController<[ArtistWithCounts]>, AS

if let recentShows = self.recentlyPlayedTracks?.asTracks().map({ ($0.showInfo.show, $0.showInfo.artist, $0.showInfo.source) }) as [(show: Show, artist: Artist?, source: Source?)]? {
self.recentShowsNode.shows = recentShows
if self.isFiltering() == false {
self.tableNode.reloadSections([ Sections.recentlyPlayed.rawValue ], with: .automatic)
}
self.tableNode.reloadSections([ Sections.recentlyPlayed.rawValue ], with: .automatic)
}
}
}
Expand All @@ -215,45 +214,43 @@ class ArtistsViewController: RelistenTableViewController<[ArtistWithCounts]>, AS

let newFavoriteCount = localFavoriteArtists.count

if s.isFiltering() == false {
switch changes {
case .initial:
s.tableNode.performBatch(animated: true, updates: {
s.favoriteArtists = localFavoriteArtists
s.tableNode.reloadSections(IndexSet(integer: Sections.favorited.rawValue), with: .automatic)
}, completion: nil)
case .update(_, let deletions, let insertions, let modifications):
s.tableNode.performBatch(animated: true, updates: {
s.tableNode.insertRows(at: insertions.map({ IndexPath(row: $0, section: Sections.favorited.rawValue) }),
with: .automatic)
s.tableNode.deleteRows(at: deletions.map({ IndexPath(row: $0, section: Sections.favorited.rawValue)}),
with: .automatic)
s.tableNode.reloadRows(at: modifications.map({ IndexPath(row: $0, section: Sections.favorited.rawValue) }),
with: .automatic)

s.favoriteArtists = localFavoriteArtists

if newFavoriteCount == 0 {
s.tableNode.deleteRows(at: (0..<s.recentlyPerformedShows.count).map( { IndexPath(row: $0, section: Sections.recentlyPerformed.rawValue) }), with: .automatic)
s.tableNode.reloadSections(IndexSet(integer: Sections.recentlyPerformed.rawValue), with: .automatic)

s.resourceRecentlyPerformed = nil
s.recentlyPerformedShows = []
s.recentlyPerformedNode.shows = []
}
else {
s.resourceRecentlyPerformed = RelistenApi.recentlyPerformed(byArtists: s.favoriteArtists)
s.resourceRecentlyPerformed?.addObserver(s)
s.resourceRecentlyPerformed?.loadFromCacheThenUpdate()
}
switch changes {
case .initial:
s.tableNode.performBatch(animated: true, updates: {
s.favoriteArtists = localFavoriteArtists
s.tableNode.reloadSections(IndexSet(integer: Sections.favorited.rawValue), with: .automatic)
}, completion: nil)
case .update(_, let deletions, let insertions, let modifications):
s.tableNode.performBatch(animated: true, updates: {
s.tableNode.insertRows(at: insertions.map({ IndexPath(row: $0, section: Sections.favorited.rawValue) }),
with: .automatic)
s.tableNode.deleteRows(at: deletions.map({ IndexPath(row: $0, section: Sections.favorited.rawValue)}),
with: .automatic)
s.tableNode.reloadRows(at: modifications.map({ IndexPath(row: $0, section: Sections.favorited.rawValue) }),
with: .automatic)

s.favoriteArtists = localFavoriteArtists

if newFavoriteCount == 0 {
s.tableNode.deleteRows(at: (0..<s.recentlyPerformedShows.count).map( { IndexPath(row: $0, section: Sections.recentlyPerformed.rawValue) }), with: .automatic)
s.tableNode.reloadSections(IndexSet(integer: Sections.recentlyPerformed.rawValue), with: .automatic)

if previousFavoriteCount == 0, newFavoriteCount > 0 {
s.tableNode.reloadSections(IndexSet(integer: Sections.favorited.rawValue), with: .automatic)
}
}, completion: nil)
case .error(let error):
fatalError(error.localizedDescription)
}
s.resourceRecentlyPerformed = nil
s.recentlyPerformedShows = []
s.recentlyPerformedNode.shows = []
}
else {
s.resourceRecentlyPerformed = RelistenApi.recentlyPerformed(byArtists: s.favoriteArtists)
s.resourceRecentlyPerformed?.addObserver(s)
s.resourceRecentlyPerformed?.loadFromCacheThenUpdate()
}

if previousFavoriteCount == 0, newFavoriteCount > 0 {
s.tableNode.reloadSections(IndexSet(integer: Sections.favorited.rawValue), with: .automatic)
}
}, completion: nil)
case .error(let error):
fatalError(error.localizedDescription)
}
}
}
Expand All @@ -270,11 +267,11 @@ class ArtistsViewController: RelistenTableViewController<[ArtistWithCounts]>, AS

func filterContentForSearchText(_ searchText: String) {
let searchTextLC = searchText.lowercased()

resultsViewController.favoriteArtists = favoriteArtists

tableUpdateQueue.async {
self.filteredArtists = self.allArtists.filter({ $0.name.lowercased().contains(searchTextLC) })
DispatchQueue.main.async {
self.tableNode.reloadData()
}
self.resultsViewController.filteredArtists = self.allArtists.filter({ $0.name.lowercased().contains(searchTextLC) })
}
}

Expand All @@ -299,16 +296,12 @@ class ArtistsViewController: RelistenTableViewController<[ArtistWithCounts]>, AS
if resource == self.resourceRecentlyPerformed {
self.recentlyPerformedShows = resource.typedContent(ifNone: [])
self.recentlyPerformedNode.shows = self.recentlyPerformedShows.map { (show: $0, artist: $0.artist, nil) }
if self.isFiltering() == false {
self.tableNode.reloadSections([ Sections.recentlyPerformed.rawValue ], with: .automatic)
}
self.tableNode.reloadSections([ Sections.recentlyPerformed.rawValue ], with: .automatic)
}
else if resource == self.resourceRecentlyUpdated {
self.allRecentlyUpdatedShows = resource.typedContent(ifNone: [])
self.allRecentlyUpdatedNode.shows = self.allRecentlyUpdatedShows.map { (show: $0, artist: $0.artist, nil) }
if self.isFiltering() == false {
self.tableNode.reloadSections([ Sections.allRecentlyUpdated.rawValue ], with: .automatic)
}
self.tableNode.reloadSections([ Sections.allRecentlyUpdated.rawValue ], with: .automatic)
}
}
}
Expand All @@ -322,105 +315,80 @@ class ArtistsViewController: RelistenTableViewController<[ArtistWithCounts]>, AS
// MARK: UITableViewDataSource

override public func numberOfSections(in tableNode: ASTableNode) -> Int {
if isFiltering() {
return 1
} else {
return Sections.count.rawValue
}
return Sections.count.rawValue
}

override public func tableNode(_ tableNode: ASTableNode, numberOfRowsInSection section: Int) -> Int {
if isFiltering() {
var count : Int = 0
tableUpdateQueue.sync {
count = filteredArtists.count
}
return count
} else {
switch Sections(rawValue: section)! {
case .recentlyPlayed:
if let recentlyPlayedTracks = recentlyPlayedTracks {
return recentlyPlayedTracks.count > 0 ? 1 : 0
} else {
return 0
}
case .availableOffline:
return offlineShows.count > 0 ? 1 : 0
case .favorited:
return allArtists.count == 0 ? 0 : favoriteArtists.count
case .featured:
return featuredArtists.count
case .all:
return allArtists.count
case .favoritedShows:
return favoriteShows.count > 0 ? 1 : 0
case .recentlyPerformed:
return recentlyPerformedShows.count > 0 ? 1 : 0
case .allRecentlyUpdated:
return allRecentlyUpdatedShows.count > 0 ? 1 : 0
case .count:
fatalError()
switch Sections(rawValue: section)! {
case .recentlyPlayed:
if let recentlyPlayedTracks = recentlyPlayedTracks {
return recentlyPlayedTracks.count > 0 ? 1 : 0
} else {
return 0
}
case .availableOffline:
return offlineShows.count > 0 ? 1 : 0
case .favorited:
return allArtists.count == 0 ? 0 : favoriteArtists.count
case .featured:
return featuredArtists.count
case .all:
return allArtists.count
case .favoritedShows:
return favoriteShows.count > 0 ? 1 : 0
case .recentlyPerformed:
return recentlyPerformedShows.count > 0 ? 1 : 0
case .allRecentlyUpdated:
return allRecentlyUpdatedShows.count > 0 ? 1 : 0
case .count:
fatalError()
}
}

public func tableNode(_ tableNode: ASTableNode, nodeBlockForRowAt indexPath: IndexPath) -> ASCellNodeBlock {
if isFiltering() {
var artist : ArtistWithCounts? = nil
tableUpdateQueue.sync {
artist = filteredArtists[indexPath.row]
}

if let artist = artist {
return { ArtistCellNode(artist: artist, withFavoritedArtists: self.favoriteArtists) }
} else {
fatalError("Couldn't get an artist at \(indexPath)")
}
} else {
let row = indexPath.row

switch Sections(rawValue: indexPath.section)! {
case .recentlyPlayed:
let n = recentShowsNode
return { n }
case .availableOffline:
let n = offlineShowsNode
return { n }
case .favoritedShows:
let n = favoritedSourcesNode
return { n }
case .recentlyPerformed:
let n = recentlyPerformedNode
return { n }
case .allRecentlyUpdated:
let n = allRecentlyUpdatedNode
return { n }

case .favorited:
let artist = allArtists.first(where: { art in art.uuid == favoriteArtists[row] })!

return { ArtistCellNode(artist: artist, withFavoritedArtists: self.favoriteArtists) }
case .featured:
let artist = featuredArtists[row]

return { ArtistCellNode(artist: artist, withFavoritedArtists: self.favoriteArtists) }
case .all:
let artist = allArtists[indexPath.row]

return { ArtistCellNode(artist: artist, withFavoritedArtists: self.favoriteArtists) }
case .count:
fatalError()
}
let row = indexPath.row

switch Sections(rawValue: indexPath.section)! {
case .recentlyPlayed:
let n = recentShowsNode
return { n }
case .availableOffline:
let n = offlineShowsNode
return { n }
case .favoritedShows:
let n = favoritedSourcesNode
return { n }
case .recentlyPerformed:
let n = recentlyPerformedNode
return { n }
case .allRecentlyUpdated:
let n = allRecentlyUpdatedNode
return { n }

case .favorited:
let artist = allArtists.first(where: { art in art.uuid == favoriteArtists[row] })!

return { ArtistCellNode(artist: artist, withFavoritedArtists: self.favoriteArtists) }
case .featured:
let artist = featuredArtists[row]

return { ArtistCellNode(artist: artist, withFavoritedArtists: self.favoriteArtists) }
case .all:
let artist = allArtists[indexPath.row]

return { ArtistCellNode(artist: artist, withFavoritedArtists: self.favoriteArtists) }
case .count:
fatalError()
}
}

override public func tableNode(_ tableNode: ASTableNode, didSelectRowAt indexPath: IndexPath) {
tableNode.deselectRow(at: indexPath, animated: true)

if isFiltering() {
if tableNode == self.resultsViewController.tableNode {
var artist : ArtistWithCounts? = nil
tableUpdateQueue.sync {
artist = filteredArtists[indexPath.row]
artist = self.resultsViewController.filteredArtists[indexPath.row]
}
if let artist = artist {
navigationController?.pushViewController(ArtistViewController(artist: artist), animated: true)
Expand Down Expand Up @@ -450,10 +418,6 @@ class ArtistsViewController: RelistenTableViewController<[ArtistWithCounts]>, AS
}

override public func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
if isFiltering() {
return nil
}

switch Sections(rawValue: section)! {
case .recentlyPlayed:
if let recentlyPlayedTracks = recentlyPlayedTracks {
Expand Down
Loading