Browse Source

Development

master
Dwayne Harris 6 years ago
parent
commit
0970919364
  1. 149
      elpha-ios.xcodeproj/project.pbxproj
  2. 5
      elpha-ios/Assets.xcassets/Boost Bold.imageset/Contents.json
  3. BIN
      elpha-ios/Assets.xcassets/Boost Bold.imageset/Repeat-Boost-Bold.pdf
  4. 12
      elpha-ios/Assets.xcassets/Boost Regular.imageset/Contents.json
  5. BIN
      elpha-ios/Assets.xcassets/Boost Regular.imageset/Repeat-Boost-Regular.pdf
  6. BIN
      elpha-ios/Assets.xcassets/Clock.imageset/Clock.pdf
  7. 12
      elpha-ios/Assets.xcassets/Clock.imageset/Contents.json
  8. 12
      elpha-ios/Assets.xcassets/Compose.imageset/Contents.json
  9. BIN
      elpha-ios/Assets.xcassets/Compose.imageset/Feather-Compose.pdf
  10. 12
      elpha-ios/Assets.xcassets/Down.imageset/Contents.json
  11. BIN
      elpha-ios/Assets.xcassets/Down.imageset/chevron-down.pdf
  12. 12
      elpha-ios/Assets.xcassets/Message.imageset/Contents.json
  13. BIN
      elpha-ios/Assets.xcassets/Message.imageset/Message-Reply.pdf
  14. 12
      elpha-ios/Assets.xcassets/Star Filled.imageset/Contents.json
  15. BIN
      elpha-ios/Assets.xcassets/Star Filled.imageset/Star-Favorite-Fill.pdf
  16. 12
      elpha-ios/Assets.xcassets/Star Regular.imageset/Contents.json
  17. BIN
      elpha-ios/Assets.xcassets/Star Regular.imageset/Star-Favorite.pdf
  18. 12
      elpha-ios/Assets.xcassets/Up.imageset/Contents.json
  19. BIN
      elpha-ios/Assets.xcassets/Up.imageset/chevron-up.pdf
  20. 1
      elpha-ios/AuthenticationManager.swift
  21. 490
      elpha-ios/Base.lproj/Main.storyboard
  22. 28
      elpha-ios/Date+TimeAgo.swift
  23. 4
      elpha-ios/Elpha.xcdatamodeld/Elpha.xcdatamodel/contents
  24. 1
      elpha-ios/InstanceViewController.swift
  25. 1
      elpha-ios/InstancesDataManager.swift
  26. 1
      elpha-ios/InstancesTableViewCell.swift
  27. 49
      elpha-ios/MastodonDataManager.swift
  28. 24
      elpha-ios/TimelineTableViewCell.swift
  29. 126
      elpha-ios/TimelineTableViewController.swift
  30. 24
      elpha-ios/TimelineViewController.swift
  31. 2
      elpha-ios/TimelinesNavigationController.swift

149
elpha-ios.xcodeproj/project.pbxproj

@ -7,6 +7,14 @@
objects = {
/* Begin PBXBuildFile section */
151AD4D8216899AD00F07403 /* AlamofireImage.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1517EA842159D72200DE80D6 /* AlamofireImage.framework */; };
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, ); }; };
151AD4E1216899F900F07403 /* MastodonKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 15A79B02215B3CC5007A326E /* MastodonKit.framework */; };
151AD4E2216899F900F07403 /* MastodonKit.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 15A79B02215B3CC5007A326E /* MastodonKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
151AD4E521689A0F00F07403 /* Alamofire.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 157405C3215890BC00EEAAEB /* Alamofire.framework */; };
151AD4E621689A0F00F07403 /* Alamofire.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 157405C3215890BC00EEAAEB /* Alamofire.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
157405A82150588A00EEAAEB /* InstanceViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 157405A72150588A00EEAAEB /* InstanceViewController.swift */; };
157405B12151A5DA00EEAAEB /* README.md in Resources */ = {isa = PBXBuildFile; fileRef = 157405AF2151A5DA00EEAAEB /* README.md */; };
157405B42151A93E00EEAAEB /* InstancesDataManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 157405B32151A93E00EEAAEB /* InstancesDataManager.swift */; };
@ -26,7 +34,6 @@
15960E7A2132387A00C38CE9 /* MainTabBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15960E792132387A00C38CE9 /* MainTabBarController.swift */; };
15960E7C213272CD00C38CE9 /* AuthenticationManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15960E7B213272CD00C38CE9 /* AuthenticationManager.swift */; };
15960E7E21329FED00C38CE9 /* AuthenticateViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15960E7D21329FED00C38CE9 /* AuthenticateViewController.swift */; };
15960E8021353DCF00C38CE9 /* TimelineViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15960E7F21353DCF00C38CE9 /* TimelineViewController.swift */; };
15960E822136668500C38CE9 /* TimelinesNavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15960E812136668500C38CE9 /* TimelinesNavigationController.swift */; };
15960E84213774FC00C38CE9 /* InstancesTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15960E83213774FC00C38CE9 /* InstancesTableViewController.swift */; };
15A79B07215B3CD5007A326E /* MastodonKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 15A79B02215B3CC5007A326E /* MastodonKit.framework */; };
@ -94,6 +101,34 @@
remoteGlobalIDString = 4C11830B2150517E007A8298;
remoteInfo = "iOS Example";
};
151AD4DA216899AD00F07403 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 1517EA6F2159D72200DE80D6 /* AlamofireImage.xcodeproj */;
proxyType = 1;
remoteGlobalIDString = 4C9043761AABBFC5001B4E60;
remoteInfo = "AlamofireImage iOS";
};
151AD4DF216899E000F07403 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 15A79B08215B438C007A326E /* OAuthSwift.xcodeproj */;
proxyType = 1;
remoteGlobalIDString = F43502791A6791B200038A29;
remoteInfo = OAuthSwift;
};
151AD4E3216899F900F07403 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 15A79AE7215B3CC5007A326E /* MastodonKit.xcodeproj */;
proxyType = 1;
remoteGlobalIDString = 629A4ACC213AF5B100A6386E;
remoteInfo = "MastodonKit-iOS";
};
151AD4E721689A0F00F07403 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 157405B7215890BC00EEAAEB /* Alamofire.xcodeproj */;
proxyType = 1;
remoteGlobalIDString = F8111E3219A95C8B0040E7D1;
remoteInfo = "Alamofire iOS";
};
157405C2215890BC00EEAAEB /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 157405B7215890BC00EEAAEB /* Alamofire.xcodeproj */;
@ -222,6 +257,23 @@
};
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
151AD4DC216899AD00F07403 /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
151AD4DE216899E000F07403 /* OAuthSwift.framework in Embed Frameworks */,
151AD4D9216899AD00F07403 /* AlamofireImage.framework in Embed Frameworks */,
151AD4E2216899F900F07403 /* MastodonKit.framework in Embed Frameworks */,
151AD4E621689A0F00F07403 /* Alamofire.framework in Embed Frameworks */,
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
1517EA6F2159D72200DE80D6 /* AlamofireImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = AlamofireImage.xcodeproj; path = Frameworks/AlamofireImage/AlamofireImage.xcodeproj; sourceTree = "<group>"; };
157405A72150588A00EEAAEB /* InstanceViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InstanceViewController.swift; sourceTree = "<group>"; };
@ -245,7 +297,6 @@
15960E792132387A00C38CE9 /* MainTabBarController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainTabBarController.swift; sourceTree = "<group>"; };
15960E7B213272CD00C38CE9 /* AuthenticationManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticationManager.swift; sourceTree = "<group>"; };
15960E7D21329FED00C38CE9 /* AuthenticateViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticateViewController.swift; sourceTree = "<group>"; };
15960E7F21353DCF00C38CE9 /* TimelineViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineViewController.swift; sourceTree = "<group>"; };
15960E812136668500C38CE9 /* TimelinesNavigationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelinesNavigationController.swift; sourceTree = "<group>"; };
15960E83213774FC00C38CE9 /* InstancesTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InstancesTableViewController.swift; sourceTree = "<group>"; };
15A79AE7215B3CC5007A326E /* MastodonKit.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = MastodonKit.xcodeproj; path = Frameworks/MastodonKit/MastodonKit.xcodeproj; sourceTree = "<group>"; };
@ -261,9 +312,13 @@
buildActionMask = 2147483647;
files = (
15A79B2E215C63B6007A326E /* AlamofireImage.framework in Frameworks */,
151AD4D8216899AD00F07403 /* AlamofireImage.framework in Frameworks */,
151AD4DD216899E000F07403 /* OAuthSwift.framework in Frameworks */,
151AD4E1216899F900F07403 /* MastodonKit.framework in Frameworks */,
15A79B20215B439A007A326E /* OAuthSwift.framework in Frameworks */,
15A79B07215B3CD5007A326E /* MastodonKit.framework in Frameworks */,
157405D1215890D700EEAAEB /* Alamofire.framework in Frameworks */,
151AD4E521689A0F00F07403 /* Alamofire.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -285,6 +340,50 @@
name = Products;
sourceTree = "<group>";
};
151AD4AB2166DCEE00F07403 /* Storyboards */ = {
isa = PBXGroup;
children = (
15960E60213145E100C38CE9 /* Main.storyboard */,
15960E65213145E200C38CE9 /* LaunchScreen.storyboard */,
);
name = Storyboards;
sourceTree = "<group>";
};
151AD4AC2166DD0200F07403 /* Managers */ = {
isa = PBXGroup;
children = (
15960E7B213272CD00C38CE9 /* AuthenticationManager.swift */,
15A79B42215EB959007A326E /* CoreDataManager.swift */,
157405B32151A93E00EEAAEB /* InstancesDataManager.swift */,
15F998342162C0E8009E58DA /* MastodonDataManager.swift */,
);
name = Managers;
sourceTree = "<group>";
};
151AD4AD2166DD1B00F07403 /* Reusable Views */ = {
isa = PBXGroup;
children = (
);
name = "Reusable Views";
sourceTree = "<group>";
};
151AD4AE2166DD3500F07403 /* Views */ = {
isa = PBXGroup;
children = (
159048AE214F5015004F4014 /* InstancesTableViewCell.swift */,
159026AD2162CF5600D362DD /* TimelineTableViewCell.swift */,
);
name = Views;
sourceTree = "<group>";
};
151AD4AF2166DDA000F07403 /* Extensions */ = {
isa = PBXGroup;
children = (
159026CF2163069600D362DD /* Date+TimeAgo.swift */,
);
name = Extensions;
sourceTree = "<group>";
};
157405B8215890BC00EEAAEB /* Products */ = {
isa = PBXGroup;
children = (
@ -333,18 +432,16 @@
children = (
15960E68213145E200C38CE9 /* Info.plist */,
15960E5A213145E100C38CE9 /* AppDelegate.swift */,
15960E7B213272CD00C38CE9 /* AuthenticationManager.swift */,
15960E7621322C6F00C38CE9 /* Configuration.swift */,
15A79B42215EB959007A326E /* CoreDataManager.swift */,
159026CF2163069600D362DD /* Date+TimeAgo.swift */,
157405B32151A93E00EEAAEB /* InstancesDataManager.swift */,
15F998342162C0E8009E58DA /* MastodonDataManager.swift */,
15960E63213145E200C38CE9 /* Assets.xcassets */,
15960E6E21321FA500C38CE9 /* Elpha.xcdatamodeld */,
151AD4AF2166DDA000F07403 /* Extensions */,
15960E7121322B9F00C38CE9 /* Keychain Helper */,
15960E65213145E200C38CE9 /* LaunchScreen.storyboard */,
15960E60213145E100C38CE9 /* Main.storyboard */,
151AD4AC2166DD0200F07403 /* Managers */,
151AD4AD2166DD1B00F07403 /* Reusable Views */,
151AD4AB2166DCEE00F07403 /* Storyboards */,
15960E782132383600C38CE9 /* View Controllers */,
151AD4AE2166DD3500F07403 /* Views */,
);
path = "elpha-ios";
sourceTree = "<group>";
@ -362,15 +459,12 @@
isa = PBXGroup;
children = (
15960E7D21329FED00C38CE9 /* AuthenticateViewController.swift */,
159048AE214F5015004F4014 /* InstancesTableViewCell.swift */,
15960E83213774FC00C38CE9 /* InstancesTableViewController.swift */,
157405A72150588A00EEAAEB /* InstanceViewController.swift */,
15960E792132387A00C38CE9 /* MainTabBarController.swift */,
15960E5E213145E100C38CE9 /* SecondViewController.swift */,
15960E812136668500C38CE9 /* TimelinesNavigationController.swift */,
159026AD2162CF5600D362DD /* TimelineTableViewCell.swift */,
15F9981621629965009E58DA /* TimelineTableViewController.swift */,
15960E7F21353DCF00C38CE9 /* TimelineViewController.swift */,
);
name = "View Controllers";
sourceTree = "<group>";
@ -410,10 +504,15 @@
15960E53213145E100C38CE9 /* Sources */,
15960E54213145E100C38CE9 /* Frameworks */,
15960E55213145E100C38CE9 /* Resources */,
151AD4DC216899AD00F07403 /* Embed Frameworks */,
);
buildRules = (
);
dependencies = (
151AD4DB216899AD00F07403 /* PBXTargetDependency */,
151AD4E0216899E000F07403 /* PBXTargetDependency */,
151AD4E4216899F900F07403 /* PBXTargetDependency */,
151AD4E821689A0F00F07403 /* PBXTargetDependency */,
);
name = "elpha-ios";
productName = "elpha-ios";
@ -683,7 +782,6 @@
157405B42151A93E00EEAAEB /* InstancesDataManager.swift in Sources */,
15960E5F213145E100C38CE9 /* SecondViewController.swift in Sources */,
15F998352162C0E8009E58DA /* MastodonDataManager.swift in Sources */,
15960E8021353DCF00C38CE9 /* TimelineViewController.swift in Sources */,
15960E7A2132387A00C38CE9 /* MainTabBarController.swift in Sources */,
15960E7C213272CD00C38CE9 /* AuthenticationManager.swift in Sources */,
15960E7E21329FED00C38CE9 /* AuthenticateViewController.swift in Sources */,
@ -701,6 +799,29 @@
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
151AD4DB216899AD00F07403 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = "AlamofireImage iOS";
targetProxy = 151AD4DA216899AD00F07403 /* PBXContainerItemProxy */;
};
151AD4E0216899E000F07403 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = OAuthSwift;
targetProxy = 151AD4DF216899E000F07403 /* PBXContainerItemProxy */;
};
151AD4E4216899F900F07403 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = "MastodonKit-iOS";
targetProxy = 151AD4E3216899F900F07403 /* PBXContainerItemProxy */;
};
151AD4E821689A0F00F07403 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = "Alamofire iOS";
targetProxy = 151AD4E721689A0F00F07403 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
15960E60213145E100C38CE9 /* Main.storyboard */ = {
isa = PBXVariantGroup;
@ -838,6 +959,7 @@
15960E6C213145E200C38CE9 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = R9PMLQGTGZ;
@ -857,6 +979,7 @@
15960E6D213145E200C38CE9 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = R9PMLQGTGZ;

5
elpha-ios/Assets.xcassets/Toot.imageset/Contents.json → elpha-ios/Assets.xcassets/Boost Bold.imageset/Contents.json

@ -2,14 +2,11 @@
"images" : [
{
"idiom" : "universal",
"filename" : "toot.pdf"
"filename" : "Repeat-Boost-Bold.pdf"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
},
"properties" : {
"preserves-vector-representation" : true
}
}

BIN
elpha-ios/Assets.xcassets/Boost Bold.imageset/Repeat-Boost-Bold.pdf

12
elpha-ios/Assets.xcassets/Boost Regular.imageset/Contents.json

@ -0,0 +1,12 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "Repeat-Boost-Regular.pdf"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

BIN
elpha-ios/Assets.xcassets/Boost Regular.imageset/Repeat-Boost-Regular.pdf

BIN
elpha-ios/Assets.xcassets/Toot.imageset/toot.pdf → elpha-ios/Assets.xcassets/Clock.imageset/Clock.pdf

12
elpha-ios/Assets.xcassets/Clock.imageset/Contents.json

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

12
elpha-ios/Assets.xcassets/Compose.imageset/Contents.json

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

BIN
elpha-ios/Assets.xcassets/Compose.imageset/Feather-Compose.pdf

12
elpha-ios/Assets.xcassets/Down.imageset/Contents.json

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

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

12
elpha-ios/Assets.xcassets/Message.imageset/Contents.json

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

BIN
elpha-ios/Assets.xcassets/Message.imageset/Message-Reply.pdf

12
elpha-ios/Assets.xcassets/Star Filled.imageset/Contents.json

@ -0,0 +1,12 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "Star-Favorite-Fill.pdf"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

BIN
elpha-ios/Assets.xcassets/Star Filled.imageset/Star-Favorite-Fill.pdf

12
elpha-ios/Assets.xcassets/Star Regular.imageset/Contents.json

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

BIN
elpha-ios/Assets.xcassets/Star Regular.imageset/Star-Favorite.pdf

12
elpha-ios/Assets.xcassets/Up.imageset/Contents.json

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

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

1
elpha-ios/AuthenticationManager.swift

@ -7,7 +7,6 @@
//
import CoreData
import Foundation
import MastodonKit
import UIKit

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

@ -561,89 +561,436 @@
<scene sceneID="jGL-v8-K0I">
<objects>
<tableViewController id="9RY-uh-Cwh" customClass="TimelineTableViewController" customModule="elpha_ios" customModuleProvider="target" sceneMemberID="viewController">
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" id="fgT-hp-jpg">
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="none" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" id="fgT-hp-jpg">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<prototypes>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="TimelineTableViewCell" rowHeight="150" id="ltf-IW-WJt" customClass="TimelineTableViewCell" customModule="elpha_ios" customModuleProvider="target">
<rect key="frame" x="0.0" y="28" width="414" height="150"/>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="TimelineTableViewCell" rowHeight="500" id="ltf-IW-WJt" customClass="TimelineTableViewCell" customModule="elpha_ios" customModuleProvider="target">
<rect key="frame" x="0.0" y="28" width="414" height="500"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="ltf-IW-WJt" id="n6I-gD-BmS">
<rect key="frame" x="0.0" y="0.0" width="414" height="149.5"/>
<rect key="frame" x="0.0" y="0.0" width="414" height="500"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="oQB-FK-89W">
<rect key="frame" x="20" y="11" width="50" height="50"/>
<constraints>
<constraint firstAttribute="width" constant="50" id="8ca-j9-jUQ"/>
<constraint firstAttribute="height" constant="50" id="rs8-rd-h8m"/>
</constraints>
</imageView>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="oRN-Cg-Tuh">
<rect key="frame" x="78" y="16" width="258" height="50"/>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="Bk1-Te-ST5">
<rect key="frame" x="0.0" y="0.0" width="414" height="500"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="WfV-kx-uwj">
<rect key="frame" x="0.0" y="0.0" width="258" height="18"/>
<fontDescription key="fontDescription" type="system" pointSize="15"/>
<color key="textColor" red="0.090196078430000007" green="0.047058823530000002" blue="0.28627450980000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Jzk-kb-RSG">
<rect key="frame" x="0.0" y="23" width="258" height="14.5"/>
<fontDescription key="fontDescription" type="system" pointSize="12"/>
<color key="textColor" red="0.090196078430000007" green="0.047058823530000002" blue="0.28627450980000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Fb6-oy-z8M">
<rect key="frame" x="0.0" y="0.0" width="414" height="5"/>
<color key="backgroundColor" red="0.93725490196078431" green="0.93725490196078431" blue="0.93725490196078431" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="height" constant="5" id="LVZ-HF-tZa"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="7fe-eL-1qu">
<rect key="frame" x="0.0" y="5" width="414" height="50"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="7J1-mc-hnw">
<rect key="frame" x="167" y="11" width="80" height="28"/>
<subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="Up" translatesAutoresizingMaskIntoConstraints="NO" id="Ocy-VU-QZn">
<rect key="frame" x="34" y="0.0" width="12" height="6"/>
<color key="tintColor" red="0.090196078430000007" green="0.047058823530000002" blue="0.28627450980000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="width" constant="12" id="nhn-ZW-gRV"/>
<constraint firstAttribute="height" constant="6" id="uHN-OE-47w"/>
</constraints>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Load More" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="gR6-aN-8MJ">
<rect key="frame" x="8" y="11" width="64" height="14.5"/>
<fontDescription key="fontDescription" type="system" pointSize="12"/>
<color key="textColor" red="0.090196078430000007" green="0.047058823530000002" blue="0.28627450980000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" red="0.72941176470000002" green="0.6705882353" blue="0.83921568629999999" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="trailing" secondItem="gR6-aN-8MJ" secondAttribute="trailing" constant="8" id="1wK-Xh-mFV"/>
<constraint firstAttribute="height" constant="28" id="JZl-g3-X1b"/>
<constraint firstItem="gR6-aN-8MJ" firstAttribute="top" secondItem="Ocy-VU-QZn" secondAttribute="bottom" constant="5" id="Rm1-BO-h2h"/>
<constraint firstAttribute="width" constant="80" id="Xo7-eO-J8c"/>
<constraint firstItem="Ocy-VU-QZn" firstAttribute="centerX" secondItem="7J1-mc-hnw" secondAttribute="centerX" id="eMd-5V-6pj"/>
<constraint firstItem="gR6-aN-8MJ" firstAttribute="leading" secondItem="7J1-mc-hnw" secondAttribute="leading" constant="8" id="v1k-O7-qRw"/>
<constraint firstItem="Ocy-VU-QZn" firstAttribute="top" secondItem="7J1-mc-hnw" secondAttribute="top" id="zNa-bM-7n8"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" red="0.72941176470000002" green="0.6705882353" blue="0.83921568629999999" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="height" constant="50" id="6ie-d5-Mbg"/>
<constraint firstItem="7J1-mc-hnw" firstAttribute="centerY" secondItem="7fe-eL-1qu" secondAttribute="centerY" id="C8Z-WH-lg3"/>
<constraint firstItem="7J1-mc-hnw" firstAttribute="centerX" secondItem="7fe-eL-1qu" secondAttribute="centerX" id="QQr-tW-cHV"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="9fS-a9-pwm">
<rect key="frame" x="0.0" y="55" width="414" height="100"/>
<subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="ocT-ux-M2p">
<rect key="frame" x="8" y="18" width="40" height="40"/>
<constraints>
<constraint firstAttribute="width" constant="40" id="FOT-Id-1ck"/>
<constraint firstAttribute="height" constant="40" id="hZI-kx-4rP"/>
</constraints>
</imageView>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="Boost Regular" translatesAutoresizingMaskIntoConstraints="NO" id="IKt-wC-rQf">
<rect key="frame" x="56" y="60" width="12" height="16"/>
<constraints>
<constraint firstAttribute="width" constant="12" id="iEj-7l-ylL"/>
<constraint firstAttribute="height" constant="16" id="pWe-WP-xba"/>
</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="ukb-MJ-igh">
<rect key="frame" x="56" y="18" width="100.5" height="18"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
<color key="textColor" red="0.090196078430000007" green="0.047058823530000002" blue="0.28627450980000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<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="dvA-pE-bQJ">
<rect key="frame" x="56" y="40" width="62" height="16"/>
<fontDescription key="fontDescription" type="system" pointSize="13"/>
<color key="textColor" red="0.090196078430000007" green="0.047058823530000002" blue="0.28627450980000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="8DN-mV-NXI">
<rect key="frame" x="20" y="93" width="374" height="2"/>
<color key="backgroundColor" cocoaTouchSystemColor="groupTableViewBackgroundColor"/>
<constraints>
<constraint firstAttribute="height" constant="2" id="dA1-jU-Sbe"/>
</constraints>
</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="gXx-Tg-gLN">
<rect key="frame" x="76" y="60" width="47" height="14.5"/>
<fontDescription key="fontDescription" type="system" pointSize="12"/>
<color key="textColor" red="0.090196078430000007" green="0.047058823530000002" blue="0.28627450980000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="IKt-wC-rQf" firstAttribute="leading" secondItem="dvA-pE-bQJ" secondAttribute="leading" id="1Px-vS-dOJ"/>
<constraint firstItem="dvA-pE-bQJ" firstAttribute="leading" secondItem="ocT-ux-M2p" secondAttribute="trailing" constant="8" id="49y-Or-GyX"/>
<constraint firstItem="gXx-Tg-gLN" firstAttribute="top" secondItem="dvA-pE-bQJ" secondAttribute="bottom" constant="4" id="8vA-Cq-EED"/>
<constraint firstAttribute="height" constant="100" id="AsD-s0-pkq"/>
<constraint firstItem="ocT-ux-M2p" firstAttribute="top" secondItem="9fS-a9-pwm" secondAttribute="top" constant="18" id="Bvi-2N-0r3"/>
<constraint firstItem="dvA-pE-bQJ" firstAttribute="top" secondItem="ukb-MJ-igh" secondAttribute="bottom" constant="4" id="CTi-We-t02"/>
<constraint firstItem="ocT-ux-M2p" firstAttribute="leading" secondItem="9fS-a9-pwm" secondAttribute="leading" constant="8" id="HwA-0T-yqS"/>
<constraint firstAttribute="bottom" secondItem="8DN-mV-NXI" secondAttribute="bottom" constant="5" id="KHL-w9-61f"/>
<constraint firstItem="ukb-MJ-igh" firstAttribute="top" secondItem="9fS-a9-pwm" secondAttribute="top" constant="18" id="ZGu-Y9-Izj"/>
<constraint firstItem="gXx-Tg-gLN" firstAttribute="leading" secondItem="IKt-wC-rQf" secondAttribute="trailing" constant="8" id="avD-BX-C95"/>
<constraint firstItem="8DN-mV-NXI" firstAttribute="leading" secondItem="9fS-a9-pwm" secondAttribute="leading" constant="20" id="eTl-sX-JY6"/>
<constraint firstItem="IKt-wC-rQf" firstAttribute="top" secondItem="dvA-pE-bQJ" secondAttribute="bottom" constant="4" id="fMa-hv-fSt"/>
<constraint firstItem="ukb-MJ-igh" firstAttribute="leading" secondItem="ocT-ux-M2p" secondAttribute="trailing" constant="8" id="hDb-E4-iJq"/>
<constraint firstAttribute="trailing" secondItem="8DN-mV-NXI" secondAttribute="trailing" constant="20" id="soR-hM-eq3"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="xpm-gm-QTe">
<rect key="frame" x="0.0" y="155" width="414" height="100"/>
<subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="Z85-Y0-P4Y">
<rect key="frame" x="8" y="18" width="40" height="40"/>
<constraints>
<constraint firstAttribute="height" constant="40" id="iUg-5Z-Frr"/>
<constraint firstAttribute="width" constant="40" id="jVE-Dv-15H"/>
</constraints>
</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="BX6-Js-Nhi">
<rect key="frame" x="76" y="18" width="56.5" height="14.5"/>
<fontDescription key="fontDescription" type="system" pointSize="12"/>
<color key="textColor" red="0.090196078430000007" green="0.047058823530000002" blue="0.28627450980000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="Message" translatesAutoresizingMaskIntoConstraints="NO" id="o2s-le-wFQ">
<rect key="frame" x="56" y="20" width="12" height="12"/>
<constraints>
<constraint firstAttribute="height" constant="12" id="Ojf-mK-U2A"/>
<constraint firstAttribute="width" constant="12" id="a7d-f5-sju"/>
</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="Spo-Jx-UQY">
<rect key="frame" x="56" y="36.5" width="100.5" height="18"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
<color key="textColor" red="0.090196078430000007" green="0.047058823530000002" blue="0.28627450980000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="4Gf-aV-jSP">
<rect key="frame" x="20" y="93" width="374" height="2"/>
<color key="backgroundColor" red="0.93725490199999995" green="0.93725490199999995" blue="0.95686274510000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="height" constant="2" id="lPl-ql-kES"/>
</constraints>
</view>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Username" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="vCq-bh-CMA">
<rect key="frame" x="56" y="58.5" width="62" height="16"/>
<fontDescription key="fontDescription" type="system" pointSize="13"/>
<color key="textColor" red="0.090196078430000007" green="0.047058823530000002" blue="0.28627450980000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="BX6-Js-Nhi" firstAttribute="top" secondItem="xpm-gm-QTe" secondAttribute="top" constant="18" id="1jk-D3-Bsh"/>
<constraint firstAttribute="height" constant="100" id="3ZW-GL-Mj5"/>
<constraint firstItem="Spo-Jx-UQY" firstAttribute="leading" secondItem="Z85-Y0-P4Y" secondAttribute="trailing" constant="8" id="5l7-bV-uJQ"/>
<constraint firstItem="o2s-le-wFQ" firstAttribute="top" secondItem="xpm-gm-QTe" secondAttribute="top" constant="20" id="7BG-C0-w5O"/>
<constraint firstItem="Z85-Y0-P4Y" firstAttribute="leading" secondItem="xpm-gm-QTe" secondAttribute="leading" constant="8" id="B1J-au-QNS"/>
<constraint firstItem="4Gf-aV-jSP" firstAttribute="leading" secondItem="xpm-gm-QTe" secondAttribute="leading" constant="20" id="OaZ-lQ-DRF"/>
<constraint firstItem="BX6-Js-Nhi" firstAttribute="leading" secondItem="o2s-le-wFQ" secondAttribute="trailing" constant="8" id="QVG-2z-RBl"/>
<constraint firstAttribute="trailing" secondItem="4Gf-aV-jSP" secondAttribute="trailing" constant="20" id="alp-MQ-dTO"/>
<constraint firstItem="vCq-bh-CMA" firstAttribute="leading" secondItem="Spo-Jx-UQY" secondAttribute="leading" id="biR-A0-SVf"/>
<constraint firstItem="vCq-bh-CMA" firstAttribute="top" secondItem="Spo-Jx-UQY" secondAttribute="bottom" constant="4" id="c8u-6u-7Kf"/>
<constraint firstAttribute="bottom" secondItem="4Gf-aV-jSP" secondAttribute="bottom" constant="5" id="dJh-Ld-Doo"/>
<constraint firstItem="Spo-Jx-UQY" firstAttribute="top" secondItem="BX6-Js-Nhi" secondAttribute="bottom" constant="4" id="rdh-yu-BHe"/>
<constraint firstItem="Z85-Y0-P4Y" firstAttribute="top" secondItem="xpm-gm-QTe" secondAttribute="top" constant="18" id="sz1-t1-hxY"/>
<constraint firstItem="o2s-le-wFQ" firstAttribute="leading" secondItem="Z85-Y0-P4Y" secondAttribute="trailing" constant="8" id="weK-2y-Ycg"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="OwU-e4-gmT">
<rect key="frame" x="0.0" y="255" width="414" height="190"/>
<subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="AOi-ot-xXa">
<rect key="frame" x="8" y="18" width="45" height="45"/>
<constraints>
<constraint firstAttribute="height" constant="45" id="3lv-lh-lug"/>
<constraint firstAttribute="width" constant="45" id="hII-wY-bcl"/>
</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="Nsu-8a-xsG">
<rect key="frame" x="61" y="18" width="112" height="20.5"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
<color key="textColor" red="0.090196078430000007" green="0.047058823530000002" blue="0.28627450980000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<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="dvJ-7r-JOr">
<rect key="frame" x="61" y="40.5" width="70.5" height="18"/>
<fontDescription key="fontDescription" type="system" pointSize="15"/>
<color key="textColor" red="0.090196078430000007" green="0.047058823530000002" blue="0.28627450980000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Content" textAlignment="natural" lineBreakMode="wordWrap" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="VmZ-Cs-XbK">
<rect key="frame" x="8" y="78" width="398" height="20.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.090196078430000007" green="0.047058823530000002" blue="0.28627450980000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="pGF-ol-Wqu">
<rect key="frame" x="8" y="145" width="100" height="30"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Timestamp" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="g0I-Zp-Y9h">
<rect key="frame" x="20" y="7" width="67.5" height="16"/>
<fontDescription key="fontDescription" type="system" pointSize="13"/>
<color key="textColor" red="0.090196078430000007" green="0.047058823530000002" blue="0.28627450980000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="Clock" translatesAutoresizingMaskIntoConstraints="NO" id="aeb-vM-xuk">
<rect key="frame" x="0.0" y="7.5" width="15" height="15"/>
<constraints>
<constraint firstAttribute="height" constant="15" id="1J8-hQ-jsb"/>
<constraint firstAttribute="width" constant="15" id="MYc-OS-HyA"/>
</constraints>
</imageView>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="height" constant="30" id="6cC-Bm-dsh"/>
<constraint firstAttribute="width" constant="100" id="QgS-Ss-UU0"/>
<constraint firstItem="g0I-Zp-Y9h" firstAttribute="centerY" secondItem="pGF-ol-Wqu" secondAttribute="centerY" id="XeP-2L-8Gi"/>
<constraint firstItem="aeb-vM-xuk" firstAttribute="leading" secondItem="pGF-ol-Wqu" secondAttribute="leading" id="Y9E-Kd-bFD"/>
<constraint firstItem="g0I-Zp-Y9h" firstAttribute="leading" secondItem="aeb-vM-xuk" secondAttribute="trailing" constant="5" id="ZrB-fL-WyG"/>
<constraint firstItem="aeb-vM-xuk" firstAttribute="centerY" secondItem="pGF-ol-Wqu" secondAttribute="centerY" id="j3V-yK-fuP"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="ZOn-0n-hPZ">
<rect key="frame" x="346" y="145" width="60" height="30"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="100" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Jfd-Nt-QbG">
<rect key="frame" x="28" y="6.5" width="24" height="17"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<color key="textColor" red="0.090196078430000007" green="0.047058823530000002" blue="0.28627450980000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="Star Regular" translatesAutoresizingMaskIntoConstraints="NO" id="fYQ-Zp-0Sm">
<rect key="frame" x="5" y="7.5" width="15" height="15"/>
<constraints>
<constraint firstAttribute="height" constant="15" id="ChY-1e-ldQ"/>
<constraint firstAttribute="width" constant="15" id="Mqw-bX-FDD"/>
</constraints>
</imageView>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="Jfd-Nt-QbG" firstAttribute="leading" secondItem="fYQ-Zp-0Sm" secondAttribute="trailing" constant="8" id="3fk-gy-wS8"/>
<constraint firstAttribute="height" constant="30" id="7Xv-qF-vRd"/>
<constraint firstAttribute="trailing" secondItem="Jfd-Nt-QbG" secondAttribute="trailing" constant="8" id="9ys-Xj-tDz"/>
<constraint firstItem="Jfd-Nt-QbG" firstAttribute="centerY" secondItem="ZOn-0n-hPZ" secondAttribute="centerY" id="G8V-yt-pEb"/>
<constraint firstItem="fYQ-Zp-0Sm" firstAttribute="centerY" secondItem="ZOn-0n-hPZ" secondAttribute="centerY" id="cpM-gC-wX2"/>
<constraint firstAttribute="width" constant="60" id="cvA-sB-o7w"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="dbI-17-JiR">
<rect key="frame" x="278" y="145" width="60" height="30"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="100" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="jbL-pa-f8U">
<rect key="frame" x="36" y="6.5" width="24" height="17"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<color key="textColor" red="0.090196078430000007" green="0.047058823530000002" blue="0.28627450980000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="Boost Regular" translatesAutoresizingMaskIntoConstraints="NO" id="6nH-wa-zK5">
<rect key="frame" x="14" y="6" width="14" height="18"/>
<constraints>
<constraint firstAttribute="width" constant="14" id="1AH-Bj-6b5"/>
<constraint firstAttribute="height" constant="18" id="cZg-wp-aLM"/>
</constraints>
</imageView>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="6nH-wa-zK5" firstAttribute="centerY" secondItem="dbI-17-JiR" secondAttribute="centerY" id="1nD-1h-wub"/>
<constraint firstAttribute="width" constant="60" id="9N4-hp-MnN"/>
<constraint firstAttribute="height" constant="30" id="CpC-Xa-DaS"/>
<constraint firstAttribute="trailing" secondItem="jbL-pa-f8U" secondAttribute="trailing" id="dHR-zf-kOZ"/>
<constraint firstItem="jbL-pa-f8U" firstAttribute="centerY" secondItem="dbI-17-JiR" secondAttribute="centerY" id="kkF-Hj-kir"/>
<constraint firstItem="jbL-pa-f8U" firstAttribute="leading" secondItem="6nH-wa-zK5" secondAttribute="trailing" constant="8" id="vrc-QW-nJv"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="IsJ-nH-idi">
<rect key="frame" x="210" y="145" width="60" height="30"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="100" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="WWx-tD-ydV">
<rect key="frame" x="36" y="6.5" width="24" height="17"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<color key="textColor" red="0.090196078430000007" green="0.047058823530000002" blue="0.28627450980000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="Message" translatesAutoresizingMaskIntoConstraints="NO" id="BaX-Vk-itT">
<rect key="frame" x="13" y="7.5" width="15" height="15"/>
<constraints>
<constraint firstAttribute="height" constant="15" id="DpY-ZJ-e9f"/>
<constraint firstAttribute="width" constant="15" id="qQ7-Ih-KmL"/>
</constraints>
</imageView>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="WWx-tD-ydV" firstAttribute="centerY" secondItem="IsJ-nH-idi" secondAttribute="centerY" id="BvB-ss-NW2"/>
<constraint firstAttribute="width" constant="60" id="RrM-ce-exD"/>
<constraint firstAttribute="height" constant="30" id="nC6-Ld-bVM"/>
<constraint firstItem="WWx-tD-ydV" firstAttribute="leading" secondItem="BaX-Vk-itT" secondAttribute="trailing" constant="8" id="oW1-Ts-3lY"/>
<constraint firstAttribute="trailing" secondItem="WWx-tD-ydV" secondAttribute="trailing" id="rzF-o6-kIn"/>
<constraint firstItem="BaX-Vk-itT" firstAttribute="centerY" secondItem="IsJ-nH-idi" secondAttribute="centerY" id="xlm-en-NCW"/>
</constraints>
</view>
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="eY8-HB-QXO">
<rect key="frame" x="0.0" y="106.5" width="414" height="30.5"/>
</imageView>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="trailing" secondItem="VmZ-Cs-XbK" secondAttribute="trailing" constant="8" id="32g-8R-k8N"/>
<constraint firstItem="eY8-HB-QXO" firstAttribute="top" secondItem="VmZ-Cs-XbK" secondAttribute="bottom" constant="8" id="8U0-7c-Pnn"/>
<constraint firstAttribute="bottom" secondItem="dbI-17-JiR" secondAttribute="bottom" constant="15" id="976-ZN-32I"/>
<constraint firstAttribute="bottom" secondItem="pGF-ol-Wqu" secondAttribute="bottom" constant="15" id="9Ff-UD-7Ke"/>
<constraint firstAttribute="trailing" secondItem="eY8-HB-QXO" secondAttribute="trailing" id="AsU-r4-iEi"/>
<constraint firstItem="dvJ-7r-JOr" firstAttribute="top" secondItem="Nsu-8a-xsG" secondAttribute="bottom" constant="2" id="KVY-bN-5l0"/>
<constraint firstAttribute="bottom" secondItem="IsJ-nH-idi" secondAttribute="bottom" constant="15" id="KfX-d0-Yfc"/>
<constraint firstItem="Nsu-8a-xsG" firstAttribute="top" secondItem="OwU-e4-gmT" secondAttribute="top" constant="18" id="TNR-QZ-3f8"/>
<constraint firstItem="AOi-ot-xXa" firstAttribute="top" secondItem="OwU-e4-gmT" secondAttribute="top" constant="18" id="VZr-nm-9C5"/>
<constraint firstItem="dbI-17-JiR" firstAttribute="leading" secondItem="IsJ-nH-idi" secondAttribute="trailing" constant="8" id="Wcj-uc-coX"/>
<constraint firstItem="pGF-ol-Wqu" firstAttribute="leading" secondItem="OwU-e4-gmT" secondAttribute="leading" constant="8" id="X1O-8M-ZkZ"/>
<constraint firstItem="VmZ-Cs-XbK" firstAttribute="leading" secondItem="OwU-e4-gmT" secondAttribute="leading" constant="8" id="awE-TQ-TF0"/>
<constraint firstItem="AOi-ot-xXa" firstAttribute="leading" secondItem="OwU-e4-gmT" secondAttribute="leading" constant="8" id="dZ3-VC-SPP"/>
<constraint firstAttribute="bottom" secondItem="ZOn-0n-hPZ" secondAttribute="bottom" constant="15" id="e7x-WD-Jdf"/>
<constraint firstItem="Nsu-8a-xsG" firstAttribute="leading" secondItem="AOi-ot-xXa" secondAttribute="trailing" constant="8" id="iZn-vn-Xtt"/>
<constraint firstItem="VmZ-Cs-XbK" firstAttribute="top" secondItem="AOi-ot-xXa" secondAttribute="bottom" constant="15" id="kni-Ko-qpY"/>
<constraint firstItem="dvJ-7r-JOr" firstAttribute="leading" secondItem="AOi-ot-xXa" secondAttribute="trailing" constant="8" id="oyQ-0e-9qz"/>
<constraint firstAttribute="trailing" secondItem="ZOn-0n-hPZ" secondAttribute="trailing" constant="8" id="q9C-Xy-DDI"/>
<constraint firstItem="ZOn-0n-hPZ" firstAttribute="leading" secondItem="dbI-17-JiR" secondAttribute="trailing" constant="8" id="sII-EP-kkK"/>
<constraint firstItem="pGF-ol-Wqu" firstAttribute="top" secondItem="eY8-HB-QXO" secondAttribute="bottom" constant="8" id="so0-Ep-VbV"/>
<constraint firstItem="eY8-HB-QXO" firstAttribute="leading" secondItem="OwU-e4-gmT" secondAttribute="leading" id="zPq-t1-vzJ"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="1pv-7u-4nG">
<rect key="frame" x="0.0" y="445" width="414" height="50"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="h6S-BG-PFa">
<rect key="frame" x="167" y="11" width="80" height="28"/>
<subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="Down" translatesAutoresizingMaskIntoConstraints="NO" id="tk1-p1-u0D">
<rect key="frame" x="34" y="22" width="12" height="6"/>
<constraints>
<constraint firstAttribute="width" constant="12" id="fWG-Sr-I1H"/>
<constraint firstAttribute="height" constant="6" id="pmJ-FG-qTv"/>
</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="iH0-8P-Kth">
<rect key="frame" x="8" y="2.5" width="64" height="14.5"/>
<fontDescription key="fontDescription" type="system" pointSize="12"/>
<color key="textColor" red="0.090196078430000007" green="0.047058823530000002" blue="0.28627450980000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" red="0.72941176470000002" green="0.6705882353" blue="0.83921568629999999" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="iH0-8P-Kth" firstAttribute="leading" secondItem="h6S-BG-PFa" secondAttribute="leading" constant="8" id="BhX-G8-ZHa"/>
<constraint firstItem="tk1-p1-u0D" firstAttribute="top" secondItem="iH0-8P-Kth" secondAttribute="bottom" constant="5" id="I1U-mK-4ig"/>
<constraint firstItem="tk1-p1-u0D" firstAttribute="centerX" secondItem="h6S-BG-PFa" secondAttribute="centerX" id="R4V-4U-S3Q"/>
<constraint firstAttribute="width" constant="80" id="cHv-vY-jyT"/>
<constraint firstAttribute="bottom" secondItem="tk1-p1-u0D" secondAttribute="bottom" id="iko-df-3hi"/>
<constraint firstAttribute="trailing" secondItem="iH0-8P-Kth" secondAttribute="trailing" constant="8" id="wcW-i2-31a"/>
<constraint firstAttribute="height" constant="28" id="yCg-xM-EUn"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" red="0.72941176470000002" green="0.6705882353" blue="0.83921568629999999" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="height" constant="50" id="4Tp-H0-5C6"/>
<constraint firstItem="h6S-BG-PFa" firstAttribute="centerX" secondItem="1pv-7u-4nG" secondAttribute="centerX" id="Hjm-vc-SbQ"/>
<constraint firstItem="h6S-BG-PFa" firstAttribute="centerY" secondItem="1pv-7u-4nG" secondAttribute="centerY" id="Vwj-uE-lzL"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="eS7-7y-Xkh">
<rect key="frame" x="0.0" y="495" width="414" height="5"/>
<color key="backgroundColor" red="0.93725490196078431" green="0.93725490196078431" blue="0.93725490196078431" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="height" constant="5" id="04g-oC-yxr"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="WfV-kx-uwj" firstAttribute="top" secondItem="oRN-Cg-Tuh" secondAttribute="top" id="CF4-vW-ksc"/>
<constraint firstAttribute="height" constant="50" id="FKR-wN-R79"/>
<constraint firstAttribute="trailing" secondItem="Jzk-kb-RSG" secondAttribute="trailing" id="NSm-0a-Puo"/>
<constraint firstItem="Jzk-kb-RSG" firstAttribute="leading" secondItem="oRN-Cg-Tuh" secondAttribute="leading" id="e07-cg-ilX"/>
<constraint firstItem="Jzk-kb-RSG" firstAttribute="top" secondItem="WfV-kx-uwj" secondAttribute="bottom" constant="5" id="kt5-Ce-afJ"/>
<constraint firstAttribute="trailing" secondItem="WfV-kx-uwj" secondAttribute="trailing" id="orG-rZ-afg"/>
<constraint firstItem="WfV-kx-uwj" firstAttribute="leading" secondItem="oRN-Cg-Tuh" secondAttribute="leading" id="zTG-Wl-wrg"/>
</constraints>
</view>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="u1N-eJ-oKk">
<rect key="frame" x="344" y="11" width="50" height="50"/>
<constraints>
<constraint firstAttribute="width" constant="50" id="0pw-Ep-hi5"/>
<constraint firstAttribute="height" constant="50" id="dMz-Rn-S3b"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="11"/>
<color key="textColor" red="0.090196078430000007" green="0.047058823530000002" blue="0.28627450980000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="wordWrap" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Uxx-lg-rdv">
<rect key="frame" x="20" y="76" width="374" height="63"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.090196078430000007" green="0.047058823530000002" blue="0.28627450980000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
</stackView>
</subviews>
<constraints>
<constraint firstItem="oQB-FK-89W" firstAttribute="top" secondItem="n6I-gD-BmS" secondAttribute="topMargin" id="0Q6-R0-IwX"/>
<constraint firstItem="Uxx-lg-rdv" firstAttribute="leading" secondItem="n6I-gD-BmS" secondAttribute="leadingMargin" id="3js-ld-GRK"/>
<constraint firstItem="u1N-eJ-oKk" firstAttribute="trailing" secondItem="n6I-gD-BmS" secondAttribute="trailingMargin" id="Ekk-lS-cal"/>
<constraint firstItem="Uxx-lg-rdv" firstAttribute="top" secondItem="oQB-FK-89W" secondAttribute="bottom" constant="15" id="Idj-Tv-uBu"/>
<constraint firstItem="oQB-FK-89W" firstAttribute="leading" secondItem="n6I-gD-BmS" secondAttribute="leadingMargin" id="Kq3-2O-M8V"/>
<constraint firstItem="oRN-Cg-Tuh" firstAttribute="leading" secondItem="oQB-FK-89W" secondAttribute="trailing" constant="8" id="Lhi-K2-Odq"/>
<constraint firstItem="u1N-eJ-oKk" firstAttribute="leading" secondItem="oRN-Cg-Tuh" secondAttribute="trailing" constant="8" id="nwg-gI-09m"/>
<constraint firstItem="u1N-eJ-oKk" firstAttribute="top" secondItem="n6I-gD-BmS" secondAttribute="topMargin" id="smr-C3-RRE"/>
<constraint firstAttribute="trailingMargin" secondItem="Uxx-lg-rdv" secondAttribute="trailing" id="uDD-HN-8e1"/>
<constraint firstItem="oRN-Cg-Tuh" firstAttribute="top" secondItem="n6I-gD-BmS" secondAttribute="topMargin" constant="5" id="v8J-VK-mN3"/>
<constraint firstAttribute="bottomMargin" secondItem="Uxx-lg-rdv" secondAttribute="bottom" id="vrh-TW-fBX"/>
<constraint firstAttribute="bottom" secondItem="Bk1-Te-ST5" secondAttribute="bottom" id="abo-o1-E85"/>
<constraint firstItem="Bk1-Te-ST5" firstAttribute="top" secondItem="n6I-gD-BmS" secondAttribute="top" id="fz7-6e-e0b"/>
<constraint firstItem="Bk1-Te-ST5" firstAttribute="leading" secondItem="n6I-gD-BmS" secondAttribute="leading" id="lY9-mG-lrz"/>
<constraint firstAttribute="trailing" secondItem="Bk1-Te-ST5" secondAttribute="trailing" id="nFp-aj-8Gd"/>
</constraints>
</tableViewCellContentView>
<connections>
<outlet property="acctLabel" destination="Jzk-kb-RSG" id="h1c-eN-uYC"/>
<outlet property="avatarImageView" destination="oQB-FK-89W" id="ui0-Hf-fxP"/>
<outlet property="contentLabel" destination="Uxx-lg-rdv" id="gZl-GN-45S"/>
<outlet property="displayNameLabel" destination="WfV-kx-uwj" id="qDC-lL-bRb"/>
<outlet property="timestampLabel" destination="u1N-eJ-oKk" id="GEV-Rv-sWI"/>
<outlet property="attachmentImageView" destination="eY8-HB-QXO" id="Bf8-TY-sQ6"/>
<outlet property="avatarImageView" destination="AOi-ot-xXa" id="4Z4-8h-dAo"/>
<outlet property="boostAvatarImageView" destination="ocT-ux-M2p" id="Vfi-vL-ttC"/>
<outlet property="boostDisplayNameLabel" destination="ukb-MJ-igh" id="Ps1-Wf-C1x"/>
<outlet property="boostUsernameLabel" destination="dvA-pE-bQJ" id="cEd-Gg-bvd"/>
<outlet property="boostView" destination="9fS-a9-pwm" id="ffV-XI-YoW"/>
<outlet property="boostsImageView" destination="6nH-wa-zK5" id="9iA-Ej-ahu"/>
<outlet property="boostsLabel" destination="jbL-pa-f8U" id="oe3-Fs-Sdz"/>
<outlet property="bottomDividerView" destination="eS7-7y-Xkh" id="oVJ-VK-RhI"/>
<outlet property="bottomLoadMoreView" destination="1pv-7u-4nG" id="nUZ-gi-RCB"/>
<outlet property="contentLabel" destination="VmZ-Cs-XbK" id="rX1-BF-rFB"/>
<outlet property="displayNameLabel" destination="Nsu-8a-xsG" id="1yz-dB-XXO"/>
<outlet property="favoritesImageView" destination="fYQ-Zp-0Sm" id="iWD-IB-X6F"/>
<outlet property="favoritesLabel" destination="Jfd-Nt-QbG" id="3uy-Ds-RZo"/>
<outlet property="repliesImageView" destination="BaX-Vk-itT" id="CIw-BJ-kVK"/>
<outlet property="repliesLabel" destination="WWx-tD-ydV" id="Srz-rn-OsA"/>
<outlet property="replyAvatarImageView" destination="Z85-Y0-P4Y" id="xl1-aj-fXb"/>
<outlet property="replyDisplayNameLabel" destination="Spo-Jx-UQY" id="Iow-hF-IMu"/>
<outlet property="replyUsernameLabel" destination="vCq-bh-CMA" id="3Gq-8X-qdU"/>
<outlet property="replyView" destination="xpm-gm-QTe" id="wD0-44-sSG"/>
<outlet property="timestampLabel" destination="g0I-Zp-Y9h" id="8eD-tt-0FB"/>
<outlet property="topDividerView" destination="Fb6-oy-z8M" id="5Oj-26-s7B"/>
<outlet property="topLoadMoreView" destination="7fe-eL-1qu" id="UyI-0q-WLR"/>
<outlet property="usernameLabel" destination="dvJ-7r-JOr" id="XQc-R6-4gD"/>
</connections>
</tableViewCell>
</prototypes>
@ -654,6 +1001,7 @@
</tableView>
<navigationItem key="navigationItem" title="Timeline" id="Ffm-5G-rCg"/>
<refreshControl key="refreshControl" opaque="NO" multipleTouchEnabled="YES" contentMode="center" insetsLayoutMarginsFromSafeArea="NO" enabled="NO" contentHorizontalAlignment="center" contentVerticalAlignment="center" id="CMZ-BQ-MbK">
<rect key="frame" x="0.0" y="0.0" width="1000" height="1000"/>
<autoresizingMask key="autoresizingMask"/>
<attributedString key="attributedTitle"/>
</refreshControl>
@ -690,10 +1038,16 @@
</scene>
</scenes>
<resources>
<image name="Boost Regular" width="20" height="24"/>
<image name="Clock" width="22" height="22"/>
<image name="Down" width="14" height="8"/>
<image name="Globe" width="25" height="25"/>
<image name="Instance Placeholder" width="135" height="135"/>
<image name="Logo" width="400" height="400"/>
<image name="Message" width="20" height="20"/>
<image name="Star Regular" width="22" height="22"/>
<image name="Timelines" width="25" height="25"/>
<image name="Up" width="14" height="8"/>
<image name="second" width="30" height="30"/>
</resources>
</document>

28
elpha-ios/Date+TimeAgo.swift

@ -20,58 +20,58 @@ extension Date {
if let year = components.year {
if (year >= 2) {
return "\(year)y"
return "\(year) years"
} else if (year >= 1) {
return "1y"
return "last year"
}
}
if let month = components.month {
if (month >= 2) {
return "\(month)m"
return "\(month) months"
} else if (month >= 1) {
return "1m"
return "last month"
}
}
if let weekOfMonth = components.weekOfMonth {
if (weekOfMonth >= 2) {
return "\(weekOfMonth)w"
return "\(weekOfMonth) weeks"
} else if (weekOfMonth >= 1) {
return "1w"
return "last week"
}
}
if let day = components.day {
if (day >= 2) {
return "\(day)d"
return "\(day) days"
} else if (day >= 1) {
return "1d"
return "yesterday"
}
}
if let hour = components.hour {
if (hour >= 2) {
return "\(hour)h"
return "\(hour) hours"
} else if (hour >= 1) {
return "1h"
return "an hour ago"
}
}
if let minute = components.minute {
if (minute >= 2) {
return "\(minute)m"
return "\(minute) mins"
} else if (minute >= 1) {
return "1m"
return "a minute ago"
}
}
if let second = components.second {
if (second >= 3) {
return "\(second)s"
return "\(second) seconds"
}
}
return "Now"
return "just now"
}
}

4
elpha-ios/Elpha.xcdatamodeld/Elpha.xcdatamodel/contents

@ -125,6 +125,8 @@
<relationship name="app" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="App" inverseName="statuses" inverseEntity="App" syncable="YES"/>
<relationship name="attachments" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="Attachment" inverseName="status" inverseEntity="Attachment" syncable="YES"/>
<relationship name="mentions" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="Mention" inverseName="status" inverseEntity="Mention" syncable="YES"/>
<relationship name="reblog" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Status" inverseName="reblogs" inverseEntity="Status" syncable="YES"/>
<relationship name="reblogs" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="Status" inverseName="reblog" inverseEntity="Status" syncable="YES"/>
<relationship name="tags" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="Tag" inverseName="statuses" inverseEntity="Tag" syncable="YES"/>
<relationship name="timelines" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="Timeline" inverseName="statuses" inverseEntity="Timeline" syncable="YES"/>
</entity>
@ -156,7 +158,7 @@
<element name="ISLanguage" positionX="-286.21875" positionY="512.6171875" width="128" height="75"/>
<element name="Mention" positionX="-441" positionY="234" width="128" height="120"/>
<element name="Session" positionX="-445.046875" positionY="277.31640625" width="128" height="150"/>
<element name="Status" positionX="-459" positionY="216" width="128" height="360"/>
<element name="Status" positionX="-459" positionY="216" width="128" height="390"/>
<element name="Tag" positionX="-432" positionY="243" width="128" height="90"/>
<element name="Timeline" positionX="-468" positionY="207" width="128" height="120"/>
<element name="TimelineBoundary" positionX="-468" positionY="207" width="128" height="105"/>

1
elpha-ios/InstanceViewController.swift

@ -7,7 +7,6 @@
//
import AlamofireImage
import Foundation
import UIKit
import SafariServices

1
elpha-ios/InstancesDataManager.swift

@ -8,7 +8,6 @@
import Alamofire
import CoreData
import Foundation
import UIKit
class InstancesDataManager {

1
elpha-ios/InstancesTableViewCell.swift

@ -7,7 +7,6 @@
//
import AlamofireImage
import Foundation
import UIKit
class InstancesTableViewCell: UITableViewCell {

49
elpha-ios/MastodonDataManager.swift

@ -158,7 +158,7 @@ public class MastodonDataManager {
}
}
static func upsertStatus(remoteStatus: Status) -> StatusMO? {
static func upsertStatus(_ remoteStatus: Status) -> StatusMO? {
func saveStatus(_ status: StatusMO) -> StatusMO? {
status.id = remoteStatus.id
status.uri = URL(string: remoteStatus.uri)
@ -199,6 +199,11 @@ public class MastodonDataManager {
}
}
if let reblog = remoteStatus.reblog {
let savedReblog = upsertStatus(reblog)
status.reblog = savedReblog
}
return status
}
@ -229,4 +234,46 @@ public class MastodonDataManager {
CoreDataManager.shared.saveContext()
return client
}
static func getAccountByID(_ id: String) -> AccountMO? {
let request = NSFetchRequest<AccountMO>(entityName: "Account")
request.predicate = NSPredicate(format: "id == %@", id)
do {
let results = try CoreDataManager.shared.getContext().fetch(request)
guard let account = results.first else {
return nil
}
return account
} catch {
print("\(error)")
return nil
}
}
static func getRemoteAccountByID(id: String, completion: @escaping (AccountMO?, Error?) -> Void ) {
if let account = getAccountByID(id) {
completion(account, nil)
return
}
guard let client = AuthenticationManager.shared.getMKClientForSelectedSession() else {
completion(nil, NSError())
return
}
let request = Accounts.account(id: id)
client.run(request) { result in
switch result {
case .success(let account, _):
completion(upsertAccount(account), nil)
return
case .failure(let error):
completion(nil, error)
return
}
}
}
}

24
elpha-ios/TimelineTableViewCell.swift

@ -6,13 +6,31 @@
// Copyright © 2018 Elpha. All rights reserved.
//
import Foundation
import UIKit
class TimelineTableViewCell: UITableViewCell {
@IBOutlet var boostView: UIView!
@IBOutlet var boostAvatarImageView: UIImageView!
@IBOutlet var boostDisplayNameLabel: UILabel!
@IBOutlet var boostUsernameLabel: UILabel!
@IBOutlet var replyView: UIView!
@IBOutlet var replyAvatarImageView: UIImageView!
@IBOutlet var replyDisplayNameLabel: UILabel!
@IBOutlet var replyUsernameLabel: UILabel!
@IBOutlet var avatarImageView: UIImageView!
@IBOutlet var displayNameLabel: UILabel!
@IBOutlet var acctLabel: UILabel!
@IBOutlet var timestampLabel: UILabel!
@IBOutlet var usernameLabel: UILabel!
@IBOutlet var contentLabel: UILabel!
@IBOutlet var timestampLabel: UILabel!
@IBOutlet var repliesImageView: UIImageView!
@IBOutlet var repliesLabel: UILabel!
@IBOutlet var boostsImageView: UIImageView!
@IBOutlet var boostsLabel: UILabel!
@IBOutlet var favoritesImageView: UIImageView!
@IBOutlet var favoritesLabel: UILabel!
@IBOutlet var topDividerView: UIView!
@IBOutlet var topLoadMoreView: UIView!
@IBOutlet var bottomDividerView: UIView!
@IBOutlet var bottomLoadMoreView: UIView!
@IBOutlet var attachmentImageView: UIImageView!
}

126
elpha-ios/TimelineTableViewController.swift

@ -8,7 +8,6 @@
import AlamofireImage
import CoreData
import Foundation
import MastodonKit
import UIKit
@ -32,10 +31,20 @@ class TimelineTableViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
let composeButtonItem = UIBarButtonItem(image: UIImage(named: "Compose"), style: .plain, target: self, action: #selector(compose))
navigationItem.rightBarButtonItem = composeButtonItem
navigationItem.title = "Home"
refreshControl?.addTarget(self, action: #selector(self.fetchTimelineWithDefaultRange), for: .valueChanged)
fetchTimelineWithDefaultRange()
}
@objc func compose() {
let alertController = UIAlertController(title: "Compose", message: "Toot", preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
present(alertController, animated: true)
}
func createDefaultTimelines(account: AccountMO) {
let context = CoreDataManager.shared.getContext()
let timelineNames = [
@ -62,7 +71,7 @@ class TimelineTableViewController: UITableViewController {
DispatchQueue.main.async {
let context = CoreDataManager.shared.getContext()
let statuses = remoteStatuses.compactMap { status in
return MastodonDataManager.upsertStatus(remoteStatus: status)
return MastodonDataManager.upsertStatus(status)
}
for (index, status) in statuses.enumerated() {
@ -87,6 +96,7 @@ class TimelineTableViewController: UITableViewController {
timeline.addToStatuses(NSSet(array: statuses))
CoreDataManager.shared.saveContext()
self.loading = false
self.tableView.reloadData()
}
case .failure(let error):
@ -123,9 +133,6 @@ class TimelineTableViewController: UITableViewController {
}
loading = true
defer {
loading = false
}
if let selectedTimeline = session.selectedTimeline {
var request: Request<[Status]>
@ -183,6 +190,14 @@ class TimelineTableViewController: UITableViewController {
return statuses.count
}
func getTimelineBoundaries() -> NSSet? {
guard let session = AuthenticationManager.shared.selectedSession, let timeline = session.selectedTimeline else {
return nil
}
return timeline.boundaries
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
@ -196,23 +211,84 @@ class TimelineTableViewController: UITableViewController {
fatalError("Unable to find reusable cell")
}
cell.topDividerView.isHidden = false
cell.topLoadMoreView.isHidden = true
cell.boostView.isHidden = true
cell.replyView.isHidden = true
cell.bottomLoadMoreView.isHidden = true
cell.bottomDividerView.isHidden = false
cell.attachmentImageView.isHidden = true
if let statuses = getTimelineStatuses() {
let status = statuses[indexPath.row]
if let account = status.account {
let filter = AspectScaledToFillSizeWithRoundedCornersFilter(
size: CGSize(width: 40.0, height: 40.0),
radius: 20.0,
divideRadiusByImageScale: true
)
let boundaries = getTimelineBoundaries() ?? NSSet()
let avatarFilter = AspectScaledToFillSizeWithRoundedCornersFilter(
size: CGSize(width: 40.0, height: 40.0),
radius: 20.0,
divideRadiusByImageScale: true
)
if indexPath.row != 0 {
if let boundary = boundaries.filtered(using: NSPredicate(format: "statusID = %@", status.id!)).first as? TimelineBoundaryMO {
if boundary.start {
if let previousBoundary = boundaries.filtered(using: NSPredicate(format: "statusID = %@", statuses[indexPath.row - 1])).first as? TimelineBoundaryMO {
if !previousBoundary.start {
cell.topDividerView.isHidden = true
cell.topLoadMoreView.isHidden = false
}
}
}
}
}
if indexPath.row < statuses.count - 1 {
if let boundary = boundaries.filtered(using: NSPredicate(format: "statusID = %@", status.id!)).first as? TimelineBoundaryMO {
if !boundary.start {
if let nextBoundary = boundaries.filtered(using: NSPredicate(format: "statusID = %@", statuses[indexPath.row + 1])).first as? TimelineBoundaryMO {
if nextBoundary.start {
cell.bottomDividerView.isHidden = true
cell.bottomLoadMoreView.isHidden = false
}
}
}
}
}
if let reblog = status.reblog {
cell.boostView.isHidden = false
cell.avatarImageView.af_setImage(withURL: account.avatarURL!, filter: filter)
cell.displayNameLabel.text = account.displayName
cell.acctLabel.text = account.acct
if let account = reblog.account {
cell.avatarImageView.af_setImage(withURL: account.avatarURL!, filter: avatarFilter)
cell.displayNameLabel.text = account.displayName
cell.usernameLabel.text = account.acct
}
if let account = status.account {
cell.boostAvatarImageView.af_setImage(withURL: account.avatarURL!, filter: avatarFilter)
cell.boostDisplayNameLabel.text = account.displayName
cell.boostUsernameLabel.text = account.acct
}
} else {
if let account = status.account {
cell.avatarImageView.af_setImage(withURL: account.avatarURL!, filter: avatarFilter)
cell.displayNameLabel.text = account.displayName
cell.usernameLabel.text = account.acct
}
}
if let replyAccountID = status.inReplyToAccountID {
if let replyAccount = MastodonDataManager.getAccountByID(replyAccountID) {
cell.replyView.isHidden = false
cell.replyAvatarImageView.af_setImage(withURL: replyAccount.avatarURL!, filter: avatarFilter)
cell.replyDisplayNameLabel.text = replyAccount.displayName
cell.replyUsernameLabel.text = replyAccount.acct
}
}
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 } html, body { margin: 0; padding: 0 }</style> \(content)"
let attributedText = try NSAttributedString(
data: styledContent.data(using: String.Encoding.unicode, allowLossyConversion: true)!,
options: [.documentType: NSAttributedString.DocumentType.html],
@ -225,7 +301,27 @@ class TimelineTableViewController: UITableViewController {
}
}
if let attachments = status.attachments, let attachment = attachments.anyObject() as? AttachmentMO {
cell.attachmentImageView.isHidden = false
cell.attachmentImageView.af_setImage(withURL: attachment.url!)
}
cell.timestampLabel.text = status.createdAt!.timeAgo()
cell.repliesLabel.text = "0"
cell.boostsLabel.text = NumberFormatter.localizedString(from: NSNumber(value: status.reblogsCount), number: .decimal)
cell.favoritesLabel.text = NumberFormatter.localizedString(from: NSNumber(value: status.favouritesCount), number: .decimal)
if status.reblogged {
cell.boostsImageView.image = UIImage(named: "Boost Bold")
} else {
cell.boostsImageView.image = UIImage(named: "Boost Regular")
}
if status.favourited {
cell.favoritesImageView.image = UIImage(named: "Star Filled")
} else {
cell.favoritesImageView.image = UIImage(named: "Star Regular")
}
if indexPath.row == statuses.count - 1 && !loading {
fetchTimeline(withRange: .max(id: status.id!, limit: fetchLimit))

24
elpha-ios/TimelineViewController.swift

@ -1,24 +0,0 @@
//
// TimelinesViewController.swift
// elpha-ios
//
// Created by Dwayne Harris on 8/28/18.
// Copyright © 2018 Elpha. All rights reserved.
//
import UIKit
class TimelineViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let tootButtonItem = UIBarButtonItem(image: UIImage(named: "Toot"), style: .plain, target: self, action: #selector(compose))
navigationItem.rightBarButtonItem = tootButtonItem
}
@objc func compose() {
let alertController = UIAlertController(title: "Compose", message: "Toot", preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
present(alertController, animated: true)
}
}

2
elpha-ios/TimelinesNavigationController.swift

@ -9,5 +9,5 @@
import UIKit
class TimelinesNavigationController: UINavigationController {
}
Loading…
Cancel
Save