Browse Source

Replace most storyboards with XIBs

pixelfed
Shadowfacts 3 years ago
parent
commit
eb9e1276df
Signed by: shadowfacts GPG Key ID: 94A5AB95422746E5
  1. 60
      Tusker.xcodeproj/project.pbxproj
  2. 42
      Tusker/AppDelegate.swift
  3. 1
      Tusker/Controllers/MastodonController.swift
  4. 2
      Tusker/Info.plist
  5. 232
      Tusker/Screens/Compose/Compose.storyboard
  6. 54
      Tusker/Screens/Compose/ComposeViewController.swift
  7. 200
      Tusker/Screens/Compose/ComposeViewController.xib
  8. 30
      Tusker/Screens/Conversation/Conversation.storyboard
  9. 21
      Tusker/Screens/Conversation/ConversationTableViewController.swift
  10. 152
      Tusker/Screens/Large Image/LargeImage.storyboard
  11. 50
      Tusker/Screens/Large Image/LargeImageViewController.swift
  12. 130
      Tusker/Screens/Large Image/LargeImageViewController.xib
  13. 27
      Tusker/Screens/Main/Base.lproj/Main.storyboard
  14. 13
      Tusker/Screens/Main/MainTabBarViewController.swift
  15. 55
      Tusker/Screens/Notifications/Notifications.storyboard
  16. 34
      Tusker/Screens/Notifications/NotificationsTableViewController.swift
  17. 68
      Tusker/Screens/Onboarding/Onboarding.storyboard
  18. 8
      Tusker/Screens/Onboarding/OnboardingViewController.swift
  19. 63
      Tusker/Screens/Onboarding/OnboardingViewController.xib
  20. 44
      Tusker/Screens/Profile/Profile.storyboard
  21. 36
      Tusker/Screens/Profile/ProfileTableViewController.swift
  22. 53
      Tusker/Screens/Timeline/Timeline.storyboard
  23. 54
      Tusker/Screens/Timeline/TimelineTableViewController.swift
  24. 2
      Tusker/Shortcuts/UserActivityManager.swift
  25. 21
      Tusker/TuskerNavigationDelegate.swift
  26. 12
      Tusker/XCallbackURL/XCBActions.swift

60
Tusker.xcodeproj/project.pbxproj

@ -60,13 +60,13 @@
D621544821682A9D0003D87D /* TabsTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D621544721682A9D0003D87D /* TabsTableViewController.swift */; };
D621544B21682AD30003D87D /* TabTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D621544A21682AD30003D87D /* TabTableViewCell.swift */; };
D621544D21682AD90003D87D /* TabTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = D621544C21682AD90003D87D /* TabTableViewCell.xib */; };
D6289E84217B795D0003D1D7 /* LargeImageViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = D6289E83217B795D0003D1D7 /* LargeImageViewController.xib */; };
D62D2422217AA7E1005076CC /* UserActivityManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = D62D2421217AA7E1005076CC /* UserActivityManager.swift */; };
D62D2424217ABF3F005076CC /* NSUserActivity+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D62D2423217ABF3F005076CC /* NSUserActivity+Extensions.swift */; };
D62D2426217ABF63005076CC /* UserActivityType.swift in Sources */ = {isa = PBXBuildFile; fileRef = D62D2425217ABF63005076CC /* UserActivityType.swift */; };
D6333B372137838300CE884A /* AttributedString+Trim.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6333B362137838300CE884A /* AttributedString+Trim.swift */; };
D6333B772138D94E00CE884A /* ComposeMediaView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6333B762138D94E00CE884A /* ComposeMediaView.swift */; };
D6333B792139AEFD00CE884A /* Date+TimeAgo.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6333B782139AEFD00CE884A /* Date+TimeAgo.swift */; };
D641C771213CA9EC004B4513 /* Notifications.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D641C770213CA9EC004B4513 /* Notifications.storyboard */; };
D641C773213CAA25004B4513 /* NotificationsTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D641C772213CAA25004B4513 /* NotificationsTableViewController.swift */; };
D641C777213CAA9E004B4513 /* ActionNotificationTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D641C776213CAA9E004B4513 /* ActionNotificationTableViewCell.swift */; };
D641C779213CAC56004B4513 /* ActionNotificationTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = D641C778213CAC56004B4513 /* ActionNotificationTableViewCell.xib */; };
@ -79,7 +79,6 @@
D646C958213B367000269FB5 /* LargeImageShrinkAnimationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D646C957213B367000269FB5 /* LargeImageShrinkAnimationController.swift */; };
D646C95A213B5D0500269FB5 /* LargeImageInteractionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D646C959213B5D0500269FB5 /* LargeImageInteractionController.swift */; };
D64D0AAD2128D88B005A6F37 /* LocalData.swift in Sources */ = {isa = PBXBuildFile; fileRef = D64D0AAC2128D88B005A6F37 /* LocalData.swift */; };
D64D0AAF2128D954005A6F37 /* Onboarding.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D64D0AAE2128D954005A6F37 /* Onboarding.storyboard */; };
D64D0AB12128D9AE005A6F37 /* OnboardingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D64D0AB02128D9AE005A6F37 /* OnboardingViewController.swift */; };
D64F80E2215875CC00BEF393 /* XCBActionType.swift in Sources */ = {isa = PBXBuildFile; fileRef = D64F80E1215875CC00BEF393 /* XCBActionType.swift */; };
D6538945214D6D7500E3CEFC /* TableViewSwipeActionProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6538944214D6D7500E3CEFC /* TableViewSwipeActionProvider.swift */; };
@ -92,17 +91,14 @@
D663626821360E2C00C9CBA2 /* PreferencesTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D663626721360E2C00C9CBA2 /* PreferencesTableViewController.swift */; };
D663626A2136163000C9CBA2 /* PreferencesAdaptive.swift in Sources */ = {isa = PBXBuildFile; fileRef = D66362692136163000C9CBA2 /* PreferencesAdaptive.swift */; };
D663626C21361C6700C9CBA2 /* Account+Preferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = D663626B21361C6700C9CBA2 /* Account+Preferences.swift */; };
D663626F213632A000C9CBA2 /* Compose.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D663626E213632A000C9CBA2 /* Compose.storyboard */; };
D66362712136338600C9CBA2 /* ComposeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D66362702136338600C9CBA2 /* ComposeViewController.swift */; };
D66362752137068A00C9CBA2 /* Visibility+Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = D66362742137068A00C9CBA2 /* Visibility+Helpers.swift */; };
D667E5E12134937B0057A976 /* StatusTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = D667E5E02134937B0057A976 /* StatusTableViewCell.xib */; };
D667E5E3213499F70057A976 /* Profile.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D667E5E2213499F70057A976 /* Profile.storyboard */; };
D667E5E721349D4C0057A976 /* ProfileTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D667E5E621349D4C0057A976 /* ProfileTableViewController.swift */; };
D667E5E921349EE50057A976 /* ProfileHeaderTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = D667E5E821349EE50057A976 /* ProfileHeaderTableViewCell.xib */; };
D667E5EB21349EF80057A976 /* ProfileHeaderTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D667E5EA21349EF80057A976 /* ProfileHeaderTableViewCell.swift */; };
D667E5F12134D5050057A976 /* UIViewController+Delegates.swift in Sources */ = {isa = PBXBuildFile; fileRef = D667E5F02134D5050057A976 /* UIViewController+Delegates.swift */; };
D667E5F32135BC260057A976 /* Conversation.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D667E5F22135BC260057A976 /* Conversation.storyboard */; };
D667E5F52135BCD50057A976 /* ConversationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D667E5F42135BCD50057A976 /* ConversationViewController.swift */; };
D667E5F52135BCD50057A976 /* ConversationTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D667E5F42135BCD50057A976 /* ConversationTableViewController.swift */; };
D667E5F82135C3040057A976 /* Mastodon+Equatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D667E5F72135C3040057A976 /* Mastodon+Equatable.swift */; };
D6757A7C2157E01900721E32 /* XCBManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6757A7B2157E01900721E32 /* XCBManager.swift */; };
D6757A7E2157E02600721E32 /* XCBRequestSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6757A7D2157E02600721E32 /* XCBRequestSpec.swift */; };
@ -110,6 +106,8 @@
D679C09F215850EF00DA27FE /* XCBActions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D679C09E215850EF00DA27FE /* XCBActions.swift */; };
D67E0513216438A7000E0927 /* AppearanceTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D67E0512216438A7000E0927 /* AppearanceTableViewController.swift */; };
D67E051521643C77000E0927 /* Tab.swift in Sources */ = {isa = PBXBuildFile; fileRef = D67E051421643C77000E0927 /* Tab.swift */; };
D6A5FAF1217B7E05003DB2D9 /* ComposeViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = D6A5FAF0217B7E05003DB2D9 /* ComposeViewController.xib */; };
D6A5FAFB217B86CE003DB2D9 /* OnboardingViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = D6A5FAFA217B86CE003DB2D9 /* OnboardingViewController.xib */; };
D6BED170212663DA00F02DA0 /* SwiftSoup.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = D6BED16E212663DA00F02DA0 /* SwiftSoup.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
D6BED174212667E900F02DA0 /* StatusTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6BED173212667E900F02DA0 /* StatusTableViewCell.swift */; };
D6C693CA2161253F007D6A6D /* SilentActionPermissionsTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6C693C92161253F007D6A6D /* SilentActionPermissionsTableViewController.swift */; };
@ -119,11 +117,9 @@
D6C693F92162E4DB007D6A6D /* StatusContentLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6C693F82162E4DB007D6A6D /* StatusContentLabel.swift */; };
D6C693FC2162FE6F007D6A6D /* LoadingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6C693FB2162FE6F007D6A6D /* LoadingViewController.swift */; };
D6C693FE2162FEEA007D6A6D /* UIViewController+Children.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6C693FD2162FEEA007D6A6D /* UIViewController+Children.swift */; };
D6C94D852139DFD800CB5196 /* LargeImage.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D6C94D842139DFD800CB5196 /* LargeImage.storyboard */; };
D6C94D872139E62700CB5196 /* LargeImageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6C94D862139E62700CB5196 /* LargeImageViewController.swift */; };
D6C94D892139E6EC00CB5196 /* AttachmentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6C94D882139E6EC00CB5196 /* AttachmentView.swift */; };
D6D4DDD0212518A000E1C4BB /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6D4DDCF212518A000E1C4BB /* AppDelegate.swift */; };
D6D4DDD5212518A000E1C4BB /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D6D4DDD3212518A000E1C4BB /* Main.storyboard */; };
D6D4DDD7212518A200E1C4BB /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D6D4DDD6212518A200E1C4BB /* Assets.xcassets */; };
D6D4DDDA212518A200E1C4BB /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D6D4DDD8212518A200E1C4BB /* LaunchScreen.storyboard */; };
D6D4DDE5212518A200E1C4BB /* TuskerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6D4DDE4212518A200E1C4BB /* TuskerTests.swift */; };
@ -132,7 +128,6 @@
D6E6F26321603F8B006A8599 /* CharacterCounter.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6E6F26221603F8B006A8599 /* CharacterCounter.swift */; };
D6E6F26521604242006A8599 /* CharacterCounterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6E6F26421604242006A8599 /* CharacterCounterTests.swift */; };
D6F953EC212519E700CF0F2B /* TimelineTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6F953EB212519E700CF0F2B /* TimelineTableViewController.swift */; };
D6F953EE21251A0700CF0F2B /* Timeline.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D6F953ED21251A0700CF0F2B /* Timeline.storyboard */; };
D6F953F021251A2900CF0F2B /* MastodonController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6F953EF21251A2900CF0F2B /* MastodonController.swift */; };
/* End PBXBuildFile section */
@ -252,13 +247,13 @@
D621544721682A9D0003D87D /* TabsTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabsTableViewController.swift; sourceTree = "<group>"; };
D621544A21682AD30003D87D /* TabTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabTableViewCell.swift; sourceTree = "<group>"; };
D621544C21682AD90003D87D /* TabTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = TabTableViewCell.xib; sourceTree = "<group>"; };
D6289E83217B795D0003D1D7 /* LargeImageViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = LargeImageViewController.xib; sourceTree = "<group>"; };
D62D2421217AA7E1005076CC /* UserActivityManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserActivityManager.swift; sourceTree = "<group>"; };
D62D2423217ABF3F005076CC /* NSUserActivity+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSUserActivity+Extensions.swift"; sourceTree = "<group>"; };
D62D2425217ABF63005076CC /* UserActivityType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserActivityType.swift; sourceTree = "<group>"; };
D6333B362137838300CE884A /* AttributedString+Trim.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AttributedString+Trim.swift"; sourceTree = "<group>"; };
D6333B762138D94E00CE884A /* ComposeMediaView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeMediaView.swift; sourceTree = "<group>"; };
D6333B782139AEFD00CE884A /* Date+TimeAgo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Date+TimeAgo.swift"; sourceTree = "<group>"; };
D641C770213CA9EC004B4513 /* Notifications.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Notifications.storyboard; sourceTree = "<group>"; };
D641C772213CAA25004B4513 /* NotificationsTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationsTableViewController.swift; sourceTree = "<group>"; };
D641C776213CAA9E004B4513 /* ActionNotificationTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionNotificationTableViewCell.swift; sourceTree = "<group>"; };
D641C778213CAC56004B4513 /* ActionNotificationTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ActionNotificationTableViewCell.xib; sourceTree = "<group>"; };
@ -271,7 +266,6 @@
D646C957213B367000269FB5 /* LargeImageShrinkAnimationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LargeImageShrinkAnimationController.swift; sourceTree = "<group>"; };
D646C959213B5D0500269FB5 /* LargeImageInteractionController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LargeImageInteractionController.swift; sourceTree = "<group>"; };
D64D0AAC2128D88B005A6F37 /* LocalData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalData.swift; sourceTree = "<group>"; };
D64D0AAE2128D954005A6F37 /* Onboarding.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Onboarding.storyboard; sourceTree = "<group>"; };
D64D0AB02128D9AE005A6F37 /* OnboardingViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingViewController.swift; sourceTree = "<group>"; };
D64F80E1215875CC00BEF393 /* XCBActionType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XCBActionType.swift; sourceTree = "<group>"; };
D6538944214D6D7500E3CEFC /* TableViewSwipeActionProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TableViewSwipeActionProvider.swift; sourceTree = "<group>"; };
@ -283,17 +277,14 @@
D663626721360E2C00C9CBA2 /* PreferencesTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferencesTableViewController.swift; sourceTree = "<group>"; };
D66362692136163000C9CBA2 /* PreferencesAdaptive.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferencesAdaptive.swift; sourceTree = "<group>"; };
D663626B21361C6700C9CBA2 /* Account+Preferences.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Account+Preferences.swift"; sourceTree = "<group>"; };
D663626E213632A000C9CBA2 /* Compose.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Compose.storyboard; sourceTree = "<group>"; };
D66362702136338600C9CBA2 /* ComposeViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeViewController.swift; sourceTree = "<group>"; };
D66362742137068A00C9CBA2 /* Visibility+Helpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Visibility+Helpers.swift"; sourceTree = "<group>"; };
D667E5E02134937B0057A976 /* StatusTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = StatusTableViewCell.xib; sourceTree = "<group>"; };
D667E5E2213499F70057A976 /* Profile.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Profile.storyboard; sourceTree = "<group>"; };
D667E5E621349D4C0057A976 /* ProfileTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileTableViewController.swift; sourceTree = "<group>"; };
D667E5E821349EE50057A976 /* ProfileHeaderTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ProfileHeaderTableViewCell.xib; sourceTree = "<group>"; };
D667E5EA21349EF80057A976 /* ProfileHeaderTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileHeaderTableViewCell.swift; sourceTree = "<group>"; };
D667E5F02134D5050057A976 /* UIViewController+Delegates.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIViewController+Delegates.swift"; sourceTree = "<group>"; };
D667E5F22135BC260057A976 /* Conversation.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Conversation.storyboard; sourceTree = "<group>"; };
D667E5F42135BCD50057A976 /* ConversationViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConversationViewController.swift; sourceTree = "<group>"; };
D667E5F42135BCD50057A976 /* ConversationTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConversationTableViewController.swift; sourceTree = "<group>"; };
D667E5F72135C3040057A976 /* Mastodon+Equatable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Mastodon+Equatable.swift"; sourceTree = "<group>"; };
D6757A7B2157E01900721E32 /* XCBManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XCBManager.swift; sourceTree = "<group>"; };
D6757A7D2157E02600721E32 /* XCBRequestSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XCBRequestSpec.swift; sourceTree = "<group>"; };
@ -301,6 +292,8 @@
D679C09E215850EF00DA27FE /* XCBActions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XCBActions.swift; sourceTree = "<group>"; };
D67E0512216438A7000E0927 /* AppearanceTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppearanceTableViewController.swift; sourceTree = "<group>"; };
D67E051421643C77000E0927 /* Tab.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tab.swift; sourceTree = "<group>"; };
D6A5FAF0217B7E05003DB2D9 /* ComposeViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ComposeViewController.xib; sourceTree = "<group>"; };
D6A5FAFA217B86CE003DB2D9 /* OnboardingViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = OnboardingViewController.xib; sourceTree = "<group>"; };
D6BED16E212663DA00F02DA0 /* SwiftSoup.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = SwiftSoup.framework; sourceTree = BUILT_PRODUCTS_DIR; };
D6BED173212667E900F02DA0 /* StatusTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusTableViewCell.swift; sourceTree = "<group>"; };
D6C693C92161253F007D6A6D /* SilentActionPermissionsTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SilentActionPermissionsTableViewController.swift; sourceTree = "<group>"; };
@ -310,12 +303,10 @@
D6C693F82162E4DB007D6A6D /* StatusContentLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusContentLabel.swift; sourceTree = "<group>"; };
D6C693FB2162FE6F007D6A6D /* LoadingViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoadingViewController.swift; sourceTree = "<group>"; };
D6C693FD2162FEEA007D6A6D /* UIViewController+Children.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIViewController+Children.swift"; sourceTree = "<group>"; };
D6C94D842139DFD800CB5196 /* LargeImage.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = LargeImage.storyboard; sourceTree = "<group>"; };
D6C94D862139E62700CB5196 /* LargeImageViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LargeImageViewController.swift; sourceTree = "<group>"; };
D6C94D882139E6EC00CB5196 /* AttachmentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttachmentView.swift; sourceTree = "<group>"; };
D6D4DDCC212518A000E1C4BB /* Tusker.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Tusker.app; sourceTree = BUILT_PRODUCTS_DIR; };
D6D4DDCF212518A000E1C4BB /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
D6D4DDD4212518A000E1C4BB /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
D6D4DDD6212518A200E1C4BB /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
D6D4DDD9212518A200E1C4BB /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
D6D4DDDB212518A200E1C4BB /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
@ -329,7 +320,6 @@
D6E6F26221603F8B006A8599 /* CharacterCounter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CharacterCounter.swift; sourceTree = "<group>"; };
D6E6F26421604242006A8599 /* CharacterCounterTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CharacterCounterTests.swift; sourceTree = "<group>"; };
D6F953EB212519E700CF0F2B /* TimelineTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineTableViewController.swift; sourceTree = "<group>"; };
D6F953ED21251A0700CF0F2B /* Timeline.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Timeline.storyboard; sourceTree = "<group>"; };
D6F953EF21251A2900CF0F2B /* MastodonController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonController.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
@ -519,7 +509,6 @@
D641C781213DD7DD004B4513 /* Timeline */ = {
isa = PBXGroup;
children = (
D6F953ED21251A0700CF0F2B /* Timeline.storyboard */,
D6F953EB212519E700CF0F2B /* TimelineTableViewController.swift */,
);
path = Timeline;
@ -528,7 +517,6 @@
D641C782213DD7F0004B4513 /* Main */ = {
isa = PBXGroup;
children = (
D6D4DDD3212518A000E1C4BB /* Main.storyboard */,
04DACE8B212CB14B009840C4 /* MainTabBarViewController.swift */,
);
path = Main;
@ -537,7 +525,7 @@
D641C783213DD7FE004B4513 /* Onboarding */ = {
isa = PBXGroup;
children = (
D64D0AAE2128D954005A6F37 /* Onboarding.storyboard */,
D6A5FAFA217B86CE003DB2D9 /* OnboardingViewController.xib */,
D64D0AB02128D9AE005A6F37 /* OnboardingViewController.swift */,
);
path = Onboarding;
@ -546,7 +534,6 @@
D641C784213DD819004B4513 /* Profile */ = {
isa = PBXGroup;
children = (
D667E5E2213499F70057A976 /* Profile.storyboard */,
D667E5E621349D4C0057A976 /* ProfileTableViewController.swift */,
);
path = Profile;
@ -555,8 +542,7 @@
D641C785213DD83B004B4513 /* Conversation */ = {
isa = PBXGroup;
children = (
D667E5F22135BC260057A976 /* Conversation.storyboard */,
D667E5F42135BCD50057A976 /* ConversationViewController.swift */,
D667E5F42135BCD50057A976 /* ConversationTableViewController.swift */,
);
path = Conversation;
sourceTree = "<group>";
@ -564,7 +550,6 @@
D641C786213DD852004B4513 /* Notifications */ = {
isa = PBXGroup;
children = (
D641C770213CA9EC004B4513 /* Notifications.storyboard */,
D641C772213CAA25004B4513 /* NotificationsTableViewController.swift */,
);
path = Notifications;
@ -573,7 +558,7 @@
D641C787213DD862004B4513 /* Compose */ = {
isa = PBXGroup;
children = (
D663626E213632A000C9CBA2 /* Compose.storyboard */,
D6A5FAF0217B7E05003DB2D9 /* ComposeViewController.xib */,
D66362702136338600C9CBA2 /* ComposeViewController.swift */,
);
path = Compose;
@ -583,7 +568,7 @@
isa = PBXGroup;
children = (
D646C954213B364600269FB5 /* Transitions */,
D6C94D842139DFD800CB5196 /* LargeImage.storyboard */,
D6289E83217B795D0003D1D7 /* LargeImageViewController.xib */,
D6C94D862139E62700CB5196 /* LargeImageViewController.swift */,
);
path = "Large Image";
@ -1019,22 +1004,17 @@
buildActionMask = 2147483647;
files = (
D641C779213CAC56004B4513 /* ActionNotificationTableViewCell.xib in Resources */,
D667E5F32135BC260057A976 /* Conversation.storyboard in Resources */,
D667E5E921349EE50057A976 /* ProfileHeaderTableViewCell.xib in Resources */,
D6C693CD2161257B007D6A6D /* SilentActionPermissionCell.xib in Resources */,
D6D4DDDA212518A200E1C4BB /* LaunchScreen.storyboard in Resources */,
D64D0AAF2128D954005A6F37 /* Onboarding.storyboard in Resources */,
D6D4DDD7212518A200E1C4BB /* Assets.xcassets in Resources */,
D663625D2135C74800C9CBA2 /* ConversationMainStatusTableViewCell.xib in Resources */,
D6F953EE21251A0700CF0F2B /* Timeline.storyboard in Resources */,
D663626F213632A000C9CBA2 /* Compose.storyboard in Resources */,
D6A5FAFB217B86CE003DB2D9 /* OnboardingViewController.xib in Resources */,
D641C77B213CB017004B4513 /* FollowNotificationTableViewCell.xib in Resources */,
D6C94D852139DFD800CB5196 /* LargeImage.storyboard in Resources */,
D6D4DDD5212518A000E1C4BB /* Main.storyboard in Resources */,
D667E5E3213499F70057A976 /* Profile.storyboard in Resources */,
D641C771213CA9EC004B4513 /* Notifications.storyboard in Resources */,
D6289E84217B795D0003D1D7 /* LargeImageViewController.xib in Resources */,
D663626621360DD700C9CBA2 /* Preferences.storyboard in Resources */,
D667E5E12134937B0057A976 /* StatusTableViewCell.xib in Resources */,
D6A5FAF1217B7E05003DB2D9 /* ComposeViewController.xib in Resources */,
D621544D21682AD90003D87D /* TabTableViewCell.xib in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -1122,7 +1102,7 @@
D6757A822157E8FA00721E32 /* XCBSession.swift in Sources */,
04DACE8C212CB14B009840C4 /* MainTabBarViewController.swift in Sources */,
D6C693F92162E4DB007D6A6D /* StatusContentLabel.swift in Sources */,
D667E5F52135BCD50057A976 /* ConversationViewController.swift in Sources */,
D667E5F52135BCD50057A976 /* ConversationTableViewController.swift in Sources */,
D6F953F021251A2900CF0F2B /* MastodonController.swift in Sources */,
D62D2426217ABF63005076CC /* UserActivityType.swift in Sources */,
D66362712136338600C9CBA2 /* ComposeViewController.swift in Sources */,
@ -1232,14 +1212,6 @@
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
D6D4DDD3212518A000E1C4BB /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
D6D4DDD4212518A000E1C4BB /* Base */,
);
name = Main.storyboard;
sourceTree = "<group>";
};
D6D4DDD8212518A200E1C4BB /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (

42
Tusker/AppDelegate.swift

@ -14,16 +14,16 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
window = UIWindow(frame: UIScreen.main.bounds)
if LocalData.shared.onboardingComplete {
MastodonController.createClient()
MastodonController.getOwnAccount()
MastodonController.getOwnInstance()
showAppUI()
} else {
showOnboarding()
showOnboardingUI()
}
window!.makeKeyAndVisible()
return true
}
@ -60,28 +60,26 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
func applicationWillTerminate(_ application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
func showAppUI() {
MastodonController.createClient()
MastodonController.getOwnAccount()
MastodonController.getOwnInstance()
window!.rootViewController = MainTabBarViewController()
}
func showOnboardingUI() {
let onboarding = OnboardingViewController()
onboarding.delegate = self
window!.rootViewController = onboarding
}
}
extension AppDelegate: OnboardingViewControllerDelegate {
func showOnboarding() {
if let window = self.window,
let onboardingViewController = UIStoryboard(name: "Onboarding", bundle: nil).instantiateInitialViewController() as? OnboardingViewController {
onboardingViewController.delegate = self
window.makeKeyAndVisible()
window.rootViewController?.present(onboardingViewController, animated: true, completion: nil)
}
}
func hideOnboarding() {
if let window = UIApplication.shared.keyWindow {
window.rootViewController?.dismiss(animated: true, completion: nil)
}
}
func didFinishOnboarding() {
hideOnboarding()
LocalData.shared.onboardingComplete = true
showAppUI()
}
}

1
Tusker/Controllers/MastodonController.swift

@ -59,6 +59,7 @@ class MastodonController {
client.run(request) { response in
guard case let .success(account, _) = response else { fatalError() }
self.account = account
MastodonCache.add(account: account)
completion?(account)
}
}

2
Tusker/Info.plist

@ -46,8 +46,6 @@
<string>Post photos from the photo library.</string>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>

232
Tusker/Screens/Compose/Compose.storyboard

@ -1,232 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14460.15" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="8eV-YC-Spl">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.9"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--Compose-->
<scene sceneID="Dve-lH-JJK">
<objects>
<viewController id="svD-Ql-HGm" customClass="ComposeViewController" customModule="Tusker" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="qto-r6-ocp">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" keyboardDismissMode="onDrag" translatesAutoresizingMaskIntoConstraints="NO" id="L3H-aB-fGr">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="WID-nQ-ZzS">
<rect key="frame" x="16" y="16" width="343" height="735"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="l0G-YS-00D">
<rect key="frame" x="0.0" y="0.0" width="343" height="128"/>
<subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="2fn-pv-lwV">
<rect key="frame" x="0.0" y="0.0" width="50" height="50"/>
<constraints>
<constraint firstAttribute="height" constant="50" id="L4b-xJ-V5E"/>
<constraint firstAttribute="width" constant="50" id="V0U-ps-ejP"/>
</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="kBr-of-4cF">
<rect key="frame" x="58" y="0.0" width="105" height="20.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" verticalHuggingPriority="251" text="@username" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="neM-1F-PcJ">
<rect key="frame" x="171" y="0.0" width="172" height="20.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" white="0.33333333333333331" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" text="Content" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="WcY-cJ-FqF" customClass="StatusContentLabel" customModule="Tusker" customModuleProvider="target">
<rect key="frame" x="58" y="28.5" width="285" height="99.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="2fn-pv-lwV" firstAttribute="top" secondItem="l0G-YS-00D" secondAttribute="top" id="17U-sX-oMw"/>
<constraint firstAttribute="bottom" secondItem="WcY-cJ-FqF" secondAttribute="bottom" id="EVN-o1-tfI"/>
<constraint firstItem="neM-1F-PcJ" firstAttribute="leading" secondItem="kBr-of-4cF" secondAttribute="trailing" constant="8" id="Iy1-we-N0r"/>
<constraint firstAttribute="trailing" secondItem="neM-1F-PcJ" secondAttribute="trailing" id="XK2-sV-Cgu"/>
<constraint firstItem="WcY-cJ-FqF" firstAttribute="leading" secondItem="2fn-pv-lwV" secondAttribute="trailing" constant="8" id="ZuW-k7-y14"/>
<constraint firstItem="WcY-cJ-FqF" firstAttribute="top" secondItem="kBr-of-4cF" secondAttribute="bottom" constant="8" id="bwQ-WL-uN8"/>
<constraint firstAttribute="trailing" secondItem="WcY-cJ-FqF" secondAttribute="trailing" id="jUB-n1-YWr"/>
<constraint firstItem="neM-1F-PcJ" firstAttribute="top" secondItem="l0G-YS-00D" secondAttribute="top" id="mam-bN-10G"/>
<constraint firstItem="kBr-of-4cF" firstAttribute="top" secondItem="l0G-YS-00D" secondAttribute="top" id="vgj-G0-dv2"/>
<constraint firstItem="kBr-of-4cF" firstAttribute="leading" secondItem="2fn-pv-lwV" secondAttribute="trailing" constant="8" id="yZV-4x-7s6"/>
<constraint firstItem="2fn-pv-lwV" firstAttribute="leading" secondItem="l0G-YS-00D" secondAttribute="leading" id="zdv-5N-Xyl"/>
</constraints>
</view>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="6" translatesAutoresizingMaskIntoConstraints="NO" id="bGo-tx-r56">
<rect key="frame" x="0.0" y="136" width="343" height="599"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="In reply to Display Name" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="NGI-fk-d7F">
<rect key="frame" x="0.0" y="0.0" width="343" height="20.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" white="0.33333333333333331" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
</label>
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" textAlignment="natural" translatesAutoresizingMaskIntoConstraints="NO" id="gQU-rc-mM7">
<rect key="frame" x="0.0" y="26.5" width="343" height="200"/>
<color key="backgroundColor" red="0.8980392157" green="0.8980392157" blue="0.91764705879999997" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="height" constant="200" id="ugS-rN-LrW"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
</textView>
<stackView opaque="NO" contentMode="scaleToFill" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="cfA-uo-q9g">
<rect key="frame" x="0.0" y="232.5" width="343" height="30"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="wW4-Zd-GH4">
<rect key="frame" x="0.0" y="0.0" width="42" height="30"/>
<state key="normal" title="Media"/>
<connections>
<action selector="mediaPressed:" destination="svD-Ql-HGm" eventType="touchUpInside" id="0pB-L2-VZa"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="EOO-If-BeL">
<rect key="frame" x="50" y="0.0" width="30" height="30"/>
<state key="normal" title="CW"/>
<connections>
<action selector="contentWarningPressed:" destination="svD-Ql-HGm" eventType="touchUpInside" id="O1a-3w-Ofr"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="caP-6L-HWj">
<rect key="frame" x="88" y="0.0" width="42" height="30"/>
<state key="normal" title="Public"/>
<connections>
<action selector="visibilityPressed:" destination="svD-Ql-HGm" eventType="touchUpInside" id="aeI-Wi-7Mz"/>
</connections>
</button>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="249" verticalHuggingPriority="251" text="500" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="3x1-3A-7c4">
<rect key="frame" x="138" y="0.0" width="166" height="30"/>
<fontDescription key="fontDescription" type="system" pointSize="15"/>
<color key="textColor" white="0.33333333333333331" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="right" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="wg4-nL-Q7B">
<rect key="frame" x="312" y="0.0" width="31" height="30"/>
<state key="normal" title="Post"/>
<connections>
<action selector="postPressed:" destination="svD-Ql-HGm" eventType="touchUpInside" id="HqO-kb-qcz"/>
</connections>
</button>
</subviews>
</stackView>
<textField hidden="YES" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Content Warning" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="Rbm-SO-Cpp">
<rect key="frame" x="0.0" y="265.5" width="343" height="0.0"/>
<nil key="textColor"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<textInputTraits key="textInputTraits" returnKeyType="done"/>
</textField>
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="gcH-tf-prn">
<rect key="frame" x="0.0" y="268.5" width="343" height="100"/>
<constraints>
<constraint firstAttribute="height" constant="100" id="0BL-1Y-g90"/>
</constraints>
</stackView>
<view contentMode="scaleToFill" verticalHuggingPriority="249" translatesAutoresizingMaskIntoConstraints="NO" id="VuB-eX-IiL">
<rect key="frame" x="0.0" y="374.5" width="343" height="224.5"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</view>
</subviews>
</stackView>
</subviews>
</stackView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="What is on your mind?" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="sCM-XV-u2f">
<rect key="frame" x="20.5" y="186.5" width="170" height="20.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" white="0.66666666666666663" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<constraints>
<constraint firstAttribute="trailing" secondItem="WID-nQ-ZzS" secondAttribute="trailing" constant="16" id="0Sy-jt-Ddv"/>
<constraint firstItem="bGo-tx-r56" firstAttribute="height" secondItem="L3H-aB-fGr" secondAttribute="height" constant="-68" id="5Xh-ao-jAN"/>
<constraint firstItem="WID-nQ-ZzS" firstAttribute="leading" secondItem="L3H-aB-fGr" secondAttribute="leading" constant="16" id="8Aw-l2-092"/>
<constraint firstItem="sCM-XV-u2f" firstAttribute="top" secondItem="gQU-rc-mM7" secondAttribute="top" constant="8" id="8ws-rN-cVr"/>
<constraint firstItem="WID-nQ-ZzS" firstAttribute="top" secondItem="L3H-aB-fGr" secondAttribute="top" constant="16" id="CYg-ft-CAr"/>
<constraint firstAttribute="bottom" secondItem="WID-nQ-ZzS" secondAttribute="bottom" id="yTD-d9-Cr8"/>
<constraint firstItem="sCM-XV-u2f" firstAttribute="leading" secondItem="gQU-rc-mM7" secondAttribute="leading" constant="4.5" id="yTj-uC-5Qj"/>
</constraints>
</scrollView>
<progressView opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="750" progressViewStyle="bar" progress="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="qAh-id-u7z" customClass="SteppedProgressView" customModule="Tusker" customModuleProvider="target">
<rect key="frame" x="0.0" y="64" width="375" height="2.5"/>
</progressView>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="L3H-aB-fGr" firstAttribute="leading" secondItem="qto-r6-ocp" secondAttribute="leading" id="01l-qs-Ff4"/>
<constraint firstItem="L3H-aB-fGr" firstAttribute="top" secondItem="qto-r6-ocp" secondAttribute="topMargin" constant="-64" id="7BB-7k-gaN"/>
<constraint firstAttribute="trailing" secondItem="qAh-id-u7z" secondAttribute="trailing" id="EMl-GI-anW"/>
<constraint firstItem="WID-nQ-ZzS" firstAttribute="width" secondItem="qto-r6-ocp" secondAttribute="width" constant="-32" id="Fer-8I-o1H"/>
<constraint firstAttribute="trailing" secondItem="L3H-aB-fGr" secondAttribute="trailing" id="NWJ-dh-7ED"/>
<constraint firstItem="qAh-id-u7z" firstAttribute="top" secondItem="7ws-AM-scc" secondAttribute="top" id="hEb-Hg-oRI"/>
<constraint firstItem="qAh-id-u7z" firstAttribute="leading" secondItem="qto-r6-ocp" secondAttribute="leading" id="jVP-AN-LtR"/>
<constraint firstItem="7ws-AM-scc" firstAttribute="bottom" secondItem="L3H-aB-fGr" secondAttribute="bottom" id="uZs-Y8-hGM"/>
</constraints>
<viewLayoutGuide key="safeArea" id="7ws-AM-scc"/>
</view>
<navigationItem key="navigationItem" title="Compose" id="WVz-mo-nCC">
<barButtonItem key="leftBarButtonItem" systemItem="cancel" id="94u-El-jk4">
<connections>
<segue destination="XCi-Fs-398" kind="unwind" identifier="cancel" unwindAction="unwindToTabBarControllerWithSegue:" id="R9N-eg-Lp6"/>
</connections>
</barButtonItem>
</navigationItem>
<connections>
<outlet property="charactersRemainingLabel" destination="3x1-3A-7c4" id="Bek-Rl-mMY"/>
<outlet property="contentWarningTextField" destination="Rbm-SO-Cpp" id="d1F-yi-CnV"/>
<outlet property="inReplyToAvatarImageView" destination="2fn-pv-lwV" id="SMy-L1-bI1"/>
<outlet property="inReplyToContainerView" destination="l0G-YS-00D" id="XO0-HW-WVf"/>
<outlet property="inReplyToContentLabel" destination="WcY-cJ-FqF" id="JNr-hO-QPO"/>
<outlet property="inReplyToDisplayNameLabel" destination="kBr-of-4cF" id="bWk-5w-vJb"/>
<outlet property="inReplyToLabel" destination="NGI-fk-d7F" id="S59-D5-9bF"/>
<outlet property="inReplyToUsernameLabel" destination="neM-1F-PcJ" id="Lej-ut-yp9"/>
<outlet property="mediaStackView" destination="gcH-tf-prn" id="oM2-hc-rXY"/>
<outlet property="paddingView" destination="VuB-eX-IiL" id="wDo-4O-g30"/>
<outlet property="placeholderLabel" destination="sCM-XV-u2f" id="cVa-Mf-1cO"/>
<outlet property="postButton" destination="wg4-nL-Q7B" id="6EL-Dd-jPb"/>
<outlet property="progressView" destination="qAh-id-u7z" id="sw0-dq-eNa"/>
<outlet property="scrollView" destination="L3H-aB-fGr" id="kbS-H5-K2I"/>
<outlet property="statusTextView" destination="gQU-rc-mM7" id="FVL-nk-159"/>
<outlet property="visibilityButton" destination="caP-6L-HWj" id="89p-Bl-cRH"/>
<segue destination="XCi-Fs-398" kind="unwind" identifier="postComplete" unwindAction="unwindToTabBarControllerWithSegue:" id="00m-ok-xPA"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="jeI-ty-LsU" userLabel="First Responder" sceneMemberID="firstResponder"/>
<exit id="XCi-Fs-398" userLabel="Exit" sceneMemberID="exit"/>
</objects>
<point key="canvasLocation" x="1048.8" y="-157.87106446776613"/>
</scene>
<!--Navigation Controller-->
<scene sceneID="RHQ-fP-dlc">
<objects>
<navigationController automaticallyAdjustsScrollViewInsets="NO" id="8eV-YC-Spl" sceneMemberID="viewController">
<toolbarItems/>
<navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="PYB-mm-ur8">
<rect key="frame" x="0.0" y="20" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
</navigationBar>
<nil name="viewControllers"/>
<connections>
<segue destination="svD-Ql-HGm" kind="relationship" relationship="rootViewController" id="WUM-0u-sCZ"/>
</connections>
</navigationController>
<placeholder placeholderIdentifier="IBFirstResponder" id="RLe-aq-Yb1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="109.59999999999999" y="-157.87106446776613"/>
</scene>
</scenes>
</document>

54
Tusker/Screens/Compose/ComposeViewController.swift

@ -11,24 +11,6 @@ import Pachyderm
import Intents
class ComposeViewController: UIViewController {
static func create(inReplyTo inReplyToID: String? = nil, mentioning: String? = nil, text: String? = nil) -> UIViewController {
guard let navigationController = UIStoryboard(name: "Compose", bundle: nil).instantiateInitialViewController() as? UINavigationController,
let composeVC = navigationController.topViewController as? ComposeViewController else { fatalError() }
composeVC.inReplyToID = inReplyToID
composeVC.mentioningAcct = mentioning
composeVC.text = text
return navigationController
}
static func create(for session: XCBSession, mentioning: String? = nil, text: String? = nil) -> UIViewController {
guard let navigationController = UIStoryboard(name: "Compose", bundle: nil).instantiateInitialViewController() as? UINavigationController,
let composeVC = navigationController.topViewController as? ComposeViewController else { fatalError() }
composeVC.mentioningAcct = mentioning
composeVC.text = text
composeVC.xcbSession = session
return navigationController
}
@IBOutlet weak var scrollView: UIScrollView!
@IBOutlet weak var inReplyToContainerView: UIView!
@ -69,6 +51,18 @@ class ComposeViewController: UIViewController {
var status: Status?
init(inReplyTo inReplyToID: String? = nil, mentioningAcct: String? = nil, text: String? = nil) {
super.init(nibName: "ComposeViewController", bundle: nil)
self.inReplyToID = inReplyToID
self.mentioningAcct = mentioningAcct
self.text = text
navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(cancelPressed))
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
@ -169,20 +163,11 @@ class ComposeViewController: UIViewController {
}
// MARK: - Navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
override func dismiss(animated flag: Bool, completion: (() -> Void)? = nil) {
statusTextView.resignFirstResponder()
contentWarningTextField.resignFirstResponder()
if segue.identifier == "postComplete" {
guard let status = status else { fatalError("postComplete segue can't occur without Status") }
guard let dest = segue.destination as? MainTabBarViewController,
let navController = dest.selectedViewController as? UINavigationController,
let topVC = navController.topViewController as? StatusTableViewCellDelegate else { return }
topVC.selected(status: status.id)
} else if segue.identifier == "cancel" {
xcbSession?.complete(with: .cancel)
}
super.dismiss(animated: flag, completion: completion)
}
// MARK: - Interaction
@ -285,7 +270,9 @@ class ComposeViewController: UIViewController {
MastodonCache.add(status: status)
DispatchQueue.main.async {
self.progressView.step()
self.performSegue(withIdentifier: "postComplete", sender: self)
self.dismiss(animated: true)
// TODO: reorganize routing/navigation
(((self.presentingViewController as! MainTabBarViewController).selectedViewController as! UINavigationController).topViewController as! TuskerNavigationDelegate).selected(status: status.id)
self.xcbSession?.complete(with: .success, additionalData: [
"statusURL": status.url?.absoluteString,
@ -304,6 +291,11 @@ class ComposeViewController: UIViewController {
statusTextView.endEditing(false)
}
@objc func cancelPressed() {
dismiss(animated: true)
xcbSession?.complete(with: .cancel)
}
}
extension ComposeViewController: UITextFieldDelegate {

200
Tusker/Screens/Compose/ComposeViewController.xib

@ -0,0 +1,200 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14460.23.1" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.16.1"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="ComposeViewController" customModule="Tusker" customModuleProvider="target">
<connections>
<outlet property="charactersRemainingLabel" destination="3Ti-cT-JnH" id="hhy-k7-jBN"/>
<outlet property="contentWarningTextField" destination="FA4-UR-Pc9" id="UnZ-6T-Phn"/>
<outlet property="inReplyToAvatarImageView" destination="cOi-cF-kIg" id="bCo-zq-NYI"/>
<outlet property="inReplyToContainerView" destination="YTO-vO-WZ5" id="gsc-Qh-Roi"/>
<outlet property="inReplyToContentLabel" destination="a2k-Ax-jJd" id="wSz-ga-J2W"/>
<outlet property="inReplyToDisplayNameLabel" destination="77P-er-bd4" id="GrH-Cu-Sqw"/>
<outlet property="inReplyToLabel" destination="lZc-Z2-0vV" id="KSM-Kh-lgR"/>
<outlet property="inReplyToUsernameLabel" destination="ZNM-ey-3j8" id="hMp-DJ-7kB"/>
<outlet property="mediaStackView" destination="wHz-h7-939" id="2gr-Vs-ymW"/>
<outlet property="paddingView" destination="YyO-d2-4bx" id="wPp-TI-5Zc"/>
<outlet property="placeholderLabel" destination="blO-2d-WiC" id="cG4-Gt-c4T"/>
<outlet property="postButton" destination="i4l-LR-1kp" id="BmN-Zr-OcQ"/>
<outlet property="progressView" destination="Ncd-80-ldI" id="ZNz-kk-Rjl"/>
<outlet property="scrollView" destination="cp4-lI-aME" id="dqM-XD-7EF"/>
<outlet property="statusTextView" destination="5Yb-vo-0yN" id="r6k-fK-U5F"/>
<outlet property="view" destination="7XG-Dk-OGm" id="09I-sr-hnP"/>
<outlet property="visibilityButton" destination="6CJ-b2-876" id="jkz-te-T3u"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="7XG-Dk-OGm">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" keyboardDismissMode="onDrag" translatesAutoresizingMaskIntoConstraints="NO" id="cp4-lI-aME">
<rect key="frame" x="0.0" y="-44" width="375" height="711"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="ovj-HJ-0pD">
<rect key="frame" x="16" y="16" width="343" height="779"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="YTO-vO-WZ5">
<rect key="frame" x="0.0" y="0.0" width="343" height="128"/>
<subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="cOi-cF-kIg">
<rect key="frame" x="0.0" y="0.0" width="50" height="50"/>
<constraints>
<constraint firstAttribute="width" constant="50" id="IMp-xZ-1wk"/>
<constraint firstAttribute="height" constant="50" id="p8i-9U-qdf"/>
</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="77P-er-bd4">
<rect key="frame" x="58" y="0.0" width="105" height="20.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" verticalHuggingPriority="251" text="@username" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ZNM-ey-3j8">
<rect key="frame" x="171" y="0.0" width="172" height="20.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" white="0.33333333329999998" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" text="Content" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="a2k-Ax-jJd" customClass="StatusContentLabel" customModule="Tusker" customModuleProvider="target">
<rect key="frame" x="58" y="28.5" width="285" height="99.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="a2k-Ax-jJd" firstAttribute="top" secondItem="77P-er-bd4" secondAttribute="bottom" constant="8" id="6oq-wI-C5d"/>
<constraint firstAttribute="trailing" secondItem="ZNM-ey-3j8" secondAttribute="trailing" id="9v0-fI-wi5"/>
<constraint firstItem="cOi-cF-kIg" firstAttribute="top" secondItem="YTO-vO-WZ5" secondAttribute="top" id="Fnv-I3-PLN"/>
<constraint firstItem="cOi-cF-kIg" firstAttribute="leading" secondItem="YTO-vO-WZ5" secondAttribute="leading" id="J0g-iO-Hsy"/>
<constraint firstItem="77P-er-bd4" firstAttribute="top" secondItem="YTO-vO-WZ5" secondAttribute="top" id="anu-L8-kpt"/>
<constraint firstAttribute="trailing" secondItem="a2k-Ax-jJd" secondAttribute="trailing" id="cIX-qN-Bnr"/>
<constraint firstAttribute="bottom" secondItem="a2k-Ax-jJd" secondAttribute="bottom" id="cYK-IY-C6V"/>
<constraint firstItem="ZNM-ey-3j8" firstAttribute="leading" secondItem="77P-er-bd4" secondAttribute="trailing" constant="8" id="dV5-U5-sJL"/>
<constraint firstItem="77P-er-bd4" firstAttribute="leading" secondItem="cOi-cF-kIg" secondAttribute="trailing" constant="8" id="hva-Nf-90R"/>
<constraint firstItem="ZNM-ey-3j8" firstAttribute="top" secondItem="YTO-vO-WZ5" secondAttribute="top" id="oET-4l-974"/>
<constraint firstItem="a2k-Ax-jJd" firstAttribute="leading" secondItem="cOi-cF-kIg" secondAttribute="trailing" constant="8" id="rt2-Lx-cgH"/>
</constraints>
</view>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="6" translatesAutoresizingMaskIntoConstraints="NO" id="dpq-un-p7Y">
<rect key="frame" x="0.0" y="136" width="343" height="643"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="In reply to Display Name" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="lZc-Z2-0vV">
<rect key="frame" x="0.0" y="0.0" width="343" height="20.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" white="0.33333333329999998" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
</label>
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" textAlignment="natural" translatesAutoresizingMaskIntoConstraints="NO" id="5Yb-vo-0yN">
<rect key="frame" x="0.0" y="26.5" width="343" height="200"/>
<color key="backgroundColor" red="0.8980392157" green="0.8980392157" blue="0.91764705879999997" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="height" constant="200" id="URa-6h-Hbt"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
</textView>
<stackView opaque="NO" contentMode="scaleToFill" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="HTy-eW-OvQ">
<rect key="frame" x="0.0" y="232.5" width="343" height="30"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="pZv-DT-CdW">
<rect key="frame" x="0.0" y="0.0" width="42" height="30"/>
<state key="normal" title="Media"/>
<connections>
<action selector="mediaPressed:" destination="-1" eventType="touchUpInside" id="7Uf-WL-RnQ"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="H1c-9o-wdb">
<rect key="frame" x="50" y="0.0" width="30" height="30"/>
<state key="normal" title="CW"/>
<connections>
<action selector="contentWarningPressed:" destination="-1" eventType="touchUpInside" id="MrZ-09-UDE"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="6CJ-b2-876">
<rect key="frame" x="88" y="0.0" width="42" height="30"/>
<state key="normal" title="Public"/>
<connections>
<action selector="visibilityPressed:" destination="-1" eventType="touchUpInside" id="rg9-0L-AZ9"/>
</connections>
</button>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="249" verticalHuggingPriority="251" text="500" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="3Ti-cT-JnH">
<rect key="frame" x="138" y="0.0" width="166" height="30"/>
<fontDescription key="fontDescription" type="system" pointSize="15"/>
<color key="textColor" white="0.33333333329999998" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="right" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="i4l-LR-1kp">
<rect key="frame" x="312" y="0.0" width="31" height="30"/>
<state key="normal" title="Post"/>
<connections>
<action selector="postPressed:" destination="-1" eventType="touchUpInside" id="KKB-fz-Xra"/>
</connections>
</button>
</subviews>
</stackView>
<textField hidden="YES" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Content Warning" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="FA4-UR-Pc9">
<rect key="frame" x="0.0" y="265.5" width="343" height="0.0"/>
<nil key="textColor"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<textInputTraits key="textInputTraits" returnKeyType="done"/>
</textField>
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="wHz-h7-939">
<rect key="frame" x="0.0" y="268.5" width="343" height="100"/>
<constraints>
<constraint firstAttribute="height" constant="100" id="0qA-Te-SOn"/>
</constraints>
</stackView>
<view contentMode="scaleToFill" verticalHuggingPriority="249" translatesAutoresizingMaskIntoConstraints="NO" id="YyO-d2-4bx">
<rect key="frame" x="0.0" y="374.5" width="343" height="268.5"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</view>
</subviews>
</stackView>
</subviews>
</stackView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="What is on your mind?" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="blO-2d-WiC">
<rect key="frame" x="20.5" y="186.5" width="170" height="20.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<constraints>
<constraint firstAttribute="bottom" secondItem="ovj-HJ-0pD" secondAttribute="bottom" id="GqL-42-cue"/>
<constraint firstItem="ovj-HJ-0pD" firstAttribute="leading" secondItem="cp4-lI-aME" secondAttribute="leading" constant="16" id="I7Y-uR-bf0"/>
<constraint firstItem="blO-2d-WiC" firstAttribute="top" secondItem="5Yb-vo-0yN" secondAttribute="top" constant="8" id="Wfi-2X-213"/>
<constraint firstItem="ovj-HJ-0pD" firstAttribute="top" secondItem="cp4-lI-aME" secondAttribute="top" constant="16" id="bq1-LT-laf"/>
<constraint firstItem="blO-2d-WiC" firstAttribute="leading" secondItem="5Yb-vo-0yN" secondAttribute="leading" constant="4.5" id="dhw-kL-D2B"/>
<constraint firstAttribute="trailing" secondItem="ovj-HJ-0pD" secondAttribute="trailing" constant="16" id="hJy-JL-iae"/>
<constraint firstItem="dpq-un-p7Y" firstAttribute="height" secondItem="cp4-lI-aME" secondAttribute="height" constant="-68" id="oE5-6c-QYI"/>
</constraints>
</scrollView>
<progressView opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="750" progressViewStyle="bar" progress="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="Ncd-80-ldI" customClass="SteppedProgressView" customModule="Tusker" customModuleProvider="target">
<rect key="frame" x="0.0" y="20" width="375" height="2.5"/>
</progressView>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="Ncd-80-ldI" firstAttribute="top" secondItem="Heg-g4-sYM" secondAttribute="top" id="0eq-md-iJK"/>
<constraint firstItem="ovj-HJ-0pD" firstAttribute="width" secondItem="7XG-Dk-OGm" secondAttribute="width" constant="-32" id="0sw-Bf-MLK"/>
<constraint firstItem="cp4-lI-aME" firstAttribute="top" secondItem="7XG-Dk-OGm" secondAttribute="topMargin" constant="-64" id="7ef-so-AaW"/>
<constraint firstItem="cp4-lI-aME" firstAttribute="leading" secondItem="7XG-Dk-OGm" secondAttribute="leading" id="8fs-On-3th"/>
<constraint firstItem="Heg-g4-sYM" firstAttribute="bottom" secondItem="cp4-lI-aME" secondAttribute="bottom" id="S1A-db-SQZ"/>
<constraint firstItem="Ncd-80-ldI" firstAttribute="leading" secondItem="7XG-Dk-OGm" secondAttribute="leading" id="Wy2-V4-Jkp"/>
<constraint firstAttribute="trailing" secondItem="cp4-lI-aME" secondAttribute="trailing" id="afV-LD-XZS"/>
<constraint firstAttribute="trailing" secondItem="Ncd-80-ldI" secondAttribute="trailing" id="k6I-L5-xZc"/>
</constraints>
<viewLayoutGuide key="safeArea" id="Heg-g4-sYM"/>
</view>
</objects>
</document>

30
Tusker/Screens/Conversation/Conversation.storyboard

@ -1,30 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14460.23.1" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="twK-ED-gYg">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.16.1"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--Conversation View Controller-->
<scene sceneID="3yH-Pl-I9Z">
<objects>
<tableViewController id="twK-ED-gYg" customClass="ConversationViewController" customModule="Tusker" 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="MrD-X9-lv9">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<connections>
<outlet property="dataSource" destination="twK-ED-gYg" id="v7X-IB-dVa"/>
<outlet property="delegate" destination="twK-ED-gYg" id="9NJ-a0-VCf"/>
</connections>
</tableView>
</tableViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="EmL-wm-170" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="575" y="23"/>
</scene>
</scenes>
</document>

21
Tusker/Screens/Conversation/ConversationViewController.swift → Tusker/Screens/Conversation/ConversationTableViewController.swift

@ -9,13 +9,7 @@
import UIKit
import Pachyderm
class ConversationViewController: UITableViewController {
static func create(for mainStatusID: String) -> ConversationViewController {
guard let conversationController = UIStoryboard(name: "Conversation", bundle: nil).instantiateInitialViewController() as? ConversationViewController else { fatalError() }
conversationController.mainStatusID = mainStatusID
return conversationController
}
class ConversationTableViewController: UITableViewController {
var mainStatusID: String!
@ -27,6 +21,15 @@ class ConversationViewController: UITableViewController {
}
}
init(for mainStatusID: String) {
super.init(style: .plain)
self.mainStatusID = mainStatusID
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
@ -151,5 +154,5 @@ class ConversationViewController: UITableViewController {
}
extension ConversationViewController: StatusTableViewCellDelegate {}
extension ConversationViewController: LargeImageViewControllerDelegate {}
extension ConversationTableViewController: StatusTableViewCellDelegate {}
extension ConversationTableViewController: LargeImageViewControllerDelegate {}

152
Tusker/Screens/Large Image/LargeImage.storyboard

@ -1,152 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14313.18" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="8pH-Ao-p7G">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14283.14"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--Large Image View Controller-->
<scene sceneID="jFU-tD-Rk9">
<objects>
<viewController id="8pH-Ao-p7G" customClass="LargeImageViewController" customModule="Tusker" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="w1M-d4-X1A">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" ambiguous="YES" minimumZoomScale="0.25" maximumZoomScale="2" translatesAutoresizingMaskIntoConstraints="NO" id="2wV-8N-EFe">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<subviews>
<imageView contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Pd6-Mn-fcS">
<rect key="frame" x="0.0" y="-10" width="375" height="647"/>
<gestureRecognizers/>
</imageView>
</subviews>
<gestureRecognizers/>
<constraints>
<constraint firstAttribute="bottom" secondItem="Pd6-Mn-fcS" secondAttribute="bottom" id="4DC-Cz-yrd"/>
<constraint firstItem="Pd6-Mn-fcS" firstAttribute="leading" secondItem="2wV-8N-EFe" secondAttribute="leading" id="8NV-u8-aEP"/>
<constraint firstItem="Pd6-Mn-fcS" firstAttribute="top" secondItem="2wV-8N-EFe" secondAttribute="top" id="HLI-4J-tF7"/>
<constraint firstAttribute="trailing" secondItem="Pd6-Mn-fcS" secondAttribute="trailing" id="eYw-ke-jQP"/>
</constraints>
<connections>
<outletCollection property="gestureRecognizers" destination="vji-Fm-RJ6" appends="YES" id="62b-Mz-RSo"/>
</connections>
</scrollView>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="1EF-uu-YnK">
<rect key="frame" x="0.0" y="0.0" width="375" height="36"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Jjh-Jw-5E9">
<rect key="frame" x="16" y="16" width="20" height="20"/>
<constraints>
<constraint firstAttribute="width" constant="20" id="cBe-e6-Eng"/>
<constraint firstAttribute="height" constant="20" id="uYQ-fp-4x9"/>
</constraints>
<color key="tintColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<state key="normal" image="Download"/>
<connections>
<action selector="downloadPressed:" destination="8pH-Ao-p7G" eventType="touchUpInside" id="4LG-gn-IWR"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Z1X-K2-dVx">
<rect key="frame" x="339" y="16" width="20" height="20"/>
<constraints>
<constraint firstAttribute="width" constant="20" id="1Oj-Ht-ytC"/>
<constraint firstAttribute="height" constant="20" id="6VA-5F-Y8k"/>
</constraints>
<color key="tintColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<state key="normal" image="Close"/>
<connections>
<action selector="closeButtonPressed:" destination="8pH-Ao-p7G" eventType="touchUpInside" id="o1j-v4-hr8"/>
</connections>
</button>
</subviews>
<constraints>
<constraint firstItem="Jjh-Jw-5E9" firstAttribute="top" secondItem="1EF-uu-YnK" secondAttribute="top" constant="16" id="9zK-pO-i0Z"/>
<constraint firstAttribute="height" secondItem="Z1X-K2-dVx" secondAttribute="height" constant="16" id="IYQ-ii-Ii4"/>
<constraint firstItem="Jjh-Jw-5E9" firstAttribute="leading" secondItem="1EF-uu-YnK" secondAttribute="leading" constant="16" id="P1u-fC-6Ln"/>
<constraint firstItem="Z1X-K2-dVx" firstAttribute="top" secondItem="1EF-uu-YnK" secondAttribute="top" constant="16" id="Tsg-Oc-1jH"/>
<constraint firstAttribute="trailing" secondItem="Z1X-K2-dVx" secondAttribute="trailing" constant="16" id="wEw-jP-Teu"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="8yv-cK-4o1">
<rect key="frame" x="0.0" y="630.5" width="375" height="36.5"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="gvy-hM-kiM">
<rect key="frame" x="16" y="0.0" width="343" height="20.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<constraints>
<constraint firstAttribute="trailing" secondItem="gvy-hM-kiM" secondAttribute="trailing" constant="16" id="3YX-UN-rIa"/>
<constraint firstAttribute="height" secondItem="gvy-hM-kiM" secondAttribute="height" constant="16" id="WrI-2J-9Z5"/>
<constraint firstAttribute="bottom" secondItem="gvy-hM-kiM" secondAttribute="bottom" constant="16" id="bB4-b5-pmK"/>
<constraint firstItem="gvy-hM-kiM" firstAttribute="leading" secondItem="8yv-cK-4o1" secondAttribute="leading" constant="16" id="giM-Iz-Owe"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<gestureRecognizers/>
<constraints>
<constraint firstItem="2wV-8N-EFe" firstAttribute="centerX" secondItem="w1M-d4-X1A" secondAttribute="centerX" id="5tb-e1-ObD"/>
<constraint firstItem="MqP-FN-iGs" firstAttribute="trailing" secondItem="1EF-uu-YnK" secondAttribute="trailing" id="8Aw-Lq-1Pa"/>
<constraint firstItem="8yv-cK-4o1" firstAttribute="leading" secondItem="MqP-FN-iGs" secondAttribute="leading" id="9qz-OC-7av"/>
<constraint firstItem="2wV-8N-EFe" firstAttribute="centerY" secondItem="w1M-d4-X1A" secondAttribute="centerY" id="Z9C-TF-I3s"/>
<constraint firstItem="1EF-uu-YnK" firstAttribute="top" secondItem="w1M-d4-X1A" secondAttribute="top" id="Zgr-Ck-Ly5"/>
<constraint firstItem="2wV-8N-EFe" firstAttribute="height" secondItem="w1M-d4-X1A" secondAttribute="height" id="adX-Xo-gwg"/>
<constraint firstItem="MqP-FN-iGs" firstAttribute="bottom" secondItem="8yv-cK-4o1" secondAttribute="bottom" id="bn5-Qt-ggu"/>
<constraint firstItem="MqP-FN-iGs" firstAttribute="trailing" secondItem="8yv-cK-4o1" secondAttribute="trailing" id="eSp-qn-PwQ"/>
<constraint firstItem="2wV-8N-EFe" firstAttribute="width" secondItem="w1M-d4-X1A" secondAttribute="width" id="mZZ-WZ-o8E"/>
<constraint firstItem="1EF-uu-YnK" firstAttribute="leading" secondItem="MqP-FN-iGs" secondAttribute="leading" id="xLf-u4-n14"/>
</constraints>
<viewLayoutGuide key="safeArea" id="MqP-FN-iGs"/>
<connections>
<outletCollection property="gestureRecognizers" destination="EgN-eL-bDf" appends="YES" id="CeU-w7-YSb"/>
</connections>
</view>
<nil key="simulatedTopBarMetrics"/>
<nil key="simulatedBottomBarMetrics"/>
<connections>
<outlet property="bottomControlsView" destination="8yv-cK-4o1" id="iA6-0y-hiN"/>
<outlet property="closeButton" destination="Z1X-K2-dVx" id="kR7-e7-Q8T"/>
<outlet property="closeButtonTopConstraint" destination="Tsg-Oc-1jH" id="07w-Ob-ker"/>
<outlet property="closeButtonTrailingConstraint" destination="wEw-jP-Teu" id="j0N-dF-qzf"/>
<outlet property="descriptionLabel" destination="gvy-hM-kiM" id="cbi-iB-Lob"/>
<outlet property="downloadButton" destination="Jjh-Jw-5E9" id="EAp-fo-yxs"/>
<outlet property="downloadButtonLeadingConstraint" destination="P1u-fC-6Ln" id="v2c-eL-7Pa"/>
<outlet property="downloadButtonTopConstraint" destination="9zK-pO-i0Z" id="eSj-yq-jk2"/>
<outlet property="imageView" destination="Pd6-Mn-fcS" id="Eh4-q1-L4S"/>
<outlet property="imageViewBottomConstraint" destination="4DC-Cz-yrd" id="X7o-5I-sQT"/>
<outlet property="imageViewLeadingConstraint" destination="8NV-u8-aEP" id="Hvu-dn-5O9"/>
<outlet property="imageViewTopConstraint" destination="HLI-4J-tF7" id="vpw-JN-YHC"/>
<outlet property="imageViewTrailingConstraint" destination="eYw-ke-jQP" id="7Ln-IV-VZW"/>
<outlet property="scrollView" destination="2wV-8N-EFe" id="dLq-Dq-32G"/>
<outlet property="topControlsHeightConstraint" destination="IYQ-ii-Ii4" id="Mht-sy-5fZ"/>
<outlet property="topControlsView" destination="1EF-uu-YnK" id="Syt-Ib-He6"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="6Ga-cx-zlp" userLabel="First Responder" sceneMemberID="firstResponder"/>
<tapGestureRecognizer id="vji-Fm-RJ6">
<connections>
<action selector="scrollViewPressed:" destination="8pH-Ao-p7G" id="kYC-qd-03P"/>
</connections>
</tapGestureRecognizer>
<tapGestureRecognizer numberOfTapsRequired="2" id="EgN-eL-bDf">
<connections>
<action selector="scrollViewDoubleTapped:" destination="8pH-Ao-p7G" id="JZe-G5-okr"/>
</connections>
</tapGestureRecognizer>
</objects>
<point key="canvasLocation" x="-434.39999999999998" y="139.880059970015"/>
</scene>
</scenes>
<resources>
<image name="Close" width="209" height="209"/>
<image name="Download" width="284" height="284"/>
</resources>
</document>

50
Tusker/Screens/Large Image/LargeImageViewController.swift

@ -15,25 +15,6 @@ protocol LargeImageViewControllerDelegate {
class LargeImageViewController: UIViewController, UIScrollViewDelegate {
static func create(image: UIImage, description: String?, sourceView: UIView, sourceViewController: UIViewController) -> LargeImageViewController {
guard let vc = UIStoryboard(name: "LargeImage", bundle: nil).instantiateInitialViewController() as? LargeImageViewController else { fatalError() }
vc.image = image
vc.imageDescription = description
var frame = sourceView.convert(sourceView.bounds, to: sourceViewController.view)
if let scrollView = sourceViewController.view as? UIScrollView {
let scale = scrollView.zoomScale
let width = frame.width * scale
let height = frame.height * scale
let x = frame.minX * scale - scrollView.contentOffset.x + scrollView.frame.minX
let y = frame.minY * scale - scrollView.contentOffset.y + scrollView.frame.minY
frame = CGRect(x: x, y: y, width: width, height: height)
}
vc.originFrame = frame
vc.originCornerRadius = sourceView.layer.cornerRadius
vc.transitioningDelegate = sourceViewController
return vc
}
var delegate: LargeImageViewControllerDelegate?
var originFrame: CGRect?
@ -83,6 +64,28 @@ class LargeImageViewController: UIViewController, UIScrollViewDelegate {
return true
}
init(image: UIImage, description: String?, sourceView: UIView, sourceViewController: UIViewController) {
super.init(nibName: "LargeImageViewController", bundle: nil)
self.image = image
self.imageDescription = description
var frame = sourceView.convert(sourceView.bounds, to: sourceViewController.view)
if let scrollView = sourceViewController.view as? UIScrollView {
let scale = scrollView.zoomScale
let width = frame.width * scale
let height = frame.height * scale
let x = frame.minX * scale - scrollView.contentOffset.x + scrollView.frame.minX
let y = frame.minY * scale - scrollView.contentOffset.y + scrollView.frame.minY
frame = CGRect(x: x, y: y, width: width, height: height)
}
self.originFrame = frame
self.originCornerRadius = sourceView.layer.cornerRadius
self.transitioningDelegate = sourceViewController
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
@ -97,6 +100,11 @@ class LargeImageViewController: UIViewController, UIScrollViewDelegate {
}
dismissInteractionController = LargeImageInteractionController(viewController: self)
view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(scrollViewPressed(_:))))
let doubleTap = UITapGestureRecognizer(target: self, action: #selector(scrollViewDoubleTapped(_:)))
doubleTap.numberOfTapsRequired = 2
view.addGestureRecognizer(doubleTap)
}
@ -176,7 +184,7 @@ class LargeImageViewController: UIViewController, UIScrollViewDelegate {
}
*/
@IBAction func scrollViewPressed(_ sender: UITapGestureRecognizer) {
@objc func scrollViewPressed(_ sender: UITapGestureRecognizer) {
if scrollView.zoomScale > scrollView.minimumZoomScale {
animateZoomOut()
} else {
@ -184,7 +192,7 @@ class LargeImageViewController: UIViewController, UIScrollViewDelegate {
}
}
@IBAction func scrollViewDoubleTapped(_ recognizer: UITapGestureRecognizer) {
@objc func scrollViewDoubleTapped(_ recognizer: UITapGestureRecognizer) {
if scrollView.zoomScale <= scrollView.minimumZoomScale {
let point = recognizer.location(in: recognizer.view)
let scale: CGFloat

130
Tusker/Screens/Large Image/LargeImageViewController.xib

@ -0,0 +1,130 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14460.23.1" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.16.1"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="LargeImageViewController" customModule="Tusker" customModuleProvider="target">
<connections>
<outlet property="bottomControlsView" destination="rPa-Zu-T6g" id="Rgz-AQ-9nt"/>
<outlet property="closeButton" destination="pnA-ne-k0v" id="RPP-cB-9ap"/>
<outlet property="closeButtonTopConstraint" destination="ImD-2H-0XK" id="DUe-b1-a2N"/>
<outlet property="closeButtonTrailingConstraint" destination="JFe-ig-3Ic" id="cWO-Rr-y3F"/>
<outlet property="descriptionLabel" destination="eo5-fc-RV8" id="vrW-RJ-y5k"/>
<outlet property="downloadButton" destination="vhp-0u-Q0S" id="JZS-K9-4w9"/>
<outlet property="downloadButtonLeadingConstraint" destination="MJx-2r-p0k" id="Dn5-Eg-Pid"/>
<outlet property="downloadButtonTopConstraint" destination="sgG-dC-xXP" id="Rjp-od-00F"/>
<outlet property="imageView" destination="qcn-1t-3sS" id="Q01-G2-y1c"/>
<outlet property="imageViewBottomConstraint" destination="3JF-Yo-5OR" id="1dh-W6-E8S"/>
<outlet property="imageViewLeadingConstraint" destination="bI3-V8-M70" id="nIe-xI-E9u"/>
<outlet property="imageViewTopConstraint" destination="tfL-hp-2I2" id="EDV-RO-pTe"/>
<outlet property="imageViewTrailingConstraint" destination="3bU-AI-KLl" id="IRq-jZ-u2s"/>
<outlet property="scrollView" destination="Skj-xq-AgQ" id="TFb-zF-m1b"/>
<outlet property="topControlsHeightConstraint" destination="6XT-D6-8FS" id="mTB-LF-50H"/>
<outlet property="topControlsView" destination="kHo-B9-R7a" id="8sJ-xQ-7ix"/>
<outlet property="view" destination="BJw-5C-9nT" id="1C2-VA-mNf"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="BJw-5C-9nT">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" ambiguous="YES" minimumZoomScale="0.25" maximumZoomScale="2" translatesAutoresizingMaskIntoConstraints="NO" id="Skj-xq-AgQ">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<subviews>
<imageView contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="qcn-1t-3sS">
<rect key="frame" x="0.0" y="-10" width="375" height="647"/>
<gestureRecognizers/>
</imageView>
</subviews>
<gestureRecognizers/>
<constraints>
<constraint firstAttribute="bottom" secondItem="qcn-1t-3sS" secondAttribute="bottom" id="3JF-Yo-5OR"/>
<constraint firstAttribute="trailing" secondItem="qcn-1t-3sS" secondAttribute="trailing" id="3bU-AI-KLl"/>
<constraint firstItem="qcn-1t-3sS" firstAttribute="leading" secondItem="Skj-xq-AgQ" secondAttribute="leading" id="bI3-V8-M70"/>
<constraint firstItem="qcn-1t-3sS" firstAttribute="top" secondItem="Skj-xq-AgQ" secondAttribute="top" id="tfL-hp-2I2"/>
</constraints>
</scrollView>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="kHo-B9-R7a">
<rect key="frame" x="0.0" y="0.0" width="375" height="36"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="vhp-0u-Q0S">
<rect key="frame" x="16" y="16" width="20" height="20"/>
<constraints>
<constraint firstAttribute="height" constant="20" id="4tF-oL-qXT"/>
<constraint firstAttribute="width" constant="20" id="zWx-jJ-dBj"/>
</constraints>
<color key="tintColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<state key="normal" image="Download"/>
<connections>
<action selector="downloadPressed:" destination="-1" eventType="touchUpInside" id="7Oz-zv-m2t"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="pnA-ne-k0v">
<rect key="frame" x="339" y="16" width="20" height="20"/>
<constraints>
<constraint firstAttribute="width" constant="20" id="eg0-hN-rda"/>
<constraint firstAttribute="height" constant="20" id="fmA-pI-8WB"/>
</constraints>
<color key="tintColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<state key="normal" image="Close"/>
<connections>
<action selector="closeButtonPressed:" destination="-1" eventType="touchUpInside" id="7o3-ET-EMo"/>
</connections>
</button>
</subviews>
<constraints>
<constraint firstAttribute="height" secondItem="pnA-ne-k0v" secondAttribute="height" constant="16" id="6XT-D6-8FS"/>
<constraint firstItem="pnA-ne-k0v" firstAttribute="top" secondItem="kHo-B9-R7a" secondAttribute="top" constant="16" id="ImD-2H-0XK"/>
<constraint firstAttribute="trailing" secondItem="pnA-ne-k0v" secondAttribute="trailing" constant="16" id="JFe-ig-3Ic"/>
<constraint firstItem="vhp-0u-Q0S" firstAttribute="leading" secondItem="kHo-B9-R7a" secondAttribute="leading" constant="16" id="MJx-2r-p0k"/>
<constraint firstItem="vhp-0u-Q0S" firstAttribute="top" secondItem="kHo-B9-R7a" secondAttribute="top" constant="16" id="sgG-dC-xXP"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="rPa-Zu-T6g">
<rect key="frame" x="0.0" y="630.5" width="375" height="36.5"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="eo5-fc-RV8">
<rect key="frame" x="16" y="0.0" width="343" height="20.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<constraints>
<constraint firstAttribute="trailing" secondItem="eo5-fc-RV8" secondAttribute="trailing" constant="16" id="6uL-vY-tqk"/>
<constraint firstItem="eo5-fc-RV8" firstAttribute="leading" secondItem="rPa-Zu-T6g" secondAttribute="leading" constant="16" id="KIF-vw-K7n"/>
<constraint firstAttribute="height" secondItem="eo5-fc-RV8" secondAttribute="height" constant="16" id="bt3-XT-WzC"/>
<constraint firstAttribute="bottom" secondItem="eo5-fc-RV8" secondAttribute="bottom" constant="16" id="v43-mS-tyR"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<gestureRecognizers/>
<constraints>
<constraint firstItem="Skj-xq-AgQ" firstAttribute="centerY" secondItem="BJw-5C-9nT" secondAttribute="centerY" id="0Xb-ib-2hg"/>
<constraint firstItem="w1g-VC-Ll9" firstAttribute="trailing" secondItem="rPa-Zu-T6g" secondAttribute="trailing" id="2GG-7P-Qv1"/>
<constraint firstItem="w1g-VC-Ll9" firstAttribute="bottom" secondItem="rPa-Zu-T6g" secondAttribute="bottom" id="3qf-5e-vl0"/>
<constraint firstItem="kHo-B9-R7a" firstAttribute="leading" secondItem="w1g-VC-Ll9" secondAttribute="leading" id="IvH-gU-Kie"/>
<constraint firstItem="Skj-xq-AgQ" firstAttribute="centerX" secondItem="BJw-5C-9nT" secondAttribute="centerX" id="KMe-Zc-NZq"/>
<constraint firstItem="Skj-xq-AgQ" firstAttribute="width" secondItem="BJw-5C-9nT" secondAttribute="width" id="Onj-l9-fBu"/>
<constraint firstItem="w1g-VC-Ll9" firstAttribute="trailing" secondItem="kHo-B9-R7a" secondAttribute="trailing" id="Uh0-ub-R9V"/>
<constraint firstItem="rPa-Zu-T6g" firstAttribute="leading" secondItem="w1g-VC-Ll9" secondAttribute="leading" id="asz-Xj-FUC"/>
<constraint firstItem="Skj-xq-AgQ" firstAttribute="height" secondItem="BJw-5C-9nT" secondAttribute="height" id="jvz-QW-n9c"/>
<constraint firstItem="kHo-B9-R7a" firstAttribute="top" secondItem="BJw-5C-9nT" secondAttribute="top" id="n1O-C3-yQR"/>
</constraints>
<viewLayoutGuide key="safeArea" id="w1g-VC-Ll9"/>
<point key="canvasLocation" x="-164" y="476"/>
</view>
</objects>
<resources>
<image name="Close" width="209" height="209"/>
<image name="Download" width="284" height="284"/>
</resources>
</document>

27
Tusker/Screens/Main/Base.lproj/Main.storyboard

@ -1,27 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14313.13.2" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="hVq-Vu-bEj">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14283.9"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--Main Tab Bar View Controller-->
<scene sceneID="ELt-Cr-gbC">
<objects>
<tabBarController automaticallyAdjustsScrollViewInsets="NO" id="hVq-Vu-bEj" customClass="MainTabBarViewController" customModule="Tusker" customModuleProvider="target" sceneMemberID="viewController">
<toolbarItems/>
<tabBar key="tabBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="cjv-gb-Kie">
<rect key="frame" x="0.0" y="0.0" width="1000" height="1000"/>
<autoresizingMask key="autoresizingMask"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</tabBar>
</tabBarController>
<placeholder placeholderIdentifier="IBFirstResponder" id="1cN-fA-SM9" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-210.40000000000001" y="31.934032983508249"/>
</scene>
</scenes>
</document>

13
Tusker/Screens/Main/MainTabBarViewController.swift

@ -31,20 +31,20 @@ class MainTabBarViewController: UITabBarController {
func createVC(for tab: Tab) -> UIViewController {
switch tab {
case .home:
return TimelineTableViewController.create(for: .home)
return TimelineTableViewController(for: .home)
case .federated:
return TimelineTableViewController.create(for: .public(local: false))
return TimelineTableViewController(for: .public(local: false))
case .local:
return TimelineTableViewController.create(for: .public(local: true))
return TimelineTableViewController(for: .public(local: true))
case .myProfile:
let myProfile = ProfileTableViewController.createForPending()
let myProfile = ProfileTableViewController(accountID: nil)
myProfile.title = "My Profile"
MastodonController.getOwnAccount { (account) in
myProfile.accountID = account.id
}
return myProfile
case .notifications:
return NotificationsTableViewController.create()
return embedInNavigationController(NotificationsTableViewController())
case .preferences:
return PreferencesTableViewController.create()
}
@ -67,8 +67,5 @@ class MainTabBarViewController: UITabBarController {
// Pass the selected object to the new view controller.
}
*/
@IBAction func unwindToTabBarController(segue: UIStoryboardSegue) {
}
}

55
Tusker/Screens/Notifications/Notifications.storyboard

@ -1,55 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14313.13.2" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="EzH-QO-2dB">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14283.9"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--Notifications-->
<scene sceneID="vSO-cl-PiH">
<objects>
<tableViewController id="E5I-Er-vAb" customClass="NotificationsTableViewController" customModule="Tusker" 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="0DS-T6-PUs">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<connections>
<outlet property="dataSource" destination="E5I-Er-vAb" id="w6K-Pf-fhT"/>
<outlet property="delegate" destination="E5I-Er-vAb" id="O7J-GD-Bmh"/>
</connections>
</tableView>
<navigationItem key="navigationItem" title="Notifications" id="wg3-0i-z0p"/>
<refreshControl key="refreshControl" opaque="NO" multipleTouchEnabled="YES" contentMode="center" insetsLayoutMarginsFromSafeArea="NO" enabled="NO" contentHorizontalAlignment="center" contentVerticalAlignment="center" id="Mmb-i6-RhA">
<autoresizingMask key="autoresizingMask"/>
<connections>
<action selector="refreshNotifications:" destination="E5I-Er-vAb" eventType="primaryActionTriggered" id="Old-Un-zAH"/>
</connections>
</refreshControl>
</tableViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="rl4-aD-Trs" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="390" y="139"/>
</scene>
<!--Notifications-->
<scene sceneID="4AI-j7-p9U">
<objects>
<navigationController id="EzH-QO-2dB" sceneMemberID="viewController">
<tabBarItem key="tabBarItem" title="Notifications" id="rKf-9n-3CY"/>
<simulatedTabBarMetrics key="simulatedBottomBarMetrics"/>
<navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="zS8-NX-vjx">
<rect key="frame" x="0.0" y="20" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
</navigationBar>
<connections>
<segue destination="E5I-Er-vAb" kind="relationship" relationship="rootViewController" id="udi-gd-H1N"/>
</connections>
</navigationController>
<placeholder placeholderIdentifier="IBFirstResponder" id="2A9-Wz-JHf" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-562" y="139"/>
</scene>
</scenes>
</document>

34
Tusker/Screens/Notifications/NotificationsTableViewController.swift

@ -10,11 +10,6 @@ import UIKit
import Pachyderm
class NotificationsTableViewController: UITableViewController {
static func create() -> UINavigationController {
guard let navigationController = UIStoryboard(name: "Notifications", bundle: nil).instantiateInitialViewController() as? UINavigationController else { fatalError() }
return navigationController
}
var notifications: [Pachyderm.Notification] = [] {
didSet {
@ -27,14 +22,19 @@ class NotificationsTableViewController: UITableViewController {
var newer: RequestRange?
var older: RequestRange?
init() {
super.init(style: .plain)
self.title = "Notifications"
self.refreshControl = UIRefreshControl()
refreshControl!.addTarget(self, action: #selector(refreshNotifications(_:)), for: .valueChanged)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonIte