Skip to content

Commit

Permalink
Merge pull request #17750 from wordpress-mobile/issue/17697_msd_sync_…
Browse files Browse the repository at this point in the history
…posts

My Site Dashboard: sync posts in the post card
  • Loading branch information
leandroalonso authored Jan 13, 2022
2 parents d514c4f + 3f43aa4 commit 27fac2a
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ import UIKit
@objc class PostsCardViewController: UIViewController {
var blog: Blog

private let postsTableView = IntrinsicTableView()
let tableView: UITableView = IntrinsicTableView()

private var viewModel: PostsCardViewModel!
private var ghostableTableView: UITableView?

@objc init(blog: Blog) {
self.blog = blog
Expand All @@ -23,23 +24,68 @@ import UIKit
override func viewDidLoad() {
super.viewDidLoad()
configureView()
viewModel = PostsCardViewModel(tableView: postsTableView, blog: blog)
viewModel = PostsCardViewModel(blog: blog, viewController: self)
viewModel.viewDidLoad()
}

override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
postsTableView.dataSource = viewModel
tableView.dataSource = viewModel
viewModel.refresh()
}
}

extension PostsCardViewController: PostsCardView {
func showLoading() {
configureGhostableTableView()
}

func hideLoading() {
removeGhostableTableView()
}
}

private extension PostsCardViewController {
func configureView() {
view.addSubview(postsTableView)
postsTableView.translatesAutoresizingMaskIntoConstraints = false
view.pinSubviewToAllEdges(postsTableView)
configureTableView()
}

func configureTableView() {
view.addSubview(tableView)
tableView.translatesAutoresizingMaskIntoConstraints = false
view.pinSubviewToAllEdges(tableView)
let postCompactCellNib = PostCompactCell.defaultNib
tableView.register(postCompactCellNib, forCellReuseIdentifier: PostCompactCell.defaultReuseID)
}

func configureGhostableTableView() {
let ghostableTableView = IntrinsicTableView()

view.addSubview(ghostableTableView)

ghostableTableView.translatesAutoresizingMaskIntoConstraints = false
view.pinSubviewToAllEdges(ghostableTableView)

ghostableTableView.isScrollEnabled = false

let postCompactCellNib = PostCompactCell.defaultNib
postsTableView.register(postCompactCellNib, forCellReuseIdentifier: PostCompactCell.defaultReuseID)
ghostableTableView.register(postCompactCellNib, forCellReuseIdentifier: PostCompactCell.defaultReuseID)

let ghostOptions = GhostOptions(displaysSectionHeader: false, reuseIdentifier: PostCompactCell.defaultReuseID, rowsPerSection: [Constants.numberOfPosts])
let style = GhostStyle(beatDuration: GhostStyle.Defaults.beatDuration,
beatStartColor: .placeholderElement,
beatEndColor: .placeholderElementFaded)
ghostableTableView.removeGhostContent()
ghostableTableView.displayGhostContent(options: ghostOptions, style: style)

self.ghostableTableView = ghostableTableView
}

func removeGhostableTableView() {
ghostableTableView?.removeFromSuperview()
}

enum Constants {
static let numberOfPosts = 3
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,42 +2,53 @@ import Foundation
import CoreData
import UIKit

protocol PostsCardView: AnyObject {
var tableView: UITableView { get }

func showLoading()
func hideLoading()
}

/// Responsible for populating a table view with posts
///
class PostsCardViewModel: NSObject {
var blog: Blog

private let managedObjectContext: NSManagedObjectContext

private let tableView: UITableView
private let postService: PostService

lazy var filterSettings: PostListFilterSettings = {
PostListFilterSettings(blog: blog, postType: .post)
}()

private var fetchedResultsController: NSFetchedResultsController<Post>!

init(tableView: UITableView, blog: Blog, managedObjectContext: NSManagedObjectContext = ContextManager.shared.mainContext) {
private weak var viewController: PostsCardView?

init(blog: Blog, viewController: PostsCardView, managedObjectContext: NSManagedObjectContext = ContextManager.shared.mainContext) {
self.blog = blog
self.viewController = viewController
self.managedObjectContext = managedObjectContext
self.tableView = tableView
self.postService = PostService(managedObjectContext: managedObjectContext)
super.init()
}


/// Refresh the results and reload the data on the table view
func refresh() {
do {
try fetchedResultsController.performFetch()
tableView.reloadData()
viewController?.tableView.reloadData()
} catch {
print("Fetch failed")
}
}

/// Set up the view model to be ready for use
func viewDidLoad() {
viewController?.showLoading()
createFetchedResultsController()
sync()
}
}

Expand Down Expand Up @@ -83,8 +94,28 @@ private extension PostsCardViewModel {
return filterSettings.currentPostListFilter().sortDescriptors
}

func sync() {
let filter = filterSettings.currentPostListFilter()

let options = PostServiceSyncOptions()
options.statuses = filter.statuses.strings
options.number = Constants.numberOfPostsToSync
options.purgesLocalSync = true

postService.syncPosts(
ofType: .post,
with: options,
for: blog,
success: { _ in

}, failure: { (error: Error?) -> () in

})
}

enum Constants {
static let numberOfPosts = 3
static let numberOfPostsToSync: NSNumber = 4
}
}

Expand All @@ -98,6 +129,8 @@ extension PostsCardViewModel: UITableViewDataSource {
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: PostCompactCell.defaultReuseID, for: indexPath)

viewController?.hideLoading()

configureCell(cell, at: indexPath)

return cell
Expand All @@ -120,45 +153,45 @@ extension PostsCardViewModel: UITableViewDataSource {

extension PostsCardViewModel: NSFetchedResultsControllerDelegate {
func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
tableView.beginUpdates()
viewController?.tableView.beginUpdates()
}

func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
tableView.endUpdates()
viewController?.tableView.endUpdates()

// When going to the post list all displayed posts there will be displayed
// here too. This check ensures that we never display more than what
// is specified on the `fetchLimit` property
if fetchedResultsController.fetchRequest.fetchLimit > 0 && fetchedResultsController.fetchRequest.fetchLimit < fetchedResultsController.fetchedObjects?.count ?? 0 {
try? fetchedResultsController.performFetch()
tableView.reloadData()
viewController?.tableView.reloadData()
}
}

func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
switch type {
case .insert:
if let indexPath = newIndexPath {
tableView.insertRows(at: [indexPath], with: .fade)
viewController?.tableView.insertRows(at: [indexPath], with: .fade)
}
break
case .delete:
if let indexPath = indexPath {
tableView.deleteRows(at: [indexPath], with: .fade)
viewController?.tableView.deleteRows(at: [indexPath], with: .fade)
}
break
case .update:
if let indexPath = indexPath, let cell = tableView.cellForRow(at: indexPath) {
if let indexPath = indexPath, let cell = viewController?.tableView.cellForRow(at: indexPath) {
configureCell(cell, at: indexPath)
}
break
case .move:
if let indexPath = indexPath {
tableView.deleteRows(at: [indexPath], with: .fade)
viewController?.tableView.deleteRows(at: [indexPath], with: .fade)
}

if let newIndexPath = newIndexPath {
tableView.insertRows(at: [newIndexPath], with: .fade)
viewController?.tableView.insertRows(at: [newIndexPath], with: .fade)
}
break
@unknown default:
Expand Down

0 comments on commit 27fac2a

Please sign in to comment.