|
|
@ -13,6 +13,8 @@ import MastodonKit |
|
|
|
import UIKit |
|
|
|
|
|
|
|
class TimelineTableViewController: UITableViewController { |
|
|
|
let fetchLimit = 50 |
|
|
|
|
|
|
|
var loading: Bool = false { |
|
|
|
didSet { |
|
|
|
DispatchQueue.main.async { |
|
|
@ -30,17 +32,8 @@ class TimelineTableViewController: UITableViewController { |
|
|
|
override func viewDidLoad() { |
|
|
|
super.viewDidLoad() |
|
|
|
|
|
|
|
refreshControl?.addTarget(self, action: #selector(self.fetchTimeline), for: .valueChanged) |
|
|
|
|
|
|
|
let statusesCount = getTimelineStatusesCount() |
|
|
|
fetchTimeline() |
|
|
|
|
|
|
|
if statusesCount == 0 { |
|
|
|
self.tableView.reloadData() |
|
|
|
} else { |
|
|
|
print("More data to load...") |
|
|
|
self.tableView.reloadData() |
|
|
|
} |
|
|
|
refreshControl?.addTarget(self, action: #selector(self.fetchTimelineWithDefaultRange), for: .valueChanged) |
|
|
|
fetchTimelineWithDefaultRange() |
|
|
|
} |
|
|
|
|
|
|
|
func createDefaultTimelines(account: AccountMO) { |
|
|
@ -62,16 +55,40 @@ class TimelineTableViewController: UITableViewController { |
|
|
|
|
|
|
|
func fetchStatuses(request: Request<[Status]>, forTimeline timeline: TimelineMO) { |
|
|
|
if let client = AuthenticationManager.shared.getMKClientForSelectedSession() { |
|
|
|
print("Running request \(request)") |
|
|
|
client.run(request) { result in |
|
|
|
switch result { |
|
|
|
case .success(let remoteStatuses, _): |
|
|
|
let statuses = remoteStatuses.compactMap { status in |
|
|
|
return MastodonDataManager.upsertStatus(remoteStatus: status) |
|
|
|
DispatchQueue.main.async { |
|
|
|
let context = CoreDataManager.shared.getContext() |
|
|
|
let statuses = remoteStatuses.compactMap { status in |
|
|
|
return MastodonDataManager.upsertStatus(remoteStatus: status) |
|
|
|
} |
|
|
|
|
|
|
|
for (index, status) in statuses.enumerated() { |
|
|
|
if index == 0 { |
|
|
|
let boundary = TimelineBoundaryMO(context: context) |
|
|
|
boundary.statusID = status.id! |
|
|
|
boundary.start = true |
|
|
|
boundary.createdAt = Date() |
|
|
|
timeline.mutableSetValue(forKey: "boundaries").add(boundary) |
|
|
|
} else if index == statuses.count { |
|
|
|
let boundary = TimelineBoundaryMO(context: context) |
|
|
|
boundary.statusID = status.id! |
|
|
|
boundary.start = false |
|
|
|
boundary.createdAt = Date() |
|
|
|
timeline.mutableSetValue(forKey: "boundaries").add(boundary) |
|
|
|
} else { |
|
|
|
let predicate = NSPredicate(format: "statusID != %@", status.id!) |
|
|
|
timeline.mutableSetValue(forKey: "boundaries").filter(using: predicate) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
timeline.addToStatuses(NSSet(array: statuses)) |
|
|
|
CoreDataManager.shared.saveContext() |
|
|
|
|
|
|
|
self.tableView.reloadData() |
|
|
|
} |
|
|
|
|
|
|
|
timeline.addToStatuses(NSSet(array: statuses)) |
|
|
|
|
|
|
|
CoreDataManager.shared.saveContext() |
|
|
|
case .failure(let error): |
|
|
|
print("\(error)") |
|
|
|
} |
|
|
@ -79,7 +96,11 @@ class TimelineTableViewController: UITableViewController { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@objc func fetchTimeline() { |
|
|
|
@objc func fetchTimelineWithDefaultRange() { |
|
|
|
fetchTimeline(withRange: .limit(fetchLimit)) |
|
|
|
} |
|
|
|
|
|
|
|
func fetchTimeline(withRange requestRange: RequestRange) { |
|
|
|
guard let session = AuthenticationManager.shared.selectedSession, let account = session.account else { |
|
|
|
return |
|
|
|
} |
|
|
@ -107,16 +128,20 @@ class TimelineTableViewController: UITableViewController { |
|
|
|
} |
|
|
|
|
|
|
|
if let selectedTimeline = session.selectedTimeline { |
|
|
|
var request: Request<[Status]> |
|
|
|
|
|
|
|
switch selectedTimeline.name { |
|
|
|
case "Home": |
|
|
|
fetchStatuses(request: Timelines.home(), forTimeline: selectedTimeline) |
|
|
|
request = Timelines.home(range: requestRange) |
|
|
|
case "Local": |
|
|
|
fetchStatuses(request: Timelines.public(local: true), forTimeline: selectedTimeline) |
|
|
|
request = Timelines.public(local: true, range: requestRange) |
|
|
|
case "Federated": |
|
|
|
fetchStatuses(request: Timelines.public(local: false), forTimeline: selectedTimeline) |
|
|
|
default: |
|
|
|
print("Tags not implemented") |
|
|
|
request = Timelines.public(local: false, range: requestRange) |
|
|
|
case let tag: |
|
|
|
request = Timelines.tag(tag!, range: requestRange) |
|
|
|
} |
|
|
|
|
|
|
|
fetchStatuses(request: request, forTimeline: selectedTimeline) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
@ -187,7 +212,7 @@ class TimelineTableViewController: UITableViewController { |
|
|
|
|
|
|
|
if let content = status.content { |
|
|
|
do { |
|
|
|
let styledContent = "<style>html * { font-size: 16px; color: #170c49; font-family: -apple-system }</style> \(content)" |
|
|
|
let styledContent = "<style>html * { font-size: 15px; color: #170c49; font-family: -apple-system }</style> \(content)" |
|
|
|
let attributedText = try NSAttributedString( |
|
|
|
data: styledContent.data(using: String.Encoding.unicode, allowLossyConversion: true)!, |
|
|
|
options: [.documentType: NSAttributedString.DocumentType.html], |
|
|
@ -202,6 +227,10 @@ class TimelineTableViewController: UITableViewController { |
|
|
|
|
|
|
|
cell.timestampLabel.text = status.createdAt!.timeAgo() |
|
|
|
|
|
|
|
if indexPath.row == statuses.count - 1 && !loading { |
|
|
|
fetchTimeline(withRange: .max(id: status.id!, limit: fetchLimit)) |
|
|
|
} |
|
|
|
|
|
|
|
return cell |
|
|
|
} |
|
|
|
|
|
|
|