Allow more browsing of instance public timelines

Closes #74
This commit is contained in:
Shadowfacts 2020-09-13 15:51:06 -04:00
parent ab4bcfa50f
commit 911e66a159
Signed by untrusted user: shadowfacts
GPG Key ID: 94A5AB95422746E5
11 changed files with 63 additions and 45 deletions

View File

@ -36,10 +36,10 @@ class OpenInSafariActivity: UIActivity {
activityDidFinish(true) activityDidFinish(true)
} }
static func completionHandler(viewController: UIViewController, url: URL) -> UIActivityViewController.CompletionWithItemsHandler { static func completionHandler(navigator: TuskerNavigationDelegate, url: URL) -> UIActivityViewController.CompletionWithItemsHandler {
return { (activityType, _, _, _) in return { (activityType, _, _, _) in
if activityType == .openInSafari { if activityType == .openInSafari {
viewController.present(SFSafariViewController(url: url), animated: true) navigator.show(SFSafariViewController(url: url))
} }
} }
} }

View File

@ -45,6 +45,10 @@ class MastodonController {
var account: Account! var account: Account!
var instance: Instance! var instance: Instance!
var loggedIn: Bool {
accountInfo != nil
}
init(instanceURL: URL, transient: Bool = false) { init(instanceURL: URL, transient: Bool = false) {
self.instanceURL = instanceURL self.instanceURL = instanceURL
self.accountInfo = nil self.accountInfo = nil

View File

@ -46,6 +46,7 @@ extension FindInstanceViewController: InstanceSelectorTableViewControllerDelegat
func didSelectInstance(url: URL) { func didSelectInstance(url: URL) {
let instanceTimelineController = InstanceTimelineViewController(for: url, parentMastodonController: parentMastodonController!) let instanceTimelineController = InstanceTimelineViewController(for: url, parentMastodonController: parentMastodonController!)
instanceTimelineController.delegate = instanceTimelineDelegate instanceTimelineController.delegate = instanceTimelineDelegate
instanceTimelineController.browsingEnabled = false
show(instanceTimelineController, sender: self) show(instanceTimelineController, sender: self)
} }
} }

View File

@ -211,7 +211,7 @@ extension ProfileViewController: ProfileHeaderViewDelegate {
func showActivityController(activities: [UIActivity]) { func showActivityController(activities: [UIActivity]) {
let activityController = UIActivityViewController(activityItems: [account.url, AccountActivityItemSource(account)], applicationActivities: activities) let activityController = UIActivityViewController(activityItems: [account.url, AccountActivityItemSource(account)], applicationActivities: activities)
activityController.completionWithItemsHandler = OpenInSafariActivity.completionHandler(viewController: self, url: account.url) activityController.completionWithItemsHandler = OpenInSafariActivity.completionHandler(navigator: self, url: account.url)
activityController.popoverPresentationController?.sourceView = sourceView activityController.popoverPresentationController?.sourceView = sourceView
self.present(activityController, animated: true) self.present(activityController, animated: true)
} }

View File

@ -31,6 +31,8 @@ class InstanceTimelineViewController: TimelineTableViewController {
} }
} }
var browsingEnabled = true
init(for url: URL, parentMastodonController: MastodonController) { init(for url: URL, parentMastodonController: MastodonController) {
self.parentMastodonController = parentMastodonController self.parentMastodonController = parentMastodonController
@ -66,36 +68,15 @@ class InstanceTimelineViewController: TimelineTableViewController {
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = super.tableView(tableView, cellForRowAt: indexPath) as! TimelineStatusTableViewCell let cell = super.tableView(tableView, cellForRowAt: indexPath) as! TimelineStatusTableViewCell
cell.delegate = nil cell.delegate = browsingEnabled ? self : nil
cell.overrideMastodonController = mastodonController
return cell return cell
} }
// MARK: - Table view delegate // MARK: - Table view delegate
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// no-op, we don't currently support viewing whole conversations from other instances guard browsingEnabled else { return }
} super.tableView(tableView, didSelectRowAt: indexPath)
override func tableView(_ tableView: UITableView, contextMenuConfigurationForRowAt indexPath: IndexPath, point: CGPoint) -> UIContextMenuConfiguration? {
// don't show other screens or actions for other instances
return nil
}
override func tableView(_ tableView: UITableView, leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
// don't show swipe actions for other instances
return nil
}
override func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
// only show more actions for other instances
let more = UIContextualAction(style: .normal, title: "More") { (action, view, completion) in
completion(true)
self.showMoreOptions(forStatus: self.timelineSegments[indexPath.section][indexPath.row].id, sourceView: tableView.cellForRow(at: indexPath))
}
more.image = UIImage(systemName: "ellipsis.circle.fill")
more.backgroundColor = .lightGray
return UISwipeActionsConfiguration(actions: [more])
} }
// MARK: - Interaction // MARK: - Interaction

View File

@ -9,7 +9,7 @@
import UIKit import UIKit
import Pachyderm import Pachyderm
class TimelineTableViewController: EnhancedTableViewController { class TimelineTableViewController: EnhancedTableViewController, StatusTableViewCellDelegate {
var timeline: Timeline! var timeline: Timeline!
weak var mastodonController: MastodonController! weak var mastodonController: MastodonController!
@ -206,7 +206,7 @@ class TimelineTableViewController: EnhancedTableViewController {
return (tableView.cellForRow(at: indexPath) as? TableViewSwipeActionProvider)?.trailingSwipeActionsConfiguration() return (tableView.cellForRow(at: indexPath) as? TableViewSwipeActionProvider)?.trailingSwipeActionsConfiguration()
} }
// MARK: Interaction // MARK: - Interaction
@objc func refreshStatuses(_ sender: Any) { @objc func refreshStatuses(_ sender: Any) {
guard let newer = newer else { return } guard let newer = newer else { return }
@ -244,16 +244,18 @@ class TimelineTableViewController: EnhancedTableViewController {
compose() compose()
} }
} // MARK: - TuskerNavigationDelegate
extension TimelineTableViewController: StatusTableViewCellDelegate {
var apiController: MastodonController { mastodonController } var apiController: MastodonController { mastodonController }
// MARK: - StatusTableViewCellDelegate
func statusCellCollapsedStateChanged(_ cell: BaseStatusTableViewCell) { func statusCellCollapsedStateChanged(_ cell: BaseStatusTableViewCell) {
// causes the table view to recalculate the cell heights // causes the table view to recalculate the cell heights
tableView.beginUpdates() tableView.beginUpdates()
tableView.endUpdates() tableView.endUpdates()
} }
} }
extension TimelineTableViewController: UITableViewDataSourcePrefetching { extension TimelineTableViewController: UITableViewDataSourcePrefetching {

View File

@ -37,6 +37,16 @@ extension MenuPreviewProvider {
guard let mastodonController = mastodonController, guard let mastodonController = mastodonController,
let account = mastodonController.persistentContainer.account(for: accountID) else { return [] } let account = mastodonController.persistentContainer.account(for: accountID) else { return [] }
guard mastodonController.loggedIn else {
return [
openInSafariAction(url: account.url),
createAction(identifier: "share", title: "Share...", systemImageName: "square.and.arrow.up", handler: { [weak self] (_) in
guard let self = self else { return }
self.navigationDelegate?.showMoreOptions(forAccount: accountID, sourceView: sourceView)
})
]
}
var actionsSection: [UIMenuElement] = [ var actionsSection: [UIMenuElement] = [
createAction(identifier: "sendmessage", title: "Send Message", systemImageName: "envelope", handler: { [weak self] (_) in createAction(identifier: "sendmessage", title: "Send Message", systemImageName: "envelope", handler: { [weak self] (_) in
guard let self = self else { return } guard let self = self else { return }
@ -123,6 +133,17 @@ extension MenuPreviewProvider {
func actionsForStatus(statusID: String, sourceView: UIView?) -> [UIMenuElement] { func actionsForStatus(statusID: String, sourceView: UIView?) -> [UIMenuElement] {
guard let mastodonController = mastodonController, guard let mastodonController = mastodonController,
let status = mastodonController.persistentContainer.status(for: statusID) else { return [] } let status = mastodonController.persistentContainer.status(for: statusID) else { return [] }
guard mastodonController.loggedIn else {
return [
openInSafariAction(url: status.url!),
createAction(identifier: "share", title: "Share...", systemImageName: "square.and.arrow.up", handler: { [weak self] (_) in
guard let self = self else { return }
self.navigationDelegate?.showMoreOptions(forStatus: statusID, sourceView: sourceView)
})
]
}
let bookmarked = status.bookmarked ?? false let bookmarked = status.bookmarked ?? false
let muted = status.muted let muted = status.muted

View File

@ -118,7 +118,7 @@ extension TuskerNavigationDelegate {
OpenInSafariActivity() OpenInSafariActivity()
] ]
let activityController = UIActivityViewController(activityItems: [url], applicationActivities: customActivites) let activityController = UIActivityViewController(activityItems: [url], applicationActivities: customActivites)
activityController.completionWithItemsHandler = OpenInSafariActivity.completionHandler(viewController: self, url: url) activityController.completionWithItemsHandler = OpenInSafariActivity.completionHandler(navigator: self, url: url)
return activityController return activityController
} }
@ -142,7 +142,7 @@ extension TuskerNavigationDelegate {
} }
let activityController = UIActivityViewController(activityItems: [url, StatusActivityItemSource(status)], applicationActivities: customActivites) let activityController = UIActivityViewController(activityItems: [url, StatusActivityItemSource(status)], applicationActivities: customActivites)
activityController.completionWithItemsHandler = OpenInSafariActivity.completionHandler(viewController: self, url: url) activityController.completionWithItemsHandler = OpenInSafariActivity.completionHandler(navigator: self, url: url)
return activityController return activityController
} }
} }
@ -158,7 +158,7 @@ extension TuskerNavigationDelegate {
] ]
let activityController = UIActivityViewController(activityItems: [account.url, AccountActivityItemSource(account)], applicationActivities: customActivities) let activityController = UIActivityViewController(activityItems: [account.url, AccountActivityItemSource(account)], applicationActivities: customActivities)
activityController.completionWithItemsHandler = OpenInSafariActivity.completionHandler(viewController: self, url: account.url) activityController.completionWithItemsHandler = OpenInSafariActivity.completionHandler(navigator: self, url: account.url)
return activityController return activityController
} }
} }

View File

@ -114,7 +114,7 @@ class ProfileHeaderView: UIView {
noteTextView.setEmojis(account.emojis) noteTextView.setEmojis(account.emojis)
// don't show relationship label for the user's own account // don't show relationship label for the user's own account
if accountID != mastodonController.account.id { if accountID != mastodonController.account?.id {
let request = Client.getRelationships(accounts: [accountID]) let request = Client.getRelationships(accounts: [accountID])
mastodonController.run(request) { [weak self] (response) in mastodonController.run(request) { [weak self] (response) in
guard let self = self, guard let self = self,

View File

@ -162,7 +162,10 @@ class BaseStatusTableViewCell: UITableViewCell {
// Pleroma allows 'Boost to original audience' for your own private posts // Pleroma allows 'Boost to original audience' for your own private posts
reblogDisabled = status.visibility == .direct || (status.visibility == .private && status.account.id != mastodonController.account.id) reblogDisabled = status.visibility == .direct || (status.visibility == .private && status.account.id != mastodonController.account.id)
} }
reblogButton.isEnabled = !reblogDisabled reblogButton.isEnabled = !reblogDisabled && mastodonController.loggedIn
favoriteButton.isEnabled = mastodonController.loggedIn
replyButton.isEnabled = mastodonController.loggedIn
updateStatusIconsForPreferences(status) updateStatusIconsForPreferences(status)

View File

@ -196,7 +196,8 @@ extension TimelineStatusTableViewCell: SelectableTableViewCell {
extension TimelineStatusTableViewCell: TableViewSwipeActionProvider { extension TimelineStatusTableViewCell: TableViewSwipeActionProvider {
func leadingSwipeActionsConfiguration() -> UISwipeActionsConfiguration? { func leadingSwipeActionsConfiguration() -> UISwipeActionsConfiguration? {
guard let mastodonController = mastodonController else { return nil } guard let mastodonController = mastodonController,
mastodonController.loggedIn else { return nil }
guard let status = mastodonController.persistentContainer.status(for: statusID) else { fatalError("Missing cached status \(statusID!)") } guard let status = mastodonController.persistentContainer.status(for: statusID) else { fatalError("Missing cached status \(statusID!)") }
let favoriteTitle: String let favoriteTitle: String
@ -258,13 +259,6 @@ extension TimelineStatusTableViewCell: TableViewSwipeActionProvider {
} }
func trailingSwipeActionsConfiguration() -> UISwipeActionsConfiguration? { func trailingSwipeActionsConfiguration() -> UISwipeActionsConfiguration? {
let reply = UIContextualAction(style: .normal, title: "Reply") { (action, view, completion) in
completion(true)
self.reply()
}
reply.image = UIImage(systemName: "arrowshape.turn.up.left.fill")
reply.backgroundColor = tintColor
let moreTitle: String let moreTitle: String
let moreImage: UIImage let moreImage: UIImage
// on iOS 14+, more actions are in the context menu so display this as 'Share' // on iOS 14+, more actions are in the context menu so display this as 'Share'
@ -284,6 +278,18 @@ extension TimelineStatusTableViewCell: TableViewSwipeActionProvider {
} }
more.image = moreImage more.image = moreImage
more.backgroundColor = .lightGray more.backgroundColor = .lightGray
guard mastodonController.loggedIn else {
return UISwipeActionsConfiguration(actions: [more])
}
let reply = UIContextualAction(style: .normal, title: "Reply") { (action, view, completion) in
completion(true)
self.reply()
}
reply.image = UIImage(systemName: "arrowshape.turn.up.left.fill")
reply.backgroundColor = tintColor
return UISwipeActionsConfiguration(actions: [reply, more]) return UISwipeActionsConfiguration(actions: [reply, more])
} }