forked from shadowfacts/Tusker
Add Trending Hashtags screen
This commit is contained in:
parent
37e90229c2
commit
9d5c004ec4
|
@ -196,6 +196,7 @@
|
|||
D68E6F5F253C9B2D001A1B4C /* BaseEmojiLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D68E6F5E253C9B2D001A1B4C /* BaseEmojiLabel.swift */; };
|
||||
D68FEC4F232C5BC300C84F23 /* SegmentedPageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D68FEC4E232C5BC300C84F23 /* SegmentedPageViewController.swift */; };
|
||||
D690797324A4EF9700023A34 /* UIBezierPath+Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = D690797224A4EF9700023A34 /* UIBezierPath+Helpers.swift */; };
|
||||
D693A72825CF282E003A14E2 /* TrendingHashtagsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D693A72725CF282E003A14E2 /* TrendingHashtagsViewController.swift */; };
|
||||
D693DE5723FE1A6A0061E07D /* EnhancedNavigationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D693DE5623FE1A6A0061E07D /* EnhancedNavigationViewController.swift */; };
|
||||
D693DE5923FE24310061E07D /* InteractivePushTransition.swift in Sources */ = {isa = PBXBuildFile; fileRef = D693DE5823FE24300061E07D /* InteractivePushTransition.swift */; };
|
||||
D6945C2F23AC47C3005C403C /* SavedDataManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6945C2E23AC47C3005C403C /* SavedDataManager.swift */; };
|
||||
|
@ -562,6 +563,7 @@
|
|||
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>"; };
|
||||
D690797224A4EF9700023A34 /* UIBezierPath+Helpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIBezierPath+Helpers.swift"; sourceTree = "<group>"; };
|
||||
D693A72725CF282E003A14E2 /* TrendingHashtagsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrendingHashtagsViewController.swift; sourceTree = "<group>"; };
|
||||
D693DE5623FE1A6A0061E07D /* EnhancedNavigationViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EnhancedNavigationViewController.swift; sourceTree = "<group>"; };
|
||||
D693DE5823FE24300061E07D /* InteractivePushTransition.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InteractivePushTransition.swift; sourceTree = "<group>"; };
|
||||
D6945C2E23AC47C3005C403C /* SavedDataManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SavedDataManager.swift; sourceTree = "<group>"; };
|
||||
|
@ -914,6 +916,7 @@
|
|||
D6945C3323AC6431005C403C /* AddSavedHashtagViewController.swift */,
|
||||
D6093F9A25BDD4B9004811E6 /* HashtagSearchResultsViewController.swift */,
|
||||
D6945C3923AC75E2005C403C /* FindInstanceViewController.swift */,
|
||||
D693A72725CF282E003A14E2 /* TrendingHashtagsViewController.swift */,
|
||||
);
|
||||
path = Explore;
|
||||
sourceTree = "<group>";
|
||||
|
@ -2044,6 +2047,7 @@
|
|||
D681E4D7246E32290053414F /* StatusActivityItemSource.swift in Sources */,
|
||||
D646C95A213B5D0500269FB5 /* LargeImageInteractionController.swift in Sources */,
|
||||
D6A3BC7C232195C600FD64D5 /* ActionNotificationGroupTableViewCell.swift in Sources */,
|
||||
D693A72825CF282E003A14E2 /* TrendingHashtagsViewController.swift in Sources */,
|
||||
D62275A824F1CA2800B82A16 /* ComposeReplyContentView.swift in Sources */,
|
||||
D677284824ECBCB100C732D3 /* ComposeView.swift in Sources */,
|
||||
D68232F72464F4FD00325FB8 /* ComposeDrawingViewController.swift in Sources */,
|
||||
|
|
|
@ -34,8 +34,8 @@ class AddSavedHashtagViewController: EnhancedTableViewController {
|
|||
title = NSLocalizedString("Search", comment: "search screen title")
|
||||
|
||||
tableView.register(UINib(nibName: "TrendingHashtagTableViewCell", bundle: .main), forCellReuseIdentifier: "trendingTagCell")
|
||||
tableView.rowHeight = 44
|
||||
|
||||
tableView.rowHeight = 60 // 44 for content + 2 * 8 spacing
|
||||
|
||||
dataSource = DataSource(tableView: tableView, cellProvider: { (tableView, indexPath, item) -> UITableViewCell? in
|
||||
switch item {
|
||||
case let .tag(hashtag):
|
||||
|
|
|
@ -134,6 +134,7 @@ class ExploreViewController: UIViewController, UICollectionViewDelegate {
|
|||
var snapshot = NSDiffableDataSourceSnapshot<Section, Item>()
|
||||
snapshot.appendSections(Section.allCases)
|
||||
snapshot.appendItems([.bookmarks], toSection: .bookmarks)
|
||||
snapshot.appendItems([.trendingTags], toSection: .discover)
|
||||
snapshot.appendItems([.addList], toSection: .lists)
|
||||
snapshot.appendItems(SavedDataManager.shared.sortedHashtags(for: account).map { .savedHashtag($0) }, toSection: .savedHashtags)
|
||||
snapshot.appendItems([.addSavedHashtag], toSection: .savedHashtags)
|
||||
|
@ -255,6 +256,9 @@ class ExploreViewController: UIViewController, UICollectionViewDelegate {
|
|||
case .bookmarks:
|
||||
show(BookmarksTableViewController(mastodonController: mastodonController), sender: nil)
|
||||
|
||||
case .trendingTags:
|
||||
show(TrendingHashtagsViewController(mastodonController: mastodonController), sender: nil)
|
||||
|
||||
case let .list(list):
|
||||
show(ListTimelineViewController(for: list, mastodonController: mastodonController), sender: nil)
|
||||
|
||||
|
@ -308,6 +312,7 @@ class ExploreViewController: UIViewController, UICollectionViewDelegate {
|
|||
extension ExploreViewController {
|
||||
enum Section: CaseIterable {
|
||||
case bookmarks
|
||||
case discover
|
||||
case lists
|
||||
case savedHashtags
|
||||
case savedInstances
|
||||
|
@ -316,6 +321,8 @@ extension ExploreViewController {
|
|||
switch self {
|
||||
case .bookmarks:
|
||||
return nil
|
||||
case .discover:
|
||||
return NSLocalizedString("Discover", comment: "discover section title")
|
||||
case .lists:
|
||||
return NSLocalizedString("Lists", comment: "explore lists section title")
|
||||
case .savedHashtags:
|
||||
|
@ -328,6 +335,7 @@ extension ExploreViewController {
|
|||
|
||||
enum Item: Hashable {
|
||||
case bookmarks
|
||||
case trendingTags
|
||||
case list(List)
|
||||
case addList
|
||||
case savedHashtag(Hashtag)
|
||||
|
@ -339,6 +347,8 @@ extension ExploreViewController {
|
|||
switch self {
|
||||
case .bookmarks:
|
||||
return NSLocalizedString("Bookmarks", comment: "bookmarks nav item title")
|
||||
case .trendingTags:
|
||||
return NSLocalizedString("Trending Hashtags", comment: "trending hashtags nav item title")
|
||||
case let .list(list):
|
||||
return list.title
|
||||
case .addList:
|
||||
|
@ -359,6 +369,8 @@ extension ExploreViewController {
|
|||
switch self {
|
||||
case .bookmarks:
|
||||
name = "bookmark.fill"
|
||||
case .trendingTags:
|
||||
name = "arrow.up.arrow.down"
|
||||
case .list(_):
|
||||
name = "list.bullet"
|
||||
case .addList, .addSavedHashtag:
|
||||
|
@ -377,6 +389,8 @@ extension ExploreViewController {
|
|||
switch (lhs, rhs) {
|
||||
case (.bookmarks, .bookmarks):
|
||||
return true
|
||||
case (.trendingTags, .trendingTags):
|
||||
return true
|
||||
case let (.list(a), .list(b)):
|
||||
return a.id == b.id
|
||||
case (.addList, .addList):
|
||||
|
@ -398,6 +412,8 @@ extension ExploreViewController {
|
|||
switch self {
|
||||
case .bookmarks:
|
||||
hasher.combine("bookmarks")
|
||||
case .trendingTags:
|
||||
hasher.combine("trendingTags")
|
||||
case let .list(list):
|
||||
hasher.combine("list")
|
||||
hasher.combine(list.id)
|
||||
|
@ -452,7 +468,7 @@ extension ExploreViewController: UICollectionViewDragDelegate {
|
|||
case let .savedInstance(url):
|
||||
provider = NSItemProvider(object: url as NSURL)
|
||||
// todo: should dragging public timelines into new windows be supported?
|
||||
case .addList, .addSavedHashtag, .findInstance:
|
||||
case .trendingTags, .addList, .addSavedHashtag, .findInstance:
|
||||
return []
|
||||
}
|
||||
return [UIDragItem(itemProvider: provider)]
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
//
|
||||
// TrendingHashtagsViewController.swift
|
||||
// Tusker
|
||||
//
|
||||
// Created by Shadowfacts on 2/6/21.
|
||||
// Copyright © 2021 Shadowfacts. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import Pachyderm
|
||||
|
||||
class TrendingHashtagsViewController: EnhancedTableViewController {
|
||||
|
||||
weak var mastodonController: MastodonController!
|
||||
|
||||
private var dataSource: UITableViewDiffableDataSource<Section, Item>!
|
||||
|
||||
init(mastodonController: MastodonController) {
|
||||
self.mastodonController = mastodonController
|
||||
|
||||
super.init(style: .grouped)
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
title = NSLocalizedString("Trending Hashtags", comment: "trending hashtags screen title")
|
||||
|
||||
tableView.register(UINib(nibName: "TrendingHashtagTableViewCell", bundle: .main), forCellReuseIdentifier: "trendingTagCell")
|
||||
tableView.rowHeight = 60 // 44 for content + 2 * 8 spacing
|
||||
|
||||
// todo: enable drag
|
||||
|
||||
dataSource = UITableViewDiffableDataSource<Section, Item>(tableView: tableView) { (tableView, indexPath, item) in
|
||||
switch item {
|
||||
case let .tag(hashtag):
|
||||
let cell = tableView.dequeueReusableCell(withIdentifier: "trendingTagCell", for: indexPath) as! TrendingHashtagTableViewCell
|
||||
cell.updateUI(hashtag: hashtag)
|
||||
return cell
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override func viewWillAppear(_ animated: Bool) {
|
||||
super.viewWillAppear(animated)
|
||||
|
||||
let request = Client.getTrends(limit: 10)
|
||||
mastodonController.run(request) { (response) in
|
||||
var snapshot = NSDiffableDataSourceSnapshot<Section, Item>()
|
||||
|
||||
guard case let .success(hashtags, _) = response,
|
||||
hashtags.count > 0 else {
|
||||
self.dataSource.apply(snapshot)
|
||||
return
|
||||
}
|
||||
|
||||
snapshot.appendSections([.trendingTags])
|
||||
snapshot.appendItems(hashtags.map { .tag($0) })
|
||||
self.dataSource.apply(snapshot)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Table View Delegate
|
||||
|
||||
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||
guard let item = dataSource.itemIdentifier(for: indexPath),
|
||||
case let .tag(hashtag) = item else {
|
||||
return
|
||||
}
|
||||
|
||||
show(HashtagTimelineViewController(for: hashtag, mastodonController: mastodonController), sender: nil)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension TrendingHashtagsViewController {
|
||||
enum Section {
|
||||
case trendingTags
|
||||
}
|
||||
enum Item: Hashable {
|
||||
case tag(Hashtag)
|
||||
}
|
||||
}
|
|
@ -1,9 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="17701" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="18121" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
|
||||
<device id="retina6_1" orientation="portrait" appearance="light"/>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17703"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="18091"/>
|
||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||
<capability name="System colors in document resources" minToolsVersion="11.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
|
@ -22,16 +21,16 @@
|
|||
<rect key="frame" x="16" y="0.0" width="288" height="66"/>
|
||||
<subviews>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="iCc-do-llt">
|
||||
<rect key="frame" x="0.0" y="15.5" width="180" height="35"/>
|
||||
<rect key="frame" x="0.0" y="15" width="180" height="36.5"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="#hashtag" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="SIS-9e-Paj">
|
||||
<rect key="frame" x="0.0" y="0.0" width="180" height="20.5"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="180" height="23"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleTitle2"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="6 people today" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Kc5-BL-bmu">
|
||||
<rect key="frame" x="0.0" y="20.5" width="180" height="14.5"/>
|
||||
<rect key="frame" x="0.0" y="23" width="180" height="13.5"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleCaption1"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
|
@ -39,10 +38,10 @@
|
|||
</subviews>
|
||||
</stackView>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Xrw-2v-ybZ" customClass="HashtagHistoryView" customModule="Tusker" customModuleProvider="target">
|
||||
<rect key="frame" x="188" y="19" width="100" height="28"/>
|
||||
<rect key="frame" x="188" y="11" width="100" height="44"/>
|
||||
<color key="backgroundColor" systemColor="secondarySystemGroupedBackgroundColor"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="28" id="W4C-uw-zWg"/>
|
||||
<constraint firstAttribute="height" constant="44" id="W4C-uw-zWg"/>
|
||||
<constraint firstAttribute="width" constant="100" id="XHb-vd-qNk"/>
|
||||
</constraints>
|
||||
</view>
|
||||
|
|
Loading…
Reference in New Issue