mirror of
https://github.com/sudosylabs/vnidrop.git
synced 2026-08-07 19:29:57 +02:00
fix: stop the device picker hanging on an offer
Two causes. The connect step had no timeout, so an unreachable device was retried indefinitely instead of falling through to hold-for-later; it now gives up after 15s and holds the offer as designed. The picker also waited on the whole exchange, which includes a person on the other device deciding — up to two minutes. It now closes on tap and reports the outcome as a message, and a decline or an unanswered offer is shown as information rather than an error, since the offer did arrive.
This commit is contained in:
@@ -3,6 +3,12 @@ import VnidropCore
|
||||
|
||||
/// Maps technical failures to stable, user-facing catalog keys. Ported from
|
||||
/// `ui/feedback/UserFacingError.kt`. Never exposes raw `reason=` blobs.
|
||||
/// How an offered transfer ended without being accepted.
|
||||
enum OfferRefusal {
|
||||
case declined
|
||||
case noAnswer
|
||||
}
|
||||
|
||||
extension Error {
|
||||
func toUiText() -> UiText {
|
||||
if let invitation = self as? InvitationError {
|
||||
@@ -57,6 +63,19 @@ extension Error {
|
||||
|| haystack.contains("user canceled")
|
||||
}
|
||||
|
||||
/// The other device answered, and the answer was no.
|
||||
///
|
||||
/// Not a failure of this device: the offer was delivered and a person
|
||||
/// declined it, so it is reported as information rather than an error.
|
||||
var offerRefusal: OfferRefusal? {
|
||||
let haystack = technicalDetail.lowercased()
|
||||
if haystack.contains("receiver-declined") || haystack.contains("declined-recently") {
|
||||
return .declined
|
||||
}
|
||||
if haystack.contains("no-response") { return .noAnswer }
|
||||
return nil
|
||||
}
|
||||
|
||||
/// Prefers a `VnidropError` reason; else the localized description.
|
||||
var technicalDetail: String {
|
||||
if let vni = self as? VnidropError {
|
||||
|
||||
Reference in New Issue
Block a user