Compare commits
6 Commits
5a82851fe9
...
b2096f22c3
Author | SHA1 | Date |
---|---|---|
Shadowfacts | b2096f22c3 | |
Shadowfacts | 14c456df22 | |
Shadowfacts | 3f34357692 | |
Shadowfacts | 429dcefa88 | |
Shadowfacts | d1a35620c9 | |
Shadowfacts | ce741d6e1f |
|
@ -216,7 +216,7 @@
|
||||||
D68ACE5D279B1ABA001CE8EB /* AssetPickerControlCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D68ACE5C279B1ABA001CE8EB /* AssetPickerControlCollectionViewCell.swift */; };
|
D68ACE5D279B1ABA001CE8EB /* AssetPickerControlCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D68ACE5C279B1ABA001CE8EB /* AssetPickerControlCollectionViewCell.swift */; };
|
||||||
D68C2AE325869BAB00548EFF /* AuxiliarySceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D68C2AE225869BAB00548EFF /* AuxiliarySceneDelegate.swift */; };
|
D68C2AE325869BAB00548EFF /* AuxiliarySceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D68C2AE225869BAB00548EFF /* AuxiliarySceneDelegate.swift */; };
|
||||||
D68E525B24A3D77E0054355A /* TuskerRootViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D68E525A24A3D77E0054355A /* TuskerRootViewController.swift */; };
|
D68E525B24A3D77E0054355A /* TuskerRootViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D68E525A24A3D77E0054355A /* TuskerRootViewController.swift */; };
|
||||||
D68E525D24A3E8F00054355A /* SearchViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D68E525C24A3E8F00054355A /* SearchViewController.swift */; };
|
D68E525D24A3E8F00054355A /* InlineTrendsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D68E525C24A3E8F00054355A /* InlineTrendsViewController.swift */; };
|
||||||
D68E6F59253C9969001A1B4C /* MultiSourceEmojiLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D68E6F58253C9969001A1B4C /* MultiSourceEmojiLabel.swift */; };
|
D68E6F59253C9969001A1B4C /* MultiSourceEmojiLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D68E6F58253C9969001A1B4C /* MultiSourceEmojiLabel.swift */; };
|
||||||
D68E6F5F253C9B2D001A1B4C /* BaseEmojiLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D68E6F5E253C9B2D001A1B4C /* BaseEmojiLabel.swift */; };
|
D68E6F5F253C9B2D001A1B4C /* BaseEmojiLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D68E6F5E253C9B2D001A1B4C /* BaseEmojiLabel.swift */; };
|
||||||
D68FEC4F232C5BC300C84F23 /* SegmentedPageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D68FEC4E232C5BC300C84F23 /* SegmentedPageViewController.swift */; };
|
D68FEC4F232C5BC300C84F23 /* SegmentedPageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D68FEC4E232C5BC300C84F23 /* SegmentedPageViewController.swift */; };
|
||||||
|
@ -298,6 +298,7 @@
|
||||||
D6C3F4F5298ED0890009FCFF /* LocalPredicateStatusesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6C3F4F4298ED0890009FCFF /* LocalPredicateStatusesViewController.swift */; };
|
D6C3F4F5298ED0890009FCFF /* LocalPredicateStatusesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6C3F4F4298ED0890009FCFF /* LocalPredicateStatusesViewController.swift */; };
|
||||||
D6C3F4F7298ED7F70009FCFF /* FavoritesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6C3F4F6298ED7F70009FCFF /* FavoritesViewController.swift */; };
|
D6C3F4F7298ED7F70009FCFF /* FavoritesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6C3F4F6298ED7F70009FCFF /* FavoritesViewController.swift */; };
|
||||||
D6C3F4F9298EDBF20009FCFF /* ConversationTree.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6C3F4F8298EDBF20009FCFF /* ConversationTree.swift */; };
|
D6C3F4F9298EDBF20009FCFF /* ConversationTree.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6C3F4F8298EDBF20009FCFF /* ConversationTree.swift */; };
|
||||||
|
D6C3F4FB299035650009FCFF /* TrendsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6C3F4FA299035650009FCFF /* TrendsViewController.swift */; };
|
||||||
D6C693EF216192C2007D6A6D /* TuskerNavigationDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6C693EE216192C2007D6A6D /* TuskerNavigationDelegate.swift */; };
|
D6C693EF216192C2007D6A6D /* TuskerNavigationDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6C693EE216192C2007D6A6D /* TuskerNavigationDelegate.swift */; };
|
||||||
D6C693FC2162FE6F007D6A6D /* LoadingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6C693FB2162FE6F007D6A6D /* LoadingViewController.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 */; };
|
D6C693FE2162FEEA007D6A6D /* UIViewController+Children.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6C693FD2162FEEA007D6A6D /* UIViewController+Children.swift */; };
|
||||||
|
@ -626,7 +627,7 @@
|
||||||
D68ACE5C279B1ABA001CE8EB /* AssetPickerControlCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssetPickerControlCollectionViewCell.swift; sourceTree = "<group>"; };
|
D68ACE5C279B1ABA001CE8EB /* AssetPickerControlCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssetPickerControlCollectionViewCell.swift; sourceTree = "<group>"; };
|
||||||
D68C2AE225869BAB00548EFF /* AuxiliarySceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuxiliarySceneDelegate.swift; sourceTree = "<group>"; };
|
D68C2AE225869BAB00548EFF /* AuxiliarySceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuxiliarySceneDelegate.swift; sourceTree = "<group>"; };
|
||||||
D68E525A24A3D77E0054355A /* TuskerRootViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TuskerRootViewController.swift; sourceTree = "<group>"; };
|
D68E525A24A3D77E0054355A /* TuskerRootViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TuskerRootViewController.swift; sourceTree = "<group>"; };
|
||||||
D68E525C24A3E8F00054355A /* SearchViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchViewController.swift; sourceTree = "<group>"; };
|
D68E525C24A3E8F00054355A /* InlineTrendsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InlineTrendsViewController.swift; sourceTree = "<group>"; };
|
||||||
D68E6F58253C9969001A1B4C /* MultiSourceEmojiLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultiSourceEmojiLabel.swift; sourceTree = "<group>"; };
|
D68E6F58253C9969001A1B4C /* MultiSourceEmojiLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultiSourceEmojiLabel.swift; sourceTree = "<group>"; };
|
||||||
D68E6F5E253C9B2D001A1B4C /* BaseEmojiLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseEmojiLabel.swift; sourceTree = "<group>"; };
|
D68E6F5E253C9B2D001A1B4C /* BaseEmojiLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseEmojiLabel.swift; sourceTree = "<group>"; };
|
||||||
D68FEC4E232C5BC300C84F23 /* SegmentedPageViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SegmentedPageViewController.swift; sourceTree = "<group>"; };
|
D68FEC4E232C5BC300C84F23 /* SegmentedPageViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SegmentedPageViewController.swift; sourceTree = "<group>"; };
|
||||||
|
@ -708,6 +709,7 @@
|
||||||
D6C3F4F4298ED0890009FCFF /* LocalPredicateStatusesViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalPredicateStatusesViewController.swift; sourceTree = "<group>"; };
|
D6C3F4F4298ED0890009FCFF /* LocalPredicateStatusesViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalPredicateStatusesViewController.swift; sourceTree = "<group>"; };
|
||||||
D6C3F4F6298ED7F70009FCFF /* FavoritesViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FavoritesViewController.swift; sourceTree = "<group>"; };
|
D6C3F4F6298ED7F70009FCFF /* FavoritesViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FavoritesViewController.swift; sourceTree = "<group>"; };
|
||||||
D6C3F4F8298EDBF20009FCFF /* ConversationTree.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConversationTree.swift; sourceTree = "<group>"; };
|
D6C3F4F8298EDBF20009FCFF /* ConversationTree.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConversationTree.swift; sourceTree = "<group>"; };
|
||||||
|
D6C3F4FA299035650009FCFF /* TrendsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrendsViewController.swift; sourceTree = "<group>"; };
|
||||||
D6C693EE216192C2007D6A6D /* TuskerNavigationDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TuskerNavigationDelegate.swift; sourceTree = "<group>"; };
|
D6C693EE216192C2007D6A6D /* TuskerNavigationDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TuskerNavigationDelegate.swift; sourceTree = "<group>"; };
|
||||||
D6C693FB2162FE6F007D6A6D /* LoadingViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoadingViewController.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>"; };
|
D6C693FD2162FEEA007D6A6D /* UIViewController+Children.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIViewController+Children.swift"; sourceTree = "<group>"; };
|
||||||
|
@ -925,6 +927,7 @@
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
D6C82B4025C5BB7E0017F1E6 /* ExploreViewController.swift */,
|
D6C82B4025C5BB7E0017F1E6 /* ExploreViewController.swift */,
|
||||||
|
D68E525C24A3E8F00054355A /* InlineTrendsViewController.swift */,
|
||||||
D6945C3323AC6431005C403C /* AddSavedHashtagViewController.swift */,
|
D6945C3323AC6431005C403C /* AddSavedHashtagViewController.swift */,
|
||||||
D6093F9A25BDD4B9004811E6 /* HashtagSearchResultsViewController.swift */,
|
D6093F9A25BDD4B9004811E6 /* HashtagSearchResultsViewController.swift */,
|
||||||
D6945C3923AC75E2005C403C /* FindInstanceViewController.swift */,
|
D6945C3923AC75E2005C403C /* FindInstanceViewController.swift */,
|
||||||
|
@ -939,6 +942,7 @@
|
||||||
D693A72925CF8C1E003A14E2 /* ProfileDirectoryViewController.swift */,
|
D693A72925CF8C1E003A14E2 /* ProfileDirectoryViewController.swift */,
|
||||||
D693A72D25CF91C6003A14E2 /* FeaturedProfileCollectionViewCell.swift */,
|
D693A72D25CF91C6003A14E2 /* FeaturedProfileCollectionViewCell.swift */,
|
||||||
D693A72E25CF91C6003A14E2 /* FeaturedProfileCollectionViewCell.xib */,
|
D693A72E25CF91C6003A14E2 /* FeaturedProfileCollectionViewCell.xib */,
|
||||||
|
D6C3F4FA299035650009FCFF /* TrendsViewController.swift */,
|
||||||
);
|
);
|
||||||
path = Explore;
|
path = Explore;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -1410,7 +1414,6 @@
|
||||||
D6BC9DD8232D8BCA002CA326 /* Search */ = {
|
D6BC9DD8232D8BCA002CA326 /* Search */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
D68E525C24A3E8F00054355A /* SearchViewController.swift */,
|
|
||||||
D6BC9DD9232D8BE5002CA326 /* SearchResultsViewController.swift */,
|
D6BC9DD9232D8BE5002CA326 /* SearchResultsViewController.swift */,
|
||||||
);
|
);
|
||||||
path = Search;
|
path = Search;
|
||||||
|
@ -1959,7 +1962,7 @@
|
||||||
D61F759229365C6C00C0B37F /* CollectionViewController.swift in Sources */,
|
D61F759229365C6C00C0B37F /* CollectionViewController.swift in Sources */,
|
||||||
D6DD8FFD298495A8002AD3FD /* LogoutService.swift in Sources */,
|
D6DD8FFD298495A8002AD3FD /* LogoutService.swift in Sources */,
|
||||||
04DACE8C212CB14B009840C4 /* MainTabBarViewController.swift in Sources */,
|
04DACE8C212CB14B009840C4 /* MainTabBarViewController.swift in Sources */,
|
||||||
D68E525D24A3E8F00054355A /* SearchViewController.swift in Sources */,
|
D68E525D24A3E8F00054355A /* InlineTrendsViewController.swift in Sources */,
|
||||||
D61F75BB293C183100C0B37F /* HTMLConverter.swift in Sources */,
|
D61F75BB293C183100C0B37F /* HTMLConverter.swift in Sources */,
|
||||||
D61F75A5293ABD6F00C0B37F /* EditFilterView.swift in Sources */,
|
D61F75A5293ABD6F00C0B37F /* EditFilterView.swift in Sources */,
|
||||||
D6BC9DB1232C61BC002CA326 /* NotificationsPageViewController.swift in Sources */,
|
D6BC9DB1232C61BC002CA326 /* NotificationsPageViewController.swift in Sources */,
|
||||||
|
@ -2178,6 +2181,7 @@
|
||||||
D6E77D0B286D426E00D8B732 /* TrendingLinkCardCollectionViewCell.swift in Sources */,
|
D6E77D0B286D426E00D8B732 /* TrendingLinkCardCollectionViewCell.swift in Sources */,
|
||||||
D6114E1127F899B30080E273 /* TrendingLinksViewController.swift in Sources */,
|
D6114E1127F899B30080E273 /* TrendingLinksViewController.swift in Sources */,
|
||||||
D65B4B58297203A700DABDFB /* ReportSelectRulesView.swift in Sources */,
|
D65B4B58297203A700DABDFB /* ReportSelectRulesView.swift in Sources */,
|
||||||
|
D6C3F4FB299035650009FCFF /* TrendsViewController.swift in Sources */,
|
||||||
D6B81F442560390300F6E31D /* MenuController.swift in Sources */,
|
D6B81F442560390300F6E31D /* MenuController.swift in Sources */,
|
||||||
D65B4B542971F71D00DABDFB /* EditedReport.swift in Sources */,
|
D65B4B542971F71D00DABDFB /* EditedReport.swift in Sources */,
|
||||||
D65234E12561AA68001AF9CF /* NotificationsTableViewController.swift in Sources */,
|
D65234E12561AA68001AF9CF /* NotificationsTableViewController.swift in Sources */,
|
||||||
|
|
|
@ -80,7 +80,7 @@ class Preferences: Codable, ObservableObject {
|
||||||
self.defaultNotificationsMode = try container.decode(NotificationsMode.self, forKey: .defaultNotificationsType)
|
self.defaultNotificationsMode = try container.decode(NotificationsMode.self, forKey: .defaultNotificationsType)
|
||||||
self.grayscaleImages = try container.decodeIfPresent(Bool.self, forKey: .grayscaleImages) ?? false
|
self.grayscaleImages = try container.decodeIfPresent(Bool.self, forKey: .grayscaleImages) ?? false
|
||||||
self.disableInfiniteScrolling = try container.decodeIfPresent(Bool.self, forKey: .disableInfiniteScrolling) ?? false
|
self.disableInfiniteScrolling = try container.decodeIfPresent(Bool.self, forKey: .disableInfiniteScrolling) ?? false
|
||||||
self.hideDiscover = try container.decodeIfPresent(Bool.self, forKey: .hideDiscover) ?? false
|
self.hideTrends = try container.decodeIfPresent(Bool.self, forKey: .hideTrends) ?? false
|
||||||
|
|
||||||
self.statusContentType = try container.decode(StatusContentType.self, forKey: .statusContentType)
|
self.statusContentType = try container.decode(StatusContentType.self, forKey: .statusContentType)
|
||||||
|
|
||||||
|
@ -130,7 +130,7 @@ class Preferences: Codable, ObservableObject {
|
||||||
try container.encode(defaultNotificationsMode, forKey: .defaultNotificationsType)
|
try container.encode(defaultNotificationsMode, forKey: .defaultNotificationsType)
|
||||||
try container.encode(grayscaleImages, forKey: .grayscaleImages)
|
try container.encode(grayscaleImages, forKey: .grayscaleImages)
|
||||||
try container.encode(disableInfiniteScrolling, forKey: .disableInfiniteScrolling)
|
try container.encode(disableInfiniteScrolling, forKey: .disableInfiniteScrolling)
|
||||||
try container.encode(hideDiscover, forKey: .hideDiscover)
|
try container.encode(hideTrends, forKey: .hideTrends)
|
||||||
|
|
||||||
try container.encode(statusContentType, forKey: .statusContentType)
|
try container.encode(statusContentType, forKey: .statusContentType)
|
||||||
|
|
||||||
|
@ -190,7 +190,7 @@ class Preferences: Codable, ObservableObject {
|
||||||
@Published var defaultNotificationsMode = NotificationsMode.allNotifications
|
@Published var defaultNotificationsMode = NotificationsMode.allNotifications
|
||||||
@Published var grayscaleImages = false
|
@Published var grayscaleImages = false
|
||||||
@Published var disableInfiniteScrolling = false
|
@Published var disableInfiniteScrolling = false
|
||||||
@Published var hideDiscover = false
|
@Published var hideTrends = false
|
||||||
|
|
||||||
// MARK: Advanced
|
// MARK: Advanced
|
||||||
@Published var statusContentType: StatusContentType = .plain
|
@Published var statusContentType: StatusContentType = .plain
|
||||||
|
@ -241,7 +241,7 @@ class Preferences: Codable, ObservableObject {
|
||||||
case defaultNotificationsType
|
case defaultNotificationsType
|
||||||
case grayscaleImages
|
case grayscaleImages
|
||||||
case disableInfiniteScrolling
|
case disableInfiniteScrolling
|
||||||
case hideDiscover
|
case hideTrends = "hideDiscover"
|
||||||
|
|
||||||
case statusContentType
|
case statusContentType
|
||||||
|
|
||||||
|
|
|
@ -82,7 +82,7 @@ class AuxiliarySceneDelegate: UIResponder, UIWindowSceneDelegate {
|
||||||
return NotificationsPageViewController(initialMode: mode, mastodonController: mastodonController)
|
return NotificationsPageViewController(initialMode: mode, mastodonController: mastodonController)
|
||||||
|
|
||||||
case .search:
|
case .search:
|
||||||
return SearchViewController(mastodonController: mastodonController)
|
return InlineTrendsViewController(mastodonController: mastodonController)
|
||||||
|
|
||||||
case .bookmarks:
|
case .bookmarks:
|
||||||
return BookmarksViewController(mastodonController: mastodonController)
|
return BookmarksViewController(mastodonController: mastodonController)
|
||||||
|
|
|
@ -156,7 +156,7 @@ class ExploreViewController: UIViewController, UICollectionViewDelegate, Collect
|
||||||
snapshot.appendSections(Section.allCases.filter { $0 != .discover })
|
snapshot.appendSections(Section.allCases.filter { $0 != .discover })
|
||||||
snapshot.appendItems([.bookmarks, .favorites], toSection: .bookmarks)
|
snapshot.appendItems([.bookmarks, .favorites], toSection: .bookmarks)
|
||||||
if mastodonController.instanceFeatures.trends,
|
if mastodonController.instanceFeatures.trends,
|
||||||
!Preferences.shared.hideDiscover {
|
!Preferences.shared.hideTrends {
|
||||||
addDiscoverSection(to: &snapshot)
|
addDiscoverSection(to: &snapshot)
|
||||||
}
|
}
|
||||||
snapshot.appendItems([.addList], toSection: .lists)
|
snapshot.appendItems([.addList], toSection: .lists)
|
||||||
|
@ -175,19 +175,17 @@ class ExploreViewController: UIViewController, UICollectionViewDelegate, Collect
|
||||||
|
|
||||||
private func addDiscoverSection(to snapshot: inout NSDiffableDataSourceSnapshot<Section, Item>) {
|
private func addDiscoverSection(to snapshot: inout NSDiffableDataSourceSnapshot<Section, Item>) {
|
||||||
snapshot.insertSections([.discover], afterSection: .bookmarks)
|
snapshot.insertSections([.discover], afterSection: .bookmarks)
|
||||||
snapshot.appendItems([.trendingTags, .profileDirectory], toSection: .discover)
|
snapshot.appendItems([.trends], toSection: .discover)
|
||||||
if mastodonController.instanceFeatures.trendingStatusesAndLinks {
|
|
||||||
snapshot.insertItems([.trendingStatuses], beforeItem: .trendingTags)
|
|
||||||
snapshot.insertItems([.trendingLinks], afterItem: .trendingTags)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private func ownInstanceLoaded(_ instance: Instance) {
|
private func ownInstanceLoaded(_ instance: Instance) {
|
||||||
var snapshot = self.dataSource.snapshot()
|
var snapshot = self.dataSource.snapshot()
|
||||||
if mastodonController.instanceFeatures.trends,
|
if mastodonController.instanceFeatures.trends,
|
||||||
!snapshot.sectionIdentifiers.contains(.discover) {
|
!snapshot.sectionIdentifiers.contains(.discover) {
|
||||||
snapshot.insertSections([.discover], afterSection: .bookmarks)
|
addDiscoverSection(to: &snapshot)
|
||||||
snapshot.appendItems([.trendingTags, .profileDirectory], toSection: .discover)
|
} else if !mastodonController.instanceFeatures.trends,
|
||||||
|
snapshot.sectionIdentifiers.contains(.discover) {
|
||||||
|
snapshot.deleteSections([.discover])
|
||||||
}
|
}
|
||||||
self.dataSource.apply(snapshot)
|
self.dataSource.apply(snapshot)
|
||||||
}
|
}
|
||||||
|
@ -250,7 +248,7 @@ class ExploreViewController: UIViewController, UICollectionViewDelegate, Collect
|
||||||
@objc private func preferencesChanged() {
|
@objc private func preferencesChanged() {
|
||||||
var snapshot = dataSource.snapshot()
|
var snapshot = dataSource.snapshot()
|
||||||
let hasSection = snapshot.sectionIdentifiers.contains(.discover)
|
let hasSection = snapshot.sectionIdentifiers.contains(.discover)
|
||||||
let hide = Preferences.shared.hideDiscover
|
let hide = Preferences.shared.hideTrends
|
||||||
if hasSection && hide {
|
if hasSection && hide {
|
||||||
snapshot.deleteSections([.discover])
|
snapshot.deleteSections([.discover])
|
||||||
} else if !hasSection && !hide {
|
} else if !hasSection && !hide {
|
||||||
|
@ -339,17 +337,8 @@ class ExploreViewController: UIViewController, UICollectionViewDelegate, Collect
|
||||||
case .favorites:
|
case .favorites:
|
||||||
show(FavoritesViewController(mastodonController: mastodonController), sender: nil)
|
show(FavoritesViewController(mastodonController: mastodonController), sender: nil)
|
||||||
|
|
||||||
case .trendingStatuses:
|
case .trends:
|
||||||
show(TrendingStatusesViewController(mastodonController: mastodonController), sender: nil)
|
show(TrendsViewController(mastodonController: mastodonController), sender: nil)
|
||||||
|
|
||||||
case .trendingTags:
|
|
||||||
show(TrendingHashtagsViewController(mastodonController: mastodonController), sender: nil)
|
|
||||||
|
|
||||||
case .trendingLinks:
|
|
||||||
show(TrendingLinksViewController(mastodonController: mastodonController), sender: nil)
|
|
||||||
|
|
||||||
case .profileDirectory:
|
|
||||||
show(ProfileDirectoryViewController(mastodonController: mastodonController), sender: nil)
|
|
||||||
|
|
||||||
case let .list(list):
|
case let .list(list):
|
||||||
show(ListTimelineViewController(for: list, mastodonController: mastodonController), sender: nil)
|
show(ListTimelineViewController(for: list, mastodonController: mastodonController), sender: nil)
|
||||||
|
@ -398,7 +387,7 @@ extension ExploreViewController {
|
||||||
case .bookmarks:
|
case .bookmarks:
|
||||||
return nil
|
return nil
|
||||||
case .discover:
|
case .discover:
|
||||||
return NSLocalizedString("Discover", comment: "discover section title")
|
return nil
|
||||||
case .lists:
|
case .lists:
|
||||||
return NSLocalizedString("Lists", comment: "explore lists section title")
|
return NSLocalizedString("Lists", comment: "explore lists section title")
|
||||||
case .savedHashtags:
|
case .savedHashtags:
|
||||||
|
@ -412,10 +401,7 @@ extension ExploreViewController {
|
||||||
enum Item: Hashable {
|
enum Item: Hashable {
|
||||||
case bookmarks
|
case bookmarks
|
||||||
case favorites
|
case favorites
|
||||||
case trendingStatuses
|
case trends
|
||||||
case trendingTags
|
|
||||||
case trendingLinks
|
|
||||||
case profileDirectory
|
|
||||||
case list(List)
|
case list(List)
|
||||||
case addList
|
case addList
|
||||||
case savedHashtag(Hashtag)
|
case savedHashtag(Hashtag)
|
||||||
|
@ -429,14 +415,8 @@ extension ExploreViewController {
|
||||||
return NSLocalizedString("Bookmarks", comment: "bookmarks nav item title")
|
return NSLocalizedString("Bookmarks", comment: "bookmarks nav item title")
|
||||||
case .favorites:
|
case .favorites:
|
||||||
return NSLocalizedString("Favorites", comment: "favorites nav item title")
|
return NSLocalizedString("Favorites", comment: "favorites nav item title")
|
||||||
case .trendingStatuses:
|
case .trends:
|
||||||
return NSLocalizedString("Trending Posts", comment: "trending statuses nav item title")
|
return NSLocalizedString("Trends", comment: "trends nav item title")
|
||||||
case .trendingTags:
|
|
||||||
return NSLocalizedString("Trending Hashtags", comment: "trending hashtags nav item title")
|
|
||||||
case .trendingLinks:
|
|
||||||
return NSLocalizedString("Trending Links", comment: "trending links nav item title")
|
|
||||||
case .profileDirectory:
|
|
||||||
return NSLocalizedString("Profile Directory", comment: "profile directory nav item title")
|
|
||||||
case let .list(list):
|
case let .list(list):
|
||||||
return list.title
|
return list.title
|
||||||
case .addList:
|
case .addList:
|
||||||
|
@ -459,14 +439,8 @@ extension ExploreViewController {
|
||||||
name = "bookmark.fill"
|
name = "bookmark.fill"
|
||||||
case .favorites:
|
case .favorites:
|
||||||
name = "star.fill"
|
name = "star.fill"
|
||||||
case .trendingStatuses:
|
case .trends:
|
||||||
name = "doc.text.image"
|
name = "chart.line.uptrend.xyaxis"
|
||||||
case .trendingTags:
|
|
||||||
name = "number"
|
|
||||||
case .trendingLinks:
|
|
||||||
name = "link"
|
|
||||||
case .profileDirectory:
|
|
||||||
name = "person.2.fill"
|
|
||||||
case .list(_):
|
case .list(_):
|
||||||
name = "list.bullet"
|
name = "list.bullet"
|
||||||
case .addList, .addSavedHashtag:
|
case .addList, .addSavedHashtag:
|
||||||
|
@ -487,13 +461,7 @@ extension ExploreViewController {
|
||||||
return true
|
return true
|
||||||
case (.favorites, .favorites):
|
case (.favorites, .favorites):
|
||||||
return true
|
return true
|
||||||
case (.trendingStatuses, .trendingStatuses):
|
case (.trends, .trends):
|
||||||
return true
|
|
||||||
case (.trendingTags, .trendingTags):
|
|
||||||
return true
|
|
||||||
case (.trendingLinks, .trendingLinks):
|
|
||||||
return true
|
|
||||||
case (.profileDirectory, .profileDirectory):
|
|
||||||
return true
|
return true
|
||||||
case let (.list(a), .list(b)):
|
case let (.list(a), .list(b)):
|
||||||
return a.id == b.id && a.title == b.title
|
return a.id == b.id && a.title == b.title
|
||||||
|
@ -518,14 +486,8 @@ extension ExploreViewController {
|
||||||
hasher.combine("bookmarks")
|
hasher.combine("bookmarks")
|
||||||
case .favorites:
|
case .favorites:
|
||||||
hasher.combine("favorites")
|
hasher.combine("favorites")
|
||||||
case .trendingStatuses:
|
case .trends:
|
||||||
hasher.combine("trendingStatuses")
|
hasher.combine("trends")
|
||||||
case .trendingTags:
|
|
||||||
hasher.combine("trendingTags")
|
|
||||||
case .trendingLinks:
|
|
||||||
hasher.combine("trendingLinks")
|
|
||||||
case .profileDirectory:
|
|
||||||
hasher.combine("profileDirectory")
|
|
||||||
case let .list(list):
|
case let .list(list):
|
||||||
hasher.combine("list")
|
hasher.combine("list")
|
||||||
hasher.combine(list.id)
|
hasher.combine(list.id)
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
//
|
||||||
|
// InlineTrendsViewController.swift
|
||||||
|
// Tusker
|
||||||
|
//
|
||||||
|
// Created by Shadowfacts on 6/24/20.
|
||||||
|
// Copyright © 2020 Shadowfacts. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
class InlineTrendsViewController: UIViewController {
|
||||||
|
|
||||||
|
weak var mastodonController: MastodonController!
|
||||||
|
|
||||||
|
var resultsController: SearchResultsViewController!
|
||||||
|
var searchController: UISearchController!
|
||||||
|
|
||||||
|
var searchControllerStatusOnAppearance: Bool? = nil
|
||||||
|
|
||||||
|
init(mastodonController: MastodonController) {
|
||||||
|
self.mastodonController = mastodonController
|
||||||
|
|
||||||
|
super.init(nibName: nil, bundle: nil)
|
||||||
|
|
||||||
|
title = NSLocalizedString("Explore", comment: "explore tab title")
|
||||||
|
}
|
||||||
|
|
||||||
|
required init?(coder: NSCoder) {
|
||||||
|
fatalError("init(coder:) has not been implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
override func viewDidLoad() {
|
||||||
|
super.viewDidLoad()
|
||||||
|
|
||||||
|
resultsController = SearchResultsViewController(mastodonController: mastodonController)
|
||||||
|
resultsController.exploreNavigationController = self.navigationController
|
||||||
|
searchController = UISearchController(searchResultsController: resultsController)
|
||||||
|
searchController.obscuresBackgroundDuringPresentation = true
|
||||||
|
if #available(iOS 16.0, *) {
|
||||||
|
searchController.scopeBarActivation = .onSearchActivation
|
||||||
|
}
|
||||||
|
searchController.searchBar.autocapitalizationType = .none
|
||||||
|
searchController.searchBar.delegate = resultsController
|
||||||
|
searchController.searchBar.scopeButtonTitles = SearchResultsViewController.Scope.allCases.map(\.title)
|
||||||
|
searchController.hidesNavigationBarDuringPresentation = false
|
||||||
|
definesPresentationContext = true
|
||||||
|
|
||||||
|
navigationItem.searchController = searchController
|
||||||
|
navigationItem.hidesSearchBarWhenScrolling = false
|
||||||
|
if #available(iOS 16.0, *) {
|
||||||
|
navigationItem.preferredSearchBarPlacement = .stacked
|
||||||
|
}
|
||||||
|
|
||||||
|
let trends = TrendsViewController(mastodonController: mastodonController)
|
||||||
|
trends.view.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
addChild(trends)
|
||||||
|
view.addSubview(trends.view)
|
||||||
|
NSLayoutConstraint.activate([
|
||||||
|
trends.view.leadingAnchor.constraint(equalTo: view.leadingAnchor),
|
||||||
|
trends.view.trailingAnchor.constraint(equalTo: view.trailingAnchor),
|
||||||
|
trends.view.topAnchor.constraint(equalTo: view.topAnchor),
|
||||||
|
trends.view.bottomAnchor.constraint(equalTo: view.bottomAnchor),
|
||||||
|
])
|
||||||
|
trends.didMove(toParent: self)
|
||||||
|
}
|
||||||
|
|
||||||
|
override func viewDidAppear(_ animated: Bool) {
|
||||||
|
super.viewDidAppear(animated)
|
||||||
|
|
||||||
|
// this is a workaround for the issue that setting isActive on a search controller that is not visible
|
||||||
|
// does not cause it to automatically become active once it becomes visible
|
||||||
|
// see FB7814561
|
||||||
|
if let active = searchControllerStatusOnAppearance {
|
||||||
|
searchController.isActive = active
|
||||||
|
searchControllerStatusOnAppearance = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,42 +1,41 @@
|
||||||
//
|
//
|
||||||
// SearchViewController.swift
|
// TrendsViewController.swift
|
||||||
// Tusker
|
// Tusker
|
||||||
//
|
//
|
||||||
// Created by Shadowfacts on 6/24/20.
|
// Created by Shadowfacts on 2/5/23.
|
||||||
// Copyright © 2020 Shadowfacts. All rights reserved.
|
// Copyright © 2023 Shadowfacts. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
import Pachyderm
|
import Pachyderm
|
||||||
import SafariServices
|
import SafariServices
|
||||||
import WebURLFoundationExtras
|
|
||||||
|
|
||||||
class SearchViewController: UIViewController, CollectionViewController {
|
class TrendsViewController: UIViewController, CollectionViewController {
|
||||||
|
|
||||||
weak var mastodonController: MastodonController!
|
let mastodonController: MastodonController
|
||||||
|
|
||||||
var collectionView: UICollectionView!
|
var collectionView: UICollectionView!
|
||||||
private var dataSource: UICollectionViewDiffableDataSource<Section, Item>!
|
private var dataSource: UICollectionViewDiffableDataSource<Section, Item>!
|
||||||
|
|
||||||
var resultsController: SearchResultsViewController!
|
|
||||||
var searchController: UISearchController!
|
|
||||||
|
|
||||||
var searchControllerStatusOnAppearance: Bool? = nil
|
|
||||||
|
|
||||||
private var loadTask: Task<Void, Never>?
|
private var loadTask: Task<Void, Never>?
|
||||||
|
|
||||||
|
private var isShowingTrends = false
|
||||||
|
private var shouldShowTrends: Bool {
|
||||||
|
mastodonController.instanceFeatures.trends && !Preferences.shared.hideTrends
|
||||||
|
}
|
||||||
|
|
||||||
init(mastodonController: MastodonController) {
|
init(mastodonController: MastodonController) {
|
||||||
self.mastodonController = mastodonController
|
self.mastodonController = mastodonController
|
||||||
|
|
||||||
super.init(nibName: nil, bundle: nil)
|
super.init(nibName: nil, bundle: nil)
|
||||||
|
|
||||||
title = NSLocalizedString("Explore", comment: "explore tab title")
|
title = "Trends"
|
||||||
}
|
}
|
||||||
|
|
||||||
required init?(coder: NSCoder) {
|
required init?(coder: NSCoder) {
|
||||||
fatalError("init(coder:) has not been implemented")
|
fatalError("init(coder:) has not been implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
override func viewDidLoad() {
|
override func viewDidLoad() {
|
||||||
super.viewDidLoad()
|
super.viewDidLoad()
|
||||||
|
|
||||||
|
@ -53,9 +52,9 @@ class SearchViewController: UIViewController, CollectionViewController {
|
||||||
let item = NSCollectionLayoutItem(layoutSize: itemSize)
|
let item = NSCollectionLayoutItem(layoutSize: itemSize)
|
||||||
let groupSize = NSCollectionLayoutSize(widthDimension: .absolute(250), heightDimension: .estimated(280))
|
let groupSize = NSCollectionLayoutSize(widthDimension: .absolute(250), heightDimension: .estimated(280))
|
||||||
let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item])
|
let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item])
|
||||||
group.edgeSpacing = NSCollectionLayoutEdgeSpacing(leading: .fixed(8), top: nil, trailing: .fixed(8), bottom: nil)
|
group.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 8, bottom: 0, trailing: 8)
|
||||||
let section = NSCollectionLayoutSection(group: group)
|
let section = NSCollectionLayoutSection(group: group)
|
||||||
section.orthogonalScrollingBehavior = .continuousGroupLeadingBoundary
|
section.orthogonalScrollingBehavior = .groupPaging
|
||||||
section.boundarySupplementaryItems = [
|
section.boundarySupplementaryItems = [
|
||||||
NSCollectionLayoutBoundarySupplementaryItem(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .estimated(12)), elementKind: UICollectionView.elementKindSectionHeader, alignment: .topLeading)
|
NSCollectionLayoutBoundarySupplementaryItem(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .estimated(12)), elementKind: UICollectionView.elementKindSectionHeader, alignment: .topLeading)
|
||||||
]
|
]
|
||||||
|
@ -67,9 +66,9 @@ class SearchViewController: UIViewController, CollectionViewController {
|
||||||
let item = NSCollectionLayoutItem(layoutSize: itemSize)
|
let item = NSCollectionLayoutItem(layoutSize: itemSize)
|
||||||
let groupSize = NSCollectionLayoutSize(widthDimension: .absolute(350), heightDimension: .absolute(250))
|
let groupSize = NSCollectionLayoutSize(widthDimension: .absolute(350), heightDimension: .absolute(250))
|
||||||
let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item])
|
let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item])
|
||||||
group.edgeSpacing = NSCollectionLayoutEdgeSpacing(leading: .fixed(8), top: nil, trailing: .fixed(8), bottom: nil)
|
group.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 8, bottom: 0, trailing: 8)
|
||||||
let section = NSCollectionLayoutSection(group: group)
|
let section = NSCollectionLayoutSection(group: group)
|
||||||
section.orthogonalScrollingBehavior = .continuousGroupLeadingBoundary
|
section.orthogonalScrollingBehavior = .groupPaging
|
||||||
section.boundarySupplementaryItems = [
|
section.boundarySupplementaryItems = [
|
||||||
NSCollectionLayoutBoundarySupplementaryItem(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .estimated(12)), elementKind: UICollectionView.elementKindSectionHeader, alignment: .topLeading)
|
NSCollectionLayoutBoundarySupplementaryItem(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .estimated(12)), elementKind: UICollectionView.elementKindSectionHeader, alignment: .topLeading)
|
||||||
]
|
]
|
||||||
|
@ -92,53 +91,9 @@ class SearchViewController: UIViewController, CollectionViewController {
|
||||||
|
|
||||||
dataSource = createDataSource()
|
dataSource = createDataSource()
|
||||||
|
|
||||||
resultsController = SearchResultsViewController(mastodonController: mastodonController)
|
|
||||||
resultsController.exploreNavigationController = self.navigationController
|
|
||||||
searchController = UISearchController(searchResultsController: resultsController)
|
|
||||||
searchController.obscuresBackgroundDuringPresentation = true
|
|
||||||
if #available(iOS 16.0, *) {
|
|
||||||
searchController.scopeBarActivation = .onSearchActivation
|
|
||||||
}
|
|
||||||
searchController.searchBar.autocapitalizationType = .none
|
|
||||||
searchController.searchBar.delegate = resultsController
|
|
||||||
searchController.searchBar.scopeButtonTitles = SearchResultsViewController.Scope.allCases.map(\.title)
|
|
||||||
searchController.hidesNavigationBarDuringPresentation = false
|
|
||||||
definesPresentationContext = true
|
|
||||||
|
|
||||||
navigationItem.searchController = searchController
|
|
||||||
navigationItem.hidesSearchBarWhenScrolling = false
|
|
||||||
if #available(iOS 16.0, *) {
|
|
||||||
navigationItem.preferredSearchBarPlacement = .stacked
|
|
||||||
}
|
|
||||||
|
|
||||||
NotificationCenter.default.addObserver(self, selector: #selector(preferencesChanged), name: .preferencesChanged, object: nil)
|
NotificationCenter.default.addObserver(self, selector: #selector(preferencesChanged), name: .preferencesChanged, object: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
override func viewWillAppear(_ animated: Bool) {
|
|
||||||
super.viewWillAppear(animated)
|
|
||||||
|
|
||||||
clearSelectionOnAppear(animated: animated)
|
|
||||||
|
|
||||||
loadTask?.cancel()
|
|
||||||
loadTask = Task(priority: .userInitiated) {
|
|
||||||
if (try? await mastodonController.getOwnInstance()) != nil {
|
|
||||||
await applySnapshot()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override func viewDidAppear(_ animated: Bool) {
|
|
||||||
super.viewDidAppear(animated)
|
|
||||||
|
|
||||||
// this is a workaround for the issue that setting isActive on a search controller that is not visible
|
|
||||||
// does not cause it to automatically become active once it becomes visible
|
|
||||||
// see FB7814561
|
|
||||||
if let active = searchControllerStatusOnAppearance {
|
|
||||||
searchController.isActive = active
|
|
||||||
searchControllerStatusOnAppearance = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private func createDataSource() -> UICollectionViewDiffableDataSource<Section, Item> {
|
private func createDataSource() -> UICollectionViewDiffableDataSource<Section, Item> {
|
||||||
let sectionHeaderCell = UICollectionView.SupplementaryRegistration<UICollectionViewListCell>(elementKind: UICollectionView.elementKindSectionHeader) { [unowned self] (headerView, collectionView, indexPath) in
|
let sectionHeaderCell = UICollectionView.SupplementaryRegistration<UICollectionViewListCell>(elementKind: UICollectionView.elementKindSectionHeader) { [unowned self] (headerView, collectionView, indexPath) in
|
||||||
let section = self.dataSource.snapshot().sectionIdentifiers[indexPath.section]
|
let section = self.dataSource.snapshot().sectionIdentifiers[indexPath.section]
|
||||||
|
@ -188,10 +143,27 @@ class SearchViewController: UIViewController, CollectionViewController {
|
||||||
return dataSource
|
return dataSource
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override func viewWillAppear(_ animated: Bool) {
|
||||||
|
super.viewWillAppear(animated)
|
||||||
|
|
||||||
|
clearSelectionOnAppear(animated: animated)
|
||||||
|
|
||||||
|
if loadTask == nil {
|
||||||
|
loadTask = Task(priority: .userInitiated) {
|
||||||
|
if (try? await mastodonController.getOwnInstance()) != nil {
|
||||||
|
await loadTrends()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
private func applySnapshot() async {
|
private func loadTrends() async {
|
||||||
guard mastodonController.instanceFeatures.trends,
|
guard isShowingTrends != shouldShowTrends else {
|
||||||
!Preferences.shared.hideDiscover else {
|
return
|
||||||
|
}
|
||||||
|
isShowingTrends = shouldShowTrends
|
||||||
|
guard shouldShowTrends else {
|
||||||
await dataSource.apply(NSDiffableDataSourceSnapshot())
|
await dataSource.apply(NSDiffableDataSourceSnapshot())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -244,9 +216,11 @@ class SearchViewController: UIViewController, CollectionViewController {
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc private func preferencesChanged() {
|
@objc private func preferencesChanged() {
|
||||||
loadTask?.cancel()
|
if isShowingTrends != shouldShowTrends {
|
||||||
loadTask = Task {
|
loadTask?.cancel()
|
||||||
await applySnapshot()
|
loadTask = Task {
|
||||||
|
await loadTrends()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -273,10 +247,9 @@ class SearchViewController: UIViewController, CollectionViewController {
|
||||||
self.showToast(configuration: config, animated: true)
|
self.showToast(configuration: config, animated: true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension SearchViewController {
|
extension TrendsViewController {
|
||||||
enum Section {
|
enum Section {
|
||||||
case trendingHashtags
|
case trendingHashtags
|
||||||
case trendingLinks
|
case trendingLinks
|
||||||
|
@ -302,7 +275,7 @@ extension SearchViewController {
|
||||||
case link(Card)
|
case link(Card)
|
||||||
case account(String, Suggestion.Source)
|
case account(String, Suggestion.Source)
|
||||||
|
|
||||||
static func == (lhs: SearchViewController.Item, rhs: SearchViewController.Item) -> Bool {
|
static func == (lhs: Item, rhs: Item) -> Bool {
|
||||||
switch (lhs, rhs) {
|
switch (lhs, rhs) {
|
||||||
case let (.status(a, _), .status(b, _)):
|
case let (.status(a, _), .status(b, _)):
|
||||||
return a == b
|
return a == b
|
||||||
|
@ -336,7 +309,7 @@ extension SearchViewController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension SearchViewController: UICollectionViewDelegate {
|
extension TrendsViewController: UICollectionViewDelegate {
|
||||||
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
|
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
|
||||||
guard let item = dataSource.itemIdentifier(for: indexPath) else {
|
guard let item = dataSource.itemIdentifier(for: indexPath) else {
|
||||||
return
|
return
|
||||||
|
@ -443,7 +416,7 @@ extension SearchViewController: UICollectionViewDelegate {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension SearchViewController: UICollectionViewDragDelegate {
|
extension TrendsViewController: UICollectionViewDragDelegate {
|
||||||
func collectionView(_ collectionView: UICollectionView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem] {
|
func collectionView(_ collectionView: UICollectionView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem] {
|
||||||
guard let item = dataSource.itemIdentifier(for: indexPath) else {
|
guard let item = dataSource.itemIdentifier(for: indexPath) else {
|
||||||
return []
|
return []
|
||||||
|
@ -490,17 +463,17 @@ extension SearchViewController: UICollectionViewDragDelegate {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension SearchViewController: TuskerNavigationDelegate {
|
extension TrendsViewController: TuskerNavigationDelegate {
|
||||||
var apiController: MastodonController! { mastodonController }
|
var apiController: MastodonController! { mastodonController }
|
||||||
}
|
}
|
||||||
|
|
||||||
extension SearchViewController: ToastableViewController {
|
extension TrendsViewController: ToastableViewController {
|
||||||
}
|
}
|
||||||
|
|
||||||
extension SearchViewController: MenuActionProvider {
|
extension TrendsViewController: MenuActionProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
extension SearchViewController: StatusCollectionViewCellDelegate {
|
extension TrendsViewController: StatusCollectionViewCellDelegate {
|
||||||
func statusCellNeedsReconfigure(_ cell: StatusCollectionViewCell, animated: Bool, completion: (() -> Void)?) {
|
func statusCellNeedsReconfigure(_ cell: StatusCollectionViewCell, animated: Bool, completion: (() -> Void)?) {
|
||||||
if let indexPath = collectionView.indexPath(for: cell) {
|
if let indexPath = collectionView.indexPath(for: cell) {
|
||||||
var snapshot = dataSource.snapshot()
|
var snapshot = dataSource.snapshot()
|
|
@ -41,7 +41,7 @@ class MainSidebarViewController: UIViewController {
|
||||||
}
|
}
|
||||||
|
|
||||||
var exploreTabItems: [Item] {
|
var exploreTabItems: [Item] {
|
||||||
var items: [Item] = [.explore, .bookmarks, .favorites, .profileDirectory]
|
var items: [Item] = [.explore, .bookmarks, .favorites]
|
||||||
let snapshot = dataSource.snapshot()
|
let snapshot = dataSource.snapshot()
|
||||||
for case let .list(list) in snapshot.itemIdentifiers(inSection: .lists) {
|
for case let .list(list) in snapshot.itemIdentifiers(inSection: .lists) {
|
||||||
items.append(.list(list))
|
items.append(.list(list))
|
||||||
|
@ -104,7 +104,6 @@ class MainSidebarViewController: UIViewController {
|
||||||
select(item: .tab(.timelines), animated: false)
|
select(item: .tab(.timelines), animated: false)
|
||||||
|
|
||||||
NotificationCenter.default.addObserver(self, selector: #selector(reloadSavedInstances), name: .savedInstancesChanged, object: nil)
|
NotificationCenter.default.addObserver(self, selector: #selector(reloadSavedInstances), name: .savedInstancesChanged, object: nil)
|
||||||
NotificationCenter.default.addObserver(self, selector: #selector(preferencesChanged), name: .preferencesChanged, object: nil)
|
|
||||||
|
|
||||||
mastodonController.$lists
|
mastodonController.$lists
|
||||||
.sink { [unowned self] in self.reloadLists($0) }
|
.sink { [unowned self] in self.reloadLists($0) }
|
||||||
|
@ -166,7 +165,7 @@ class MainSidebarViewController: UIViewController {
|
||||||
|
|
||||||
private func applyInitialSnapshot() {
|
private func applyInitialSnapshot() {
|
||||||
var snapshot = NSDiffableDataSourceSnapshot<Section, Item>()
|
var snapshot = NSDiffableDataSourceSnapshot<Section, Item>()
|
||||||
snapshot.appendSections(Section.allCases.filter { $0 != .discover })
|
snapshot.appendSections(Section.allCases)
|
||||||
snapshot.appendItems([
|
snapshot.appendItems([
|
||||||
.tab(.timelines),
|
.tab(.timelines),
|
||||||
.tab(.notifications),
|
.tab(.notifications),
|
||||||
|
@ -178,36 +177,14 @@ class MainSidebarViewController: UIViewController {
|
||||||
snapshot.appendItems([
|
snapshot.appendItems([
|
||||||
.tab(.compose)
|
.tab(.compose)
|
||||||
], toSection: .compose)
|
], toSection: .compose)
|
||||||
if mastodonController.instanceFeatures.trends,
|
|
||||||
!Preferences.shared.hideDiscover {
|
|
||||||
snapshot.insertSections([.discover], afterSection: .compose)
|
|
||||||
}
|
|
||||||
dataSource.apply(snapshot, animatingDifferences: false)
|
dataSource.apply(snapshot, animatingDifferences: false)
|
||||||
|
|
||||||
applyDiscoverSectionSnapshot()
|
|
||||||
reloadLists(mastodonController.lists)
|
reloadLists(mastodonController.lists)
|
||||||
updateHashtagsSection(followed: mastodonController.followedHashtags)
|
updateHashtagsSection(followed: mastodonController.followedHashtags)
|
||||||
reloadSavedInstances()
|
reloadSavedInstances()
|
||||||
}
|
}
|
||||||
|
|
||||||
private func applyDiscoverSectionSnapshot() {
|
|
||||||
var discoverSnapshot = NSDiffableDataSourceSectionSnapshot<Item>()
|
|
||||||
discoverSnapshot.append([.discoverHeader])
|
|
||||||
discoverSnapshot.append([
|
|
||||||
.profileDirectory,
|
|
||||||
], to: .discoverHeader)
|
|
||||||
dataSource.apply(discoverSnapshot, to: .discover)
|
|
||||||
}
|
|
||||||
|
|
||||||
private func ownInstanceLoaded(_ instance: Instance) {
|
private func ownInstanceLoaded(_ instance: Instance) {
|
||||||
if mastodonController.instanceFeatures.trends {
|
|
||||||
var snapshot = self.dataSource.snapshot()
|
|
||||||
if !snapshot.sectionIdentifiers.contains(.discover) {
|
|
||||||
snapshot.appendSections([.discover])
|
|
||||||
dataSource.apply(snapshot, animatingDifferences: false)
|
|
||||||
}
|
|
||||||
applyDiscoverSectionSnapshot()
|
|
||||||
}
|
|
||||||
let prevSelected = collectionView.indexPathsForSelectedItems
|
let prevSelected = collectionView.indexPathsForSelectedItems
|
||||||
|
|
||||||
if let prevSelected = prevSelected?.first {
|
if let prevSelected = prevSelected?.first {
|
||||||
|
@ -290,22 +267,6 @@ class MainSidebarViewController: UIViewController {
|
||||||
self.dataSource.apply(instancesSnapshot, to: .savedInstances)
|
self.dataSource.apply(instancesSnapshot, to: .savedInstances)
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc private func preferencesChanged() {
|
|
||||||
var snapshot = dataSource.snapshot()
|
|
||||||
let hasSection = snapshot.sectionIdentifiers.contains(.discover)
|
|
||||||
let hide = Preferences.shared.hideDiscover
|
|
||||||
if hasSection && hide {
|
|
||||||
snapshot.deleteSections([.discover])
|
|
||||||
dataSource.apply(snapshot)
|
|
||||||
} else if !hasSection && !hide {
|
|
||||||
snapshot.insertSections([.discover], afterSection: .compose)
|
|
||||||
dataSource.apply(snapshot)
|
|
||||||
applyDiscoverSectionSnapshot()
|
|
||||||
} else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private func returnToPreviousItem() {
|
private func returnToPreviousItem() {
|
||||||
let item = previouslySelectedItem ?? .tab(.timelines)
|
let item = previouslySelectedItem ?? .tab(.timelines)
|
||||||
previouslySelectedItem = nil
|
previouslySelectedItem = nil
|
||||||
|
@ -378,7 +339,6 @@ extension MainSidebarViewController {
|
||||||
enum Section: Int, Hashable, CaseIterable {
|
enum Section: Int, Hashable, CaseIterable {
|
||||||
case tabs
|
case tabs
|
||||||
case compose
|
case compose
|
||||||
case discover
|
|
||||||
case lists
|
case lists
|
||||||
case savedHashtags
|
case savedHashtags
|
||||||
case savedInstances
|
case savedInstances
|
||||||
|
@ -386,7 +346,6 @@ extension MainSidebarViewController {
|
||||||
enum Item: Hashable {
|
enum Item: Hashable {
|
||||||
case tab(MainTabBarViewController.Tab)
|
case tab(MainTabBarViewController.Tab)
|
||||||
case explore, bookmarks, favorites
|
case explore, bookmarks, favorites
|
||||||
case discoverHeader, profileDirectory
|
|
||||||
case listsHeader, list(List), addList
|
case listsHeader, list(List), addList
|
||||||
case savedHashtagsHeader, savedHashtag(Hashtag), addSavedHashtag
|
case savedHashtagsHeader, savedHashtag(Hashtag), addSavedHashtag
|
||||||
case savedInstancesHeader, savedInstance(URL), addSavedInstance
|
case savedInstancesHeader, savedInstance(URL), addSavedInstance
|
||||||
|
@ -401,10 +360,6 @@ extension MainSidebarViewController {
|
||||||
return "Bookmarks"
|
return "Bookmarks"
|
||||||
case .favorites:
|
case .favorites:
|
||||||
return "Favorites"
|
return "Favorites"
|
||||||
case .discoverHeader:
|
|
||||||
return "Discover"
|
|
||||||
case .profileDirectory:
|
|
||||||
return "Profile Directory"
|
|
||||||
case .listsHeader:
|
case .listsHeader:
|
||||||
return "Lists"
|
return "Lists"
|
||||||
case let .list(list):
|
case let .list(list):
|
||||||
|
@ -436,15 +391,13 @@ extension MainSidebarViewController {
|
||||||
return "bookmark"
|
return "bookmark"
|
||||||
case .favorites:
|
case .favorites:
|
||||||
return "star"
|
return "star"
|
||||||
case .profileDirectory:
|
|
||||||
return "person.2.fill"
|
|
||||||
case .list(_):
|
case .list(_):
|
||||||
return "list.bullet"
|
return "list.bullet"
|
||||||
case .savedHashtag(_):
|
case .savedHashtag(_):
|
||||||
return "number"
|
return "number"
|
||||||
case .savedInstance(_):
|
case .savedInstance(_):
|
||||||
return "globe"
|
return "globe"
|
||||||
case .discoverHeader, .listsHeader, .savedHashtagsHeader, .savedInstancesHeader:
|
case .listsHeader, .savedHashtagsHeader, .savedInstancesHeader:
|
||||||
return nil
|
return nil
|
||||||
case .addList, .addSavedHashtag, .addSavedInstance:
|
case .addList, .addSavedHashtag, .addSavedInstance:
|
||||||
return "plus"
|
return "plus"
|
||||||
|
@ -453,7 +406,7 @@ extension MainSidebarViewController {
|
||||||
|
|
||||||
var hasChildren: Bool {
|
var hasChildren: Bool {
|
||||||
switch self {
|
switch self {
|
||||||
case .discoverHeader, .listsHeader, .savedHashtagsHeader, .savedInstancesHeader:
|
case .listsHeader, .savedHashtagsHeader, .savedInstancesHeader:
|
||||||
return true
|
return true
|
||||||
default:
|
default:
|
||||||
return false
|
return false
|
||||||
|
|
|
@ -217,7 +217,7 @@ extension MainSplitViewController: UISplitViewControllerDelegate {
|
||||||
// Make sure viewDidLoad is called so that the searchController/resultsController have been initialized
|
// Make sure viewDidLoad is called so that the searchController/resultsController have been initialized
|
||||||
explore.loadViewIfNeeded()
|
explore.loadViewIfNeeded()
|
||||||
|
|
||||||
let search = secondaryNavController.viewControllers.first as! SearchViewController
|
let search = secondaryNavController.viewControllers.first as! InlineTrendsViewController
|
||||||
// Copy the search query from the search VC to the Explore VC's search controller.
|
// Copy the search query from the search VC to the Explore VC's search controller.
|
||||||
let query = search.searchController.searchBar.text ?? ""
|
let query = search.searchController.searchBar.text ?? ""
|
||||||
explore.searchController.searchBar.text = query
|
explore.searchController.searchBar.text = query
|
||||||
|
@ -232,7 +232,7 @@ extension MainSplitViewController: UISplitViewControllerDelegate {
|
||||||
|
|
||||||
tabBarViewController.select(tab: .explore)
|
tabBarViewController.select(tab: .explore)
|
||||||
|
|
||||||
case .bookmarks, .favorites, .profileDirectory, .list(_), .savedHashtag(_), .savedInstance(_):
|
case .bookmarks, .favorites, .list(_), .savedHashtag(_), .savedInstance(_):
|
||||||
tabBarViewController.select(tab: .explore)
|
tabBarViewController.select(tab: .explore)
|
||||||
// Make sure the Explore VC doesn't show its search bar when it appears, in case the user was previously
|
// Make sure the Explore VC doesn't show its search bar when it appears, in case the user was previously
|
||||||
// in compact mode and performing a search.
|
// in compact mode and performing a search.
|
||||||
|
@ -240,7 +240,7 @@ extension MainSplitViewController: UISplitViewControllerDelegate {
|
||||||
let explore = exploreNav.viewControllers.first as! ExploreViewController
|
let explore = exploreNav.viewControllers.first as! ExploreViewController
|
||||||
explore.searchControllerStatusOnAppearance = false
|
explore.searchControllerStatusOnAppearance = false
|
||||||
|
|
||||||
case .discoverHeader, .listsHeader, .addList, .savedHashtagsHeader, .addSavedHashtag, .savedInstancesHeader, .addSavedInstance:
|
case .listsHeader, .addList, .savedHashtagsHeader, .addSavedHashtag, .savedInstancesHeader, .addSavedInstance:
|
||||||
// These items are not selectable in the sidebar collection view, so this code is unreachable.
|
// These items are not selectable in the sidebar collection view, so this code is unreachable.
|
||||||
fatalError("unexpected selected sidebar item: \(sidebar.selectedItem!)")
|
fatalError("unexpected selected sidebar item: \(sidebar.selectedItem!)")
|
||||||
}
|
}
|
||||||
|
@ -286,7 +286,7 @@ extension MainSplitViewController: UISplitViewControllerDelegate {
|
||||||
if tabNavigationStack.count == 1 || ((tabNavigationStack.first as? ExploreViewController)?.searchController?.isActive ?? false) {
|
if tabNavigationStack.count == 1 || ((tabNavigationStack.first as? ExploreViewController)?.searchController?.isActive ?? false) {
|
||||||
exploreItem = .explore
|
exploreItem = .explore
|
||||||
// reuse the existing VC, if there is one
|
// reuse the existing VC, if there is one
|
||||||
let searchVC = getOrCreateNavigationStack(item: .explore).first! as! SearchViewController
|
let searchVC = getOrCreateNavigationStack(item: .explore).first! as! InlineTrendsViewController
|
||||||
// load the view so that the search controller is accessible
|
// load the view so that the search controller is accessible
|
||||||
searchVC.loadViewIfNeeded()
|
searchVC.loadViewIfNeeded()
|
||||||
let explore = tabNavigationStack.first as! ExploreViewController
|
let explore = tabNavigationStack.first as! ExploreViewController
|
||||||
|
@ -317,8 +317,6 @@ extension MainSplitViewController: UISplitViewControllerDelegate {
|
||||||
exploreItem = .explore
|
exploreItem = .explore
|
||||||
// these three VCs are part of the root SearchViewController, so we don't need to transfer them
|
// these three VCs are part of the root SearchViewController, so we don't need to transfer them
|
||||||
skipFirst = 2
|
skipFirst = 2
|
||||||
case is ProfileDirectoryViewController:
|
|
||||||
exploreItem = .profileDirectory
|
|
||||||
default:
|
default:
|
||||||
// transfer the navigation stack prepending, the existing explore VC
|
// transfer the navigation stack prepending, the existing explore VC
|
||||||
// if there was other stuff on the explore stack, it will get discarded
|
// if there was other stuff on the explore stack, it will get discarded
|
||||||
|
@ -379,20 +377,18 @@ fileprivate extension MainSidebarViewController.Item {
|
||||||
case let .tab(tab):
|
case let .tab(tab):
|
||||||
return tab.createViewController(mastodonController)
|
return tab.createViewController(mastodonController)
|
||||||
case .explore:
|
case .explore:
|
||||||
return SearchViewController(mastodonController: mastodonController)
|
return InlineTrendsViewController(mastodonController: mastodonController)
|
||||||
case .bookmarks:
|
case .bookmarks:
|
||||||
return BookmarksViewController(mastodonController: mastodonController)
|
return BookmarksViewController(mastodonController: mastodonController)
|
||||||
case .favorites:
|
case .favorites:
|
||||||
return FavoritesViewController(mastodonController: mastodonController)
|
return FavoritesViewController(mastodonController: mastodonController)
|
||||||
case .profileDirectory:
|
|
||||||
return ProfileDirectoryViewController(mastodonController: mastodonController)
|
|
||||||
case let .list(list):
|
case let .list(list):
|
||||||
return ListTimelineViewController(for: list, mastodonController: mastodonController)
|
return ListTimelineViewController(for: list, mastodonController: mastodonController)
|
||||||
case let .savedHashtag(hashtag):
|
case let .savedHashtag(hashtag):
|
||||||
return HashtagTimelineViewController(for: hashtag, mastodonController: mastodonController)
|
return HashtagTimelineViewController(for: hashtag, mastodonController: mastodonController)
|
||||||
case let .savedInstance(url):
|
case let .savedInstance(url):
|
||||||
return InstanceTimelineViewController(for: url, parentMastodonController: mastodonController)
|
return InstanceTimelineViewController(for: url, parentMastodonController: mastodonController)
|
||||||
case .discoverHeader, .listsHeader, .addList, .savedHashtagsHeader, .addSavedHashtag, .savedInstancesHeader, .addSavedInstance:
|
case .listsHeader, .addList, .savedHashtagsHeader, .addSavedHashtag, .savedInstancesHeader, .addSavedInstance:
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -482,7 +478,7 @@ extension MainSplitViewController: TuskerRootViewController {
|
||||||
select(item: .explore)
|
select(item: .explore)
|
||||||
}
|
}
|
||||||
|
|
||||||
guard let searchViewController = secondaryNavController.viewControllers.first as? SearchViewController else {
|
guard let searchViewController = secondaryNavController.viewControllers.first as? InlineTrendsViewController else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ struct WellnessPrefsView: View {
|
||||||
notificationsMode
|
notificationsMode
|
||||||
grayscaleImages
|
grayscaleImages
|
||||||
disableInfiniteScrolling
|
disableInfiniteScrolling
|
||||||
hideDiscover
|
hideTrends
|
||||||
}
|
}
|
||||||
.listStyle(InsetGroupedListStyle())
|
.listStyle(InsetGroupedListStyle())
|
||||||
.navigationBarTitle(Text("Digital Wellness"))
|
.navigationBarTitle(Text("Digital Wellness"))
|
||||||
|
@ -57,10 +57,10 @@ struct WellnessPrefsView: View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private var hideDiscover: some View {
|
private var hideTrends: some View {
|
||||||
Section(footer: Text("Do not show the Discover section (Trends, Profile Directory) of the Explore screen or sidebar.")) {
|
Section(footer: Text("Do not show Trends (hashtags, links, posts, suggested accounts) on the Explore screen.")) {
|
||||||
Toggle(isOn: $preferences.hideDiscover) {
|
Toggle(isOn: $preferences.hideTrends) {
|
||||||
Text("Hide Discover Section")
|
Text("Hide Trends")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue