chore: suggestion use v2 api

This commit is contained in:
sunxiaojian 2021-04-20 15:40:10 +08:00
parent eb89ff6bdc
commit 731b49aaa0
10 changed files with 98 additions and 28 deletions

View File

@ -84,7 +84,7 @@ final class HashtagTimelineViewModel: NSObject {
guard let activeMastodonAuthenticationBox = context.authenticationService.activeMastodonAuthenticationBox.value else {
return
}
let query = Mastodon.API.Search.Query(q: hashtag, type: .hashtags)
let query = Mastodon.API.V2.Search.Query(q: hashtag, type: .hashtags)
context.apiService.search(domain: activeMastodonAuthenticationBox.domain, query: query, mastodonAuthenticationBox: activeMastodonAuthenticationBox)
.sink { _ in

View File

@ -217,11 +217,11 @@ extension SearchViewController: UISearchBarDelegate {
func searchBar(_ searchBar: UISearchBar, selectedScopeButtonIndexDidChange selectedScope: Int) {
switch selectedScope {
case 0:
viewModel.searchScope.value = Mastodon.API.Search.SearchType.default
viewModel.searchScope.value = Mastodon.API.V2.Search.SearchType.default
case 1:
viewModel.searchScope.value = Mastodon.API.Search.SearchType.accounts
viewModel.searchScope.value = Mastodon.API.V2.Search.SearchType.accounts
case 2:
viewModel.searchScope.value = Mastodon.API.Search.SearchType.hashtags
viewModel.searchScope.value = Mastodon.API.V2.Search.SearchType.hashtags
default:
break
}

View File

@ -53,14 +53,14 @@ extension SearchViewModel.LoadOldestState {
}
var offset = 0
switch viewModel.searchScope.value {
case Mastodon.API.Search.SearchType.accounts:
case Mastodon.API.V2.Search.SearchType.accounts:
offset = oldSearchResult.accounts.count
case Mastodon.API.Search.SearchType.hashtags:
case Mastodon.API.V2.Search.SearchType.hashtags:
offset = oldSearchResult.hashtags.count
default:
return
}
let query = Mastodon.API.Search.Query(q: viewModel.searchText.value,
let query = Mastodon.API.V2.Search.Query(q: viewModel.searchText.value,
type: viewModel.searchScope.value,
accountID: nil,
maxID: nil,
@ -82,7 +82,7 @@ extension SearchViewModel.LoadOldestState {
}
} receiveValue: { result in
switch viewModel.searchScope.value {
case Mastodon.API.Search.SearchType.accounts:
case Mastodon.API.V2.Search.SearchType.accounts:
if result.value.accounts.isEmpty {
stateMachine.enter(NoMore.self)
} else {
@ -93,7 +93,7 @@ extension SearchViewModel.LoadOldestState {
viewModel.searchResult.value = Mastodon.Entity.SearchResult(accounts: newAccounts, statuses: oldSearchResult.statuses, hashtags: oldSearchResult.hashtags)
stateMachine.enter(Idle.self)
}
case Mastodon.API.Search.SearchType.hashtags:
case Mastodon.API.V2.Search.SearchType.hashtags:
if result.value.hashtags.isEmpty {
stateMachine.enter(NoMore.self)
} else {

View File

@ -26,7 +26,7 @@ final class SearchViewModel: NSObject {
// output
let searchText = CurrentValueSubject<String, Never>("")
let searchScope = CurrentValueSubject<Mastodon.API.Search.SearchType, Never>(Mastodon.API.Search.SearchType.default)
let searchScope = CurrentValueSubject<Mastodon.API.V2.Search.SearchType, Never>(Mastodon.API.V2.Search.SearchType.default)
let isSearching = CurrentValueSubject<Bool, Never>(false)
@ -86,7 +86,7 @@ final class SearchViewModel: NSObject {
}
.flatMap { (text, scope) -> AnyPublisher<Mastodon.Response.Content<Mastodon.Entity.SearchResult>, Error> in
let query = Mastodon.API.Search.Query(q: text,
let query = Mastodon.API.V2.Search.Query(q: text,
type: scope,
accountID: nil,
maxID: nil,
@ -130,8 +130,8 @@ final class SearchViewModel: NSObject {
snapshot.appendSections([.mixed])
searchHistories.forEach { searchHistory in
let containsAccount = scope == Mastodon.API.Search.SearchType.accounts || scope == Mastodon.API.Search.SearchType.default
let containsHashTag = scope == Mastodon.API.Search.SearchType.hashtags || scope == Mastodon.API.Search.SearchType.default
let containsAccount = scope == Mastodon.API.V2.Search.SearchType.accounts || scope == Mastodon.API.V2.Search.SearchType.default
let containsHashTag = scope == Mastodon.API.V2.Search.SearchType.hashtags || scope == Mastodon.API.V2.Search.SearchType.default
if let mastodonUser = searchHistory.account, containsAccount {
let item = SearchResultItem.accountObjectID(accountObjectID: mastodonUser.objectID)
snapshot.appendItems([item], toSection: .mixed)
@ -186,7 +186,7 @@ final class SearchViewModel: NSObject {
snapshot.appendSections([.account])
let items = accounts.compactMap { SearchResultItem.account(account: $0) }
snapshot.appendItems(items, toSection: .account)
if self.searchScope.value == Mastodon.API.Search.SearchType.accounts, !items.isEmpty {
if self.searchScope.value == Mastodon.API.V2.Search.SearchType.accounts, !items.isEmpty {
snapshot.appendItems([.bottomLoader], toSection: .account)
}
}
@ -194,7 +194,7 @@ final class SearchViewModel: NSObject {
snapshot.appendSections([.hashtag])
let items = tags.compactMap { SearchResultItem.hashtag(tag: $0) }
snapshot.appendItems(items, toSection: .hashtag)
if self.searchScope.value == Mastodon.API.Search.SearchType.hashtags, !items.isEmpty {
if self.searchScope.value == Mastodon.API.V2.Search.SearchType.hashtags, !items.isEmpty {
snapshot.appendItems([.bottomLoader], toSection: .hashtag)
}
}
@ -245,7 +245,7 @@ final class SearchViewModel: NSObject {
}
} receiveValue: { [weak self] accounts in
guard let self = self else { return }
let ids = accounts.value.compactMap({$0.id})
let ids = accounts.value.compactMap({$0.account.id})
let userFetchRequest = MastodonUser.sortedFetchRequest
userFetchRequest.predicate = MastodonUser.predicate(domain: activeMastodonAuthenticationBox.domain, ids: ids)
let mastodonUsers: [MastodonUser]? = {

View File

@ -17,21 +17,22 @@ extension APIService {
domain: String,
query: Mastodon.API.Suggestions.Query?,
mastodonAuthenticationBox: AuthenticationService.MastodonAuthenticationBox
) -> AnyPublisher<Mastodon.Response.Content<[Mastodon.Entity.Account]>, Error> {
) -> AnyPublisher<Mastodon.Response.Content<[Mastodon.Entity.V2.SuggestionAccount]>, Error> {
let authorization = mastodonAuthenticationBox.userAuthorization
return Mastodon.API.Suggestions.get(session: session, domain: domain, query: query, authorization: authorization)
.flatMap { response -> AnyPublisher<Mastodon.Response.Content<[Mastodon.Entity.Account]>, Error> in
return Mastodon.API.V2.Suggestions.get(session: session, domain: domain, query: query, authorization: authorization)
.flatMap { response -> AnyPublisher<Mastodon.Response.Content<[Mastodon.Entity.V2.SuggestionAccount]>, Error> in
let log = OSLog.api
return self.backgroundManagedObjectContext.performChanges {
response.value.forEach { user in
response.value.forEach { suggestionAccount in
let user = suggestionAccount.account
let (mastodonUser,isCreated) = APIService.CoreData.createOrMergeMastodonUser(into: self.backgroundManagedObjectContext, for: nil, in: domain, entity: user, userCache: nil, networkDate: Date(), log: log)
let flag = isCreated ? "+" : "-"
os_log(.info, log: log, "%{public}s[%{public}ld], %{public}s: fetch mastodon user [%s](%s)%s", (#file as NSString).lastPathComponent, #line, #function, flag, mastodonUser.id, mastodonUser.username)
}
}
.setFailureType(to: Error.self)
.tryMap { result -> Mastodon.Response.Content<[Mastodon.Entity.Account]> in
.tryMap { result -> Mastodon.Response.Content<[Mastodon.Entity.V2.SuggestionAccount]> in
switch result {
case .success:
return response

View File

@ -13,11 +13,11 @@ extension APIService {
func search(
domain: String,
query: Mastodon.API.Search.Query,
query: Mastodon.API.V2.Search.Query,
mastodonAuthenticationBox: AuthenticationService.MastodonAuthenticationBox
) -> AnyPublisher<Mastodon.Response.Content<Mastodon.Entity.SearchResult>, Error> {
let authorization = mastodonAuthenticationBox.userAuthorization
return Mastodon.API.Search.search(session: session, domain: domain, query: query, authorization: authorization)
return Mastodon.API.V2.Search.search(session: session, domain: domain, query: query, authorization: authorization)
}
}

View File

@ -8,7 +8,7 @@
import Combine
import Foundation
extension Mastodon.API.Search {
extension Mastodon.API.V2.Search {
static func searchURL(domain: String) -> URL {
Mastodon.API.endpointV2URL(domain: domain).appendingPathComponent("search")
}
@ -32,7 +32,7 @@ extension Mastodon.API.Search {
public static func search(
session: URLSession,
domain: String,
query: Mastodon.API.Search.Query,
query: Mastodon.API.V2.Search.Query,
authorization: Mastodon.API.OAuth.Authorization
) -> AnyPublisher<Mastodon.Response.Content<Mastodon.Entity.SearchResult>, Error> {
let request = Mastodon.API.get(
@ -49,7 +49,7 @@ extension Mastodon.API.Search {
}
}
extension Mastodon.API.Search {
extension Mastodon.API.V2.Search {
public struct Query: Codable, GetQuery {
public init(q: String,
@ -105,7 +105,7 @@ extension Mastodon.API.Search {
}
}
public extension Mastodon.API.Search {
public extension Mastodon.API.V2.Search {
enum SearchType: String, Codable {
case accounts
case hashtags

View File

@ -0,0 +1,41 @@
//
// Mastodon+API+V2+Suggestions.swift
//
//
// Created by sxiaojian on 2021/4/20.
//
import Combine
import Foundation
extension Mastodon.API.V2.Suggestions {
static func suggestionsURL(domain: String) -> URL {
Mastodon.API.endpointV2URL(domain: domain).appendingPathComponent("suggestions")
}
/// Follow suggestions, No document for now
/// - Parameters:
/// - session: `URLSession`
/// - domain: Mastodon instance domain. e.g. "example.com"
/// - query: query
/// - authorization: User token.
/// - Returns: `AnyPublisher` contains `AccountsSuggestion` nested in the response
public static func get(
session: URLSession,
domain: String,
query: Mastodon.API.Suggestions.Query?,
authorization: Mastodon.API.OAuth.Authorization
) -> AnyPublisher<Mastodon.Response.Content<[Mastodon.Entity.V2.SuggestionAccount]>, Error> {
let request = Mastodon.API.get(
url: suggestionsURL(domain: domain),
query: query,
authorization: authorization
)
return session.dataTaskPublisher(for: request)
.tryMap { data, response in
let value = try Mastodon.API.decode(type: [Mastodon.Entity.V2.SuggestionAccount].self, from: data, response: response)
return Mastodon.Response.Content(value: value, response: response)
}
.eraseToAnyPublisher()
}
}

View File

@ -99,6 +99,7 @@ extension Mastodon.API {
}
extension Mastodon.API {
public enum V2 { }
public enum Account { }
public enum App { }
public enum CustomEmojis { }
@ -111,13 +112,17 @@ extension Mastodon.API {
public enum Reblog { }
public enum Statuses { }
public enum Timeline { }
public enum Search { }
public enum Trends { }
public enum Suggestions { }
public enum Notifications { }
public enum Subscriptions { }
}
extension Mastodon.API.V2 {
public enum Search { }
public enum Suggestions { }
}
extension Mastodon.API {
static func get(

View File

@ -0,0 +1,23 @@
//
// Mastodon+Entity+Suggestion.swift
//
//
// Created by sxiaojian on 2021/4/20.
//
import Foundation
extension Mastodon.Entity.V2 {
public struct SuggestionAccount: Codable {
public let source: String
public let account: Mastodon.Entity.Account
enum CodingKeys: String, CodingKey {
case source
case account
}
}
}