Skip to content

Commit

Permalink
Merge pull request #167 from Maj0rPaine/master
Browse files Browse the repository at this point in the history
#162 - Handle favoriting an artist from search results
  • Loading branch information
farktronix authored Mar 15, 2019
2 parents 2111b75 + 4633f88 commit a73e549
Show file tree
Hide file tree
Showing 4 changed files with 158 additions and 1,772 deletions.
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

0 comments on commit a73e549

Please sign in to comment.