2019-12-17 05:22:25 +00:00
//
// E x p l o r e V i e w C o n t r o l l e r . s w i f t
// T u s k e r
//
// C r e a t e d b y S h a d o w f a c t s o n 1 2 / 1 4 / 1 9 .
// C o p y r i g h t © 2 0 1 9 S h a d o w f a c t s . A l l r i g h t s r e s e r v e d .
//
import UIKit
import Combine
2019-12-17 23:48:29 +00:00
import Pachyderm
2019-12-17 05:22:25 +00:00
class ExploreViewController : EnhancedTableViewController {
var dataSource : UITableViewDiffableDataSource < Section , Item > !
var resultsController : SearchResultsViewController !
var searchController : UISearchController !
let searchSubject = PassthroughSubject < String ? , Never > ( )
init ( ) {
super . init ( style : . insetGrouped )
title = NSLocalizedString ( " Explore " , comment : " explore tab title " )
tabBarItem . image = UIImage ( systemName : " magnifyingglass " )
}
required init ? ( coder : NSCoder ) {
fatalError ( " init(coder:) has not been implemented " )
}
override func viewDidLoad ( ) {
super . viewDidLoad ( )
tableView . register ( UINib ( nibName : " BasicTableViewCell " , bundle : . main ) , forCellReuseIdentifier : " basicCell " )
dataSource = DataSource ( tableView : tableView , cellProvider : { ( tableView , indexPath , item ) -> UITableViewCell ? in
2019-12-18 02:18:32 +00:00
let cell = tableView . dequeueReusableCell ( withIdentifier : " basicCell " , for : indexPath )
2019-12-17 05:22:25 +00:00
switch item {
case . bookmarks :
cell . imageView ! . image = UIImage ( systemName : " bookmark.fill " )
cell . textLabel ! . text = NSLocalizedString ( " Bookmarks " , comment : " bookmarks nav item title " )
cell . accessoryType = . disclosureIndicator
2019-12-18 02:18:32 +00:00
2019-12-17 23:48:29 +00:00
case let . list ( list ) :
2019-12-17 05:22:25 +00:00
cell . imageView ! . image = nil
2019-12-17 23:48:29 +00:00
cell . textLabel ! . text = list . title
2019-12-17 05:22:25 +00:00
cell . accessoryType = . disclosureIndicator
2019-12-18 02:18:32 +00:00
case . addList :
cell . imageView ! . image = UIImage ( systemName : " plus " )
cell . textLabel ! . text = NSLocalizedString ( " New List... " , comment : " new list nav item title " )
cell . accessoryType = . none
2019-12-17 05:22:25 +00:00
}
2019-12-18 02:18:32 +00:00
return cell
2019-12-17 05:22:25 +00:00
} )
var snapshot = NSDiffableDataSourceSnapshot < Section , Item > ( )
snapshot . appendSections ( [ . bookmarks , . lists ] )
snapshot . appendItems ( [ . bookmarks ] , toSection : . bookmarks )
2019-12-18 02:18:32 +00:00
snapshot . appendItems ( [ . addList ] , toSection : . lists )
2019-12-17 05:22:25 +00:00
// t h e i n i t i a l , s t a t i c i t e m s s h o u l d n o t b e d i s p l a y e d w i t h a n a n i m a t i o n
UIView . performWithoutAnimation {
dataSource . apply ( snapshot )
}
resultsController = SearchResultsViewController ( )
resultsController . exploreNavigationController = self . navigationController !
searchController = UISearchController ( searchResultsController : resultsController )
searchController . searchResultsUpdater = resultsController
searchController . searchBar . autocapitalizationType = . none
searchController . searchBar . delegate = resultsController
definesPresentationContext = true
navigationItem . searchController = searchController
navigationItem . hidesSearchBarWhenScrolling = false
2019-12-17 23:48:29 +00:00
2019-12-18 02:18:32 +00:00
reloadLists ( )
}
func reloadLists ( ) {
2019-12-17 23:48:29 +00:00
let request = MastodonController . client . getLists ( )
MastodonController . client . run ( request ) { ( response ) in
guard case let . success ( lists , _ ) = response else {
fatalError ( )
}
var snapshot = self . dataSource . snapshot ( )
2019-12-18 02:18:32 +00:00
snapshot . deleteSections ( [ . lists ] )
snapshot . appendSections ( [ . lists ] )
snapshot . appendItems ( lists . map { . list ( $0 ) } + [ . addList ] , toSection : . lists )
2019-12-17 23:48:29 +00:00
DispatchQueue . main . async {
self . dataSource . apply ( snapshot )
}
}
2019-12-17 05:22:25 +00:00
}
2019-12-17 23:48:29 +00:00
2019-12-17 05:22:25 +00:00
// MARK: - T a b l e v i e w d e l e g a t e
override func tableView ( _ tableView : UITableView , didSelectRowAt indexPath : IndexPath ) {
switch dataSource . itemIdentifier ( for : indexPath ) {
case nil :
return
case . bookmarks :
show ( BookmarksTableViewController ( ) , sender : nil )
2019-12-17 23:48:29 +00:00
case let . list ( list ) :
show ( ListTimelineViewController ( for : list ) , sender : nil )
2019-12-18 02:18:32 +00:00
case . addList :
tableView . selectRow ( at : nil , animated : true , scrollPosition : . none )
let alert = UIAlertController ( title : NSLocalizedString ( " New List " , comment : " new list alert title " ) , message : NSLocalizedString ( " Choose a title for your new list " , comment : " new list alert message " ) , preferredStyle : . alert )
alert . addTextField ( configurationHandler : nil )
alert . addAction ( UIAlertAction ( title : NSLocalizedString ( " Cancel " , comment : " new list alert cancel button " ) , style : . cancel , handler : nil ) )
alert . addAction ( UIAlertAction ( title : NSLocalizedString ( " Create List " , comment : " new list create button " ) , style : . default , handler : { ( _ ) in
guard let title = alert . textFields ? . first ? . text else {
fatalError ( )
}
let request = MastodonController . client . createList ( title : title )
MastodonController . client . run ( request ) { ( response ) in
guard case let . success ( list , _ ) = response else { fatalError ( ) }
self . reloadLists ( )
DispatchQueue . main . async {
self . show ( ListTimelineViewController ( for : list ) , sender : nil )
}
}
} ) )
present ( alert , animated : true )
2019-12-17 05:22:25 +00:00
}
}
}
extension ExploreViewController {
enum Section : CaseIterable {
case bookmarks
case lists
}
enum Item : Hashable {
case bookmarks
2019-12-17 23:48:29 +00:00
case list ( List )
2019-12-18 02:18:32 +00:00
case addList
2019-12-17 23:48:29 +00:00
static func = = ( lhs : ExploreViewController . Item , rhs : ExploreViewController . Item ) -> Bool {
switch ( lhs , rhs ) {
case ( . bookmarks , . bookmarks ) :
return true
case let ( . list ( a ) , . list ( b ) ) :
return a . id = = b . id
2019-12-18 02:18:32 +00:00
case ( . addList , . addList ) :
return true
2019-12-17 23:48:29 +00:00
default :
return false
}
}
func hash ( into hasher : inout Hasher ) {
switch self {
case . bookmarks :
hasher . combine ( " bookmarks " )
case let . list ( list ) :
hasher . combine ( " list " )
hasher . combine ( list . id )
2019-12-18 02:18:32 +00:00
case . addList :
hasher . combine ( " addList " )
2019-12-17 23:48:29 +00:00
}
}
2019-12-17 05:22:25 +00:00
}
class DataSource : UITableViewDiffableDataSource < Section , Item > {
override func tableView ( _ tableView : UITableView , titleForHeaderInSection section : Int ) -> String ? {
switch section {
case 1 :
return NSLocalizedString ( " Lists " , comment : " explore lists section title " )
default :
return nil
}
}
}
}