@@ -49,7 +49,7 @@ module App =
4949 type ConnStatus =
5050 | Offline
5151 | Connecting
52− | Online of url: string * token: string
52+ | Online of token: string
5353
5454 type AuthState =
5555 | NoIdentity
@@ -57,10 +57,12 @@ module App =
5757
5858 type IncomingMessage = { SenderPubkey: string; Message: ChatMessage }
5959
60+ type PollReceived = { Events: int; Messages: int; Errors: int; FirstError: string option }
61+
6062 type PollStatus =
6163 | Idle
6264 | Polling
63− | Received of events: int * messages: int * errors: int * firstError: string option
65+ | Received of PollReceived
6466 | PollError of string
6567
6668 // ── Model ──
@@ -160,7 +162,7 @@ module App =
160162
161163 let private trySession model =
162164 match model.Auth with
163− | Identified(id, Online(url, token)) -> Some { Url = url; Token = token; Identity = id }
165+ | Identified(id, Online token) -> Some { Url = model.ServerUrl; Token = token; Identity = id }
164166 | _ -> None
165167
166168 let private setConn status model =
@@ -225,7 +227,7 @@ module App =
225227 match model.Auth with
226228 | Identified(id, Connecting) ->
227229 let session = { Url = model.ServerUrl; Token = token; Identity = id }
228− { model with Auth = Identified(id, Online(model.ServerUrl, token)); Page = Conversations; Error = None },
230+ { model with Auth = Identified(id, Online token); Page = Conversations; Error = None },
229231 [ CmdPoll(session, model.PollCursor) ]
230232 | _ -> model, []
231233
@@ -392,7 +394,7 @@ module App =
392394 if not ackIds.IsEmpty then
393395 do! ackMessages session.Url session.Token ackIds
394396
395− let status = Received(response.Events.Length, messages.Length, errors.Length, List.tryHead errors)
397+ let status = Received { Events = response.Events.Length; Messages = messages.Length; Errors = errors.Length; FirstError = List.tryHead errors }
396398 return PollResult(messages, status, response.Cursor)
397399 with
398400 | :? TimeoutException ->
@@ -429,11 +431,20 @@ module App =
429431 let private formatPollStatus = function
430432 | Idle -> ""
431433 | Polling -> "polling..."
432− | Received(evts, msgs, errs, firstErr) ->
433− $"evts:{evts} msgs:{msgs} errs:{errs}"
434− + (match firstErr with Some e -> $" [{e}]" | None -> "")
434+ | Received r ->
435+ $"evts:{r.Events} msgs:{r.Messages} errs:{r.Errors}"
436+ + (match r.FirstError with Some e -> $" [{e}]" | None -> "")
435437 | PollError msg -> $"poll error: {msg}"
436438
439+ let private viewErrorBanner (error: string option) =
440+ VStack(spacing = 4.) {
441+ match error with
442+ | Some err ->
443+ Label(err).textColor(Colors.Red).font(size = 12.)
444+ Button("Dismiss", DismissError)
445+ | None -> ()
446+ }
447+
437448 let private viewSetup () =
438449 ContentPage(
439450 (VStack(spacing = 24.) {
@@ -471,16 +482,11 @@ module App =
471482
472483 Label("Server:")
473484
474− Entry(model.ServerUrl, SetServerUrl)
475−
476− match model.Error with
477− | Some err ->
478− Label(err)
479− .textColor(Colors.Red)
480− .font(size = 12.)
485+ match conn with
486+ | Online _ -> Label(model.ServerUrl).font(size = 14.)
487+ | _ -> Entry(model.ServerUrl, SetServerUrl)
481488
482− Button("Dismiss", DismissError)
483− | None -> ()
489+ viewErrorBanner model.Error
484490
485491 match conn with
486492 | Offline -> Button("Connect", DoConnect)
@@ -516,11 +522,7 @@ module App =
516522 .font(size = 10.)
517523 .textColor(Colors.DimGray)
518524
519− match model.Error with
520− | Some err ->
521− Label(err).textColor(Colors.Red).font(size = 12.)
522− Button("Dismiss", DismissError)
523− | None -> ()
525+ viewErrorBanner model.Error
524526
525527 if model.Contacts.IsEmpty then
526528 Label("No contacts yet. Tap + to add one.")
@@ -554,14 +556,7 @@ module App =
554556 .centerTextHorizontal()
555557 }
556558
557− match model.Error with
558− | Some err ->
559− Label(err)
560− .textColor(Colors.Red)
561− .font(size = 12.)
562−
563− Button("Dismiss", DismissError)
564− | None -> ()
559+ viewErrorBanner model.Error
565560
566561 if msgs.IsEmpty then
567562 Label("No messages yet")
@@ -593,11 +588,7 @@ module App =
593588 .font(size = 20.)
594589 }
595590
596− match model.Error with
597− | Some err ->
598− Label(err).textColor(Colors.Red).font(size = 12.)
599− Button("Dismiss", DismissError)
600− | None -> ()
591+ viewErrorBanner model.Error
601592
602593 Label("Public Key:")
603594 Entry(pubkey, SetContactPubkey)