Make redirects work
This commit is contained in:
parent
bd48fc8dbb
commit
2d05e318ff
|
@ -13,8 +13,7 @@ import GeminiProtocol
|
|||
struct ContentView: View {
|
||||
let navigator: NavigationManager
|
||||
@State var task: GeminiDataTask?
|
||||
@State var document: Document?
|
||||
@State var errorMessage: String?
|
||||
@State var state: ViewState = .loading
|
||||
|
||||
var body: some View {
|
||||
mainView
|
||||
|
@ -24,17 +23,18 @@ struct ContentView: View {
|
|||
|
||||
@ViewBuilder
|
||||
private var mainView: some View {
|
||||
if let document = document {
|
||||
DocumentView(document: document, changeURL: navigator.changeURL)
|
||||
} else if let errorMessage = errorMessage {
|
||||
switch state {
|
||||
case .loading:
|
||||
loadingView
|
||||
.onAppear(perform: self.loadDocument)
|
||||
case let .error(message):
|
||||
VStack {
|
||||
Text("An error occurred")
|
||||
.font(.headline)
|
||||
Text(errorMessage)
|
||||
Text(message)
|
||||
}
|
||||
} else {
|
||||
loadingView
|
||||
.onAppear(perform: self.loadDocument)
|
||||
case let .document(doc):
|
||||
DocumentView(document: doc, changeURL: navigator.changeURL)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -50,25 +50,39 @@ struct ContentView: View {
|
|||
private func loadDocument() {
|
||||
let url = navigator.currentURL
|
||||
task = try! GeminiDataTask(url: url, completion: { (response) in
|
||||
self.task = nil
|
||||
switch response {
|
||||
case let .failure(error):
|
||||
self.errorMessage = error.localizedDescription
|
||||
state = .error(error.localizedDescription)
|
||||
case let .success(response):
|
||||
guard let text = response.bodyText else {
|
||||
self.errorMessage = "Response had no body text"
|
||||
return
|
||||
if response.status.isRedirect {
|
||||
if let redirect = URL(string: response.meta) {
|
||||
navigator.changeURL(redirect)
|
||||
loadDocument()
|
||||
} else {
|
||||
state = .error("Invalid redirect URL: '\(response.meta)'")
|
||||
}
|
||||
} else if response.status.isSuccess,
|
||||
let text = response.bodyText {
|
||||
state = .document(GeminiParser.parse(text: text, baseURL: url))
|
||||
} else {
|
||||
state = .error("Unknown error: \(response.header)")
|
||||
}
|
||||
self.document = GeminiParser.parse(text: text, baseURL: url)
|
||||
}
|
||||
self.task = nil
|
||||
})
|
||||
task!.resume()
|
||||
}
|
||||
|
||||
private func urlChanged(_ newValue: URL) {
|
||||
self.task = nil
|
||||
self.document = nil
|
||||
self.errorMessage = nil
|
||||
state = .loading
|
||||
}
|
||||
}
|
||||
|
||||
extension ContentView {
|
||||
enum ViewState {
|
||||
case loading
|
||||
case document(Document)
|
||||
case error(String)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -35,15 +35,15 @@ public extension GeminiResponseHeader {
|
|||
case certificateNotValid = 62
|
||||
|
||||
// Status type helpers
|
||||
var isInput: Bool { rawValue / 10 == 1 }
|
||||
var isSuccess: Bool { rawValue / 10 == 2 }
|
||||
var isRedirect: Bool { rawValue / 10 == 3 }
|
||||
var isTemporaryFailure: Bool { rawValue / 10 == 4 }
|
||||
var isPermanentFailure: Bool { rawValue / 10 == 5 }
|
||||
var isClientCertificateRequired: Bool { rawValue / 10 == 6 }
|
||||
public var isInput: Bool { rawValue / 10 == 1 }
|
||||
public var isSuccess: Bool { rawValue / 10 == 2 }
|
||||
public var isRedirect: Bool { rawValue / 10 == 3 }
|
||||
public var isTemporaryFailure: Bool { rawValue / 10 == 4 }
|
||||
public var isPermanentFailure: Bool { rawValue / 10 == 5 }
|
||||
public var isClientCertificateRequired: Bool { rawValue / 10 == 6 }
|
||||
|
||||
// Other helpers
|
||||
var isFailure: Bool { isTemporaryFailure || isPermanentFailure }
|
||||
public var isFailure: Bool { isTemporaryFailure || isPermanentFailure }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue