Add trending hashtags to add saved hashtag controller
This commit is contained in:
parent
f9411d706b
commit
4ed862120c
|
@ -18,6 +18,10 @@
|
||||||
04DACE8C212CB14B009840C4 /* MainTabBarViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04DACE8B212CB14B009840C4 /* MainTabBarViewController.swift */; };
|
04DACE8C212CB14B009840C4 /* MainTabBarViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04DACE8B212CB14B009840C4 /* MainTabBarViewController.swift */; };
|
||||||
04DACE8E212CC7CC009840C4 /* ImageCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04DACE8D212CC7CC009840C4 /* ImageCache.swift */; };
|
04DACE8E212CC7CC009840C4 /* ImageCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04DACE8D212CC7CC009840C4 /* ImageCache.swift */; };
|
||||||
04ED00B121481ED800567C53 /* SteppedProgressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04ED00B021481ED800567C53 /* SteppedProgressView.swift */; };
|
04ED00B121481ED800567C53 /* SteppedProgressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04ED00B021481ED800567C53 /* SteppedProgressView.swift */; };
|
||||||
|
D6093F9B25BDD4B9004811E6 /* HashtagSearchResultsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6093F9A25BDD4B9004811E6 /* HashtagSearchResultsViewController.swift */; };
|
||||||
|
D6093FB025BE0B01004811E6 /* TrendingHashtagTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6093FAE25BE0B01004811E6 /* TrendingHashtagTableViewCell.swift */; };
|
||||||
|
D6093FB125BE0B01004811E6 /* TrendingHashtagTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = D6093FAF25BE0B01004811E6 /* TrendingHashtagTableViewCell.xib */; };
|
||||||
|
D6093FB725BE0CF3004811E6 /* HashtagHistoryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6093FB625BE0CF3004811E6 /* HashtagHistoryView.swift */; };
|
||||||
D60CFFDB24A290BA00D00083 /* SwiftSoup in Frameworks */ = {isa = PBXBuildFile; productRef = D60CFFDA24A290BA00D00083 /* SwiftSoup */; };
|
D60CFFDB24A290BA00D00083 /* SwiftSoup in Frameworks */ = {isa = PBXBuildFile; productRef = D60CFFDA24A290BA00D00083 /* SwiftSoup */; };
|
||||||
D60D2B8223844C71001B87A3 /* BaseStatusTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D60D2B8123844C71001B87A3 /* BaseStatusTableViewCell.swift */; };
|
D60D2B8223844C71001B87A3 /* BaseStatusTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D60D2B8123844C71001B87A3 /* BaseStatusTableViewCell.swift */; };
|
||||||
D60E2F272442372B005F8713 /* StatusMO.swift in Sources */ = {isa = PBXBuildFile; fileRef = D60E2F232442372B005F8713 /* StatusMO.swift */; };
|
D60E2F272442372B005F8713 /* StatusMO.swift in Sources */ = {isa = PBXBuildFile; fileRef = D60E2F232442372B005F8713 /* StatusMO.swift */; };
|
||||||
|
@ -296,6 +300,7 @@
|
||||||
D6E426AD25334DA500C02E1C /* FuzzyMatcherTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6E426AC25334DA500C02E1C /* FuzzyMatcherTests.swift */; };
|
D6E426AD25334DA500C02E1C /* FuzzyMatcherTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6E426AC25334DA500C02E1C /* FuzzyMatcherTests.swift */; };
|
||||||
D6E426B325337C7000C02E1C /* CustomEmojiImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6E426B225337C7000C02E1C /* CustomEmojiImageView.swift */; };
|
D6E426B325337C7000C02E1C /* CustomEmojiImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6E426B225337C7000C02E1C /* CustomEmojiImageView.swift */; };
|
||||||
D6E426B9253382B300C02E1C /* SearchResultType.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6E426B8253382B300C02E1C /* SearchResultType.swift */; };
|
D6E426B9253382B300C02E1C /* SearchResultType.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6E426B8253382B300C02E1C /* SearchResultType.swift */; };
|
||||||
|
D6E57FA325C26FAB00341037 /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = D6E57FA525C26FAB00341037 /* Localizable.stringsdict */; };
|
||||||
D6E6F26321603F8B006A8599 /* CharacterCounter.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6E6F26221603F8B006A8599 /* CharacterCounter.swift */; };
|
D6E6F26321603F8B006A8599 /* CharacterCounter.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6E6F26221603F8B006A8599 /* CharacterCounter.swift */; };
|
||||||
D6E6F26521604242006A8599 /* CharacterCounterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6E6F26421604242006A8599 /* CharacterCounterTests.swift */; };
|
D6E6F26521604242006A8599 /* CharacterCounterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6E6F26421604242006A8599 /* CharacterCounterTests.swift */; };
|
||||||
D6EAE0DB2550CC8A002DB0AC /* FocusableTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6EAE0DA2550CC8A002DB0AC /* FocusableTextField.swift */; };
|
D6EAE0DB2550CC8A002DB0AC /* FocusableTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6EAE0DA2550CC8A002DB0AC /* FocusableTextField.swift */; };
|
||||||
|
@ -376,6 +381,10 @@
|
||||||
04DACE8B212CB14B009840C4 /* MainTabBarViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainTabBarViewController.swift; sourceTree = "<group>"; };
|
04DACE8B212CB14B009840C4 /* MainTabBarViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainTabBarViewController.swift; sourceTree = "<group>"; };
|
||||||
04DACE8D212CC7CC009840C4 /* ImageCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageCache.swift; sourceTree = "<group>"; };
|
04DACE8D212CC7CC009840C4 /* ImageCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageCache.swift; sourceTree = "<group>"; };
|
||||||
04ED00B021481ED800567C53 /* SteppedProgressView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SteppedProgressView.swift; sourceTree = "<group>"; };
|
04ED00B021481ED800567C53 /* SteppedProgressView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SteppedProgressView.swift; sourceTree = "<group>"; };
|
||||||
|
D6093F9A25BDD4B9004811E6 /* HashtagSearchResultsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HashtagSearchResultsViewController.swift; sourceTree = "<group>"; };
|
||||||
|
D6093FAE25BE0B01004811E6 /* TrendingHashtagTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrendingHashtagTableViewCell.swift; sourceTree = "<group>"; };
|
||||||
|
D6093FAF25BE0B01004811E6 /* TrendingHashtagTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = TrendingHashtagTableViewCell.xib; sourceTree = "<group>"; };
|
||||||
|
D6093FB625BE0CF3004811E6 /* HashtagHistoryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HashtagHistoryView.swift; sourceTree = "<group>"; };
|
||||||
D60A4FFB238B726A008AC647 /* StatusState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusState.swift; sourceTree = "<group>"; };
|
D60A4FFB238B726A008AC647 /* StatusState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusState.swift; sourceTree = "<group>"; };
|
||||||
D60D2B8123844C71001B87A3 /* BaseStatusTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseStatusTableViewCell.swift; sourceTree = "<group>"; };
|
D60D2B8123844C71001B87A3 /* BaseStatusTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseStatusTableViewCell.swift; sourceTree = "<group>"; };
|
||||||
D60E2F232442372B005F8713 /* StatusMO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusMO.swift; sourceTree = "<group>"; };
|
D60E2F232442372B005F8713 /* StatusMO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusMO.swift; sourceTree = "<group>"; };
|
||||||
|
@ -660,6 +669,7 @@
|
||||||
D6E426B225337C7000C02E1C /* CustomEmojiImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomEmojiImageView.swift; sourceTree = "<group>"; };
|
D6E426B225337C7000C02E1C /* CustomEmojiImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomEmojiImageView.swift; sourceTree = "<group>"; };
|
||||||
D6E426B8253382B300C02E1C /* SearchResultType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchResultType.swift; sourceTree = "<group>"; };
|
D6E426B8253382B300C02E1C /* SearchResultType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchResultType.swift; sourceTree = "<group>"; };
|
||||||
D6E4885C24A2890C0011C13E /* Tusker.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Tusker.entitlements; sourceTree = "<group>"; };
|
D6E4885C24A2890C0011C13E /* Tusker.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Tusker.entitlements; sourceTree = "<group>"; };
|
||||||
|
D6E57FA425C26FAB00341037 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = en; path = en.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
||||||
D6E6F26221603F8B006A8599 /* CharacterCounter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CharacterCounter.swift; sourceTree = "<group>"; };
|
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>"; };
|
D6E6F26421604242006A8599 /* CharacterCounterTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CharacterCounterTests.swift; sourceTree = "<group>"; };
|
||||||
D6EAE0DA2550CC8A002DB0AC /* FocusableTextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FocusableTextField.swift; sourceTree = "<group>"; };
|
D6EAE0DA2550CC8A002DB0AC /* FocusableTextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FocusableTextField.swift; sourceTree = "<group>"; };
|
||||||
|
@ -834,6 +844,9 @@
|
||||||
children = (
|
children = (
|
||||||
D611C2CD232DC61100C86A49 /* HashtagTableViewCell.swift */,
|
D611C2CD232DC61100C86A49 /* HashtagTableViewCell.swift */,
|
||||||
D611C2CE232DC61100C86A49 /* HashtagTableViewCell.xib */,
|
D611C2CE232DC61100C86A49 /* HashtagTableViewCell.xib */,
|
||||||
|
D6093FAE25BE0B01004811E6 /* TrendingHashtagTableViewCell.swift */,
|
||||||
|
D6093FAF25BE0B01004811E6 /* TrendingHashtagTableViewCell.xib */,
|
||||||
|
D6093FB625BE0CF3004811E6 /* HashtagHistoryView.swift */,
|
||||||
);
|
);
|
||||||
path = "Hashtag Cell";
|
path = "Hashtag Cell";
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -901,6 +914,7 @@
|
||||||
children = (
|
children = (
|
||||||
D627943D23A564D400D38C68 /* ExploreViewController.swift */,
|
D627943D23A564D400D38C68 /* ExploreViewController.swift */,
|
||||||
D6945C3323AC6431005C403C /* AddSavedHashtagViewController.swift */,
|
D6945C3323AC6431005C403C /* AddSavedHashtagViewController.swift */,
|
||||||
|
D6093F9A25BDD4B9004811E6 /* HashtagSearchResultsViewController.swift */,
|
||||||
D6945C3923AC75E2005C403C /* FindInstanceViewController.swift */,
|
D6945C3923AC75E2005C403C /* FindInstanceViewController.swift */,
|
||||||
);
|
);
|
||||||
path = Explore;
|
path = Explore;
|
||||||
|
@ -1448,6 +1462,7 @@
|
||||||
D6CA6A91249FAD8900AD45C1 /* AudioSessionHelper.swift */,
|
D6CA6A91249FAD8900AD45C1 /* AudioSessionHelper.swift */,
|
||||||
D6E4269C2532A3E100C02E1C /* FuzzyMatcher.swift */,
|
D6E4269C2532A3E100C02E1C /* FuzzyMatcher.swift */,
|
||||||
D6B30E08254BAF63009CAEE5 /* ImageGrayscalifier.swift */,
|
D6B30E08254BAF63009CAEE5 /* ImageGrayscalifier.swift */,
|
||||||
|
D6E57FA525C26FAB00341037 /* Localizable.stringsdict */,
|
||||||
D67B506B250B28FF00FAECFB /* Vendor */,
|
D67B506B250B28FF00FAECFB /* Vendor */,
|
||||||
D6F1F84E2193B9BE00F5FE67 /* Caching */,
|
D6F1F84E2193B9BE00F5FE67 /* Caching */,
|
||||||
D6757A7A2157E00100721E32 /* XCallbackURL */,
|
D6757A7A2157E00100721E32 /* XCallbackURL */,
|
||||||
|
@ -1732,12 +1747,14 @@
|
||||||
D6A3BC7D232195C600FD64D5 /* ActionNotificationGroupTableViewCell.xib in Resources */,
|
D6A3BC7D232195C600FD64D5 /* ActionNotificationGroupTableViewCell.xib in Resources */,
|
||||||
D6412B0B24B0D4C600F5412E /* ProfileHeaderView.xib in Resources */,
|
D6412B0B24B0D4C600F5412E /* ProfileHeaderView.xib in Resources */,
|
||||||
D6D4DDDA212518A200E1C4BB /* LaunchScreen.storyboard in Resources */,
|
D6D4DDDA212518A200E1C4BB /* LaunchScreen.storyboard in Resources */,
|
||||||
|
D6E57FA325C26FAB00341037 /* Localizable.stringsdict in Resources */,
|
||||||
D6B053AC23BD2F1400A066FA /* AssetCollectionViewCell.xib in Resources */,
|
D6B053AC23BD2F1400A066FA /* AssetCollectionViewCell.xib in Resources */,
|
||||||
D6D4DDD7212518A200E1C4BB /* Assets.xcassets in Resources */,
|
D6D4DDD7212518A200E1C4BB /* Assets.xcassets in Resources */,
|
||||||
D663625D2135C74800C9CBA2 /* ConversationMainStatusTableViewCell.xib in Resources */,
|
D663625D2135C74800C9CBA2 /* ConversationMainStatusTableViewCell.xib in Resources */,
|
||||||
D640D76922BAF5E6004FBE69 /* DomainBlocks.plist in Resources */,
|
D640D76922BAF5E6004FBE69 /* DomainBlocks.plist in Resources */,
|
||||||
D6969EA4240DD28D002843CE /* UnknownNotificationTableViewCell.xib in Resources */,
|
D6969EA4240DD28D002843CE /* UnknownNotificationTableViewCell.xib in Resources */,
|
||||||
D6289E84217B795D0003D1D7 /* LargeImageViewController.xib in Resources */,
|
D6289E84217B795D0003D1D7 /* LargeImageViewController.xib in Resources */,
|
||||||
|
D6093FB125BE0B01004811E6 /* TrendingHashtagTableViewCell.xib in Resources */,
|
||||||
D627FF79217E950100CC0648 /* DraftsTableViewController.xib in Resources */,
|
D627FF79217E950100CC0648 /* DraftsTableViewController.xib in Resources */,
|
||||||
D626493323BD751600612E6E /* ShowCameraCollectionViewCell.xib in Resources */,
|
D626493323BD751600612E6E /* ShowCameraCollectionViewCell.xib in Resources */,
|
||||||
D626493D23C1000300612E6E /* AlbumTableViewCell.xib in Resources */,
|
D626493D23C1000300612E6E /* AlbumTableViewCell.xib in Resources */,
|
||||||
|
@ -1865,6 +1882,7 @@
|
||||||
D60E2F292442372B005F8713 /* AccountMO.swift in Sources */,
|
D60E2F292442372B005F8713 /* AccountMO.swift in Sources */,
|
||||||
D6412B0324AFF6A600F5412E /* TabBarScrollableViewController.swift in Sources */,
|
D6412B0324AFF6A600F5412E /* TabBarScrollableViewController.swift in Sources */,
|
||||||
D6757A822157E8FA00721E32 /* XCBSession.swift in Sources */,
|
D6757A822157E8FA00721E32 /* XCBSession.swift in Sources */,
|
||||||
|
D6093FB725BE0CF3004811E6 /* HashtagHistoryView.swift in Sources */,
|
||||||
D6EBF01723C55E0D00AE061B /* UISceneSession+MastodonController.swift in Sources */,
|
D6EBF01723C55E0D00AE061B /* UISceneSession+MastodonController.swift in Sources */,
|
||||||
04DACE8C212CB14B009840C4 /* MainTabBarViewController.swift in Sources */,
|
04DACE8C212CB14B009840C4 /* MainTabBarViewController.swift in Sources */,
|
||||||
D68E525D24A3E8F00054355A /* SearchViewController.swift in Sources */,
|
D68E525D24A3E8F00054355A /* SearchViewController.swift in Sources */,
|
||||||
|
@ -1956,6 +1974,7 @@
|
||||||
D627943223A5466600D38C68 /* SelectableTableViewCell.swift in Sources */,
|
D627943223A5466600D38C68 /* SelectableTableViewCell.swift in Sources */,
|
||||||
D6DD353F22F502EC00A9563A /* Preferences+Notification.swift in Sources */,
|
D6DD353F22F502EC00A9563A /* Preferences+Notification.swift in Sources */,
|
||||||
D6EAE0DB2550CC8A002DB0AC /* FocusableTextField.swift in Sources */,
|
D6EAE0DB2550CC8A002DB0AC /* FocusableTextField.swift in Sources */,
|
||||||
|
D6093FB025BE0B01004811E6 /* TrendingHashtagTableViewCell.swift in Sources */,
|
||||||
D63661C02381C144004B9E16 /* PreferencesNavigationController.swift in Sources */,
|
D63661C02381C144004B9E16 /* PreferencesNavigationController.swift in Sources */,
|
||||||
D6B053A223BD2C0600A066FA /* AssetPickerViewController.swift in Sources */,
|
D6B053A223BD2C0600A066FA /* AssetPickerViewController.swift in Sources */,
|
||||||
D6EE63FB2551F7F60065485C /* StatusCollapseButton.swift in Sources */,
|
D6EE63FB2551F7F60065485C /* StatusCollapseButton.swift in Sources */,
|
||||||
|
@ -2054,6 +2073,7 @@
|
||||||
D626493F23C101C500612E6E /* AlbumAssetCollectionViewController.swift in Sources */,
|
D626493F23C101C500612E6E /* AlbumAssetCollectionViewController.swift in Sources */,
|
||||||
D68015422401A74600D6103B /* MediaPrefsView.swift in Sources */,
|
D68015422401A74600D6103B /* MediaPrefsView.swift in Sources */,
|
||||||
D6C99FCB24FADC91005C74D3 /* MainComposeTextView.swift in Sources */,
|
D6C99FCB24FADC91005C74D3 /* MainComposeTextView.swift in Sources */,
|
||||||
|
D6093F9B25BDD4B9004811E6 /* HashtagSearchResultsViewController.swift in Sources */,
|
||||||
D6E4267725327FB400C02E1C /* ComposeAutocompleteView.swift in Sources */,
|
D6E4267725327FB400C02E1C /* ComposeAutocompleteView.swift in Sources */,
|
||||||
D6757A7E2157E02600721E32 /* XCBRequestSpec.swift in Sources */,
|
D6757A7E2157E02600721E32 /* XCBRequestSpec.swift in Sources */,
|
||||||
D677284E24ECC01D00C732D3 /* Draft.swift in Sources */,
|
D677284E24ECC01D00C732D3 /* Draft.swift in Sources */,
|
||||||
|
@ -2133,6 +2153,14 @@
|
||||||
name = LaunchScreen.storyboard;
|
name = LaunchScreen.storyboard;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
D6E57FA525C26FAB00341037 /* Localizable.stringsdict */ = {
|
||||||
|
isa = PBXVariantGroup;
|
||||||
|
children = (
|
||||||
|
D6E57FA425C26FAB00341037 /* en */,
|
||||||
|
);
|
||||||
|
name = Localizable.stringsdict;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
/* End PBXVariantGroup section */
|
/* End PBXVariantGroup section */
|
||||||
|
|
||||||
/* Begin XCBuildConfiguration section */
|
/* Begin XCBuildConfiguration section */
|
||||||
|
|
|
@ -9,12 +9,19 @@
|
||||||
import UIKit
|
import UIKit
|
||||||
import Pachyderm
|
import Pachyderm
|
||||||
|
|
||||||
class AddSavedHashtagViewController: SearchResultsViewController {
|
class AddSavedHashtagViewController: EnhancedTableViewController {
|
||||||
|
|
||||||
|
weak var mastodonController: MastodonController!
|
||||||
|
|
||||||
|
var resultsController: SearchResultsViewController!
|
||||||
var searchController: UISearchController!
|
var searchController: UISearchController!
|
||||||
|
|
||||||
|
var dataSource: UITableViewDiffableDataSource<Section, Item>!
|
||||||
|
|
||||||
init(mastodonController: MastodonController) {
|
init(mastodonController: MastodonController) {
|
||||||
super.init(mastodonController: mastodonController, resultTypes: [.hashtags])
|
self.mastodonController = mastodonController
|
||||||
|
|
||||||
|
super.init(style: .grouped)
|
||||||
}
|
}
|
||||||
|
|
||||||
required init?(coder: NSCoder) {
|
required init?(coder: NSCoder) {
|
||||||
|
@ -24,14 +31,32 @@ class AddSavedHashtagViewController: SearchResultsViewController {
|
||||||
override func viewDidLoad() {
|
override func viewDidLoad() {
|
||||||
super.viewDidLoad()
|
super.viewDidLoad()
|
||||||
|
|
||||||
delegate = self
|
title = NSLocalizedString("Search", comment: "search screen title")
|
||||||
|
|
||||||
searchController = UISearchController(searchResultsController: nil)
|
tableView.register(UINib(nibName: "TrendingHashtagTableViewCell", bundle: .main), forCellReuseIdentifier: "trendingTagCell")
|
||||||
searchController.obscuresBackgroundDuringPresentation = false
|
tableView.rowHeight = 44
|
||||||
|
|
||||||
|
dataSource = DataSource(tableView: tableView, cellProvider: { (tableView, indexPath, item) -> UITableViewCell? in
|
||||||
|
switch item {
|
||||||
|
case let .tag(hashtag):
|
||||||
|
let cell = tableView.dequeueReusableCell(withIdentifier: "trendingTagCell", for: indexPath) as! TrendingHashtagTableViewCell
|
||||||
|
cell.updateUI(hashtag: hashtag)
|
||||||
|
return cell
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
resultsController = HashtagSearchResultsViewController(mastodonController: mastodonController)
|
||||||
|
resultsController.delegate = self
|
||||||
|
resultsController.exploreNavigationController = self.navigationController!
|
||||||
|
|
||||||
|
searchController = UISearchController(searchResultsController: resultsController)
|
||||||
|
searchController.obscuresBackgroundDuringPresentation = true
|
||||||
searchController.hidesNavigationBarDuringPresentation = false
|
searchController.hidesNavigationBarDuringPresentation = false
|
||||||
|
searchController.searchResultsUpdater = resultsController
|
||||||
searchController.searchBar.autocapitalizationType = .none
|
searchController.searchBar.autocapitalizationType = .none
|
||||||
searchController.searchBar.placeholder = NSLocalizedString("Search for hashtags to save", comment: "add saved hashtag search field placeholder")
|
searchController.searchBar.placeholder = NSLocalizedString("Search for hashtags to save", comment: "add saved hashtag search field placeholder")
|
||||||
searchController.searchBar.delegate = self
|
searchController.searchBar.delegate = resultsController
|
||||||
|
searchController.searchBar.showsCancelButton = false
|
||||||
|
|
||||||
definesPresentationContext = true
|
definesPresentationContext = true
|
||||||
|
|
||||||
|
@ -41,11 +66,38 @@ class AddSavedHashtagViewController: SearchResultsViewController {
|
||||||
navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(cancelButtonPressed))
|
navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(cancelButtonPressed))
|
||||||
}
|
}
|
||||||
|
|
||||||
override func performSearch(query: String?) {
|
override func viewWillAppear(_ animated: Bool) {
|
||||||
if let query = query, !query.starts(with: "#") {
|
super.viewWillAppear(animated)
|
||||||
super.performSearch(query: "#\(query)")
|
|
||||||
} else {
|
let request = Client.getTrends(limit: 10)
|
||||||
super.performSearch(query: query)
|
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, animatingDifferences: false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func selectHashtag(_ hashtag: Hashtag) {
|
||||||
|
SavedDataManager.shared.add(hashtag: hashtag, for: mastodonController.accountInfo!)
|
||||||
|
presentingViewController!.dismiss(animated: true)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Table View Delegate
|
||||||
|
|
||||||
|
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||||
|
switch dataSource.itemIdentifier(for: indexPath) {
|
||||||
|
case nil:
|
||||||
|
return
|
||||||
|
case let .tag(hashtag):
|
||||||
|
selectHashtag(hashtag)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,9 +109,24 @@ class AddSavedHashtagViewController: SearchResultsViewController {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension AddSavedHashtagViewController {
|
||||||
|
enum Section {
|
||||||
|
case trendingTags
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Item: Hashable {
|
||||||
|
case tag(Hashtag)
|
||||||
|
}
|
||||||
|
|
||||||
|
class DataSource: UITableViewDiffableDataSource<Section, Item> {
|
||||||
|
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
|
||||||
|
return NSLocalizedString("Trending Hashtags", comment: "trending hashtags seciton title")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
extension AddSavedHashtagViewController: SearchResultsViewControllerDelegate {
|
extension AddSavedHashtagViewController: SearchResultsViewControllerDelegate {
|
||||||
func selectedSearchResult(hashtag: Hashtag) {
|
func selectedSearchResult(hashtag: Hashtag) {
|
||||||
SavedDataManager.shared.add(hashtag: hashtag, for: mastodonController.accountInfo!)
|
selectHashtag(hashtag)
|
||||||
dismiss(animated: true)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
//
|
||||||
|
// HashtagSearchResultsViewController.swift
|
||||||
|
// Tusker
|
||||||
|
//
|
||||||
|
// Created by Shadowfacts on 1/24/21.
|
||||||
|
// Copyright © 2021 Shadowfacts. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
class HashtagSearchResultsViewController: SearchResultsViewController {
|
||||||
|
|
||||||
|
init(mastodonController: MastodonController) {
|
||||||
|
super.init(mastodonController: mastodonController, resultTypes: [.hashtags])
|
||||||
|
}
|
||||||
|
|
||||||
|
required init?(coder: NSCoder) {
|
||||||
|
fatalError("init(coder:) has not been implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
override func performSearch(query: String?) {
|
||||||
|
if let query = query, !query.starts(with: "#") {
|
||||||
|
super.performSearch(query: "#\(query)")
|
||||||
|
} else {
|
||||||
|
super.performSearch(query: query)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -132,6 +132,7 @@ class SearchResultsViewController: EnhancedTableViewController {
|
||||||
activityIndicator.isHidden = false
|
activityIndicator.isHidden = false
|
||||||
activityIndicator.startAnimating()
|
activityIndicator.startAnimating()
|
||||||
|
|
||||||
|
let resultTypes = self.resultTypes
|
||||||
let request = Client.search(query: query, types: resultTypes, resolve: true, limit: 10)
|
let request = Client.search(query: query, types: resultTypes, resolve: true, limit: 10)
|
||||||
mastodonController.run(request) { (response) in
|
mastodonController.run(request) { (response) in
|
||||||
guard case let .success(results, _) = response else { fatalError() }
|
guard case let .success(results, _) = response else { fatalError() }
|
||||||
|
@ -161,16 +162,16 @@ class SearchResultsViewController: EnhancedTableViewController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !results.accounts.isEmpty {
|
if !results.accounts.isEmpty && (resultTypes == nil || resultTypes!.contains(.accounts)) {
|
||||||
snapshot.appendSections([.accounts])
|
snapshot.appendSections([.accounts])
|
||||||
snapshot.appendItems(results.accounts.map { .account($0.id) }, toSection: .accounts)
|
snapshot.appendItems(results.accounts.map { .account($0.id) }, toSection: .accounts)
|
||||||
addAccounts(results.accounts)
|
addAccounts(results.accounts)
|
||||||
}
|
}
|
||||||
if !results.hashtags.isEmpty {
|
if !results.hashtags.isEmpty && (resultTypes == nil || resultTypes!.contains(.hashtags)) {
|
||||||
snapshot.appendSections([.hashtags])
|
snapshot.appendSections([.hashtags])
|
||||||
snapshot.appendItems(results.hashtags.map { .hashtag($0) }, toSection: .hashtags)
|
snapshot.appendItems(results.hashtags.map { .hashtag($0) }, toSection: .hashtags)
|
||||||
}
|
}
|
||||||
if !results.statuses.isEmpty {
|
if !results.statuses.isEmpty && (resultTypes == nil || resultTypes!.contains(.statuses)) {
|
||||||
snapshot.appendSections([.statuses])
|
snapshot.appendSections([.statuses])
|
||||||
snapshot.appendItems(results.statuses.map { .status($0.id, .unknown) }, toSection: .statuses)
|
snapshot.appendItems(results.statuses.map { .status($0.id, .unknown) }, toSection: .statuses)
|
||||||
addStatuses(results.statuses)
|
addStatuses(results.statuses)
|
||||||
|
|
|
@ -0,0 +1,133 @@
|
||||||
|
//
|
||||||
|
// HashtagHistoryView.swift
|
||||||
|
// Tusker
|
||||||
|
//
|
||||||
|
// Created by Shadowfacts on 1/24/21.
|
||||||
|
// Copyright © 2021 Shadowfacts. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
import Pachyderm
|
||||||
|
|
||||||
|
class HashtagHistoryView: UIView {
|
||||||
|
|
||||||
|
private var history: [Hashtag.History]?
|
||||||
|
|
||||||
|
private let curveRadius: CGFloat = 10
|
||||||
|
|
||||||
|
override func layoutSubviews() {
|
||||||
|
super.layoutSubviews()
|
||||||
|
|
||||||
|
createLayers()
|
||||||
|
}
|
||||||
|
|
||||||
|
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
|
||||||
|
super.traitCollectionDidChange(previousTraitCollection)
|
||||||
|
|
||||||
|
createLayers()
|
||||||
|
}
|
||||||
|
|
||||||
|
func setHistory(_ history: [Hashtag.History]?) {
|
||||||
|
if let history = history {
|
||||||
|
self.history = history.sorted(by: { $0.day < $1.day })
|
||||||
|
} else {
|
||||||
|
self.history = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
createLayers()
|
||||||
|
}
|
||||||
|
|
||||||
|
private func createLayers() {
|
||||||
|
guard let history = history,
|
||||||
|
history.count >= 2 else { return }
|
||||||
|
|
||||||
|
let maxUses = history.max(by: { $0.uses < $1.uses })!.uses
|
||||||
|
|
||||||
|
// remove old layers if this view is being re-used
|
||||||
|
layer.sublayers?.forEach { $0.removeFromSuperlayer() }
|
||||||
|
|
||||||
|
let path = UIBezierPath()
|
||||||
|
|
||||||
|
let widthStep = bounds.width / CGFloat(history.count - 1)
|
||||||
|
|
||||||
|
let points: [CGPoint] = history.enumerated().map { (index, entry) in
|
||||||
|
let x = CGFloat(index) * widthStep
|
||||||
|
let yFrac = CGFloat(entry.uses) / CGFloat(maxUses)
|
||||||
|
let y = (1 - yFrac) * bounds.height
|
||||||
|
return CGPoint(x: x, y: y)
|
||||||
|
}
|
||||||
|
|
||||||
|
var gapStartPoints = [CGPoint]()
|
||||||
|
var gapEndPoints = [CGPoint]()
|
||||||
|
|
||||||
|
for (index, point) in points.enumerated().dropFirst().dropLast() {
|
||||||
|
let prev = points[index - 1]
|
||||||
|
let next = points[index + 1]
|
||||||
|
|
||||||
|
let a = atan((point.y - prev.y) / widthStep)
|
||||||
|
let b = atan((next.y - point.y) / widthStep)
|
||||||
|
let innerAngle = .pi - a - b
|
||||||
|
|
||||||
|
let gapDistance = curveRadius / sin(innerAngle / 2)
|
||||||
|
|
||||||
|
let x1 = point.x - cos(a) * gapDistance
|
||||||
|
let y1 = point.y - sin(a) * gapDistance
|
||||||
|
gapStartPoints.append(CGPoint(x: x1, y: y1))
|
||||||
|
|
||||||
|
let x2 = point.x + cos(b) * gapDistance
|
||||||
|
let y2 = point.y + sin(b) * gapDistance
|
||||||
|
gapEndPoints.append(CGPoint(x: x2, y: y2))
|
||||||
|
}
|
||||||
|
|
||||||
|
path.move(to: points.first!)
|
||||||
|
for (index, point) in points.dropFirst().dropLast().enumerated() {
|
||||||
|
path.addLine(to: gapStartPoints[index])
|
||||||
|
path.addQuadCurve(to: gapEndPoints[index], controlPoint: point)
|
||||||
|
}
|
||||||
|
path.addLine(to: points.last!)
|
||||||
|
|
||||||
|
let borderLayer = CAShapeLayer()
|
||||||
|
// copy the border path so we can continue mutating the UIBezierPath to create the fill path
|
||||||
|
borderLayer.path = path.cgPath.copy()!
|
||||||
|
borderLayer.strokeColor = tintColor.cgColor
|
||||||
|
borderLayer.fillColor = nil
|
||||||
|
borderLayer.lineWidth = 2
|
||||||
|
borderLayer.lineCap = .round
|
||||||
|
|
||||||
|
path.addLine(to: CGPoint(x: bounds.width, y: bounds.height))
|
||||||
|
path.addLine(to: CGPoint(x: 0, y: bounds.height))
|
||||||
|
path.addLine(to: points.first!)
|
||||||
|
|
||||||
|
let fillLayer = CAShapeLayer()
|
||||||
|
fillLayer.path = path.cgPath
|
||||||
|
let fillColor = self.fillColor()
|
||||||
|
fillLayer.strokeColor = fillColor
|
||||||
|
fillLayer.fillColor = fillColor
|
||||||
|
fillLayer.lineWidth = 2
|
||||||
|
|
||||||
|
layer.addSublayer(fillLayer)
|
||||||
|
layer.addSublayer(borderLayer)
|
||||||
|
}
|
||||||
|
|
||||||
|
// The non-transparent fill color.
|
||||||
|
// We blend with the view's background color ourselves so that final color is non-transparent,
|
||||||
|
// otherwise when the fill layer's border and fill overlap, there's a visibly darker patch
|
||||||
|
// because transparent colors are being blended together.
|
||||||
|
private func fillColor() -> CGColor {
|
||||||
|
var backgroundRed: CGFloat = 0
|
||||||
|
var backgroundGreen: CGFloat = 0
|
||||||
|
var backgroundBlue: CGFloat = 0
|
||||||
|
var tintRed: CGFloat = 0
|
||||||
|
var tintGreen: CGFloat = 0
|
||||||
|
var tintBlue: CGFloat = 0
|
||||||
|
traitCollection.performAsCurrent {
|
||||||
|
backgroundColor!.getRed(&backgroundRed, green: &backgroundGreen, blue: &backgroundBlue, alpha: nil)
|
||||||
|
tintColor.getRed(&tintRed, green: &tintGreen, blue: &tintBlue, alpha: nil)
|
||||||
|
}
|
||||||
|
let blendedRed = (backgroundRed + tintRed) / 2
|
||||||
|
let blendedGreen = (backgroundGreen + tintGreen) / 2
|
||||||
|
let blendedBlue = (backgroundBlue + tintBlue) / 2
|
||||||
|
return CGColor(red: blendedRed, green: blendedGreen, blue: blendedBlue, alpha: 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,8 +1,9 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14868" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
|
<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">
|
||||||
<device id="retina6_1" orientation="portrait" appearance="light"/>
|
<device id="retina6_1" orientation="portrait" appearance="light"/>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14824"/>
|
<deployment identifier="iOS"/>
|
||||||
|
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17703"/>
|
||||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
@ -17,8 +18,8 @@
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<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="vVg-1C-zJr">
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="#hashtag" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="vVg-1C-zJr">
|
||||||
<rect key="frame" x="16" y="11" width="83" height="22"/>
|
<rect key="frame" x="16" y="11" width="71.5" height="22"/>
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="20"/>
|
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||||
<nil key="textColor"/>
|
<nil key="textColor"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
//
|
||||||
|
// TrendingHashtagTableViewCell.swift
|
||||||
|
// Tusker
|
||||||
|
//
|
||||||
|
// Created by Shadowfacts on 1/24/21.
|
||||||
|
// Copyright © 2021 Shadowfacts. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
import Pachyderm
|
||||||
|
|
||||||
|
class TrendingHashtagTableViewCell: UITableViewCell {
|
||||||
|
|
||||||
|
@IBOutlet weak var hashtagLabel: UILabel!
|
||||||
|
@IBOutlet weak var peopleTodayLabel: UILabel!
|
||||||
|
@IBOutlet weak var historyView: HashtagHistoryView!
|
||||||
|
|
||||||
|
override func awakeFromNib() {
|
||||||
|
super.awakeFromNib()
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateUI(hashtag: Hashtag) {
|
||||||
|
hashtagLabel.text = "#\(hashtag.name)"
|
||||||
|
historyView.setHistory(hashtag.history)
|
||||||
|
historyView.isHidden = hashtag.history == nil || hashtag.history!.count < 2
|
||||||
|
|
||||||
|
if let history = hashtag.history {
|
||||||
|
let sorted = history.sorted(by: { $0.day < $1.day })
|
||||||
|
let lastTwo = sorted[(sorted.count - 2)...]
|
||||||
|
let accounts = lastTwo.map(\.accounts).reduce(0, +)
|
||||||
|
let uses = lastTwo.map(\.uses).reduce(0, +)
|
||||||
|
|
||||||
|
let format = NSLocalizedString("trending hashtag info", comment: "trending hashtag posts and people")
|
||||||
|
peopleTodayLabel.text = String.localizedStringWithFormat(format, accounts, uses)
|
||||||
|
peopleTodayLabel.isHidden = false
|
||||||
|
} else {
|
||||||
|
peopleTodayLabel.isHidden = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,73 @@
|
||||||
|
<?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">
|
||||||
|
<device id="retina6_1" orientation="portrait" appearance="light"/>
|
||||||
|
<dependencies>
|
||||||
|
<deployment identifier="iOS"/>
|
||||||
|
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17703"/>
|
||||||
|
<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"/>
|
||||||
|
</dependencies>
|
||||||
|
<objects>
|
||||||
|
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
|
||||||
|
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||||
|
<tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" id="KGk-i7-Jjw" customClass="TrendingHashtagTableViewCell" customModule="Tusker" customModuleProvider="target">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="320" height="66"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="KGk-i7-Jjw" id="H2p-sc-9uM">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="320" height="66"/>
|
||||||
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
|
<subviews>
|
||||||
|
<stackView opaque="NO" contentMode="scaleToFill" alignment="center" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="tEP-en-vHK">
|
||||||
|
<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"/>
|
||||||
|
<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"/>
|
||||||
|
<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"/>
|
||||||
|
<fontDescription key="fontDescription" style="UICTFontTextStyleCaption1"/>
|
||||||
|
<nil key="textColor"/>
|
||||||
|
<nil key="highlightedColor"/>
|
||||||
|
</label>
|
||||||
|
</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"/>
|
||||||
|
<color key="backgroundColor" systemColor="secondarySystemGroupedBackgroundColor"/>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstAttribute="height" constant="28" id="W4C-uw-zWg"/>
|
||||||
|
<constraint firstAttribute="width" constant="100" id="XHb-vd-qNk"/>
|
||||||
|
</constraints>
|
||||||
|
</view>
|
||||||
|
</subviews>
|
||||||
|
</stackView>
|
||||||
|
</subviews>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstItem="tEP-en-vHK" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="top" id="3Qd-rF-nGk"/>
|
||||||
|
<constraint firstAttribute="trailingMargin" secondItem="tEP-en-vHK" secondAttribute="trailing" id="Ws6-oZ-9Es"/>
|
||||||
|
<constraint firstItem="tEP-en-vHK" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leadingMargin" id="if4-Ea-awg"/>
|
||||||
|
<constraint firstAttribute="bottom" secondItem="tEP-en-vHK" secondAttribute="bottom" id="nTV-Ih-vTj"/>
|
||||||
|
</constraints>
|
||||||
|
</tableViewCellContentView>
|
||||||
|
<viewLayoutGuide key="safeArea" id="njF-e1-oar"/>
|
||||||
|
<connections>
|
||||||
|
<outlet property="hashtagLabel" destination="SIS-9e-Paj" id="1UK-Va-3rL"/>
|
||||||
|
<outlet property="historyView" destination="Xrw-2v-ybZ" id="OIh-K9-gSk"/>
|
||||||
|
<outlet property="peopleTodayLabel" destination="Kc5-BL-bmu" id="5L8-aO-zt4"/>
|
||||||
|
</connections>
|
||||||
|
<point key="canvasLocation" x="132" y="132"/>
|
||||||
|
</tableViewCell>
|
||||||
|
</objects>
|
||||||
|
<resources>
|
||||||
|
<systemColor name="secondarySystemGroupedBackgroundColor">
|
||||||
|
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||||
|
</systemColor>
|
||||||
|
</resources>
|
||||||
|
</document>
|
|
@ -0,0 +1,33 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>trending hashtag info</key>
|
||||||
|
<dict>
|
||||||
|
<key>NSStringLocalizedFormatKey</key>
|
||||||
|
<string>%#@accounts@, %#@posts@ recently</string>
|
||||||
|
<key>posts</key>
|
||||||
|
<dict>
|
||||||
|
<key>NSStringFormatSpecTypeKey</key>
|
||||||
|
<string>NSStringPluralRuleType</string>
|
||||||
|
<key>NSStringFormatValueTypeKey</key>
|
||||||
|
<string>u</string>
|
||||||
|
<key>one</key>
|
||||||
|
<string>1 post</string>
|
||||||
|
<key>other</key>
|
||||||
|
<string>%u posts</string>
|
||||||
|
</dict>
|
||||||
|
<key>accounts</key>
|
||||||
|
<dict>
|
||||||
|
<key>NSStringFormatSpecTypeKey</key>
|
||||||
|
<string>NSStringPluralRuleType</string>
|
||||||
|
<key>NSStringFormatValueTypeKey</key>
|
||||||
|
<string>u</string>
|
||||||
|
<key>one</key>
|
||||||
|
<string>1 person</string>
|
||||||
|
<key>other</key>
|
||||||
|
<string>%u people</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
Loading…
Reference in New Issue