Browse Source

Development

master
Dwayne Harris 6 years ago
parent
commit
55662cf2dc
  1. 3
      .gitmodules
  2. 1
      Frameworks/FLAnimatedImage
  3. 65
      elpha-ios.xcodeproj/project.pbxproj
  4. 65
      elpha-ios/AbstractStatusTableViewController.swift
  5. 109
      elpha-ios/AccountTableViewController.swift
  6. 3
      elpha-ios/AuthenticateViewController.swift
  7. 8
      elpha-ios/Base.lproj/Main.storyboard
  8. 39
      elpha-ios/CellHeightManager.swift
  9. 63
      elpha-ios/StatusTableViewController.swift
  10. 14
      elpha-ios/StatusView.swift
  11. 109
      elpha-ios/TimelineTableViewController.swift
  12. 5
      elpha-ios/UITextViewFixed.swift

3
.gitmodules

@ -7,3 +7,6 @@
[submodule "Frameworks/AlamofireNetworkActivityIndicator"]
path = Frameworks/AlamofireNetworkActivityIndicator
url = https://github.com/Alamofire/AlamofireNetworkActivityIndicator.git
[submodule "Frameworks/FLAnimatedImage"]
path = Frameworks/FLAnimatedImage
url = https://github.com/Flipboard/FLAnimatedImage.git

1
Frameworks/FLAnimatedImage

@ -0,0 +1 @@
Subproject commit 16fe62b540f63294cfdfdcd04ebcd9e2c093819c

65
elpha-ios.xcodeproj/project.pbxproj

@ -18,6 +18,10 @@
152734D22186DC74003DB3C8 /* TimelinesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 152734D12186DC74003DB3C8 /* TimelinesViewController.swift */; };
152FB0F8218ADC1A001D6574 /* AttachmentPageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 152FB0F7218ADC1A001D6574 /* AttachmentPageViewController.swift */; };
152FB0FA218ADDD0001D6574 /* AttachmentViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 152FB0F9218ADDD0001D6574 /* AttachmentViewController.swift */; };
152FBCD2219682E80079B3E8 /* AbstractStatusTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 152FBCD1219682E80079B3E8 /* AbstractStatusTableViewController.swift */; };
152FBCE621978C4A0079B3E8 /* CellHeightManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 152FBCE521978C4A0079B3E8 /* CellHeightManager.swift */; };
152FBCED219799FC0079B3E8 /* FLAnimatedImage.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 152FBCEC219799E50079B3E8 /* FLAnimatedImage.framework */; };
152FBCEE219799FC0079B3E8 /* FLAnimatedImage.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 152FBCEC219799E50079B3E8 /* FLAnimatedImage.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
1539509121894A38009BA6E7 /* AlertManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1539509021894A38009BA6E7 /* AlertManager.swift */; };
156FF015217289380074D9CA /* AccountTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 156FF014217289380074D9CA /* AccountTableViewCell.swift */; };
156FF0312174797E0074D9CA /* StatusTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 156FF0302174797E0074D9CA /* StatusTableViewController.swift */; };
@ -150,6 +154,20 @@
remoteGlobalIDString = 4CB928381C66E1A600CE5F08;
remoteInfo = AlamofireNetworkActivityIndicator;
};
152FBCEB219799E50079B3E8 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 152FBCE7219799E50079B3E8 /* FLAnimatedImage.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 92C9BC0C1B199DC500D79B06;
remoteInfo = FLAnimatedImage;
};
152FBCEF219799FC0079B3E8 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 152FBCE7219799E50079B3E8 /* FLAnimatedImage.xcodeproj */;
proxyType = 1;
remoteGlobalIDString = 92C9BC0B1B199DC500D79B06;
remoteInfo = FLAnimatedImage;
};
157405C2215890BC00EEAAEB /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 157405B7215890BC00EEAAEB /* Alamofire.xcodeproj */;
@ -209,6 +227,7 @@
dstSubfolderSpec = 10;
files = (
151AD4D9216899AD00F07403 /* AlamofireImage.framework in Embed Frameworks */,
152FBCEE219799FC0079B3E8 /* FLAnimatedImage.framework in Embed Frameworks */,
151AD4E621689A0F00F07403 /* Alamofire.framework in Embed Frameworks */,
1522EC802193EBCB0082C3FA /* AlamofireNetworkActivityIndicator.framework in Embed Frameworks */,
);
@ -227,6 +246,9 @@
152734D12186DC74003DB3C8 /* TimelinesViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelinesViewController.swift; sourceTree = "<group>"; };
152FB0F7218ADC1A001D6574 /* AttachmentPageViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttachmentPageViewController.swift; sourceTree = "<group>"; };
152FB0F9218ADDD0001D6574 /* AttachmentViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttachmentViewController.swift; sourceTree = "<group>"; };
152FBCD1219682E80079B3E8 /* AbstractStatusTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AbstractStatusTableViewController.swift; sourceTree = "<group>"; };
152FBCE521978C4A0079B3E8 /* CellHeightManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CellHeightManager.swift; sourceTree = "<group>"; };
152FBCE7219799E50079B3E8 /* FLAnimatedImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = FLAnimatedImage.xcodeproj; path = Frameworks/FLAnimatedImage/FLAnimatedImage.xcodeproj; sourceTree = "<group>"; };
1539509021894A38009BA6E7 /* AlertManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlertManager.swift; sourceTree = "<group>"; };
156FF014217289380074D9CA /* AccountTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountTableViewCell.swift; sourceTree = "<group>"; };
156FF0302174797E0074D9CA /* StatusTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusTableViewController.swift; sourceTree = "<group>"; };
@ -274,6 +296,7 @@
buildActionMask = 2147483647;
files = (
15A79B2E215C63B6007A326E /* AlamofireImage.framework in Frameworks */,
152FBCED219799FC0079B3E8 /* FLAnimatedImage.framework in Frameworks */,
157405D1215890D700EEAAEB /* Alamofire.framework in Frameworks */,
1522EC7F2193EBCB0082C3FA /* AlamofireNetworkActivityIndicator.framework in Frameworks */,
);
@ -312,6 +335,7 @@
1539509021894A38009BA6E7 /* AlertManager.swift */,
1574148C2169AD0100C841BD /* AttachmentManager.swift */,
15960E7B213272CD00C38CE9 /* AuthenticationManager.swift */,
152FBCE521978C4A0079B3E8 /* CellHeightManager.swift */,
15A79B42215EB959007A326E /* CoreDataManager.swift */,
157405B32151A93E00EEAAEB /* InstancesDataManager.swift */,
15F998342162C0E8009E58DA /* MastodonDataManager.swift */,
@ -362,6 +386,22 @@
name = Products;
sourceTree = "<group>";
};
152FBCE4219789450079B3E8 /* Abstract View Controllers */ = {
isa = PBXGroup;
children = (
152FBCD1219682E80079B3E8 /* AbstractStatusTableViewController.swift */,
);
name = "Abstract View Controllers";
sourceTree = "<group>";
};
152FBCE8219799E50079B3E8 /* Products */ = {
isa = PBXGroup;
children = (
152FBCEC219799E50079B3E8 /* FLAnimatedImage.framework */,
);
name = Products;
sourceTree = "<group>";
};
156FF05621779C140074D9CA /* API */ = {
isa = PBXGroup;
children = (
@ -399,6 +439,7 @@
157405B7215890BC00EEAAEB /* Alamofire.xcodeproj */,
1517EA6F2159D72200DE80D6 /* AlamofireImage.xcodeproj */,
1522EC752193EBA10082C3FA /* AlamofireNetworkActivityIndicator.xcodeproj */,
152FBCE7219799E50079B3E8 /* FLAnimatedImage.xcodeproj */,
15960E59213145E100C38CE9 /* elpha-ios */,
15960E58213145E100C38CE9 /* Products */,
157405D0215890D700EEAAEB /* Frameworks */,
@ -428,6 +469,7 @@
151AD4AC2166DD0200F07403 /* Managers */,
151AD4AD2166DD1B00F07403 /* Reusable Views */,
151AD4AB2166DCEE00F07403 /* Storyboards */,
152FBCE4219789450079B3E8 /* Abstract View Controllers */,
15960E782132383600C38CE9 /* View Controllers */,
151AD4AE2166DD3500F07403 /* Views */,
);
@ -480,6 +522,7 @@
151AD4DB216899AD00F07403 /* PBXTargetDependency */,
151AD4E821689A0F00F07403 /* PBXTargetDependency */,
1522EC822193EBCB0082C3FA /* PBXTargetDependency */,
152FBCF0219799FC0079B3E8 /* PBXTargetDependency */,
);
name = "elpha-ios";
productName = "elpha-ios";
@ -526,6 +569,10 @@
ProductGroup = 1522EC762193EBA10082C3FA /* Products */;
ProjectRef = 1522EC752193EBA10082C3FA /* AlamofireNetworkActivityIndicator.xcodeproj */;
},
{
ProductGroup = 152FBCE8219799E50079B3E8 /* Products */;
ProjectRef = 152FBCE7219799E50079B3E8 /* FLAnimatedImage.xcodeproj */;
},
);
projectRoot = "";
targets = (
@ -605,6 +652,13 @@
remoteRef = 1522EC7D2193EBA10082C3FA /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
152FBCEC219799E50079B3E8 /* FLAnimatedImage.framework */ = {
isa = PBXReferenceProxy;
fileType = wrapper.framework;
path = FLAnimatedImage.framework;
remoteRef = 152FBCEB219799E50079B3E8 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
157405C3215890BC00EEAAEB /* Alamofire.framework */ = {
isa = PBXReferenceProxy;
fileType = wrapper.framework;
@ -707,11 +761,13 @@
15960E7321322BC700C38CE9 /* KeychainItemAccessibility.swift in Sources */,
156FF051217683270074D9CA /* StatusTableViewCell.swift in Sources */,
159026D02163069600D362DD /* Date+TimeAgo.swift in Sources */,
152FBCD2219682E80079B3E8 /* AbstractStatusTableViewController.swift in Sources */,
15A79B43215EB959007A326E /* CoreDataManager.swift in Sources */,
15BB72AB2171A8D4002F1FA4 /* TimelinesTableViewCell.swift in Sources */,
1574148D2169AD0100C841BD /* AttachmentManager.swift in Sources */,
156FF015217289380074D9CA /* AccountTableViewCell.swift in Sources */,
15960E822136668500C38CE9 /* TimelinesNavigationController.swift in Sources */,
152FBCE621978C4A0079B3E8 /* CellHeightManager.swift in Sources */,
156FF04F2175CDBC0074D9CA /* MainStatusTableViewCell.swift in Sources */,
159026AE2162CF5600D362DD /* TimelineTableViewCell.swift in Sources */,
);
@ -735,6 +791,11 @@
name = AlamofireNetworkActivityIndicator;
targetProxy = 1522EC812193EBCB0082C3FA /* PBXContainerItemProxy */;
};
152FBCF0219799FC0079B3E8 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = FLAnimatedImage;
targetProxy = 152FBCEF219799FC0079B3E8 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
@ -878,7 +939,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_IDENTITY = "iPhone Developer";
CODE_SIGN_STYLE = Manual;
DEVELOPMENT_TEAM = "";
DEVELOPMENT_TEAM = 4HV9QP2X8X;
INFOPLIST_FILE = "elpha-ios/Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 12.1;
LD_RUNPATH_SEARCH_PATHS = (
@ -887,7 +948,7 @@
);
PRODUCT_BUNDLE_IDENTIFIER = "xyz.elpha.elpha-ios";
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
PROVISIONING_PROFILE_SPECIFIER = Elpha;
SWIFT_VERSION = 4.2;
TARGETED_DEVICE_FAMILY = 1;
};

65
elpha-ios/AbstractStatusTableViewController.swift

@ -0,0 +1,65 @@
//
// ELStatusTableViewController.swift
// elpha-ios
//
// Created by Dwayne Harris on 11/9/18.
// Copyright © 2018 Elpha. All rights reserved.
//
import UIKit
import SafariServices
class AbstractStatusTableViewController: UITableViewController, StatusViewDelegate {
let fetchLimit = 20
var loading: Bool = false
var currentPaginationContext: String = ""
var cellHeightsDictionary: NSMutableDictionary = [:]
func accountTapped(account: AccountMO) {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
if let controller = storyboard.instantiateViewController(withIdentifier: "AccountTableViewController") as? AccountTableViewController {
controller.account = account
self.navigationController?.pushViewController(controller, animated: true)
}
}
func statusTapped(status: StatusMO) {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
if let controller = storyboard.instantiateViewController(withIdentifier: "StatusTableViewController") as? StatusTableViewController {
controller.status = status
self.navigationController?.pushViewController(controller, animated: true)
}
}
func loadMoreTapped(status: StatusMO, direction: PaginationDirection) {
}
func attachmentTapped(status: StatusMO, index: Int) {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
if let controller = storyboard.instantiateViewController(withIdentifier: "AttachmentPageViewController") as? AttachmentPageViewController {
controller.status = status
controller.attachmentIndex = index
present(controller, animated: false)
}
}
func urlTapped(url: URL) {
let controller = SFSafariViewController(url: url)
controller.delegate = self
controller.dismissButtonStyle = .done
controller.preferredControlTintColor = UIColor(named: "Primary")
present(controller, animated: true)
}
}
extension AbstractStatusTableViewController: SFSafariViewControllerDelegate {
func safariViewControllerDidFinish(_ controller: SFSafariViewController) {
controller.dismiss(animated: true)
}
}

109
elpha-ios/AccountTableViewController.swift

@ -11,7 +11,7 @@ import CoreData
import UIKit
import SafariServices
class AccountTableViewController: UITableViewController {
class AccountTableViewController: AbstractStatusTableViewController {
@IBOutlet var headerView: UIView!
@IBOutlet var headerImageView: UIImageView!
@IBOutlet var avatarImageView: UIImageView!
@ -23,21 +23,25 @@ class AccountTableViewController: UITableViewController {
@IBOutlet var followersLabel: UILabel!
@IBOutlet var statusTypeSegmentedControl: UISegmentedControl!
let fetchLimit = 20
var fetchedResultsController: NSFetchedResultsController<StatusMO>? = nil
var account: AccountMO? = nil
var loading: Bool = false
var currentPaginationContext: String {
guard let account = self.account else {
return ""
override var currentPaginationContext: String {
get {
guard let account = self.account else {
return ""
}
switch statusTypeSegmentedControl.selectedSegmentIndex {
case 3:
return "timeline:favorites"
case let index:
return "account:\(account.acct!):\(index)"
}
}
switch statusTypeSegmentedControl.selectedSegmentIndex {
case 3:
return "timeline:favorites"
case let index:
return "account:\(account.acct!):\(index)"
set {
}
}
@ -113,6 +117,20 @@ class AccountTableViewController: UITableViewController {
}
}
override func loadMoreTapped(status: StatusMO, direction: PaginationDirection) {
if let markers = status.markers {
markers.forEach { marker in
if marker.context == self.currentPaginationContext && marker.item.direction == direction {
fetchStatuses(withPagination: marker.item) { error in
if error != nil {
AlertManager.shared.show(message: error!.localizedDescription, category: .error)
}
}
}
}
}
}
@objc func fetch() {
fetchStatuses { error in
if error != nil {
@ -260,6 +278,16 @@ extension AccountTableViewController: NSFetchedResultsControllerDelegate {
return 1
}
override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
if let cell = cell as? AccountTableViewCell {
CellHeightManager.set(status: cell.statusView.status, height: cell.frame.size.height)
}
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return CellHeightManager.get(status: fetchedResultsController?.object(at: indexPath))
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
guard let count = fetchedResultsController?.fetchedObjects?.count else {
return 0
@ -321,62 +349,3 @@ extension AccountTableViewController: NSFetchedResultsControllerDelegate {
return cell
}
}
extension AccountTableViewController: StatusViewDelegate {
func accountTapped(account: AccountMO) {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
if let controller = storyboard.instantiateViewController(withIdentifier: "AccountTableViewController") as? AccountTableViewController {
controller.account = account
self.navigationController?.pushViewController(controller, animated: true)
}
}
func statusTapped(status: StatusMO) {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
if let controller = storyboard.instantiateViewController(withIdentifier: "StatusTableViewController") as? StatusTableViewController {
controller.status = status
self.navigationController?.pushViewController(controller, animated: true)
}
}
func loadMoreTapped(status: StatusMO, direction: PaginationDirection) {
if let markers = status.markers {
markers.forEach { marker in
if marker.context == self.currentPaginationContext && marker.item.direction == direction {
fetchStatuses(withPagination: marker.item) { error in
if error != nil {
AlertManager.shared.show(message: error!.localizedDescription, category: .error)
}
}
}
}
}
}
func attachmentTapped(status: StatusMO, index: Int) {
if let controller = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "AttachmentPageViewController") as? AttachmentPageViewController {
controller.status = status
controller.attachmentIndex = index
present(controller, animated: false)
}
}
func urlTapped(url: URL) {
let controller = SFSafariViewController(url: url)
controller.delegate = self
controller.dismissButtonStyle = .done
// controller.preferredBarTintColor = UIColor(named: "Secondary")
controller.preferredControlTintColor = UIColor(named: "Text")
present(controller, animated: true)
}
}
extension AccountTableViewController: SFSafariViewControllerDelegate {
func safariViewControllerDidFinish(_ controller: SFSafariViewController) {
controller.dismiss(animated: true)
}
}

3
elpha-ios/AuthenticateViewController.swift

@ -54,8 +54,7 @@ class AuthenticateViewController: UIViewController {
let controller = SFSafariViewController(url: authorizeURL!)
controller.delegate = self
controller.dismissButtonStyle = .cancel
controller.preferredBarTintColor = UIColor(named: "Secondary")
controller.preferredControlTintColor = UIColor(named: "Text")
controller.preferredControlTintColor = UIColor(named: "Primary")
present(controller, animated: true)
}

8
elpha-ios/Base.lproj/Main.storyboard

@ -1237,10 +1237,10 @@
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" maximumZoomScale="6" translatesAutoresizingMaskIntoConstraints="NO" id="7ll-rV-5Xs">
<rect key="frame" x="0.0" y="83" width="375" height="464"/>
<rect key="frame" x="0.0" y="83" width="375" height="514"/>
<subviews>
<imageView multipleTouchEnabled="YES" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="LVW-zt-JUe">
<rect key="frame" x="0.0" y="0.0" width="375" height="464"/>
<rect key="frame" x="0.0" y="0.0" width="375" height="514"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<gestureRecognizers/>
</imageView>
@ -1256,11 +1256,11 @@
</constraints>
</scrollView>
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" editable="NO" text="Content" textAlignment="center" selectable="NO" translatesAutoresizingMaskIntoConstraints="NO" id="hd1-Nu-84c">
<rect key="frame" x="8" y="562" width="359" height="150"/>
<rect key="frame" x="8" y="612" width="359" height="100"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<color key="tintColor" name="Secondary"/>
<constraints>
<constraint firstAttribute="height" constant="150" id="qx0-dd-I7h"/>
<constraint firstAttribute="height" constant="100" id="qx0-dd-I7h"/>
</constraints>
<color key="textColor" name="Background Primary"/>
<fontDescription key="fontDescription" name=".AppleSystemUIFont" family=".AppleSystemUIFont" pointSize="17"/>

39
elpha-ios/CellHeightManager.swift

@ -0,0 +1,39 @@
//
// CellHeightManager.swift
// elpha-ios
//
// Created by Dwayne Harris on 11/10/18.
// Copyright © 2018 Elpha. All rights reserved.
//
import UIKit
class CellHeightManager {
static private var cellHeightsDictionary: NSMutableDictionary = [:]
static func set(statusID: String, height: CGFloat) {
cellHeightsDictionary[statusID] = height
}
static func set(status: StatusMO?, height: CGFloat) {
if let id = status?.id {
set(statusID: id, height: height)
}
}
static func get(statusID: String) -> CGFloat {
if let height = cellHeightsDictionary[statusID] as? CGFloat {
return height
}
return UITableView.automaticDimension
}
static func get(status: StatusMO?) -> CGFloat {
if let id = status?.id {
return get(statusID: id)
}
return UITableView.automaticDimension
}
}

63
elpha-ios/StatusTableViewController.swift

@ -15,12 +15,12 @@ enum StatusType {
case ancestor, status, descendant
}
class StatusTableViewController: UITableViewController, UIGestureRecognizerDelegate {
class StatusTableViewController: AbstractStatusTableViewController, UIGestureRecognizerDelegate {
public var status: StatusMO? = nil
var ancestors: [StatusMO] = []
var descendants: [StatusMO] = []
var feedbackGenerator: UINotificationFeedbackGenerator? = nil
var loading: Bool = false
override func viewDidLoad() {
super.viewDidLoad()
@ -209,6 +209,20 @@ extension StatusTableViewController {
return 3
}
override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
if let cell = cell as? StatusTableViewCell {
CellHeightManager.set(status: cell.statusView.status, height: cell.frame.size.height)
}
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
switch indexPath.section {
case 0: return CellHeightManager.get(status: self.ancestors[indexPath.row])
case 2: return CellHeightManager.get(status: self.descendants[indexPath.row])
default: return UITableView.automaticDimension
}
}
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
let height = CGFloat(25)
@ -330,44 +344,7 @@ extension StatusTableViewController {
}
}
extension StatusTableViewController: StatusViewDelegate {
func accountTapped(account: AccountMO) {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
if let controller = storyboard.instantiateViewController(withIdentifier: "AccountTableViewController") as? AccountTableViewController {
controller.account = account
self.navigationController?.pushViewController(controller, animated: true)
}
}
func statusTapped(status: StatusMO) {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
if let controller = storyboard.instantiateViewController(withIdentifier: "StatusTableViewController") as? StatusTableViewController {
controller.status = status
self.navigationController?.pushViewController(controller, animated: true)
}
}
func attachmentTapped(status: StatusMO, index: Int) {
if let controller = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "AttachmentPageViewController") as? AttachmentPageViewController {
controller.status = status
controller.attachmentIndex = index
present(controller, animated: false)
}
}
func urlTapped(url: URL) {
let controller = SFSafariViewController(url: url)
controller.delegate = self
controller.dismissButtonStyle = .done
// controller.preferredBarTintColor = UIColor(named: "Secondary")
controller.preferredControlTintColor = UIColor(named: "Text")
present(controller, animated: true)
}
extension StatusTableViewController {
func boostTapped() {
loadStatuses()
}
@ -385,12 +362,6 @@ extension StatusTableViewController: StatusViewDelegate {
}
}
extension StatusTableViewController: SFSafariViewControllerDelegate {
func safariViewControllerDidFinish(_ controller: SFSafariViewController) {
controller.dismiss(animated: true)
}
}
extension StatusTableViewController: AttachmentManagerDelegate {
func attachmentTapped(index: Int) {
self.attachmentTapped(status: status!, index: index)

14
elpha-ios/StatusView.swift

@ -63,6 +63,7 @@ class StatusView: UIView {
var delegate: StatusViewDelegate? = nil
var spoilerView: UIVisualEffectView? = nil
var attachmentManager: AttachmentManager = AttachmentManager()
var feedbackGenerator: UINotificationFeedbackGenerator? = nil
@IBAction func boostViewTapped(_ sender: Any) {
if let delegate = delegate, let status = status {
@ -121,6 +122,8 @@ class StatusView: UIView {
@IBAction func boostTapped(_ sender: Any) {
if let status = status {
feedbackGenerator!.prepare()
if status.reblogged {
status.reblogged = false
status.reblogsCount = status.reblogsCount - 1
@ -128,10 +131,12 @@ class StatusView: UIView {
MastodonAPI.unreblog(statusID: status.id!) { error in
guard error == nil else {
AlertManager.shared.show(message: error!.localizedDescription, category: .error)
self.feedbackGenerator!.notificationOccurred(.error)
return
}
AlertManager.shared.show(message: "Unboosted", category: .boosted)
self.feedbackGenerator!.notificationOccurred(.success)
}
} else {
status.reblogged = true
@ -140,10 +145,12 @@ class StatusView: UIView {
MastodonAPI.reblog(statusID: status.id!) { error in
guard error == nil else {
AlertManager.shared.show(message: error!.localizedDescription, category: .error)
self.feedbackGenerator!.notificationOccurred(.error)
return
}
AlertManager.shared.show(message: "Boosted!", category: .boosted)
self.feedbackGenerator!.notificationOccurred(.success)
}
}
@ -154,6 +161,8 @@ class StatusView: UIView {
@IBAction func favoriteTapped(_ sender: Any) {
if let status = status {
feedbackGenerator!.prepare()
if status.favorited {
status.favorited = false
status.favoritesCount = status.favoritesCount - 1
@ -161,10 +170,12 @@ class StatusView: UIView {
MastodonAPI.unfavorite(statusID: status.id!) { error in
guard error == nil else {
AlertManager.shared.show(message: error!.localizedDescription, category: .error)
self.feedbackGenerator!.notificationOccurred(.error)
return
}
AlertManager.shared.show(message: "Unfavorited", category: .favorited)
self.feedbackGenerator!.notificationOccurred(.success)
}
} else {
status.favorited = true
@ -173,10 +184,12 @@ class StatusView: UIView {
MastodonAPI.favorite(statusID: status.id!) { error in
guard error == nil else {
AlertManager.shared.show(message: error!.localizedDescription, category: .error)
self.feedbackGenerator!.notificationOccurred(.error)
return
}
AlertManager.shared.show(message: "Favorited!", category: .favorited)
self.feedbackGenerator!.notificationOccurred(.success)
}
}
@ -210,6 +223,7 @@ class StatusView: UIView {
contentView.frame = self.bounds
attachmentManager.delegate = self
contentTextView.delegate = self
feedbackGenerator = UINotificationFeedbackGenerator()
}
public func update(withStatus status: StatusMO) {

109
elpha-ios/TimelineTableViewController.swift

@ -12,18 +12,17 @@ import CoreData
import UIKit
import SafariServices
class TimelineTableViewController: UITableViewController {
let fetchLimit = 20
class TimelineTableViewController: AbstractStatusTableViewController {
var feedbackGenerator: UINotificationFeedbackGenerator? = nil
var fetchedResultsController: NSFetchedResultsController<StatusMO>? = nil
var loading: Bool = false
var currentPaginationContext: String {
guard let timeline = AuthenticationManager.session?.timeline, let categoryString = timeline.category else {
return ""
}
switch TimelineCategory(rawValue: categoryString)! {
override var currentPaginationContext: String {
get {
guard let timeline = AuthenticationManager.session?.timeline, let categoryString = timeline.category else {
return ""
}
switch TimelineCategory(rawValue: categoryString)! {
case .home:
return "timeline:home"
case .local:
@ -34,6 +33,11 @@ class TimelineTableViewController: UITableViewController {
return "timeline:tag:\(timeline.subcategory!)"
case .favorites:
return "timeline:favorites"
}
}
set {
}
}
@ -88,6 +92,20 @@ class TimelineTableViewController: UITableViewController {
}
}
override func loadMoreTapped(status: StatusMO, direction: PaginationDirection) {
if let markers = status.markers {
markers.forEach { marker in
if marker.context == self.currentPaginationContext && marker.item.direction == direction {
fetchTimeline(withPagination: marker.item) { error in
if error != nil {
AlertManager.shared.show(message: error!.localizedDescription, category: .error)
}
}
}
}
}
}
@objc func openSettings() {
}
@ -96,10 +114,6 @@ class TimelineTableViewController: UITableViewController {
performSegue(withIdentifier: "TimelinesSegue", sender: self)
}
@objc func compose() {
AlertManager.shared.show(message: "We'll get the compose screen working one day.")
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "TimelinesSegue" {
if let destination = segue.destination as? TimelinesViewController {
@ -108,6 +122,10 @@ class TimelineTableViewController: UITableViewController {
}
}
@objc func compose() {
AlertManager.shared.show(message: "We'll get the compose screen working one day.")
}
func createDefaultTimelines(account: AccountMO) {
let homeTimeline = TimelineMO(context: CoreDataManager.shared.context)
homeTimeline.name = "Home"
@ -337,6 +355,16 @@ extension TimelineTableViewController {
return count
}
override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
if let cell = cell as? TimelineTableViewCell {
CellHeightManager.set(status: cell.statusView.status, height: cell.frame.size.height)
}
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return CellHeightManager.get(status: fetchedResultsController?.object(at: indexPath))
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "TimelineTableViewCell", for: indexPath) as? TimelineTableViewCell else {
fatalError("Unable to find reusable cell")
@ -403,58 +431,3 @@ extension TimelineTableViewController: TimelinesViewControllerDelegate {
tableView.reloadData()
}
}
extension TimelineTableViewController: StatusViewDelegate {
func accountTapped(account: AccountMO) {
if let controller = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "AccountTableViewController") as? AccountTableViewController {
controller.account = account
self.navigationController?.pushViewController(controller, animated: true)
}
}
func statusTapped(status: StatusMO) {
if let controller = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "StatusTableViewController") as? StatusTableViewController {
controller.status = status
self.navigationController?.pushViewController(controller, animated: true)
}
}
func loadMoreTapped(status: StatusMO, direction: PaginationDirection) {
if let markers = status.markers {
markers.forEach { marker in
if marker.context == self.currentPaginationContext && marker.item.direction == direction {
fetchTimeline(withPagination: marker.item) { error in
if error != nil {
AlertManager.shared.show(message: error!.localizedDescription, category: .error)
}
}
}
}
}
}
func attachmentTapped(status: StatusMO, index: Int) {
if let controller = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "AttachmentPageViewController") as? AttachmentPageViewController {
controller.status = status
controller.attachmentIndex = index
present(controller, animated: false)
}
}
func urlTapped(url: URL) {
let controller = SFSafariViewController(url: url)
controller.delegate = self
controller.dismissButtonStyle = .done
// controller.preferredBarTintColor = UIColor(named: "Secondary")
controller.preferredControlTintColor = UIColor(named: "Text")
present(controller, animated: true)
}
}
extension TimelineTableViewController: SFSafariViewControllerDelegate {
func safariViewControllerDidFinish(_ controller: SFSafariViewController) {
controller.dismiss(animated: true)
}
}

5
elpha-ios/UITextViewFixed.swift

@ -12,7 +12,10 @@ import UIKit
override func layoutSubviews() {
super.layoutSubviews()
textContainerInset = UIEdgeInsets.zero
let inset = UIEdgeInsets(top: 0, left: 0, bottom: 10, right: 0)
contentInset = inset
textContainerInset = inset
textContainer.lineFragmentPadding = 0
}
}
Loading…
Cancel
Save