IceCubes/IceCubesApp/App/Tabs/Timeline/AddRemoteTimelineView.swift

112 lines
3.5 KiB
Swift
Raw Normal View History

2023-01-17 11:36:01 +01:00
import Combine
import DesignSystem
2023-01-17 11:36:01 +01:00
import Env
import Models
import Network
import NukeUI
2023-01-17 11:36:01 +01:00
import SwiftUI
2023-09-19 09:18:20 +02:00
@MainActor
2023-01-06 17:14:34 +01:00
struct AddRemoteTimelineView: View {
@Environment(\.dismiss) private var dismiss
2023-09-22 12:49:25 +02:00
@Environment(\.modelContext) private var context
2023-01-17 11:36:01 +01:00
2023-09-19 09:18:20 +02:00
@Environment(UserPreferences.self) private var preferences
2023-09-18 21:03:52 +02:00
@Environment(Theme.self) private var theme
2023-01-17 11:36:01 +01:00
@State private var instanceName: String = ""
@State private var instance: Instance?
@State private var instances: [InstanceSocial] = []
private let instanceNamePublisher = PassthroughSubject<String, Never>()
2023-01-17 11:36:01 +01:00
@FocusState private var isInstanceURLFieldFocused: Bool
2023-01-17 11:36:01 +01:00
var body: some View {
NavigationStack {
Form {
TextField("timeline.add.url", text: $instanceName)
.listRowBackground(theme.primaryBackgroundColor)
.keyboardType(.URL)
.textContentType(.URL)
.textInputAutocapitalization(.never)
.autocorrectionDisabled()
.focused($isInstanceURLFieldFocused)
if let instance {
Label("timeline.\(instance.title)-is-valid", systemImage: "checkmark.seal.fill")
.foregroundColor(.green)
.listRowBackground(theme.primaryBackgroundColor)
}
Button {
guard instance != nil else { return }
2023-09-22 12:49:25 +02:00
context.insert(LocalTimeline(instance: instanceName))
dismiss()
} label: {
Text("timeline.add.action.add")
}
.listRowBackground(theme.primaryBackgroundColor)
2023-01-17 11:36:01 +01:00
instancesListView
}
.formStyle(.grouped)
.navigationTitle("timeline.add-remote.title")
.navigationBarTitleDisplayMode(.inline)
#if !os(visionOS)
.scrollContentBackground(.hidden)
.background(theme.secondaryBackgroundColor)
.scrollDismissesKeyboard(.immediately)
#endif
.toolbar {
2024-01-23 08:13:45 +01:00
CancelToolbarItem()
}
.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()
Task {
instances = await client.fetchInstances(keyword: instanceName)
}
}
}
}
2023-01-17 11:36:01 +01:00
private var instancesListView: some View {
Section("instance.suggestions") {
if instances.isEmpty {
ProgressView()
.listRowBackground(theme.primaryBackgroundColor)
} else {
2023-01-17 11:36:01 +01:00
ForEach(instanceName.isEmpty ? instances : instances.filter { $0.name.contains(instanceName.lowercased()) }) { instance in
Button {
2023-09-16 14:15:03 +02:00
instanceName = instance.name
} label: {
VStack(alignment: .leading, spacing: 4) {
Text(instance.name)
.font(.scaledHeadline)
.foregroundColor(.primary)
Text(instance.info?.shortDescription ?? "")
.font(.scaledBody)
2023-12-04 15:49:44 +01:00
.foregroundStyle(Color.secondary)
2023-01-22 06:38:30 +01:00
(Text("instance.list.users-\(instance.users)")
+ Text("")
+ Text("instance.list.posts-\(instance.statuses)"))
2023-01-22 06:38:30 +01:00
.font(.scaledFootnote)
2023-12-04 15:49:44 +01:00
.foregroundStyle(Color.secondary)
}
}
.listRowBackground(theme.primaryBackgroundColor)
}
}
}
}
}