Browse Source

Development

master
Dwayne Harris 6 years ago
parent
commit
92dc8e06eb
  1. 3
      .gitmodules
  2. 1
      Frameworks/AlamofireNetworkActivityIndicator
  3. 1
      Frameworks/MastodonKit
  4. 1
      Frameworks/OAuthSwift
  5. 72
      elpha-ios.xcodeproj/project.pbxproj
  6. 30
      elpha-ios/AccountTableViewController.swift
  7. 2
      elpha-ios/AlertManager.swift
  8. 2
      elpha-ios/AppDelegate.swift
  9. 8
      elpha-ios/AuthenticateViewController.swift
  10. 33
      elpha-ios/Base.lproj/Main.storyboard
  11. 2
      elpha-ios/MainStatusTableViewCell.swift
  12. 49
      elpha-ios/StatusTableViewController.swift
  13. 23
      elpha-ios/StatusView.swift
  14. 5
      elpha-ios/StatusView.xib
  15. 62
      elpha-ios/TimelineTableViewController.swift

3
.gitmodules

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

1
Frameworks/AlamofireNetworkActivityIndicator

@ -0,0 +1 @@
Subproject commit 3ace5a928804b60cad6945a0ba50a633a3ebb4ca

1
Frameworks/MastodonKit

@ -1 +0,0 @@
Subproject commit 27b48c037aace80440396c2d1ef79621fe694cd1

1
Frameworks/OAuthSwift

@ -1 +0,0 @@
Subproject commit f46548a7d15e8d7e2c30c418373ac4bd29946efd

72
elpha-ios.xcodeproj/project.pbxproj

@ -13,6 +13,8 @@
15131EF6216DBA820092B252 /* AccountNavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15131EF5216DBA820092B252 /* AccountNavigationController.swift */; };
151AD4D9216899AD00F07403 /* AlamofireImage.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 1517EA842159D72200DE80D6 /* AlamofireImage.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
151AD4E621689A0F00F07403 /* Alamofire.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 157405C3215890BC00EEAAEB /* Alamofire.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
1522EC7F2193EBCB0082C3FA /* AlamofireNetworkActivityIndicator.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1522EC7C2193EBA10082C3FA /* AlamofireNetworkActivityIndicator.framework */; };
1522EC802193EBCB0082C3FA /* AlamofireNetworkActivityIndicator.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 1522EC7C2193EBA10082C3FA /* AlamofireNetworkActivityIndicator.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
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 */; };
@ -127,6 +129,27 @@
remoteGlobalIDString = F8111E3219A95C8B0040E7D1;
remoteInfo = "Alamofire iOS";
};
1522EC7B2193EBA10082C3FA /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 1522EC752193EBA10082C3FA /* AlamofireNetworkActivityIndicator.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 4CB928391C66E1A600CE5F08;
remoteInfo = AlamofireNetworkActivityIndicator;
};
1522EC7D2193EBA10082C3FA /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 1522EC752193EBA10082C3FA /* AlamofireNetworkActivityIndicator.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 4CB928431C66E1A700CE5F08;
remoteInfo = AlamofireNetworkActivityIndicatorTests;
};
1522EC812193EBCB0082C3FA /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 1522EC752193EBA10082C3FA /* AlamofireNetworkActivityIndicator.xcodeproj */;
proxyType = 1;
remoteGlobalIDString = 4CB928381C66E1A600CE5F08;
remoteInfo = AlamofireNetworkActivityIndicator;
};
157405C2215890BC00EEAAEB /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 157405B7215890BC00EEAAEB /* Alamofire.xcodeproj */;
@ -187,6 +210,7 @@
files = (
151AD4D9216899AD00F07403 /* AlamofireImage.framework in Embed Frameworks */,
151AD4E621689A0F00F07403 /* Alamofire.framework in Embed Frameworks */,
1522EC802193EBCB0082C3FA /* AlamofireNetworkActivityIndicator.framework in Embed Frameworks */,
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
@ -199,6 +223,7 @@
15131EF3216DB8B90092B252 /* AccountTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountTableViewController.swift; sourceTree = "<group>"; };
15131EF5216DBA820092B252 /* AccountNavigationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountNavigationController.swift; sourceTree = "<group>"; };
1517EA6F2159D72200DE80D6 /* AlamofireImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = AlamofireImage.xcodeproj; path = Frameworks/AlamofireImage/AlamofireImage.xcodeproj; sourceTree = "<group>"; };
1522EC752193EBA10082C3FA /* AlamofireNetworkActivityIndicator.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = AlamofireNetworkActivityIndicator.xcodeproj; path = Frameworks/AlamofireNetworkActivityIndicator/AlamofireNetworkActivityIndicator.xcodeproj; sourceTree = "<group>"; };
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>"; };
@ -250,6 +275,7 @@
files = (
15A79B2E215C63B6007A326E /* AlamofireImage.framework in Frameworks */,
157405D1215890D700EEAAEB /* Alamofire.framework in Frameworks */,
1522EC7F2193EBCB0082C3FA /* AlamofireNetworkActivityIndicator.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -327,6 +353,15 @@
name = Extensions;
sourceTree = "<group>";
};
1522EC762193EBA10082C3FA /* Products */ = {
isa = PBXGroup;
children = (
1522EC7C2193EBA10082C3FA /* AlamofireNetworkActivityIndicator.framework */,
1522EC7E2193EBA10082C3FA /* AlamofireNetworkActivityIndicatorTests.xctest */,
);
name = Products;
sourceTree = "<group>";
};
156FF05621779C140074D9CA /* API */ = {
isa = PBXGroup;
children = (
@ -363,6 +398,7 @@
157405AF2151A5DA00EEAAEB /* README.md */,
157405B7215890BC00EEAAEB /* Alamofire.xcodeproj */,
1517EA6F2159D72200DE80D6 /* AlamofireImage.xcodeproj */,
1522EC752193EBA10082C3FA /* AlamofireNetworkActivityIndicator.xcodeproj */,
15960E59213145E100C38CE9 /* elpha-ios */,
15960E58213145E100C38CE9 /* Products */,
157405D0215890D700EEAAEB /* Frameworks */,
@ -443,6 +479,7 @@
dependencies = (
151AD4DB216899AD00F07403 /* PBXTargetDependency */,
151AD4E821689A0F00F07403 /* PBXTargetDependency */,
1522EC822193EBCB0082C3FA /* PBXTargetDependency */,
);
name = "elpha-ios";
productName = "elpha-ios";
@ -485,6 +522,10 @@
ProductGroup = 1517EA702159D72200DE80D6 /* Products */;
ProjectRef = 1517EA6F2159D72200DE80D6 /* AlamofireImage.xcodeproj */;
},
{
ProductGroup = 1522EC762193EBA10082C3FA /* Products */;
ProjectRef = 1522EC752193EBA10082C3FA /* AlamofireNetworkActivityIndicator.xcodeproj */;
},
);
projectRoot = "";
targets = (
@ -550,6 +591,20 @@
remoteRef = 1517EA912159D72200DE80D6 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
1522EC7C2193EBA10082C3FA /* AlamofireNetworkActivityIndicator.framework */ = {
isa = PBXReferenceProxy;
fileType = wrapper.framework;
path = AlamofireNetworkActivityIndicator.framework;
remoteRef = 1522EC7B2193EBA10082C3FA /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
1522EC7E2193EBA10082C3FA /* AlamofireNetworkActivityIndicatorTests.xctest */ = {
isa = PBXReferenceProxy;
fileType = wrapper.cfbundle;
path = AlamofireNetworkActivityIndicatorTests.xctest;
remoteRef = 1522EC7D2193EBA10082C3FA /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
157405C3215890BC00EEAAEB /* Alamofire.framework */ = {
isa = PBXReferenceProxy;
fileType = wrapper.framework;
@ -675,6 +730,11 @@
name = "Alamofire iOS";
targetProxy = 151AD4E721689A0F00F07403 /* PBXContainerItemProxy */;
};
1522EC822193EBCB0082C3FA /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = AlamofireNetworkActivityIndicator;
targetProxy = 1522EC812193EBCB0082C3FA /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
@ -817,10 +877,10 @@
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_IDENTITY = "iPhone Developer";
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = R9PMLQGTGZ;
CODE_SIGN_STYLE = Manual;
DEVELOPMENT_TEAM = "";
INFOPLIST_FILE = "elpha-ios/Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
IPHONEOS_DEPLOYMENT_TARGET = 12.1;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
@ -839,10 +899,10 @@
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_IDENTITY = "iPhone Developer";
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = R9PMLQGTGZ;
CODE_SIGN_STYLE = Manual;
DEVELOPMENT_TEAM = "";
INFOPLIST_FILE = "elpha-ios/Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
IPHONEOS_DEPLOYMENT_TARGET = 12.1;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",

30
elpha-ios/AccountTableViewController.swift

@ -9,6 +9,7 @@
import AlamofireImage
import CoreData
import UIKit
import SafariServices
class AccountTableViewController: UITableViewController {
@IBOutlet var headerView: UIView!
@ -25,18 +26,7 @@ class AccountTableViewController: UITableViewController {
let fetchLimit = 20
var fetchedResultsController: NSFetchedResultsController<StatusMO>? = nil
var account: AccountMO? = nil
var loading: Bool = false {
didSet {
DispatchQueue.main.async {
if self.loading {
self.refreshControl?.beginRefreshing()
} else {
self.refreshControl?.endRefreshing()
}
}
}
}
var loading: Bool = false
var currentPaginationContext: String {
guard let account = self.account else {
@ -373,4 +363,20 @@ extension AccountTableViewController: StatusViewDelegate {
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)
}
}

2
elpha-ios/AlertManager.swift

@ -112,6 +112,8 @@ class AlertManager {
}
}
print("ALERT: \(message)")
alerts.append(Alert(category: category, message: message))
start()
}

2
elpha-ios/AppDelegate.swift

@ -6,6 +6,7 @@
// Copyright © 2018 Elpha. All rights reserved.
//
import AlamofireNetworkActivityIndicator
import CoreData
import UIKit
@ -14,6 +15,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
NetworkActivityIndicatorManager.shared.isEnabled = true
return true
}

8
elpha-ios/AuthenticateViewController.swift

@ -24,6 +24,14 @@ class AuthenticateViewController: UIViewController {
instanceTextField.attributedPlaceholder = NSAttributedString(string: "mastodon.social", attributes: [NSAttributedString.Key.foregroundColor: UIColor.init(red: 0.9, green: 0.9, blue: 0.9, alpha: 1)])
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
if AuthenticationManager.session != nil {
self.dismiss(animated: true)
}
}
override open var shouldAutorotate: Bool {
return false
}

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

@ -4,6 +4,7 @@
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.20"/>
<capability name="Named colors" minToolsVersion="9.0"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
@ -536,7 +537,7 @@
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<color key="backgroundColor" name="Background Secondary"/>
<constraints>
<constraint firstAttribute="trailing" secondItem="Eab-8s-Drh" secondAttribute="trailing" constant="8" id="5mC-u4-qwS"/>
<constraint firstAttribute="trailing" secondItem="kTz-EN-Zgx" secondAttribute="trailing" constant="8" id="6Dd-wW-L1W"/>
@ -562,7 +563,7 @@
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<color key="backgroundColor" name="Background Secondary"/>
<constraints>
<constraint firstItem="FxQ-nq-jYw" firstAttribute="top" secondItem="TkS-vn-sW3" secondAttribute="top" constant="10" id="8nY-kC-dnK"/>
<constraint firstAttribute="trailing" secondItem="l3U-wO-M4g" secondAttribute="trailing" constant="8" id="9yP-IG-4TK"/>
@ -588,7 +589,7 @@
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<color key="backgroundColor" name="Background Secondary"/>
<constraints>
<constraint firstAttribute="trailing" secondItem="J8H-VZ-dwT" secondAttribute="trailing" constant="8" id="1t1-nE-saW"/>
<constraint firstAttribute="trailing" secondItem="piT-tX-tUe" secondAttribute="trailing" constant="8" id="2La-A7-kHB"/>
@ -611,7 +612,7 @@
</connections>
</segmentedControl>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<color key="backgroundColor" name="Background Secondary"/>
<constraints>
<constraint firstItem="0jO-Rb-lcz" firstAttribute="leading" secondItem="ygB-F6-Moa" secondAttribute="leading" id="0Od-Hb-lt5"/>
<constraint firstItem="TkS-vn-sW3" firstAttribute="width" secondItem="rqF-sG-ZE7" secondAttribute="width" id="0rh-o4-LVs"/>
@ -1088,19 +1089,22 @@
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="bsb-4z-qCl">
<rect key="frame" x="0.0" y="0.0" width="375" height="32"/>
<subviews>
<label opaque="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Content" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="AT3-0d-kQ3">
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" scrollEnabled="NO" editable="NO" text="Content" textAlignment="natural" translatesAutoresizingMaskIntoConstraints="NO" id="Qno-L9-nUh" customClass="UITextViewFixed" customModule="elpha_ios" customModuleProvider="target">
<rect key="frame" x="8" y="0.0" width="359" height="32"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<color key="tintColor" name="Primary"/>
<color key="textColor" name="Text"/>
<nil key="highlightedColor"/>
</label>
<fontDescription key="fontDescription" type="system" pointSize="16"/>
<textInputTraits key="textInputTraits" autocorrectionType="no" spellCheckingType="no" smartDashesType="no" smartInsertDeleteType="no" smartQuotesType="no"/>
<dataDetectorType key="dataDetectorTypes" phoneNumber="YES" link="YES" address="YES" calendarEvent="YES" shipmentTrackingNumber="YES" flightNumber="YES" lookupSuggestion="YES"/>
</textView>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="trailing" secondItem="AT3-0d-kQ3" secondAttribute="trailing" constant="8" id="4Jm-CO-cjk"/>
<constraint firstItem="AT3-0d-kQ3" firstAttribute="top" secondItem="bsb-4z-qCl" secondAttribute="top" id="4Op-Mw-LlV"/>
<constraint firstItem="AT3-0d-kQ3" firstAttribute="leading" secondItem="bsb-4z-qCl" secondAttribute="leading" constant="8" id="fxj-Hk-a9U"/>
<constraint firstAttribute="bottom" secondItem="AT3-0d-kQ3" secondAttribute="bottom" id="ld8-0e-sbI"/>
<constraint firstAttribute="bottom" secondItem="Qno-L9-nUh" secondAttribute="bottom" id="M8W-95-H1q"/>
<constraint firstItem="Qno-L9-nUh" firstAttribute="top" secondItem="bsb-4z-qCl" secondAttribute="top" id="QpL-s9-Tq7"/>
<constraint firstItem="Qno-L9-nUh" firstAttribute="leading" secondItem="bsb-4z-qCl" secondAttribute="leading" constant="8" id="TNL-xL-hoM"/>
<constraint firstAttribute="trailing" secondItem="Qno-L9-nUh" secondAttribute="trailing" constant="8" id="pub-Jf-c6W"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="7SO-v5-Rfd">
@ -1138,7 +1142,7 @@
<outlet property="avatarImageView" destination="LHS-vw-fZE" id="PpS-hb-Hes"/>
<outlet property="boostsImageView" destination="X4x-5e-3Ms" id="dxE-vb-Ctp"/>
<outlet property="boostsLabel" destination="3Ew-31-ZWY" id="Nc5-8A-0tr"/>
<outlet property="contentLabel" destination="AT3-0d-kQ3" id="c7N-3x-fJ9"/>
<outlet property="contentTextView" destination="Qno-L9-nUh" id="WDC-55-ATi"/>
<outlet property="displayNameLabel" destination="vDe-e6-p1i" id="jxi-k7-Zll"/>
<outlet property="favoritesImageView" destination="B1s-Wp-hBJ" id="hPe-xy-EsI"/>
<outlet property="favoritesLabel" destination="Tch-E4-Saw" id="lly-D4-fkY"/>
@ -1400,6 +1404,9 @@
<namedColor name="Background Primary">
<color red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</namedColor>
<namedColor name="Background Secondary">
<color red="0.93725490196078431" green="0.93725490196078431" blue="0.93725490196078431" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</namedColor>
<namedColor name="Primary">
<color red="0.54117647058823526" green="0.4823529411764706" blue="0.68235294117647061" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</namedColor>

2
elpha-ios/MainStatusTableViewCell.swift

@ -12,7 +12,6 @@ class MainStatusTableViewCell: UITableViewCell {
@IBOutlet var avatarImageView: UIImageView!
@IBOutlet var displayNameLabel: UILabel!
@IBOutlet var usernameLabel: UILabel!
@IBOutlet var contentLabel: UILabel!
@IBOutlet var repliesImageView: UIImageView!
@IBOutlet var repliesLabel: UILabel!
@IBOutlet var boostsImageView: UIImageView!
@ -23,4 +22,5 @@ class MainStatusTableViewCell: UITableViewCell {
@IBOutlet var timestampDateLabel: UILabel!
@IBOutlet var timestampTimeLabel: UILabel!
@IBOutlet var attachmentsView: UIView!
@IBOutlet var contentTextView: UITextViewFixed!
}

49
elpha-ios/StatusTableViewController.swift

@ -9,6 +9,7 @@
import AlamofireImage
import CoreData
import UIKit
import SafariServices
enum StatusType {
case ancestor, status, descendant
@ -18,22 +19,14 @@ class StatusTableViewController: UITableViewController, UIGestureRecognizerDeleg
public var status: StatusMO? = nil
var ancestors: [StatusMO] = []
var descendants: [StatusMO] = []
var loading: Bool = false {
didSet {
DispatchQueue.main.async {
if self.loading {
self.refreshControl?.beginRefreshing()
} else {
self.refreshControl?.endRefreshing()
}
}
}
}
var feedbackGenerator: UINotificationFeedbackGenerator? = nil
var loading: Bool = false
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.title = "Detail"
feedbackGenerator = UINotificationFeedbackGenerator()
navigationItem.title = "Toot"
}
override func viewDidAppear(_ animated: Bool) {
@ -53,6 +46,8 @@ class StatusTableViewController: UITableViewController, UIGestureRecognizerDeleg
@IBAction func boostTapped(_ sender: Any) {
if let status = status {
feedbackGenerator!.prepare()
if status.reblogged {
status.reblogged = false
status.reblogsCount = status.reblogsCount - 1
@ -60,10 +55,12 @@ class StatusTableViewController: UITableViewController, UIGestureRecognizerDeleg
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
@ -72,10 +69,12 @@ class StatusTableViewController: UITableViewController, UIGestureRecognizerDeleg
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)
}
}
@ -85,6 +84,8 @@ class StatusTableViewController: UITableViewController, UIGestureRecognizerDeleg
@IBAction func favoriteTapped(_ sender: Any) {
if let status = status {
feedbackGenerator!.prepare()
if status.favorited {
status.favorited = false
status.favoritesCount = status.favoritesCount - 1
@ -92,10 +93,12 @@ class StatusTableViewController: UITableViewController, UIGestureRecognizerDeleg
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
@ -104,10 +107,12 @@ class StatusTableViewController: UITableViewController, UIGestureRecognizerDeleg
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)
}
}
@ -264,7 +269,7 @@ extension StatusTableViewController {
}
if let content = status.content {
cell.contentLabel.attributedText = content.htmlAttributed(size: 16)
cell.contentTextView.attributedText = content.htmlAttributed(size: 16)
}
cell.attachmentsView.backgroundColor = UIColor.white
@ -353,6 +358,16 @@ extension StatusTableViewController: StatusViewDelegate {
}
}
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)
}
func boostTapped() {
loadStatuses()
}
@ -370,6 +385,12 @@ 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)

23
elpha-ios/StatusView.swift

@ -14,6 +14,7 @@ protocol StatusViewDelegate {
func statusTapped(status: StatusMO)
func loadMoreTapped(status: StatusMO, direction: PaginationDirection)
func attachmentTapped(status: StatusMO, index: Int)
func urlTapped(url: URL)
func boostTapped()
func favoriteTapped()
func revealTapped()
@ -208,6 +209,7 @@ class StatusView: UIView {
addSubview(contentView)
contentView.frame = self.bounds
attachmentManager.delegate = self
contentTextView.delegate = self
}
public func update(withStatus status: StatusMO) {
@ -215,10 +217,8 @@ class StatusView: UIView {
boostView.isHidden = true
replyView.isHidden = true
attachmentsView.backgroundColor = UIColor.white
attachmentsView.isHidden = true
spoilerImageView.isHidden = true
let avatarFilter = AspectScaledToFillSizeWithRoundedCornersFilter(
@ -350,3 +350,22 @@ extension StatusView: AttachmentManagerDelegate {
}
}
}
extension StatusView: UITextViewDelegate {
func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool {
if let mentions = status?.mentions {
for mention in mentions {
if URL == mention.url {
if let account = MastodonDataManager.account(id: mention.id) {
delegate?.accountTapped(account: account)
}
return false
}
}
}
delegate?.urlTapped(url: URL)
return false
}
}

5
elpha-ios/StatusView.xib

@ -4,6 +4,7 @@
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.20"/>
<capability name="Named colors" minToolsVersion="9.0"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
@ -266,14 +267,14 @@
<outletCollection property="gestureRecognizers" destination="13W-G2-Xm4" appends="YES" id="6RI-ff-czd"/>
</connections>
</view>
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" scrollEnabled="NO" editable="NO" text="Content" textAlignment="natural" selectable="NO" translatesAutoresizingMaskIntoConstraints="NO" id="o7b-at-xQ9" customClass="UITextViewFixed" customModule="elpha_ios" customModuleProvider="target">
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" scrollEnabled="NO" editable="NO" text="Content" textAlignment="natural" translatesAutoresizingMaskIntoConstraints="NO" id="o7b-at-xQ9" customClass="UITextViewFixed" customModule="elpha_ios" customModuleProvider="target">
<rect key="frame" x="8" y="86" width="359" height="22"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<color key="tintColor" name="Primary"/>
<color key="textColor" name="Text"/>
<fontDescription key="fontDescription" type="system" pointSize="16"/>
<textInputTraits key="textInputTraits" autocorrectionType="no" spellCheckingType="no" smartDashesType="no" smartInsertDeleteType="no" smartQuotesType="no"/>
<dataDetectorType key="dataDetectorTypes" link="YES"/>
<dataDetectorType key="dataDetectorTypes" phoneNumber="YES" link="YES" address="YES" calendarEvent="YES" shipmentTrackingNumber="YES" flightNumber="YES" lookupSuggestion="YES"/>
</textView>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>

62
elpha-ios/TimelineTableViewController.swift

@ -6,25 +6,17 @@
// Copyright © 2018 Elpha. All rights reserved.
//
import Alamofire
import AlamofireImage
import CoreData
import UIKit
import SafariServices
class TimelineTableViewController: UITableViewController {
var fetchedResultsController: NSFetchedResultsController<StatusMO>? = nil
let fetchLimit = 20
var loading: Bool = false {
didSet {
DispatchQueue.main.async {
if self.loading {
self.refreshControl?.beginRefreshing()
} else {
self.refreshControl?.endRefreshing()
}
}
}
}
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 {
@ -47,6 +39,8 @@ class TimelineTableViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
feedbackGenerator = UINotificationFeedbackGenerator()
initializeFetchedResultsController()
let moreButtonItem = UIBarButtonItem(image: UIImage(named: "More"), style: .plain, target: self, action: #selector(more))
@ -55,6 +49,22 @@ class TimelineTableViewController: UITableViewController {
navigationItem.leftBarButtonItems = [moreButtonItem]
navigationItem.rightBarButtonItems = [composeButtonItem]
if let account = AuthenticationManager.session?.account {
Alamofire.request(account.avatarURL!).responseImage { response in
if let image = response.result.value {
let avatarButtonItem = UIBarButtonItem(
image: image.af_imageAspectScaled(toFit: CGSize(width: 30, height: 30)).af_imageRounded(withCornerRadius: 10).withRenderingMode(.alwaysOriginal),
style: .plain,
target: self,
action: #selector(self.openSettings)
)
avatarButtonItem.tintColor = UIColor.clear
self.navigationItem.leftBarButtonItems?.insert(avatarButtonItem, at: 0)
}
}
}
if let timeline = AuthenticationManager.session?.timeline {
navigationItem.title = timeline.name
} else {
@ -67,6 +77,10 @@ class TimelineTableViewController: UITableViewController {
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
if fetchedResultsController?.fetchedObjects?.count ?? 0 == 0 {
initializeFetchedResultsController()
}
fetchTimeline { error in
if error != nil {
AlertManager.shared.show(message: error!.localizedDescription, category: .error)
@ -74,6 +88,10 @@ class TimelineTableViewController: UITableViewController {
}
}
@objc func openSettings() {
}
@objc func more() {
performSegue(withIdentifier: "TimelinesSegue", sender: self)
}
@ -162,6 +180,7 @@ class TimelineTableViewController: UITableViewController {
DispatchQueue.main.async {
var newStatusCount = 0
self.feedbackGenerator!.prepare()
for (index, status) in data.enumerated() {
if let upsertResult = MastodonDataManager.upsertStatus(status) {
@ -201,6 +220,7 @@ class TimelineTableViewController: UITableViewController {
if newStatusCount > 0 {
let pluralization = newStatusCount == 1 ? "" : "s"
AlertManager.shared.show(message: "\(newStatusCount) new toot\(pluralization)", category: .newStatuses)
self.feedbackGenerator!.notificationOccurred(.success)
}
CoreDataManager.shared.saveContext()
@ -421,4 +441,20 @@ extension TimelineTableViewController: StatusViewDelegate {
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)
}
}
Loading…
Cancel
Save