diff --git a/Tusker.xcodeproj/project.pbxproj b/Tusker.xcodeproj/project.pbxproj index 07b7556ee5..3a5f2187da 100644 --- a/Tusker.xcodeproj/project.pbxproj +++ b/Tusker.xcodeproj/project.pbxproj @@ -7,6 +7,8 @@ objects = { /* Begin PBXBuildFile section */ + 04DACE8A212CA6B7009840C4 /* Timeline.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04DACE89212CA6B7009840C4 /* Timeline.swift */; }; + 04DACE8C212CB14B009840C4 /* MainTabBarViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04DACE8B212CB14B009840C4 /* MainTabBarViewController.swift */; }; D64D0AAD2128D88B005A6F37 /* LocalData.swift in Sources */ = {isa = PBXBuildFile; fileRef = D64D0AAC2128D88B005A6F37 /* LocalData.swift */; }; D64D0AAF2128D954005A6F37 /* Onboarding.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D64D0AAE2128D954005A6F37 /* Onboarding.storyboard */; }; D64D0AB12128D9AE005A6F37 /* OnboardingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D64D0AB02128D9AE005A6F37 /* OnboardingViewController.swift */; }; @@ -14,7 +16,6 @@ D6BED170212663DA00F02DA0 /* SwiftSoup.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = D6BED16E212663DA00F02DA0 /* SwiftSoup.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; D6BED174212667E900F02DA0 /* StatusTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6BED173212667E900F02DA0 /* StatusTableViewCell.swift */; }; D6D4DDD0212518A000E1C4BB /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6D4DDCF212518A000E1C4BB /* AppDelegate.swift */; }; - D6D4DDD2212518A000E1C4BB /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6D4DDD1212518A000E1C4BB /* ViewController.swift */; }; D6D4DDD5212518A000E1C4BB /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D6D4DDD3212518A000E1C4BB /* Main.storyboard */; }; D6D4DDD7212518A200E1C4BB /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D6D4DDD6212518A200E1C4BB /* Assets.xcassets */; }; D6D4DDDA212518A200E1C4BB /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D6D4DDD8212518A200E1C4BB /* LaunchScreen.storyboard */; }; @@ -22,8 +23,8 @@ D6D4DDF0212518A200E1C4BB /* TuskerUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6D4DDEF212518A200E1C4BB /* TuskerUITests.swift */; }; D6F953E7212519A400CF0F2B /* MastodonKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D6F953E6212519A400CF0F2B /* MastodonKit.framework */; }; D6F953E8212519A400CF0F2B /* MastodonKit.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = D6F953E6212519A400CF0F2B /* MastodonKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - D6F953EC212519E700CF0F2B /* StatusesTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6F953EB212519E700CF0F2B /* StatusesTableViewController.swift */; }; - D6F953EE21251A0700CF0F2B /* Statuses.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D6F953ED21251A0700CF0F2B /* Statuses.storyboard */; }; + D6F953EC212519E700CF0F2B /* TimelineTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6F953EB212519E700CF0F2B /* TimelineTableViewController.swift */; }; + D6F953EE21251A0700CF0F2B /* Timeline.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D6F953ED21251A0700CF0F2B /* Timeline.storyboard */; }; D6F953F021251A2900CF0F2B /* MastodonController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6F953EF21251A2900CF0F2B /* MastodonController.swift */; }; /* End PBXBuildFile section */ @@ -60,6 +61,8 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 04DACE89212CA6B7009840C4 /* Timeline.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Timeline.swift; sourceTree = ""; }; + 04DACE8B212CB14B009840C4 /* MainTabBarViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainTabBarViewController.swift; sourceTree = ""; }; D64D0AAC2128D88B005A6F37 /* LocalData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalData.swift; sourceTree = ""; }; D64D0AAE2128D954005A6F37 /* Onboarding.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Onboarding.storyboard; sourceTree = ""; }; D64D0AB02128D9AE005A6F37 /* OnboardingViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingViewController.swift; sourceTree = ""; }; @@ -67,7 +70,6 @@ D6BED173212667E900F02DA0 /* StatusTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusTableViewCell.swift; sourceTree = ""; }; D6D4DDCC212518A000E1C4BB /* Tusker.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Tusker.app; sourceTree = BUILT_PRODUCTS_DIR; }; D6D4DDCF212518A000E1C4BB /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - D6D4DDD1212518A000E1C4BB /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; D6D4DDD4212518A000E1C4BB /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; D6D4DDD6212518A200E1C4BB /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; D6D4DDD9212518A200E1C4BB /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; @@ -79,8 +81,8 @@ D6D4DDEF212518A200E1C4BB /* TuskerUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TuskerUITests.swift; sourceTree = ""; }; D6D4DDF1212518A200E1C4BB /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; D6F953E6212519A400CF0F2B /* MastodonKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = MastodonKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - D6F953EB212519E700CF0F2B /* StatusesTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusesTableViewController.swift; sourceTree = ""; }; - D6F953ED21251A0700CF0F2B /* Statuses.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Statuses.storyboard; sourceTree = ""; }; + D6F953EB212519E700CF0F2B /* TimelineTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineTableViewController.swift; sourceTree = ""; }; + D6F953ED21251A0700CF0F2B /* Timeline.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Timeline.storyboard; sourceTree = ""; }; D6F953EF21251A2900CF0F2B /* MastodonController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonController.swift; sourceTree = ""; }; /* End PBXFileReference section */ @@ -153,6 +155,7 @@ D6D4DDD6212518A200E1C4BB /* Assets.xcassets */, D6D4DDD8212518A200E1C4BB /* LaunchScreen.storyboard */, D6D4DDDB212518A200E1C4BB /* Info.plist */, + 04DACE89212CA6B7009840C4 /* Timeline.swift */, ); path = Tusker; sourceTree = ""; @@ -178,9 +181,9 @@ D6F953E9212519B800CF0F2B /* View Controllers */ = { isa = PBXGroup; children = ( - D6D4DDD1212518A000E1C4BB /* ViewController.swift */, - D6F953EB212519E700CF0F2B /* StatusesTableViewController.swift */, + D6F953EB212519E700CF0F2B /* TimelineTableViewController.swift */, D64D0AB02128D9AE005A6F37 /* OnboardingViewController.swift */, + 04DACE8B212CB14B009840C4 /* MainTabBarViewController.swift */, ); path = "View Controllers"; sourceTree = ""; @@ -189,7 +192,7 @@ isa = PBXGroup; children = ( D6D4DDD3212518A000E1C4BB /* Main.storyboard */, - D6F953ED21251A0700CF0F2B /* Statuses.storyboard */, + D6F953ED21251A0700CF0F2B /* Timeline.storyboard */, D64D0AAE2128D954005A6F37 /* Onboarding.storyboard */, ); path = Storyboards; @@ -311,7 +314,7 @@ D6D4DDDA212518A200E1C4BB /* LaunchScreen.storyboard in Resources */, D64D0AAF2128D954005A6F37 /* Onboarding.storyboard in Resources */, D6D4DDD7212518A200E1C4BB /* Assets.xcassets in Resources */, - D6F953EE21251A0700CF0F2B /* Statuses.storyboard in Resources */, + D6F953EE21251A0700CF0F2B /* Timeline.storyboard in Resources */, D6D4DDD5212518A000E1C4BB /* Main.storyboard in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -337,12 +340,13 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 04DACE8A212CA6B7009840C4 /* Timeline.swift in Sources */, + 04DACE8C212CB14B009840C4 /* MainTabBarViewController.swift in Sources */, D6F953F021251A2900CF0F2B /* MastodonController.swift in Sources */, D6BED174212667E900F02DA0 /* StatusTableViewCell.swift in Sources */, - D6D4DDD2212518A000E1C4BB /* ViewController.swift in Sources */, D64D0AAD2128D88B005A6F37 /* LocalData.swift in Sources */, D64D0AB12128D9AE005A6F37 /* OnboardingViewController.swift in Sources */, - D6F953EC212519E700CF0F2B /* StatusesTableViewController.swift in Sources */, + D6F953EC212519E700CF0F2B /* TimelineTableViewController.swift in Sources */, D6D4DDD0212518A000E1C4BB /* AppDelegate.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/Tusker/Storyboards/Base.lproj/Main.storyboard b/Tusker/Storyboards/Base.lproj/Main.storyboard index a23c0b37a1..10e4025d8a 100644 --- a/Tusker/Storyboards/Base.lproj/Main.storyboard +++ b/Tusker/Storyboards/Base.lproj/Main.storyboard @@ -8,28 +8,16 @@ - - - - - - - - - - - + - + + - - - diff --git a/Tusker/Storyboards/Statuses.storyboard b/Tusker/Storyboards/Timeline.storyboard similarity index 96% rename from Tusker/Storyboards/Statuses.storyboard rename to Tusker/Storyboards/Timeline.storyboard index 705c924282..37565668e4 100644 --- a/Tusker/Storyboards/Statuses.storyboard +++ b/Tusker/Storyboards/Timeline.storyboard @@ -8,10 +8,10 @@ - + - + @@ -69,6 +69,7 @@ + @@ -79,11 +80,11 @@ - + - + diff --git a/Tusker/Timeline.swift b/Tusker/Timeline.swift new file mode 100644 index 0000000000..bbd33e04de --- /dev/null +++ b/Tusker/Timeline.swift @@ -0,0 +1,27 @@ +// +// Timeline.swift +// Tusker +// +// Created by Shadowfactson 8/21/18. +// Copyright © 2018 Shadowfacts. All rights reserved. +// + +import Foundation +import MastodonKit + +enum Timeline { + + case home, local, federated + + func request(range: RequestRange = .default) -> Request<[Status]> { + switch self { + case .home: + return Timelines.home(range: range) + case .local: + return Timelines.public(local: true, range: range) + case .federated: + return Timelines.public(local: false, range: range) + } + } + +} diff --git a/Tusker/View Controllers/MainTabBarViewController.swift b/Tusker/View Controllers/MainTabBarViewController.swift new file mode 100644 index 0000000000..10d68452ee --- /dev/null +++ b/Tusker/View Controllers/MainTabBarViewController.swift @@ -0,0 +1,34 @@ +// +// MainTabBarViewController.swift +// Tusker +// +// Created by Shadowfactson 8/21/18. +// Copyright © 2018 Shadowfacts. All rights reserved. +// + +import UIKit + +class MainTabBarViewController: UITabBarController { + + override func viewDidLoad() { + super.viewDidLoad() + + viewControllers = [ + TimelineTableViewController.create(for: .home), + TimelineTableViewController.create(for: .federated), + TimelineTableViewController.create(for: .local) + ] + } + + + /* + // MARK: - Navigation + + // In a storyboard-based application, you will often want to do a little preparation before navigation + override func prepare(for segue: UIStoryboardSegue, sender: Any?) { + // Get the new view controller using segue.destination. + // Pass the selected object to the new view controller. + } + */ + +} diff --git a/Tusker/View Controllers/StatusesTableViewController.swift b/Tusker/View Controllers/TimelineTableViewController.swift similarity index 75% rename from Tusker/View Controllers/StatusesTableViewController.swift rename to Tusker/View Controllers/TimelineTableViewController.swift index 1137142b0a..7fb78803cf 100644 --- a/Tusker/View Controllers/StatusesTableViewController.swift +++ b/Tusker/View Controllers/TimelineTableViewController.swift @@ -10,8 +10,26 @@ import UIKit import MastodonKit import SwiftSoup -class StatusesTableViewController: UITableViewController { +class TimelineTableViewController: UITableViewController { + static func create(for timeline: Timeline) -> UIViewController { + guard let navigationController = UIStoryboard(name: "Timeline", bundle: nil).instantiateInitialViewController() as? UINavigationController, + let timelineController = navigationController.topViewController as? TimelineTableViewController else { fatalError() } + timelineController.timeline = timeline + switch timeline { + case .home: + navigationController.tabBarItem.title = "Home" + case .local: + navigationController.tabBarItem.title = "Local" + case .federated: + navigationController.tabBarItem.title = "Federated" + } + + return navigationController + } + + var timeline: Timeline! + var statuses: [Status] = [] { didSet { DispatchQueue.main.async { @@ -25,7 +43,7 @@ class StatusesTableViewController: UITableViewController { override func viewWillAppear(_ animated: Bool) { guard MastodonController.shared.client?.accessToken != nil else { return } - MastodonController.shared.client.run(Timelines.home()) { result in + MastodonController.shared.client.run(timeline.request()) { result in guard case let .success(statuses, pagination) = result else { fatalError() } self.statuses = statuses self.newer = pagination?.previous @@ -80,7 +98,7 @@ class StatusesTableViewController: UITableViewController { if indexPath.row == statuses.count - 1 { guard let older = older else { return } - MastodonController.shared.client.run(Timelines.home(range: older)) { result in + MastodonController.shared.client.run(timeline.request(range: older)) { result in guard case let .success(newStatuses, pagination) = result else { fatalError() } self.older = pagination?.next self.statuses.append(contentsOf: newStatuses) @@ -91,7 +109,7 @@ class StatusesTableViewController: UITableViewController { @IBAction func refreshStatuses(_ sender: Any) { guard let newer = newer else { return } - MastodonController.shared.client.run(Timelines.home(range: newer)) { result in + MastodonController.shared.client.run(timeline.request(range: newer)) { result in guard case let .success(newStatuses, pagination) = result else { fatalError() } self.newer = pagination?.previous self.statuses.insert(contentsOf: newStatuses, at: 0) diff --git a/Tusker/View Controllers/ViewController.swift b/Tusker/View Controllers/ViewController.swift deleted file mode 100644 index 98b00ceebf..0000000000 --- a/Tusker/View Controllers/ViewController.swift +++ /dev/null @@ -1,20 +0,0 @@ -// -// ViewController.swift -// Tusker -// -// Created by Shadowfacts on 8/15/18. -// Copyright © 2018 Shadowfacts. All rights reserved. -// - -import UIKit - -class ViewController: UIViewController { - - override func viewDidLoad() { - super.viewDidLoad() - // Do any additional setup after loading the view, typically from a nib. - } - - -} -