Less chatty api calling (#79)

* Limit API calls for instance searching

* Limit api calls

* Fix empty/initial state

* Limit API calls

* Delegate empty view logic to viewmodel

* When you boosted, display You boosted
This commit is contained in:
Sean Goldin 2023-01-15 23:43:53 -06:00 committed by GitHub
parent a49175fe69
commit 75e9516089
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 48 additions and 20 deletions

View File

@ -6,6 +6,7 @@ import DesignSystem
import NukeUI
import Shimmer
import AppAccount
import Combine
struct AddAccountView: View {
@Environment(\.dismiss) private var dismiss
@ -23,6 +24,8 @@ struct AddAccountView: View {
@State private var signInClient: Client?
@State private var instances: [InstanceSocial] = []
@State private var instanceFetchError: String?
private let instanceNamePublisher = PassthroughSubject<String, Never>()
@FocusState private var isInstanceURLFieldFocused: Bool
@ -68,6 +71,9 @@ struct AddAccountView: View {
isSigninIn = false
}
.onChange(of: instanceName) { newValue in
instanceNamePublisher.send(newValue)
}
.onReceive(instanceNamePublisher.debounce(for: .milliseconds(500), scheduler: DispatchQueue.main)) { newValue in
let client = Client(server: newValue)
Task {
do {

View File

@ -5,6 +5,7 @@ import Env
import DesignSystem
import NukeUI
import Shimmer
import Combine
struct AddRemoteTimelineView: View {
@Environment(\.dismiss) private var dismiss
@ -15,6 +16,8 @@ struct AddRemoteTimelineView: View {
@State private var instanceName: String = ""
@State private var instance: Instance?
@State private var instances: [InstanceSocial] = []
private let instanceNamePublisher = PassthroughSubject<String, Never>()
@FocusState private var isInstanceURLFieldFocused: Bool
@ -55,12 +58,15 @@ struct AddRemoteTimelineView: View {
Button("Cancel", action: { dismiss() })
}
}
.onChange(of: instanceName, perform: { newValue in
.onChange(of: instanceName) { newValue in
instanceNamePublisher.send(newValue)
}
.onReceive(instanceNamePublisher.debounce(for: .milliseconds(500), scheduler: DispatchQueue.main)) { newValue in
Task {
let client = Client(server: newValue)
instance = try? await client.get(endpoint: Instances.instance)
}
})
}
.onAppear {
isInstanceURLFieldFocused = true
let client = InstanceSocialClient()

View File

@ -26,10 +26,7 @@ public struct ExploreView: View {
}
} else if !viewModel.isLoaded {
loadingView
} else if viewModel.trendingLinks.isEmpty &&
viewModel.trendingTags.isEmpty &&
viewModel.trendingStatuses.isEmpty &&
viewModel.suggestedAccounts.isEmpty {
} else if viewModel.allSectionsEmpty {
EmptyView(iconName: "magnifyingglass",
title: "Search your instance",
message: "From this screen you can search anything on \(client.server)")

View File

@ -1,6 +1,7 @@
import SwiftUI
import Models
import Network
import Combine
@MainActor
class ExploreViewModel: ObservableObject {
@ -37,21 +38,14 @@ class ExploreViewModel: ObservableObject {
}
}
}
var allSectionsEmpty: Bool {
trendingLinks.isEmpty && trendingTags.isEmpty && trendingStatuses.isEmpty && suggestedAccounts.isEmpty
}
@Published var tokens: [Token] = []
@Published var suggestedToken: [Token] = []
@Published var searchQuery = "" {
didSet {
if searchQuery.starts(with: "@") {
suggestedToken = [.user, .statuses]
} else if searchQuery.starts(with: "#") {
suggestedToken = [.tag]
} else {
suggestedToken = []
}
search()
}
}
@Published var searchQuery = ""
@Published var results: [String: SearchResults] = [:]
@Published var isLoaded = false
@Published var suggestedAccounts: [Account] = []
@ -61,6 +55,27 @@ class ExploreViewModel: ObservableObject {
@Published var trendingLinks: [Card] = []
private var searchTask: Task<Void, Never>?
private var cancellables = Set<AnyCancellable>()
init() {
$searchQuery
.removeDuplicates()
.debounce(for: .milliseconds(500), scheduler: DispatchQueue.main)
.sink(receiveValue: { [weak self] newValue in
guard let self else { return }
if self.searchQuery.starts(with: "@") {
self.suggestedToken = [.user, .statuses]
} else if self.searchQuery.starts(with: "#") {
self.suggestedToken = [.tag]
} else {
self.suggestedToken = []
}
self.search()
})
.store(in: &cancellables)
}
func fetchTrending() async {
guard let client else { return }

View File

@ -98,8 +98,12 @@ public struct StatusRowView: View {
HStack(spacing: 2) {
Image(systemName:"arrow.left.arrow.right.circle.fill")
AvatarView(url: viewModel.status.account.avatar, size: .boost)
EmojiTextApp(viewModel.status.account.safeDisplayName.asMarkdown, emojis: viewModel.status.account.emojis)
Text("boosted")
if viewModel.status.account.username != account.account?.username {
EmojiTextApp(viewModel.status.account.safeDisplayName.asMarkdown, emojis: viewModel.status.account.emojis)
Text("boosted")
} else {
Text("You boosted")
}
}
.font(.footnote)
.foregroundColor(.gray)