diff --git a/elpha-ios.xcodeproj/project.pbxproj b/elpha-ios.xcodeproj/project.pbxproj index 82494d5..7170079 100644 --- a/elpha-ios.xcodeproj/project.pbxproj +++ b/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 = ""; }; 157405A72150588A00EEAAEB /* InstanceViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InstanceViewController.swift; sourceTree = ""; }; @@ -245,7 +297,6 @@ 15960E792132387A00C38CE9 /* MainTabBarController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainTabBarController.swift; sourceTree = ""; }; 15960E7B213272CD00C38CE9 /* AuthenticationManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticationManager.swift; sourceTree = ""; }; 15960E7D21329FED00C38CE9 /* AuthenticateViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticateViewController.swift; sourceTree = ""; }; - 15960E7F21353DCF00C38CE9 /* TimelineViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineViewController.swift; sourceTree = ""; }; 15960E812136668500C38CE9 /* TimelinesNavigationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelinesNavigationController.swift; sourceTree = ""; }; 15960E83213774FC00C38CE9 /* InstancesTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InstancesTableViewController.swift; sourceTree = ""; }; 15A79AE7215B3CC5007A326E /* MastodonKit.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = MastodonKit.xcodeproj; path = Frameworks/MastodonKit/MastodonKit.xcodeproj; sourceTree = ""; }; @@ -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 = ""; }; + 151AD4AB2166DCEE00F07403 /* Storyboards */ = { + isa = PBXGroup; + children = ( + 15960E60213145E100C38CE9 /* Main.storyboard */, + 15960E65213145E200C38CE9 /* LaunchScreen.storyboard */, + ); + name = Storyboards; + sourceTree = ""; + }; + 151AD4AC2166DD0200F07403 /* Managers */ = { + isa = PBXGroup; + children = ( + 15960E7B213272CD00C38CE9 /* AuthenticationManager.swift */, + 15A79B42215EB959007A326E /* CoreDataManager.swift */, + 157405B32151A93E00EEAAEB /* InstancesDataManager.swift */, + 15F998342162C0E8009E58DA /* MastodonDataManager.swift */, + ); + name = Managers; + sourceTree = ""; + }; + 151AD4AD2166DD1B00F07403 /* Reusable Views */ = { + isa = PBXGroup; + children = ( + ); + name = "Reusable Views"; + sourceTree = ""; + }; + 151AD4AE2166DD3500F07403 /* Views */ = { + isa = PBXGroup; + children = ( + 159048AE214F5015004F4014 /* InstancesTableViewCell.swift */, + 159026AD2162CF5600D362DD /* TimelineTableViewCell.swift */, + ); + name = Views; + sourceTree = ""; + }; + 151AD4AF2166DDA000F07403 /* Extensions */ = { + isa = PBXGroup; + children = ( + 159026CF2163069600D362DD /* Date+TimeAgo.swift */, + ); + name = Extensions; + sourceTree = ""; + }; 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 = ""; @@ -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 = ""; @@ -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; diff --git a/elpha-ios/Assets.xcassets/Toot.imageset/Contents.json b/elpha-ios/Assets.xcassets/Boost Bold.imageset/Contents.json similarity index 54% rename from elpha-ios/Assets.xcassets/Toot.imageset/Contents.json rename to elpha-ios/Assets.xcassets/Boost Bold.imageset/Contents.json index 64c7edd..630d6e5 100644 --- a/elpha-ios/Assets.xcassets/Toot.imageset/Contents.json +++ b/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 } } \ No newline at end of file diff --git a/elpha-ios/Assets.xcassets/Boost Bold.imageset/Repeat-Boost-Bold.pdf b/elpha-ios/Assets.xcassets/Boost Bold.imageset/Repeat-Boost-Bold.pdf new file mode 100644 index 0000000..90ad8c9 Binary files /dev/null and b/elpha-ios/Assets.xcassets/Boost Bold.imageset/Repeat-Boost-Bold.pdf differ diff --git a/elpha-ios/Assets.xcassets/Boost Regular.imageset/Contents.json b/elpha-ios/Assets.xcassets/Boost Regular.imageset/Contents.json new file mode 100644 index 0000000..7f2bc74 --- /dev/null +++ b/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" + } +} \ No newline at end of file diff --git a/elpha-ios/Assets.xcassets/Boost Regular.imageset/Repeat-Boost-Regular.pdf b/elpha-ios/Assets.xcassets/Boost Regular.imageset/Repeat-Boost-Regular.pdf new file mode 100644 index 0000000..a6f79c5 Binary files /dev/null and b/elpha-ios/Assets.xcassets/Boost Regular.imageset/Repeat-Boost-Regular.pdf differ diff --git a/elpha-ios/Assets.xcassets/Toot.imageset/toot.pdf b/elpha-ios/Assets.xcassets/Clock.imageset/Clock.pdf similarity index 80% rename from elpha-ios/Assets.xcassets/Toot.imageset/toot.pdf rename to elpha-ios/Assets.xcassets/Clock.imageset/Clock.pdf index c49de6f..744eaf2 100644 Binary files a/elpha-ios/Assets.xcassets/Toot.imageset/toot.pdf and b/elpha-ios/Assets.xcassets/Clock.imageset/Clock.pdf differ diff --git a/elpha-ios/Assets.xcassets/Clock.imageset/Contents.json b/elpha-ios/Assets.xcassets/Clock.imageset/Contents.json new file mode 100644 index 0000000..7d2c86b --- /dev/null +++ b/elpha-ios/Assets.xcassets/Clock.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "Clock.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/elpha-ios/Assets.xcassets/Compose.imageset/Contents.json b/elpha-ios/Assets.xcassets/Compose.imageset/Contents.json new file mode 100644 index 0000000..0d73062 --- /dev/null +++ b/elpha-ios/Assets.xcassets/Compose.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "Feather-Compose.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/elpha-ios/Assets.xcassets/Compose.imageset/Feather-Compose.pdf b/elpha-ios/Assets.xcassets/Compose.imageset/Feather-Compose.pdf new file mode 100644 index 0000000..7008348 Binary files /dev/null and b/elpha-ios/Assets.xcassets/Compose.imageset/Feather-Compose.pdf differ diff --git a/elpha-ios/Assets.xcassets/Down.imageset/Contents.json b/elpha-ios/Assets.xcassets/Down.imageset/Contents.json new file mode 100644 index 0000000..f994b75 --- /dev/null +++ b/elpha-ios/Assets.xcassets/Down.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "chevron-down.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/elpha-ios/Assets.xcassets/Down.imageset/chevron-down.pdf b/elpha-ios/Assets.xcassets/Down.imageset/chevron-down.pdf new file mode 100644 index 0000000..833821c Binary files /dev/null and b/elpha-ios/Assets.xcassets/Down.imageset/chevron-down.pdf differ diff --git a/elpha-ios/Assets.xcassets/Message.imageset/Contents.json b/elpha-ios/Assets.xcassets/Message.imageset/Contents.json new file mode 100644 index 0000000..7961c2a --- /dev/null +++ b/elpha-ios/Assets.xcassets/Message.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "Message-Reply.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/elpha-ios/Assets.xcassets/Message.imageset/Message-Reply.pdf b/elpha-ios/Assets.xcassets/Message.imageset/Message-Reply.pdf new file mode 100644 index 0000000..418ef06 Binary files /dev/null and b/elpha-ios/Assets.xcassets/Message.imageset/Message-Reply.pdf differ diff --git a/elpha-ios/Assets.xcassets/Star Filled.imageset/Contents.json b/elpha-ios/Assets.xcassets/Star Filled.imageset/Contents.json new file mode 100644 index 0000000..8feb28a --- /dev/null +++ b/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" + } +} \ No newline at end of file diff --git a/elpha-ios/Assets.xcassets/Star Filled.imageset/Star-Favorite-Fill.pdf b/elpha-ios/Assets.xcassets/Star Filled.imageset/Star-Favorite-Fill.pdf new file mode 100644 index 0000000..d472b6b Binary files /dev/null and b/elpha-ios/Assets.xcassets/Star Filled.imageset/Star-Favorite-Fill.pdf differ diff --git a/elpha-ios/Assets.xcassets/Star Regular.imageset/Contents.json b/elpha-ios/Assets.xcassets/Star Regular.imageset/Contents.json new file mode 100644 index 0000000..8c2d47f --- /dev/null +++ b/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" + } +} \ No newline at end of file diff --git a/elpha-ios/Assets.xcassets/Star Regular.imageset/Star-Favorite.pdf b/elpha-ios/Assets.xcassets/Star Regular.imageset/Star-Favorite.pdf new file mode 100644 index 0000000..0914517 Binary files /dev/null and b/elpha-ios/Assets.xcassets/Star Regular.imageset/Star-Favorite.pdf differ diff --git a/elpha-ios/Assets.xcassets/Up.imageset/Contents.json b/elpha-ios/Assets.xcassets/Up.imageset/Contents.json new file mode 100644 index 0000000..322d43e --- /dev/null +++ b/elpha-ios/Assets.xcassets/Up.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "chevron-up.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/elpha-ios/Assets.xcassets/Up.imageset/chevron-up.pdf b/elpha-ios/Assets.xcassets/Up.imageset/chevron-up.pdf new file mode 100644 index 0000000..d40fcb7 Binary files /dev/null and b/elpha-ios/Assets.xcassets/Up.imageset/chevron-up.pdf differ diff --git a/elpha-ios/AuthenticationManager.swift b/elpha-ios/AuthenticationManager.swift index d0e36ac..ba18076 100644 --- a/elpha-ios/AuthenticationManager.swift +++ b/elpha-ios/AuthenticationManager.swift @@ -7,7 +7,6 @@ // import CoreData -import Foundation import MastodonKit import UIKit diff --git a/elpha-ios/Base.lproj/Main.storyboard b/elpha-ios/Base.lproj/Main.storyboard index bf5135a..8badd60 100644 --- a/elpha-ios/Base.lproj/Main.storyboard +++ b/elpha-ios/Base.lproj/Main.storyboard @@ -561,89 +561,436 @@ - + - - + + - + - - - - - - - - - + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - + - - - - - - - - - - - + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + @@ -654,6 +1001,7 @@ + @@ -690,10 +1038,16 @@ + + + + + + diff --git a/elpha-ios/Date+TimeAgo.swift b/elpha-ios/Date+TimeAgo.swift index 068a409..bb2c9ba 100644 --- a/elpha-ios/Date+TimeAgo.swift +++ b/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" } } diff --git a/elpha-ios/Elpha.xcdatamodeld/Elpha.xcdatamodel/contents b/elpha-ios/Elpha.xcdatamodeld/Elpha.xcdatamodel/contents index bb84272..1b0e1b5 100644 --- a/elpha-ios/Elpha.xcdatamodeld/Elpha.xcdatamodel/contents +++ b/elpha-ios/Elpha.xcdatamodeld/Elpha.xcdatamodel/contents @@ -125,6 +125,8 @@ + + @@ -156,7 +158,7 @@ - + diff --git a/elpha-ios/InstanceViewController.swift b/elpha-ios/InstanceViewController.swift index 85ad6b3..3aab039 100644 --- a/elpha-ios/InstanceViewController.swift +++ b/elpha-ios/InstanceViewController.swift @@ -7,7 +7,6 @@ // import AlamofireImage -import Foundation import UIKit import SafariServices diff --git a/elpha-ios/InstancesDataManager.swift b/elpha-ios/InstancesDataManager.swift index ccb52b7..f5e76a9 100644 --- a/elpha-ios/InstancesDataManager.swift +++ b/elpha-ios/InstancesDataManager.swift @@ -8,7 +8,6 @@ import Alamofire import CoreData -import Foundation import UIKit class InstancesDataManager { diff --git a/elpha-ios/InstancesTableViewCell.swift b/elpha-ios/InstancesTableViewCell.swift index c79a9ea..5d77ed8 100644 --- a/elpha-ios/InstancesTableViewCell.swift +++ b/elpha-ios/InstancesTableViewCell.swift @@ -7,7 +7,6 @@ // import AlamofireImage -import Foundation import UIKit class InstancesTableViewCell: UITableViewCell { diff --git a/elpha-ios/MastodonDataManager.swift b/elpha-ios/MastodonDataManager.swift index c2fb168..8389b38 100644 --- a/elpha-ios/MastodonDataManager.swift +++ b/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(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 + } + } + } } diff --git a/elpha-ios/TimelineTableViewCell.swift b/elpha-ios/TimelineTableViewCell.swift index 06371cd..d75fed7 100644 --- a/elpha-ios/TimelineTableViewCell.swift +++ b/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! } diff --git a/elpha-ios/TimelineTableViewController.swift b/elpha-ios/TimelineTableViewController.swift index cc672c0..1ff203e 100644 --- a/elpha-ios/TimelineTableViewController.swift +++ b/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 = " \(content)" + let styledContent = " \(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)) diff --git a/elpha-ios/TimelineViewController.swift b/elpha-ios/TimelineViewController.swift deleted file mode 100644 index ec9b262..0000000 --- a/elpha-ios/TimelineViewController.swift +++ /dev/null @@ -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) - } -} diff --git a/elpha-ios/TimelinesNavigationController.swift b/elpha-ios/TimelinesNavigationController.swift index 7ed8e53..9f5044e 100644 --- a/elpha-ios/TimelinesNavigationController.swift +++ b/elpha-ios/TimelinesNavigationController.swift @@ -9,5 +9,5 @@ import UIKit class TimelinesNavigationController: UINavigationController { - + }