From 24d30d36b7f673a3f2d2b629df8499bac292d353 Mon Sep 17 00:00:00 2001 From: Shadowfacts Date: Thu, 16 Aug 2018 22:39:16 -0400 Subject: [PATCH] Start home timeline --- .gitmodules | 3 + SwiftSoup | 1 + Tusker.xcodeproj/project.pbxproj | 18 +++++ Tusker.xcworkspace/contents.xcworkspacedata | 3 + Tusker/Controllers/MastodonController.swift | 5 ++ Tusker/Storyboards/Base.lproj/Main.storyboard | 39 +++++++---- Tusker/Storyboards/Statuses.storyboard | 67 +++++++++++++++++-- .../StatusesTableViewController.swift | 39 ++++++++--- Tusker/Views/StatusTableViewCell.swift | 29 ++++++++ 9 files changed, 177 insertions(+), 27 deletions(-) create mode 160000 SwiftSoup create mode 100644 Tusker/Views/StatusTableViewCell.swift diff --git a/.gitmodules b/.gitmodules index ad4df465..d364a01a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "MastodonKit"] path = MastodonKit url = git://github.com/MastodonKit/MastodonKit.git +[submodule "SwiftSoup"] + path = SwiftSoup + url = git://github.com/scinfu/SwiftSoup.git diff --git a/SwiftSoup b/SwiftSoup new file mode 160000 index 00000000..f445c906 --- /dev/null +++ b/SwiftSoup @@ -0,0 +1 @@ +Subproject commit f445c9067d28346e828e615e2b43cb07b20bca35 diff --git a/Tusker.xcodeproj/project.pbxproj b/Tusker.xcodeproj/project.pbxproj index 62ded57c..7cd2edd2 100644 --- a/Tusker.xcodeproj/project.pbxproj +++ b/Tusker.xcodeproj/project.pbxproj @@ -7,6 +7,9 @@ objects = { /* Begin PBXBuildFile section */ + D6BED16F212663DA00F02DA0 /* SwiftSoup.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D6BED16E212663DA00F02DA0 /* SwiftSoup.framework */; }; + 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 */; }; @@ -46,6 +49,7 @@ dstSubfolderSpec = 10; files = ( D6F953E8212519A400CF0F2B /* MastodonKit.framework in Embed Frameworks */, + D6BED170212663DA00F02DA0 /* SwiftSoup.framework in Embed Frameworks */, ); name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; @@ -53,6 +57,8 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + D6BED16E212663DA00F02DA0 /* SwiftSoup.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = SwiftSoup.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 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 = ""; }; @@ -78,6 +84,7 @@ buildActionMask = 2147483647; files = ( D6F953E7212519A400CF0F2B /* MastodonKit.framework in Frameworks */, + D6BED16F212663DA00F02DA0 /* SwiftSoup.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -98,9 +105,18 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + D6BED1722126661300F02DA0 /* Views */ = { + isa = PBXGroup; + children = ( + D6BED173212667E900F02DA0 /* StatusTableViewCell.swift */, + ); + path = Views; + sourceTree = ""; + }; D6D4DDC3212518A000E1C4BB = { isa = PBXGroup; children = ( + D6BED16E212663DA00F02DA0 /* SwiftSoup.framework */, D6F953E6212519A400CF0F2B /* MastodonKit.framework */, D6D4DDCE212518A000E1C4BB /* Tusker */, D6D4DDE3212518A200E1C4BB /* TuskerTests */, @@ -125,6 +141,7 @@ D6D4DDCF212518A000E1C4BB /* AppDelegate.swift */, D6F953F121251A2F00CF0F2B /* Controllers */, D6F953E9212519B800CF0F2B /* View Controllers */, + D6BED1722126661300F02DA0 /* Views */, D6F953EA212519BE00CF0F2B /* Storyboards */, D6D4DDD6212518A200E1C4BB /* Assets.xcassets */, D6D4DDD8212518A200E1C4BB /* LaunchScreen.storyboard */, @@ -311,6 +328,7 @@ buildActionMask = 2147483647; files = ( D6F953F021251A2900CF0F2B /* MastodonController.swift in Sources */, + D6BED174212667E900F02DA0 /* StatusTableViewCell.swift in Sources */, D6D4DDD2212518A000E1C4BB /* ViewController.swift in Sources */, D6F953EC212519E700CF0F2B /* StatusesTableViewController.swift in Sources */, D6D4DDD0212518A000E1C4BB /* AppDelegate.swift in Sources */, diff --git a/Tusker.xcworkspace/contents.xcworkspacedata b/Tusker.xcworkspace/contents.xcworkspacedata index dc1172ae..9a8e8fd8 100644 --- a/Tusker.xcworkspace/contents.xcworkspacedata +++ b/Tusker.xcworkspace/contents.xcworkspacedata @@ -7,4 +7,7 @@ + + diff --git a/Tusker/Controllers/MastodonController.swift b/Tusker/Controllers/MastodonController.swift index 5e48a338..eb51b767 100644 --- a/Tusker/Controllers/MastodonController.swift +++ b/Tusker/Controllers/MastodonController.swift @@ -35,6 +35,11 @@ class MastodonController { login() } + + client.run(Accounts.currentUser()) { result in + guard case let .success(account, _) = result else { fatalError() } + print(account.acct) + } } private func register(completion: @escaping () -> Void) { diff --git a/Tusker/Storyboards/Base.lproj/Main.storyboard b/Tusker/Storyboards/Base.lproj/Main.storyboard index 0101e92c..a23c0b37 100644 --- a/Tusker/Storyboards/Base.lproj/Main.storyboard +++ b/Tusker/Storyboards/Base.lproj/Main.storyboard @@ -1,28 +1,39 @@ - + - - - + + - - - - - - - - - + + + + - + + + + + + + + + + + + + + + + + + diff --git a/Tusker/Storyboards/Statuses.storyboard b/Tusker/Storyboards/Statuses.storyboard index 14a9b969..f4ca6ff3 100644 --- a/Tusker/Storyboards/Statuses.storyboard +++ b/Tusker/Storyboards/Statuses.storyboard @@ -1,5 +1,5 @@ - + @@ -17,13 +17,48 @@ - - + + - + + + + + + + + + + + + + + + + + + + + + @@ -31,10 +66,32 @@ + + - + + + + + + + + + + + + + + + + + + + + + diff --git a/Tusker/View Controllers/StatusesTableViewController.swift b/Tusker/View Controllers/StatusesTableViewController.swift index f1727671..9fc79b04 100644 --- a/Tusker/View Controllers/StatusesTableViewController.swift +++ b/Tusker/View Controllers/StatusesTableViewController.swift @@ -7,12 +7,32 @@ // import UIKit +import MastodonKit +import SwiftSoup class StatusesTableViewController: UITableViewController { + var statuses: [Status] = [] { + didSet { + DispatchQueue.main.async { + self.tableView.reloadData() + } + } + } + + override func viewWillAppear(_ animated: Bool) { + MastodonController.shared.client.run(Timelines.home()) { result in + guard case let .success(statuses, _) = result else { fatalError() } + self.statuses = statuses + } + } + override func viewDidLoad() { super.viewDidLoad() + tableView.rowHeight = UITableView.automaticDimension + tableView.estimatedRowHeight = 140 + // Uncomment the following line to preserve selection between presentations // self.clearsSelectionOnViewWillAppear = false @@ -23,24 +43,27 @@ class StatusesTableViewController: UITableViewController { // MARK: - Table view data source override func numberOfSections(in tableView: UITableView) -> Int { - // #warning Incomplete implementation, return the number of sections - return 0 + return 1 } override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { // #warning Incomplete implementation, return the number of rows - return 0 + return statuses.count } - /* + override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { - let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath) - - // Configure the cell... + guard let cell = tableView.dequeueReusableCell(withIdentifier: "statusCell", for: indexPath) as? StatusTableViewCell else { + fatalError() + } + + let status = statuses[indexPath.row] + + cell.updateUI(for: status) return cell } - */ + /* // Override to support conditional editing of the table view. diff --git a/Tusker/Views/StatusTableViewCell.swift b/Tusker/Views/StatusTableViewCell.swift new file mode 100644 index 00000000..640090c5 --- /dev/null +++ b/Tusker/Views/StatusTableViewCell.swift @@ -0,0 +1,29 @@ +// +// StatusTableViewCell.swift +// Tusker +// +// Created by Shadowfacts on 8/16/18. +// Copyright © 2018 Shadowfacts. All rights reserved. +// + +import UIKit +import MastodonKit +import SwiftSoup + +class StatusTableViewCell: UITableViewCell { + + @IBOutlet weak var displayNameLabel: UILabel! + @IBOutlet weak var usernameLabel: UILabel! + @IBOutlet weak var contentLabel: UILabel! + + func updateUI(for status: Status) { + displayNameLabel.text = status.account.displayName + usernameLabel.text = "@\(status.account.acct)" + + let doc = try! SwiftSoup.parse(status.content) + let text = (try! doc.body()?.text())! + + contentLabel.text = text + } + +}