Skip to content

Commit b29b369

Browse files
committed
Retry search without the category if there are no results
1 parent bd1339e commit b29b369

File tree

12 files changed

+174
-42
lines changed

12 files changed

+174
-42
lines changed

Localization/StringsConvertor/input/Base.lproj/app.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,7 @@
346346
"search": {
347347
"placeholder": "Search name or URL"
348348
},
349+
"category_ignored_message": "No servers found in the “%s” category. Here are results from other categories:",
349350
"no_server_selected_hint": "We’ll pick a server based on your language if you continue without making a selection."
350351
},
351352
"privacy": {

Localization/app.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,7 @@
346346
"search": {
347347
"placeholder": "Search name or URL"
348348
},
349+
"category_ignored_message": "No servers found in the “%s” category. Here are results from other categories:",
349350
"no_server_selected_hint": "We’ll pick a server based on your language if you continue without making a selection."
350351
},
351352
"privacy": {

Mastodon.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@
124124
62FD27D12893707600B205C5 /* BookmarkViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62FD27D02893707600B205C5 /* BookmarkViewController.swift */; };
125125
62FD27D32893707B00B205C5 /* BookmarkViewController+DataSourceProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62FD27D22893707B00B205C5 /* BookmarkViewController+DataSourceProvider.swift */; };
126126
62FD27D52893708A00B205C5 /* BookmarkViewModel+Diffable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62FD27D42893708A00B205C5 /* BookmarkViewModel+Diffable.swift */; };
127+
852198A82A4F304500D137AC /* PickServerMessageTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 852198A72A4F304500D137AC /* PickServerMessageTableViewCell.swift */; };
127128
855149C8295F1C5F00943D96 /* UIInterfaceOrientationMask.swift in Sources */ = {isa = PBXBuildFile; fileRef = 855149C7295F1C5F00943D96 /* UIInterfaceOrientationMask.swift */; };
128129
855149CA29606D6400943D96 /* PortraitAlertController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 855149C929606D6400943D96 /* PortraitAlertController.swift */; };
129130
85904C02293BC0EB0011C817 /* ImageProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85904C01293BC0EB0011C817 /* ImageProvider.swift */; };
@@ -749,6 +750,7 @@
749750
7CB58D292DA7ACEF179A9050 /* Pods-Mastodon.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon.profile.xcconfig"; path = "Target Support Files/Pods-Mastodon/Pods-Mastodon.profile.xcconfig"; sourceTree = "<group>"; };
750751
7CEFFAE9AF9284B13C0A758D /* Pods-MastodonTests.asdk - debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MastodonTests.asdk - debug.xcconfig"; path = "Target Support Files/Pods-MastodonTests/Pods-MastodonTests.asdk - debug.xcconfig"; sourceTree = "<group>"; };
751752
819CEC9DCAD8E8E7BD85A7BB /* Pods-Mastodon.asdk.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon.asdk.xcconfig"; path = "Target Support Files/Pods-Mastodon/Pods-Mastodon.asdk.xcconfig"; sourceTree = "<group>"; };
753+
852198A72A4F304500D137AC /* PickServerMessageTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PickServerMessageTableViewCell.swift; sourceTree = "<group>"; };
752754
855149C7295F1C5F00943D96 /* UIInterfaceOrientationMask.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIInterfaceOrientationMask.swift; sourceTree = "<group>"; };
753755
855149C929606D6400943D96 /* PortraitAlertController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PortraitAlertController.swift; sourceTree = "<group>"; };
754756
85904C01293BC0EB0011C817 /* ImageProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageProvider.swift; sourceTree = "<group>"; };
@@ -1357,6 +1359,7 @@
13571359
children = (
13581360
0FB3D33725E6401400AAD544 /* PickServerCell.swift */,
13591361
DB0F814F264D1E2500F2A12B /* PickServerLoaderTableViewCell.swift */,
1362+
852198A72A4F304500D137AC /* PickServerMessageTableViewCell.swift */,
13601363
);
13611364
path = TableViewCell;
13621365
sourceTree = "<group>";
@@ -3648,6 +3651,7 @@
36483651
DB5B549F2833A72500DEF8B2 /* FamiliarFollowersViewModel+Diffable.swift in Sources */,
36493652
DB6B351E2601FAEE00DC1E11 /* ComposeStatusAttachmentCollectionViewCell.swift in Sources */,
36503653
DB8F7076279E954700E1225B /* DataSourceFacade+Follow.swift in Sources */,
3654+
852198A82A4F304500D137AC /* PickServerMessageTableViewCell.swift in Sources */,
36513655
DB63F7542799491600455B82 /* DataSourceFacade+SearchHistory.swift in Sources */,
36523656
DB7A9F912818EAF10016AF98 /* MastodonRegisterView.swift in Sources */,
36533657
DBF1572F27046F1A00EC00B7 /* SecondaryPlaceholderViewController.swift in Sources */,

Mastodon/Scene/Onboarding/PickServer/CategoryPickerItem.swift

Lines changed: 34 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,39 @@ enum CategoryPickerItem {
1717
case category(category: Mastodon.Entity.Category)
1818
}
1919

20+
extension Mastodon.Entity.Category.Kind {
21+
var label: String {
22+
switch self {
23+
case .academia:
24+
return L10n.Scene.ServerPicker.Button.Category.academia
25+
case .activism:
26+
return L10n.Scene.ServerPicker.Button.Category.activism
27+
case .food:
28+
return L10n.Scene.ServerPicker.Button.Category.food
29+
case .furry:
30+
return L10n.Scene.ServerPicker.Button.Category.furry
31+
case .games:
32+
return L10n.Scene.ServerPicker.Button.Category.games
33+
case .general:
34+
return L10n.Scene.ServerPicker.Button.Category.general
35+
case .journalism:
36+
return L10n.Scene.ServerPicker.Button.Category.journalism
37+
case .lgbt:
38+
return L10n.Scene.ServerPicker.Button.Category.lgbt
39+
case .regional:
40+
return L10n.Scene.ServerPicker.Button.Category.regional
41+
case .art:
42+
return L10n.Scene.ServerPicker.Button.Category.art
43+
case .music:
44+
return L10n.Scene.ServerPicker.Button.Category.music
45+
case .tech:
46+
return L10n.Scene.ServerPicker.Button.Category.tech
47+
case ._other:
48+
return "-" // FIXME:
49+
}
50+
}
51+
}
52+
2053
extension CategoryPickerItem {
2154

2255
var title: String {
@@ -38,34 +71,7 @@ extension CategoryPickerItem {
3871
return L10n.Scene.ServerPicker.Button.signupSpeed
3972
}
4073
case .category(let category):
41-
switch category.category {
42-
case .academia:
43-
return L10n.Scene.ServerPicker.Button.Category.academia
44-
case .activism:
45-
return L10n.Scene.ServerPicker.Button.Category.activism
46-
case .food:
47-
return L10n.Scene.ServerPicker.Button.Category.food
48-
case .furry:
49-
return L10n.Scene.ServerPicker.Button.Category.furry
50-
case .games:
51-
return L10n.Scene.ServerPicker.Button.Category.games
52-
case .general:
53-
return L10n.Scene.ServerPicker.Button.Category.general
54-
case .journalism:
55-
return L10n.Scene.ServerPicker.Button.Category.journalism
56-
case .lgbt:
57-
return L10n.Scene.ServerPicker.Button.Category.lgbt
58-
case .regional:
59-
return L10n.Scene.ServerPicker.Button.Category.regional
60-
case .art:
61-
return L10n.Scene.ServerPicker.Button.Category.art
62-
case .music:
63-
return L10n.Scene.ServerPicker.Button.Category.music
64-
case .tech:
65-
return L10n.Scene.ServerPicker.Button.Category.tech
66-
case ._other:
67-
return "-" // FIXME:
68-
}
74+
return category.category.label
6975
}
7076
}
7177

Mastodon/Scene/Onboarding/PickServer/MastodonPickServerViewModel+Diffable.swift

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -69,14 +69,21 @@ extension MastodonPickServerViewModel {
6969

7070
// TODO: handle filter
7171
var serverItems: [PickServerItem] = []
72-
for server in indexedServers {
73-
let attribute = oldSnapshotServerItemAttributeDict[server.domain] ?? PickServerItem.ServerItemAttribute(isLast: false, isExpand: false)
74-
attribute.isLast.value = false
75-
let item = PickServerItem.server(server: server, attribute: attribute)
76-
guard !serverItems.contains(item) else { continue }
77-
serverItems.append(item)
72+
if let indexedServers {
73+
if indexedServers.didIgnoreCategory,
74+
indexedServers.servers.isNotEmpty,
75+
case .category(let category) = selectCategoryItem.value {
76+
serverItems.append(.message(attribute: .categoryIgnored(category: category.category)))
77+
}
78+
for server in indexedServers.servers {
79+
let attribute = oldSnapshotServerItemAttributeDict[server.domain] ?? PickServerItem.ServerItemAttribute(isLast: false, isExpand: false)
80+
attribute.isLast.value = false
81+
let item = PickServerItem.server(server: server, attribute: attribute)
82+
guard !serverItems.contains(item) else { continue }
83+
serverItems.append(item)
84+
}
7885
}
79-
86+
8087
if let unindexedServers = unindexedServers {
8188
if !unindexedServers.isEmpty {
8289
for server in unindexedServers {
@@ -87,7 +94,8 @@ extension MastodonPickServerViewModel {
8794
serverItems.append(item)
8895
}
8996
} else {
90-
if indexedServers.isEmpty && !self.isLoadingIndexedServers.value {
97+
if (indexedServers?.servers.isEmpty ?? true),
98+
!self.isLoadingIndexedServers.value {
9199
serverItems.append(.loader(attribute: PickServerItem.LoaderItemAttribute(isLast: false, isEmptyResult: true)))
92100
}
93101
}

Mastodon/Scene/Onboarding/PickServer/MastodonPickServerViewModel.swift

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ class MastodonPickServerViewModel: NSObject {
6363
stateMachine.enter(LoadIndexedServerState.Initial.self)
6464
return stateMachine
6565
}()
66-
let filteredIndexedServers = CurrentValueSubject<[Mastodon.Entity.Server], Never>([])
66+
let filteredIndexedServers = CurrentValueSubject<FilteredServers?, Never>(nil)
6767
let servers = CurrentValueSubject<[Mastodon.Entity.Server], Error>([])
6868
let selectedServer = CurrentValueSubject<Mastodon.Entity.Server?, Never>(nil)
6969
let error = CurrentValueSubject<Error?, Never>(nil)
@@ -126,7 +126,7 @@ extension MastodonPickServerViewModel {
126126
(selectedLanguage, manualApprovalRequired)
127127
}
128128
)
129-
.map { [weak self] indexedServers, selectCategoryItem, searchText, filters -> [Mastodon.Entity.Server] in
129+
.map { [weak self] indexedServers, selectCategoryItem, searchText, filters in
130130
var indexedServers = indexedServers
131131

132132
var _indexedServers: [Mastodon.Entity.Server] = []
@@ -249,7 +249,11 @@ extension MastodonPickServerViewModel {
249249
}
250250

251251
extension MastodonPickServerViewModel {
252-
private static func filterServers(servers: [Mastodon.Entity.Server], language: String? = nil, manualApprovalRequired: Bool? = nil, category: String?, searchText: String) -> [Mastodon.Entity.Server] {
252+
struct FilteredServers {
253+
let servers: [Mastodon.Entity.Server]
254+
let didIgnoreCategory: Bool
255+
}
256+
private static func filterServers(servers: [Mastodon.Entity.Server], language: String? = nil, manualApprovalRequired: Bool? = nil, category: String?, searchText: String) -> FilteredServers {
253257
let filteredServers = servers
254258
// 1. Filter the category
255259
.filter {
@@ -275,7 +279,14 @@ extension MastodonPickServerViewModel {
275279
print("\($0.domain) \($0.approvalRequired) < \(manualApprovalRequired)")
276280
return $0.approvalRequired == manualApprovalRequired
277281
}
278-
return filteredServers
282+
283+
// if there are no results when filtering by category, drop the category filter
284+
if category != nil, filteredServers.isEmpty {
285+
let result = filterServers(servers: servers, language: language, manualApprovalRequired: manualApprovalRequired, category: nil, searchText: searchText)
286+
return FilteredServers(servers: result.servers, didIgnoreCategory: true)
287+
}
288+
289+
return FilteredServers(servers: filteredServers, didIgnoreCategory: false)
279290
}
280291
}
281292

Mastodon/Scene/Onboarding/PickServer/PickServerItem.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import MastodonSDK
1313
enum PickServerItem {
1414
case server(server: Mastodon.Entity.Server, attribute: ServerItemAttribute)
1515
case loader(attribute: LoaderItemAttribute)
16+
case message(attribute: MessageItemAttribute)
1617
}
1718

1819
extension PickServerItem {
@@ -53,6 +54,10 @@ extension PickServerItem {
5354
hasher.combine(id)
5455
}
5556
}
57+
58+
enum MessageItemAttribute: Equatable, Hashable {
59+
case categoryIgnored(category: Mastodon.Entity.Category.Kind)
60+
}
5661
}
5762

5863
extension PickServerItem: Equatable {
@@ -75,6 +80,8 @@ extension PickServerItem: Hashable {
7580
hasher.combine(server.domain)
7681
case .loader(let attribute):
7782
hasher.combine(attribute)
83+
case .message(let attribute):
84+
hasher.combine(attribute)
7885
}
7986
}
8087
}

Mastodon/Scene/Onboarding/PickServer/PickServerSection.swift

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
import UIKit
99
import MastodonSDK
10+
import MastodonLocalization
1011
import Kanna
1112
import AlamofireImage
1213

@@ -22,7 +23,8 @@ extension PickServerSection {
2223
) -> UITableViewDiffableDataSource<PickServerSection, PickServerItem> {
2324
tableView.register(PickServerCell.self, forCellReuseIdentifier: String(describing: PickServerCell.self))
2425
tableView.register(PickServerLoaderTableViewCell.self, forCellReuseIdentifier: String(describing: PickServerLoaderTableViewCell.self))
25-
26+
tableView.register(PickServerMessageTableViewCell.self, forCellReuseIdentifier: String(describing: PickServerMessageTableViewCell.self))
27+
2628
return UITableViewDiffableDataSource(tableView: tableView) { [
2729
weak dependency
2830
] tableView, indexPath, item -> UITableViewCell? in
@@ -36,6 +38,10 @@ extension PickServerSection {
3638
let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: PickServerLoaderTableViewCell.self), for: indexPath) as! PickServerLoaderTableViewCell
3739
PickServerSection.configure(cell: cell, attribute: attribute)
3840
return cell
41+
case .message(let message):
42+
let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: PickServerMessageTableViewCell.self), for: indexPath) as! PickServerMessageTableViewCell
43+
PickServerSection.configure(cell: cell, attribute: message)
44+
return cell
3945
}
4046
}
4147
}
@@ -112,3 +118,14 @@ extension PickServerSection {
112118
}
113119

114120
}
121+
122+
extension PickServerSection {
123+
124+
static func configure(cell: PickServerMessageTableViewCell, attribute: PickServerItem.MessageItemAttribute) {
125+
switch attribute {
126+
case .categoryIgnored(let category):
127+
cell.messageLabel.text = L10n.Scene.ServerPicker.categoryIgnoredMessage(category.label)
128+
}
129+
}
130+
131+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
//
2+
// PickServerMessageTableViewCell.swift
3+
// Mastodon
4+
//
5+
// Created by MainasuK Cirno on 2021-5-13.
6+
//
7+
8+
import UIKit
9+
import Combine
10+
import MastodonAsset
11+
import MastodonCore
12+
import MastodonUI
13+
import MastodonLocalization
14+
15+
public final class PickServerMessageTableViewCell: UITableViewCell {
16+
17+
let messageLabel: UILabel = {
18+
let label = UILabel()
19+
label.textColor = Asset.Colors.Label.secondary.color
20+
label.textAlignment = .center
21+
label.font = UIFontMetrics(forTextStyle: .headline).scaledFont(for: .systemFont(ofSize: 14, weight: .semibold))
22+
label.numberOfLines = 0
23+
return label
24+
}()
25+
26+
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
27+
super.init(style: style, reuseIdentifier: reuseIdentifier)
28+
_init()
29+
}
30+
31+
required init?(coder: NSCoder) {
32+
super.init(coder: coder)
33+
_init()
34+
}
35+
36+
}
37+
38+
extension PickServerMessageTableViewCell {
39+
public func _init() {
40+
selectionStyle = .none
41+
backgroundColor = .clear
42+
43+
messageLabel.translatesAutoresizingMaskIntoConstraints = false
44+
messageLabel.setContentCompressionResistancePriority(.required, for: .vertical)
45+
contentView.addSubview(messageLabel)
46+
NSLayoutConstraint.activate([
47+
messageLabel.leadingAnchor.constraint(equalTo: contentView.readableContentGuide.leadingAnchor),
48+
contentView.readableContentGuide.trailingAnchor.constraint(equalTo: messageLabel.trailingAnchor),
49+
messageLabel.topAnchor.constraint(equalTo: contentView.layoutMarginsGuide.topAnchor),
50+
messageLabel.bottomAnchor.constraint(equalTo: contentView.layoutMarginsGuide.bottomAnchor),
51+
])
52+
}
53+
54+
}
55+
56+
#if canImport(SwiftUI) && DEBUG
57+
import SwiftUI
58+
59+
struct PickServerMessageTableViewCell_Previews: PreviewProvider {
60+
61+
static var previews: some View {
62+
UIViewPreview(width: 375) {
63+
let view = PickServerMessageTableViewCell()
64+
view.messageLabel.text = "Hello, world!"
65+
return view
66+
}
67+
.previewLayout(.fixed(width: 375, height: 100))
68+
}
69+
70+
}
71+
72+
#endif

MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1302,6 +1302,10 @@ public enum L10n {
13021302
}
13031303
}
13041304
public enum ServerPicker {
1305+
/// No servers found in the “%@” category. Here are results from other categories:
1306+
public static func categoryIgnoredMessage(_ p1: Any) -> String {
1307+
return L10n.tr("Localizable", "Scene.ServerPicker.CategoryIgnoredMessage", String(describing: p1), fallback: "No servers found in the “%@” category. Here are results from other categories:")
1308+
}
13051309
/// We’ll pick a server based on your language if you continue without making a selection.
13061310
public static let noServerSelectedHint = L10n.tr("Localizable", "Scene.ServerPicker.NoServerSelectedHint", fallback: "We’ll pick a server based on your language if you continue without making a selection.")
13071311
/// Pick Server

0 commit comments

Comments
 (0)