forked from shadowfacts/Tusker
parent
ab4bcfa50f
commit
911e66a159
|
@ -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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue