A WIP iOS app for Mastodon and Pleroma.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

AppRouter.swift 5.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. //
  2. // AppRouter.swift
  3. // Tusker
  4. //
  5. // Created by Shadowfacts on 10/20/18.
  6. // Copyright © 2018 Shadowfacts. All rights reserved.
  7. //
  8. import UIKit
  9. import Pachyderm
  10. import SafariServices
  11. class AppRouter {
  12. let rootViewController: UIViewController
  13. init(root: UIViewController) {
  14. self.rootViewController = root
  15. }
  16. private func getTopViewController(parent vc: UIViewController) -> UIViewController {
  17. if let vc = vc as? UINavigationController,
  18. let top = vc.topViewController {
  19. return getTopViewController(parent: top)
  20. } else if let vc = vc as? UITabBarController,
  21. let selected = vc.selectedViewController {
  22. return getTopViewController(parent: selected)
  23. } else if let presented = vc.presentedViewController {
  24. return getTopViewController(parent: presented)
  25. } else {
  26. return vc
  27. }
  28. }
  29. private func getNavController(parent vc: UIViewController) -> UINavigationController {
  30. if let vc = vc as? UINavigationController {
  31. return vc
  32. } else if let vc = vc as? UITabBarController,
  33. let selected = vc.selectedViewController {
  34. return getNavController(parent: selected)
  35. } else {
  36. fatalError()
  37. }
  38. }
  39. func present(_ vc: UIViewController, animated: Bool) {
  40. let top = getTopViewController(parent: rootViewController)
  41. top.present(vc, animated: animated)
  42. }
  43. func push(_ vc: UIViewController, animated: Bool) {
  44. let nav = getNavController(parent: rootViewController)
  45. nav.pushViewController(vc, animated: true)
  46. }
  47. func profile(for accountID: String) -> ProfileTableViewController {
  48. return ProfileTableViewController(accountID: accountID, router: self)
  49. }
  50. func profile(for mention: Mention) -> ProfileTableViewController {
  51. return ProfileTableViewController(accountID: mention.id, router: self)
  52. }
  53. func timeline(for timeline: Timeline) -> TimelineTableViewController {
  54. return TimelineTableViewController(for: timeline, router: self)
  55. }
  56. func timeline(tag: Hashtag) -> TimelineTableViewController {
  57. return timeline(for: .tag(hashtag: tag.name))
  58. }
  59. func safariViewController(for url: URL) -> SFSafariViewController {
  60. return SFSafariViewController(url: url)
  61. }
  62. func conversation(for statusID: String) -> ConversationTableViewController {
  63. return ConversationTableViewController(for: statusID, router: self)
  64. }
  65. func compose(inReplyTo inReplyToID: String? = nil, mentioningAcct: String? = nil, text: String? = nil) -> ComposeViewController {
  66. return ComposeViewController(inReplyTo: inReplyToID, mentioningAcct: mentioningAcct, text: text, router: self)
  67. }
  68. func drafts() -> DraftsTableViewController {
  69. return DraftsTableViewController()
  70. }
  71. func largeImage(_ image: UIImage, description: String?, sourceFrame: CGRect, sourceCornerRadius: CGFloat, transitioningDelegate: UIViewControllerTransitioningDelegate?) -> LargeImageViewController {
  72. let vc = LargeImageViewController(image: image, description: description, sourceFrame: sourceFrame, sourceCornerRadius: sourceCornerRadius, router: self)
  73. vc.transitioningDelegate = transitioningDelegate
  74. return vc
  75. }
  76. func largeImage(gifData: Data, description: String?, sourceFrame: CGRect, sourceCornerRadius: CGFloat, transitioningDelegate: UIViewControllerTransitioningDelegate?) -> LargeImageViewController {
  77. let vc = LargeImageViewController(image: UIImage(data: gifData)!, description: description, sourceFrame: sourceFrame, sourceCornerRadius: sourceCornerRadius, router: self)
  78. vc.gifData = gifData
  79. vc.transitioningDelegate = transitioningDelegate
  80. return vc
  81. }
  82. func moreOptions(forStatus statusID: String) -> UIAlertController {
  83. guard let status = MastodonCache.status(for: statusID) else { fatalError("Missing cached status \(statusID)") }
  84. let alert = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
  85. if let url = status.url {
  86. alert.addAction(UIAlertAction(title: "Open in Safari", style: .default, handler: { (_) in
  87. let vc = SFSafariViewController(url: url)
  88. self.present(vc, animated: true)
  89. }))
  90. alert.addAction(UIAlertAction(title: "Copy", style: .default, handler: { (_) in
  91. UIPasteboard.general.url = url
  92. }))
  93. alert.addAction(UIAlertAction(title: "Share...", style: .default, handler: { (_) in
  94. let vc = UIActivityViewController(activityItems: [url], applicationActivities: nil)
  95. self.present(vc, animated: true)
  96. }))
  97. }
  98. alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
  99. return alert
  100. }
  101. func moreOptions(forURL url: URL) -> UIAlertController {
  102. let alert = UIAlertController(title: nil, message: url.absoluteString, preferredStyle: .actionSheet)
  103. alert.addAction(UIAlertAction(title: "Open in Safari", style: .default, handler: { (_) in
  104. let vc = SFSafariViewController(url: url)
  105. self.present(vc, animated: true)
  106. }))
  107. alert.addAction(UIAlertAction(title: "Copy", style: .default, handler: { (_) in
  108. UIPasteboard.general.url = url
  109. }))
  110. alert.addAction(UIAlertAction(title: "Share...", style: .default, handler: { (_) in
  111. let vc = UIActivityViewController(activityItems: [url], applicationActivities: nil)
  112. self.present(vc, animated: true)
  113. }))
  114. alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
  115. return alert
  116. }
  117. }