feat: make servers meet user preferred language display first

This commit is contained in:
CMK 2021-08-05 16:17:54 +08:00
parent e1a22ae01e
commit 76b033afed
5 changed files with 70 additions and 12 deletions

View File

@ -280,6 +280,7 @@
DB4FFC2C269EC39600D62E92 /* SearchTransitionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB4FFC2A269EC39600D62E92 /* SearchTransitionController.swift */; };
DB51D172262832380062B7A1 /* BlurHashDecode.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB51D170262832380062B7A1 /* BlurHashDecode.swift */; };
DB51D173262832380062B7A1 /* BlurHashEncode.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB51D171262832380062B7A1 /* BlurHashEncode.swift */; };
DB552D4F26BBD10C00E481F6 /* OrderedCollections in Frameworks */ = {isa = PBXBuildFile; productRef = DB552D4E26BBD10C00E481F6 /* OrderedCollections */; };
DB564BD0269F2F83001E39A7 /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = DB564BCE269F2F83001E39A7 /* Localizable.stringsdict */; };
DB564BD3269F3B35001E39A7 /* StatusFilterService.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB564BD2269F3B35001E39A7 /* StatusFilterService.swift */; };
DB59F0FE25EF5D96001F1DAB /* StatusProvider+UITableViewDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB59F0FD25EF5D96001F1DAB /* StatusProvider+UITableViewDelegate.swift */; };
@ -1311,6 +1312,7 @@
DB6804862637CD4C00430867 /* AppShared.framework in Frameworks */,
DBF96326262EC0A6001D8D25 /* AuthenticationServices.framework in Frameworks */,
DBAC6483267D0B21007FE9FD /* DifferenceKit in Frameworks */,
DB552D4F26BBD10C00E481F6 /* OrderedCollections in Frameworks */,
2D61336925C18A4F00CAE157 /* AlamofireNetworkActivityIndicator in Frameworks */,
DB01E23326A98F0900C3965B /* MastodonMeta in Frameworks */,
DBAC64A1267E6D02007FE9FD /* Fuzi in Frameworks */,
@ -3081,6 +3083,7 @@
DBC6462A26A1738900B0E31B /* MastodonUI */,
DB01E23226A98F0900C3965B /* MastodonMeta */,
DB01E23426A98F0900C3965B /* MetaTextKit */,
DB552D4E26BBD10C00E481F6 /* OrderedCollections */,
);
productName = Mastodon;
productReference = DB427DD225BAA00100D1B89D /* Mastodon.app */;
@ -3328,6 +3331,7 @@
DBF7A0FA26830C33004176A2 /* XCRemoteSwiftPackageReference "FPSIndicator" */,
DB0E2D2C26833FF600865C3C /* XCRemoteSwiftPackageReference "Nuke-FLAnimatedImage-Plugin" */,
DB01E23126A98F0900C3965B /* XCRemoteSwiftPackageReference "MetaTextKit" */,
DB552D4D26BBD10C00E481F6 /* XCRemoteSwiftPackageReference "swift-collections" */,
);
productRefGroup = DB427DD325BAA00100D1B89D /* Products */;
projectDirPath = "";
@ -5644,6 +5648,14 @@
minimumVersion = 4.1.0;
};
};
DB552D4D26BBD10C00E481F6 /* XCRemoteSwiftPackageReference "swift-collections" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/apple/swift-collections.git";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 0.0.5;
};
};
DB6804722637CC1200430867 /* XCRemoteSwiftPackageReference "KeychainAccess" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/kishikawakatsumi/KeychainAccess.git";
@ -5752,6 +5764,11 @@
package = DB3D0FF125BAA61700EAA174 /* XCRemoteSwiftPackageReference "AlamofireImage" */;
productName = AlamofireImage;
};
DB552D4E26BBD10C00E481F6 /* OrderedCollections */ = {
isa = XCSwiftPackageProductDependency;
package = DB552D4D26BBD10C00E481F6 /* XCRemoteSwiftPackageReference "swift-collections" */;
productName = OrderedCollections;
};
DB68050F2637D0F800430867 /* KeychainAccess */ = {
isa = XCSwiftPackageProductDependency;
package = DB6804722637CC1200430867 /* XCRemoteSwiftPackageReference "KeychainAccess" */;

View File

@ -7,12 +7,12 @@
<key>AppShared.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>24</integer>
<integer>26</integer>
</dict>
<key>CoreDataStack.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>25</integer>
<integer>24</integer>
</dict>
<key>Mastodon - ASDK.xcscheme_^#shared#^_</key>
<dict>
@ -42,7 +42,7 @@
<key>MastodonIntent.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>28</integer>
<integer>27</integer>
</dict>
<key>MastodonIntents.xcscheme_^#shared#^_</key>
<dict>
@ -62,7 +62,7 @@
<key>ShareActionExtension.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>26</integer>
<integer>25</integer>
</dict>
</dict>
<key>SuppressBuildableAutocreation</key>

View File

@ -136,6 +136,15 @@
"version": "5.11.1"
}
},
{
"package": "swift-collections",
"repositoryURL": "https://github.com/apple/swift-collections.git",
"state": {
"branch": null,
"revision": "0959ba76a1d4a98fd11163aa83fd49c25b93bfae",
"version": "0.0.5"
}
},
{
"package": "swift-nio",
"repositoryURL": "https://github.com/apple/swift-nio.git",

View File

@ -55,13 +55,7 @@ extension MastodonPickServerViewModel.LoadIndexedServerState {
} receiveValue: { [weak self] response in
guard let _ = self else { return }
stateMachine.enter(Idle.self)
// ignore approval required servers
var servers = response.value
if viewModel.mode == .signUp {
servers = servers.filter { !$0.approvalRequired }
}
viewModel.indexedServers.value = servers
viewModel.indexedServers.value = response.value
}
.store(in: &viewModel.disposeBag)
}

View File

@ -11,6 +11,7 @@ import Combine
import GameplayKit
import MastodonSDK
import CoreDataStack
import OrderedCollections
class MastodonPickServerViewModel: NSObject {
@ -167,7 +168,44 @@ extension MastodonPickServerViewModel {
searchText.debounce(for: .milliseconds(300), scheduler: DispatchQueue.main).removeDuplicates()
)
.map { indexedServers, selectCategoryItem, searchText -> [Mastodon.Entity.Server] in
// Filter the indexed servers from joinmastodon.org
// ignore approval required servers when sign-up
var indexedServers = indexedServers
if self.mode == .signUp {
indexedServers = indexedServers.filter { !$0.approvalRequired }
}
// group by language user preferred language first. Then sort by `totalUsers`
var languageToServersMapping = OrderedDictionary<String, [Mastodon.Entity.Server]>()
for language in Locale.preferredLanguages {
let local = Locale(identifier: language)
guard let languageCode = local.languageCode else { continue }
// skip if key duplicate
guard !languageToServersMapping.keys.contains(languageCode) else { continue }
// append to dict
languageToServersMapping[languageCode] = indexedServers
.filter { $0.language.lowercased() == languageCode.lowercased() }
.sorted(by: { $0.totalUsers > $1.totalUsers })
}
// sort remains servers by `totalUsers`
let remainsServers = indexedServers
.filter { server in
return !languageToServersMapping.contains { _, servers in servers.contains(server) }
}
.sorted(by: { $0.totalUsers > $1.totalUsers })
var _indexedServers: [Mastodon.Entity.Server] = []
for key in languageToServersMapping.keys {
_indexedServers.append(contentsOf: languageToServersMapping[key] ?? [])
}
_indexedServers.append(contentsOf: remainsServers)
if _indexedServers.count == indexedServers.count {
indexedServers = _indexedServers
} else {
assertionFailure("should not change dataset size")
}
// Filter the indexed servers by category or search text
switch selectCategoryItem {
case .all:
return MastodonPickServerViewModel.filterServers(servers: indexedServers, category: nil, searchText: searchText)