Browse Source

Better Load More functionality

master
Dwayne Harris 6 years ago
parent
commit
abb18921f7
  1. 8
      elpha-ios.xcodeproj/project.pbxproj
  2. 4
      elpha-ios/AccountTableViewController.swift
  3. 2
      elpha-ios/Assets.xcassets/Icons/Down.imageset/Contents.json
  4. BIN
      elpha-ios/Assets.xcassets/Icons/Down.imageset/down.pdf
  5. 12
      elpha-ios/Assets.xcassets/Icons/Pin.imageset/Contents.json
  6. BIN
      elpha-ios/Assets.xcassets/Icons/Pin.imageset/map-pin-solid.pdf
  7. 2
      elpha-ios/Assets.xcassets/Icons/Up.imageset/Contents.json
  8. BIN
      elpha-ios/Assets.xcassets/Icons/Up.imageset/up.pdf
  9. 21
      elpha-ios/AttachmentView.xib
  10. 4
      elpha-ios/Base.lproj/Main.storyboard
  11. 46
      elpha-ios/MastodonAPI.swift
  12. 7
      elpha-ios/StatusTableViewController.swift
  13. 7
      elpha-ios/StatusView.swift
  14. 147
      elpha-ios/StatusView.xib
  15. 36
      elpha-ios/TimelineTableViewController.swift

8
elpha-ios.xcodeproj/project.pbxproj

@ -11,6 +11,7 @@
15131EF2216D8D570092B252 /* StatusView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15131EF1216D8D570092B252 /* StatusView.swift */; };
15131EF4216DB8B90092B252 /* AccountTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15131EF3216DB8B90092B252 /* AccountTableViewController.swift */; };
15131EF6216DBA820092B252 /* AccountNavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15131EF5216DBA820092B252 /* AccountNavigationController.swift */; };
1517A6142182B87E00B33735 /* AttachmentView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1517A6132182B87E00B33735 /* AttachmentView.xib */; };
151AD4D9216899AD00F07403 /* AlamofireImage.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 1517EA842159D72200DE80D6 /* AlamofireImage.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
151AD4DD216899E000F07403 /* OAuthSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 15A79B13215B438C007A326E /* OAuthSwift.framework */; };
151AD4DE216899E000F07403 /* OAuthSwift.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 15A79B13215B438C007A326E /* OAuthSwift.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
@ -251,6 +252,7 @@
15131EF1216D8D570092B252 /* StatusView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusView.swift; sourceTree = "<group>"; };
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>"; };
1517A6132182B87E00B33735 /* AttachmentView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = AttachmentView.xib; sourceTree = "<group>"; };
1517EA6F2159D72200DE80D6 /* AlamofireImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = AlamofireImage.xcodeproj; path = Frameworks/AlamofireImage/AlamofireImage.xcodeproj; 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>"; };
@ -344,10 +346,11 @@
151AD4AD2166DD1B00F07403 /* Reusable Views */ = {
isa = PBXGroup;
children = (
15C91A01216AB2D600D97DC3 /* NewStatusesView.xib */,
1517A6132182B87E00B33735 /* AttachmentView.xib */,
15C91A03216AB32500D97DC3 /* NewStatusesView.swift */,
15131ED7216D8C680092B252 /* StatusView.xib */,
15C91A01216AB2D600D97DC3 /* NewStatusesView.xib */,
15131EF1216D8D570092B252 /* StatusView.swift */,
15131ED7216D8C680092B252 /* StatusView.xib */,
);
name = "Reusable Views";
sourceTree = "<group>";
@ -724,6 +727,7 @@
157405B12151A5DA00EEAAEB /* README.md in Resources */,
15960E62213145E100C38CE9 /* Main.storyboard in Resources */,
15131ED8216D8C680092B252 /* StatusView.xib in Resources */,
1517A6142182B87E00B33735 /* AttachmentView.xib in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

4
elpha-ios/AccountTableViewController.swift

@ -178,6 +178,8 @@ class AccountTableViewController: UITableViewController {
}
}
}
status.markers = markers
}
}
}
@ -291,6 +293,8 @@ extension AccountTableViewController: NSFetchedResultsControllerDelegate {
cell.statusView.delegate = self
cell.statusView.update(withStatus: status)
cell.statusView.topLoadMoreView.isHidden = true
cell.statusView.bottomLoadMoreView.isHidden = true
if let markers = status.markers {
markers.forEach { marker in

2
elpha-ios/Assets.xcassets/Icons/Down.imageset/Contents.json

@ -2,7 +2,7 @@
"images" : [
{
"idiom" : "universal",
"filename" : "chevron-down.pdf"
"filename" : "down.pdf"
}
],
"info" : {

BIN
elpha-ios/Assets.xcassets/Icons/Down.imageset/chevron-down.pdf → elpha-ios/Assets.xcassets/Icons/Down.imageset/down.pdf

12
elpha-ios/Assets.xcassets/Icons/Pin.imageset/Contents.json

@ -0,0 +1,12 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "map-pin-solid.pdf"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

BIN
elpha-ios/Assets.xcassets/Icons/Pin.imageset/map-pin-solid.pdf

2
elpha-ios/Assets.xcassets/Icons/Up.imageset/Contents.json

@ -2,7 +2,7 @@
"images" : [
{
"idiom" : "universal",
"filename" : "chevron-up.pdf"
"filename" : "up.pdf"
}
],
"info" : {

BIN
elpha-ios/Assets.xcassets/Icons/Up.imageset/chevron-up.pdf → elpha-ios/Assets.xcassets/Icons/Up.imageset/up.pdf

21
elpha-ios/AttachmentView.xib

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14313.18" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14283.14"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="iN0-l3-epB">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<viewLayoutGuide key="safeArea" id="vUN-kp-3ea"/>
</view>
</objects>
</document>

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

@ -1048,7 +1048,7 @@
<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" userInteractionEnabled="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">
<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">
<rect key="frame" x="8" y="0.0" width="359" height="32"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" name="Text"/>
@ -1109,7 +1109,7 @@
<outlet property="usernameLabel" destination="8fE-Hr-jgf" id="hiJ-he-cm4"/>
</connections>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="StatusTableViewCell" rowHeight="120" id="cLF-Rc-b4K" customClass="StatusTableViewCell" customModule="elpha_ios" customModuleProvider="target">
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="none" indentationWidth="10" reuseIdentifier="StatusTableViewCell" rowHeight="120" id="cLF-Rc-b4K" customClass="StatusTableViewCell" customModule="elpha_ios" customModuleProvider="target">
<rect key="frame" x="0.0" y="637.33333333333337" width="375" height="120"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="cLF-Rc-b4K" id="jhE-cB-Cj1">

46
elpha-ios/MastodonAPI.swift

@ -66,7 +66,7 @@ class MastodonAPI {
return []
}
let regex = try! NSRegularExpression(pattern: "<.*(?:max_id|since_id)=([0-9]+)>; rel=\"(next|prev)\"", options: .caseInsensitive)
let regex = try! NSRegularExpression(pattern: "<[\\S]+(?:max_id|since_id)=([0-9]+)[\\S]*>; rel=\"(next|prev)\"", options: .caseInsensitive)
let matches = regex.matches(in: link, options: [], range: NSRange(location: 0, length: link.count))
return matches.map { match in
let statusRange = match.range(at: 1)
@ -294,6 +294,50 @@ class MastodonAPI {
}
}
static func reblog(statusID: String, completion: @escaping (Error?) -> Void) {
self.request(path: "api/v1/statuses/\(statusID)/reblog", method: .post) { _, _, error in
guard error == nil else {
completion(error)
return
}
completion(nil)
}
}
static func unreblog(statusID: String, completion: @escaping (Error?) -> Void) {
self.request(path: "api/v1/statuses/\(statusID)/unreblog", method: .post) { _, _, error in
guard error == nil else {
completion(error)
return
}
completion(nil)
}
}
static func favorite(statusID: String, completion: @escaping (Error?) -> Void) {
self.request(path: "api/v1/statuses/\(statusID)/favorite", method: .post) { _, _, error in
guard error == nil else {
completion(error)
return
}
completion(nil)
}
}
static func unfavorite(statusID: String, completion: @escaping (Error?) -> Void) {
self.request(path: "api/v1/statuses/\(statusID)/unfavorite", method: .post) { _, _, error in
guard error == nil else {
completion(error)
return
}
completion(nil)
}
}
static func registerApp(serverURL: URL, completion: @escaping (JSONObject?, Error?) -> Void) {
let requestURL = serverURL.appendingPathComponent("api/v1/apps")
let parameters: Parameters = [

7
elpha-ios/StatusTableViewController.swift

@ -199,7 +199,7 @@ extension StatusTableViewController {
if let content = status.content {
do {
let styledContent = "<style>html * { font-size: 16px; color: #170c49; font-family: -apple-system }</style> \(content)"
let styledContent = "<style>html * { font-size: 16px; color: #170C49; font-family: -apple-system } a:link { color: #8A7BAE } a:visited { color: #BAABD6 }</style> \(content)"
let attributedText = try NSAttributedString(
data: styledContent.data(using: String.Encoding.unicode, allowLossyConversion: true)!,
options: [.documentType: NSAttributedString.DocumentType.html],
@ -255,6 +255,11 @@ extension StatusTableViewController {
cell.statusView.delegate = self
cell.statusView.update(withStatus: status)
cell.statusView.topDividerView.isHidden = indexPath.row == 0
cell.statusView.bottomDividerView.isHidden = false
cell.statusView.topLoadMoreView.isHidden = true
cell.statusView.bottomLoadMoreView.isHidden = true
cell.statusView.replyView.isHidden = true
if !loading {

7
elpha-ios/StatusView.swift

@ -40,6 +40,9 @@ class StatusView: UIView {
@IBOutlet var attachmentsView: UIView!
@IBOutlet var detailsView: UIView!
@IBOutlet var spoilerImageView: UIImageView!
@IBOutlet var pinImageView: UIImageView!
@IBOutlet var topLoadMoreView: UIView!
@IBOutlet var bottomLoadMoreView: UIView!
var status: StatusMO? = nil
var delegate: StatusViewDelegate? = nil
@ -144,7 +147,7 @@ class StatusView: UIView {
if let content = status.content {
do {
let styledContent = "<style>html * { font-size: 15px; color: #170c49; font-family: -apple-system }</style> \(content)"
let styledContent = "<style>html * { font-size: 15px; color: #170C49; font-family: -apple-system } a:link { color: #8A7BAE } a:visited { color: #BAABD6 }</style> \(content)"
let attributedText = try NSAttributedString(
data: styledContent.data(using: String.Encoding.unicode, allowLossyConversion: true)!,
options: [.documentType: NSAttributedString.DocumentType.html],
@ -217,6 +220,8 @@ class StatusView: UIView {
} else {
favoritesImageView.image = UIImage(named: "Star Regular")
}
pinImageView.isHidden = !status.pinned
}
if let reblog = status.reblog {

147
elpha-ios/StatusView.xib

@ -21,12 +21,14 @@
<outlet property="boostsImageView" destination="wns-8Z-i60" id="pPf-qQ-T2A"/>
<outlet property="boostsLabel" destination="rq6-p2-tL4" id="Osw-F4-eLa"/>
<outlet property="bottomDividerView" destination="m4t-ve-E78" id="fEE-Uh-2qq"/>
<outlet property="bottomLoadMoreView" destination="0aT-X9-NYg" id="FMc-yo-MAP"/>
<outlet property="contentLabel" destination="WPF-Oe-N2r" id="Gw6-2e-SDE"/>
<outlet property="contentView" destination="iN0-l3-epB" id="BBM-O7-PHb"/>
<outlet property="detailsView" destination="y5N-A7-27p" id="10T-HF-Veu"/>
<outlet property="displayNameLabel" destination="a9Z-2P-cZT" id="9w7-9G-cp3"/>
<outlet property="favoritesImageView" destination="EID-tt-v32" id="nxH-Fm-sb8"/>
<outlet property="favoritesLabel" destination="MHw-QN-ZwH" id="cNY-nH-fIO"/>
<outlet property="pinImageView" destination="ohG-e5-Gzy" id="xQa-hv-Gzy"/>
<outlet property="repliesImageView" destination="mRG-vF-1Ur" id="zW6-NU-fvW"/>
<outlet property="repliesLabel" destination="Uog-Tq-elS" id="5MJ-OP-hYF"/>
<outlet property="replyAvatarImageView" destination="wte-HK-KxR" id="V4R-bQ-RUa"/>
@ -36,16 +38,17 @@
<outlet property="spoilerImageView" destination="08K-bv-mOd" id="n67-gw-nMR"/>
<outlet property="timestampLabel" destination="8et-mR-yd2" id="VW6-9b-k6T"/>
<outlet property="topDividerView" destination="bg1-Q4-Ru5" id="hCA-Qw-9OZ"/>
<outlet property="topLoadMoreView" destination="fjq-Ff-PVL" id="HRM-QV-yP6"/>
<outlet property="usernameLabel" destination="1xI-cX-lcs" id="IaM-0W-3dg"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="iN0-l3-epB">
<rect key="frame" x="0.0" y="0.0" width="375" height="838"/>
<rect key="frame" x="0.0" y="0.0" width="375" height="844"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="7Og-IU-seR">
<rect key="frame" x="0.0" y="20" width="375" height="818"/>
<rect key="frame" x="0.0" y="20" width="375" height="824"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="bg1-Q4-Ru5">
<rect key="frame" x="0.0" y="0.0" width="375" height="5"/>
@ -54,8 +57,34 @@
<constraint firstAttribute="height" constant="5" id="hYF-M2-gmn"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="fjq-Ff-PVL">
<rect key="frame" x="0.0" y="5" width="375" height="40"/>
<subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="Up" translatesAutoresizingMaskIntoConstraints="NO" id="701-8A-mp6">
<rect key="frame" x="340" y="10" width="20" height="20"/>
<constraints>
<constraint firstAttribute="width" constant="20" id="BCi-a6-e9O"/>
<constraint firstAttribute="height" constant="20" id="cD5-It-mON"/>
</constraints>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Load More" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="IRZ-QQ-s88">
<rect key="frame" x="261.5" y="11.5" width="68.5" height="17"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<color key="textColor" name="Text"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" name="Secondary"/>
<constraints>
<constraint firstItem="701-8A-mp6" firstAttribute="centerY" secondItem="fjq-Ff-PVL" secondAttribute="centerY" id="Exh-9G-osC"/>
<constraint firstItem="701-8A-mp6" firstAttribute="leading" secondItem="IRZ-QQ-s88" secondAttribute="trailing" constant="10" id="GLS-PV-V9a"/>
<constraint firstAttribute="trailing" secondItem="701-8A-mp6" secondAttribute="trailing" constant="15" id="h6u-tF-dBt"/>
<constraint firstItem="IRZ-QQ-s88" firstAttribute="centerY" secondItem="fjq-Ff-PVL" secondAttribute="centerY" id="uiy-Kk-Nb7"/>
<constraint firstAttribute="height" priority="999" constant="40" id="zaz-CL-dbD"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Gnt-jG-tVj">
<rect key="frame" x="0.0" y="5" width="375" height="100"/>
<rect key="frame" x="0.0" y="45" width="375" height="100"/>
<subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="ecc-6t-6K0">
<rect key="frame" x="8" y="20" width="40" height="40"/>
@ -92,7 +121,7 @@
</view>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Boosted" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="GZD-6a-olN">
<rect key="frame" x="76" y="62" width="291" height="14.5"/>
<fontDescription key="fontDescription" type="system" pointSize="12"/>
<fontDescription key="fontDescription" type="system" weight="thin" pointSize="12"/>
<color key="textColor" name="Text"/>
<nil key="highlightedColor"/>
</label>
@ -123,7 +152,7 @@
</connections>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="v8x-tf-zFb">
<rect key="frame" x="0.0" y="105" width="375" height="100"/>
<rect key="frame" x="0.0" y="145" width="375" height="100"/>
<subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="wte-HK-KxR">
<rect key="frame" x="8" y="20" width="40" height="40"/>
@ -134,7 +163,7 @@
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="In reply to" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="nUk-PT-X4k">
<rect key="frame" x="76" y="20" width="291" height="14.5"/>
<fontDescription key="fontDescription" type="system" pointSize="12"/>
<fontDescription key="fontDescription" type="system" weight="thin" pointSize="12"/>
<color key="textColor" name="Text"/>
<nil key="highlightedColor"/>
</label>
@ -191,10 +220,10 @@
</connections>
</view>
<view contentMode="scaleToFill" verticalHuggingPriority="249" translatesAutoresizingMaskIntoConstraints="NO" id="cAR-YB-u2k">
<rect key="frame" x="0.0" y="205" width="375" height="183"/>
<rect key="frame" x="0.0" y="245" width="375" height="109"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" verticalHuggingPriority="249" text="Content" textAlignment="natural" lineBreakMode="wordWrap" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="WPF-Oe-N2r">
<rect key="frame" x="8" y="86" width="359" height="89"/>
<label opaque="NO" contentMode="left" verticalHuggingPriority="249" text="Content" textAlignment="natural" lineBreakMode="wordWrap" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="WPF-Oe-N2r">
<rect key="frame" x="8" y="86" width="359" height="15"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" name="Text"/>
<nil key="highlightedColor"/>
@ -210,14 +239,14 @@
</constraints>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Display Name" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="a9Z-2P-cZT">
<rect key="frame" x="61" y="10" width="298" height="20.5"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
<rect key="frame" x="61" y="10" width="298" height="19.5"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="16"/>
<color key="textColor" name="Text"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Username" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="1xI-cX-lcs">
<rect key="frame" x="61" y="32.5" width="298" height="18"/>
<fontDescription key="fontDescription" type="system" pointSize="15"/>
<rect key="frame" x="61" y="31.5" width="298" height="17"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<color key="textColor" name="Primary"/>
<nil key="highlightedColor"/>
</label>
@ -256,14 +285,14 @@
</connections>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="XuS-iF-YYL">
<rect key="frame" x="0.0" y="388" width="375" height="375"/>
<rect key="frame" x="0.0" y="354" width="375" height="375"/>
<color key="backgroundColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="width" secondItem="XuS-iF-YYL" secondAttribute="height" multiplier="1:1" priority="999" id="8CQ-GM-Un6"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="y5N-A7-27p">
<rect key="frame" x="0.0" y="763" width="375" height="50"/>
<rect key="frame" x="0.0" y="729" width="375" height="50"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="pJk-g2-yyR">
<rect key="frame" x="8" y="10" width="155" height="30"/>
@ -275,12 +304,42 @@
<constraint firstAttribute="width" constant="15" id="elE-cJ-aEI"/>
</constraints>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Timestamp" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="8et-mR-yd2">
<rect key="frame" x="20" y="7" width="67.5" height="16"/>
<fontDescription key="fontDescription" type="system" pointSize="13"/>
<color key="textColor" name="Primary"/>
<nil key="highlightedColor"/>
</label>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="Pin" translatesAutoresizingMaskIntoConstraints="NO" id="ohG-e5-Gzy">
<rect key="frame" x="138" y="5" width="12" height="20"/>
<constraints>
<constraint firstAttribute="width" constant="12" id="G5U-og-f1y"/>
<constraint firstAttribute="height" constant="20" id="PZH-sq-jtA"/>
</constraints>
</imageView>
<imageView contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="Alert" translatesAutoresizingMaskIntoConstraints="NO" id="08K-bv-mOd">
<rect key="frame" x="117" y="7" width="16" height="16"/>
<gestureRecognizers/>
<constraints>
<constraint firstAttribute="width" constant="16" id="bi8-gE-iFl"/>
<constraint firstAttribute="height" constant="16" id="e2J-ux-POY"/>
</constraints>
<connections>
<outletCollection property="gestureRecognizers" destination="7Bx-xz-zOf" appends="YES" id="JjH-FW-hp1"/>
</connections>
</imageView>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="trailing" secondItem="ohG-e5-Gzy" secondAttribute="trailing" constant="5" id="00u-bm-TcB"/>
<constraint firstItem="ohG-e5-Gzy" firstAttribute="centerY" secondItem="pJk-g2-yyR" secondAttribute="centerY" id="8oh-BD-SdF"/>
<constraint firstItem="8et-mR-yd2" firstAttribute="centerY" secondItem="pJk-g2-yyR" secondAttribute="centerY" id="GO8-ME-e0f"/>
<constraint firstItem="8et-mR-yd2" firstAttribute="leading" secondItem="RIE-8X-Pwy" secondAttribute="trailing" constant="5" id="fOd-uX-vVM"/>
<constraint firstAttribute="height" constant="30" id="lBc-f9-l5n"/>
<constraint firstItem="RIE-8X-Pwy" firstAttribute="leading" secondItem="pJk-g2-yyR" secondAttribute="leading" id="p7F-pf-Sks"/>
<constraint firstItem="ohG-e5-Gzy" firstAttribute="leading" secondItem="08K-bv-mOd" secondAttribute="trailing" constant="5" id="pyl-Q0-pBO"/>
<constraint firstItem="RIE-8X-Pwy" firstAttribute="centerY" secondItem="pJk-g2-yyR" secondAttribute="centerY" id="s4a-hc-DRW"/>
<constraint firstItem="08K-bv-mOd" firstAttribute="centerY" secondItem="pJk-g2-yyR" secondAttribute="centerY" id="x4S-Wp-Q7N"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="P6f-0v-SWB">
@ -364,45 +423,49 @@
<constraint firstItem="mRG-vF-1Ur" firstAttribute="centerY" secondItem="ZKM-hs-NVu" secondAttribute="centerY" id="xMG-H7-qbH"/>
</constraints>
</view>
<imageView contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="Alert" translatesAutoresizingMaskIntoConstraints="NO" id="08K-bv-mOd">
<rect key="frame" x="130" y="17" width="16" height="16"/>
<gestureRecognizers/>
<constraints>
<constraint firstAttribute="width" constant="16" id="bi8-gE-iFl"/>
<constraint firstAttribute="height" constant="16" id="e2J-ux-POY"/>
</constraints>
<connections>
<outletCollection property="gestureRecognizers" destination="7Bx-xz-zOf" appends="YES" id="JjH-FW-hp1"/>
</connections>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Timestamp" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="8et-mR-yd2">
<rect key="frame" x="28" y="17" width="102" height="16"/>
<fontDescription key="fontDescription" type="system" pointSize="13"/>
<color key="textColor" name="Primary"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="08K-bv-mOd" firstAttribute="leading" secondItem="8et-mR-yd2" secondAttribute="trailing" id="2cy-GJ-MWR"/>
<constraint firstItem="ZKM-hs-NVu" firstAttribute="centerY" secondItem="y5N-A7-27p" secondAttribute="centerY" id="2wb-g9-MnU"/>
<constraint firstAttribute="trailing" secondItem="P6f-0v-SWB" secondAttribute="trailing" constant="8" id="7l6-9R-zXM"/>
<constraint firstAttribute="height" priority="999" constant="50" id="CSD-OT-KeH"/>
<constraint firstItem="8et-mR-yd2" firstAttribute="leading" secondItem="RIE-8X-Pwy" secondAttribute="trailing" constant="5" id="N83-Wl-ZvS"/>
<constraint firstItem="P6f-0v-SWB" firstAttribute="centerY" secondItem="y5N-A7-27p" secondAttribute="centerY" id="S34-vg-5Qz"/>
<constraint firstItem="pJk-g2-yyR" firstAttribute="centerY" secondItem="y5N-A7-27p" secondAttribute="centerY" id="STf-J7-ymf"/>
<constraint firstItem="cfJ-cH-ci5" firstAttribute="centerY" secondItem="y5N-A7-27p" secondAttribute="centerY" id="ZT4-Fj-yNI"/>
<constraint firstItem="pJk-g2-yyR" firstAttribute="leading" secondItem="y5N-A7-27p" secondAttribute="leading" constant="8" id="aPb-pb-D3s"/>
<constraint firstItem="8et-mR-yd2" firstAttribute="centerY" secondItem="y5N-A7-27p" secondAttribute="centerY" id="eJg-DO-LK8"/>
<constraint firstItem="cfJ-cH-ci5" firstAttribute="leading" secondItem="ZKM-hs-NVu" secondAttribute="trailing" constant="8" id="hXF-W4-P8y"/>
<constraint firstItem="P6f-0v-SWB" firstAttribute="leading" secondItem="cfJ-cH-ci5" secondAttribute="trailing" constant="8" id="kcy-tq-hcb"/>
<constraint firstItem="08K-bv-mOd" firstAttribute="centerY" secondItem="y5N-A7-27p" secondAttribute="centerY" id="mv2-hf-g49"/>
<constraint firstItem="ZKM-hs-NVu" firstAttribute="leading" secondItem="08K-bv-mOd" secondAttribute="trailing" constant="25" id="pyF-wf-PTZ"/>
<constraint firstItem="ZKM-hs-NVu" firstAttribute="leading" secondItem="pJk-g2-yyR" secondAttribute="trailing" constant="8" id="s4k-Oq-Qhh"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="0aT-X9-NYg">
<rect key="frame" x="0.0" y="779" width="375" height="40"/>
<subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="Down" translatesAutoresizingMaskIntoConstraints="NO" id="zEk-jb-LHL">
<rect key="frame" x="15" y="10" width="20" height="20"/>
<constraints>
<constraint firstAttribute="width" constant="20" id="6Un-al-jZp"/>
<constraint firstAttribute="height" constant="20" id="M2K-o2-1k4"/>
</constraints>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Load More" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="znl-Zz-bfs">
<rect key="frame" x="45" y="11.5" width="68.5" height="17"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<color key="textColor" name="Text"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" name="Secondary"/>
<constraints>
<constraint firstItem="zEk-jb-LHL" firstAttribute="leading" secondItem="0aT-X9-NYg" secondAttribute="leading" constant="15" id="9Gu-BD-Bmd"/>
<constraint firstAttribute="height" priority="999" constant="40" id="QLd-0c-UI5"/>
<constraint firstItem="zEk-jb-LHL" firstAttribute="centerY" secondItem="0aT-X9-NYg" secondAttribute="centerY" id="TBP-rL-Wuw"/>
<constraint firstItem="znl-Zz-bfs" firstAttribute="leading" secondItem="zEk-jb-LHL" secondAttribute="trailing" constant="10" id="a1v-10-RvI"/>
<constraint firstItem="znl-Zz-bfs" firstAttribute="centerY" secondItem="0aT-X9-NYg" secondAttribute="centerY" id="vyP-n3-i6x"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="m4t-ve-E78">
<rect key="frame" x="0.0" y="813" width="375" height="5"/>
<rect key="frame" x="0.0" y="819" width="375" height="5"/>
<color key="backgroundColor" red="0.93725490199999995" green="0.93725490199999995" blue="0.93725490199999995" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="height" priority="999" constant="5" id="QFa-Y9-r5a"/>
@ -426,7 +489,7 @@
<nil key="simulatedBottomBarMetrics"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<viewLayoutGuide key="safeArea" id="vUN-kp-3ea"/>
<point key="canvasLocation" x="53.600000000000001" y="125.03748125937032"/>
<point key="canvasLocation" x="53.600000000000001" y="127.736131934033"/>
</view>
<tapGestureRecognizer id="2h0-to-AXg">
<connections>
@ -458,11 +521,17 @@
<image name="Alert" width="22" height="22"/>
<image name="Boost Regular" width="20" height="24"/>
<image name="Clock" width="22" height="22"/>
<image name="Down" width="25" height="25"/>
<image name="Message" width="20" height="20"/>
<image name="Pin" width="29" height="50"/>
<image name="Star Regular" width="22" height="22"/>
<image name="Up" width="25" height="25"/>
<namedColor name="Primary">
<color red="0.54117647058823526" green="0.4823529411764706" blue="0.68235294117647061" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</namedColor>
<namedColor name="Secondary">
<color red="0.72941176470588232" green="0.6705882352941176" blue="0.83921568627450982" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</namedColor>
<namedColor name="Text">
<color red="0.090196078431372548" green="0.047058823529411764" blue="0.28627450980392155" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</namedColor>

36
elpha-ios/TimelineTableViewController.swift

@ -177,6 +177,7 @@ class TimelineTableViewController: UITableViewController, TimelinesTableViewCont
if let pagination = pagination {
var markers: [PaginationMarker] = status.markers ?? []
markers = Array(markers.drop { $0.context == self.currentPaginationContext })
if index == 0 {
pagination.forEach { item in
@ -193,6 +194,8 @@ class TimelineTableViewController: UITableViewController, TimelinesTableViewCont
}
}
}
status.markers = markers
}
timeline.addToStatuses(status)
@ -325,15 +328,46 @@ extension TimelineTableViewController {
cell.statusView.delegate = self
cell.statusView.update(withStatus: status)
cell.statusView.topDividerView.isHidden = indexPath.row == 0
cell.statusView.bottomDividerView.isHidden = false
cell.statusView.topLoadMoreView.isHidden = true
cell.statusView.bottomLoadMoreView.isHidden = true
let statusCount = fetchedResultsController?.fetchedObjects?.count ?? 0
if let markers = status.markers {
markers.forEach { marker in
if marker.context == self.currentPaginationContext {
print("Found marker: \(marker)")
switch marker.item.direction {
case .prev:
if indexPath.row > 0, let previousStatus = fetchedResultsController?.object(at: IndexPath(row: indexPath.row - 1, section: indexPath.section)) {
let previousMarkers = previousStatus.markers ?? []
let previousMarker = previousMarkers.first { $0.context == self.currentPaginationContext && $0.item.direction == .next }
if previousStatus.id! != marker.item.statusID && previousMarker != nil {
cell.statusView.topLoadMoreView.isHidden = false
cell.statusView.topDividerView.isHidden = true
}
}
case .next:
if indexPath.row < statusCount - 1, let nextStatus = fetchedResultsController?.object(at: IndexPath(row: indexPath.row + 1, section: indexPath.section)) {
let nextMarkers = nextStatus.markers ?? []
let nextMarker = nextMarkers.first { $0.context == self.currentPaginationContext && $0.item.direction == .prev }
if nextStatus.id! != marker.item.statusID && nextMarker != nil {
cell.statusView.bottomLoadMoreView.isHidden = false
cell.statusView.bottomDividerView.isHidden = true
}
}
}
}
}
}
if indexPath.row == statusCount - 1 {
cell.statusView.bottomLoadMoreView.isHidden = false
cell.statusView.bottomDividerView.isHidden = true
}
return cell
}
}

Loading…
Cancel
Save