on master help sign in
Simplify code and improve type safety: inline Sent handling, make SendResult private, factor nowStr helper
d41c2bfiko
client/ApiClient.fs+5−2
@@ -18,7 +18,7 @@ module ApiClient =
18 type MessageStatus = Delivered | Federated | Queued | Rejected | Unauthorized
18 type MessageStatus = Delivered | Federated | Queued | Rejected | Unauthorized
19
19
20 [<CLIMutable>]
20 [<CLIMutable>]
21− type SendResult = { Status: MessageStatus; MessageId: string }
21+ type private SendResult = { Status: MessageStatus; MessageId: string }
22
22
23 [<CLIMutable>]
23 [<CLIMutable>]
24 type PollResponse = { Cursor: int64; Events: PollEvent array }
24 type PollResponse = { Cursor: int64; Events: PollEvent array }
@@ -105,7 +105,10 @@ module ApiClient =
105
105
106 let sendMessage (serverUrl: string) (token: string) (toHex: string) (blobHex: string) (timestamp: int64) =
106 let sendMessage (serverUrl: string) (token: string) (toHex: string) (blobHex: string) (timestamp: int64) =
107 let body = JsonSerializer.Serialize({| ``to`` = toHex; encryptedBlob = blobHex; timestamp = timestamp |})
107 let body = JsonSerializer.Serialize({| ``to`` = toHex; encryptedBlob = blobHex; timestamp = timestamp |})
108+ async {
108− postJson<SendResult> client $"{serverUrl}/messages" body (Some token)
109+ let! result = postJson<SendResult> client $"{serverUrl}/messages" body (Some token)
110+ return result.Status
111+ }
109
112
110 let poll (serverUrl: string) (token: string) (cursor: int64) =
113 let poll (serverUrl: string) (token: string) (cursor: int64) =
111 let body = JsonSerializer.Serialize({| cursor = cursor; timeout = 30000 |})
114 let body = JsonSerializer.Serialize({| cursor = cursor; timeout = 30000 |})
client/App.fs+15−12
@@ -67,7 +67,7 @@ module App =
67 | DoDisconnect
67 | DoDisconnect
68 | SetCompose of string
68 | SetCompose of string
69 | DoSend
69 | DoSend
70− | Sent of Result<MessageStatus, string>
70+ | Sent of Result<unit, string>
71 | SetNewPubkey of string
71 | SetNewPubkey of string
72 | SetNewNickname of string
72 | SetNewNickname of string
73 | DoSaveContact
73 | DoSaveContact
@@ -90,6 +90,9 @@ module App =
90
90
91 // ── Helpers ──
91 // ── Helpers ──
92
92
93+ let private nowStr () =
94+ DateTimeOffset.UtcNow.ToString("HH:mm:ss")
95+
93 let private truncate maxLen (s: string) =
96 let private truncate maxLen (s: string) =
94 if s.Length > maxLen then s.[..maxLen - 1] + "..." else s
97 if s.Length > maxLen then s.[..maxLen - 1] + "..." else s
95
98
@@ -204,12 +207,8 @@ module App =
204 model', [ CmdSend(session, pk, compose, id); saveCmdMsg model' ]
207 model', [ CmdSend(session, pk, compose, id); saveCmdMsg model' ]
205 | _ -> model, []
208 | _ -> model, []
206
209
207− | Sent(Ok(Delivered | Federated | Queued)) -> model, []
210+ | Sent(Ok()) -> model, []
208− | Sent(Ok Rejected) ->
209− { model with Error = Some "Message rejected by server" }, []
210− | Sent(Ok Unauthorized) ->
211− { model with Error = Some "Not authorized to deliver message" }, []
212− | Sent(Error err) -> { model with Error = Some $"Send failed: {err}" }, []
211+ | Sent(Error err) -> { model with Error = Some err }, []
213
212
214 | PollResult(incoming, status, newCursor) ->
213 | PollResult(incoming, status, newCursor) ->
215 let model' =
214 let model' =
@@ -327,10 +326,14 @@ module App =
327
326
328 let blob = Crypto.encrypt session.Identity.PrivKey recipPub payload
327 let blob = Crypto.encrypt session.Identity.PrivKey recipPub payload
329 let blobHex = Crypto.toHex blob
328 let blobHex = Crypto.toHex blob
330− let! result = sendMessage session.Url session.Token recipientHex blobHex ts
329+ let! status = sendMessage session.Url session.Token recipientHex blobHex ts
331− return Sent(Ok result.Status)
330+ return
331+ match status with
332+ | Delivered | Federated | Queued -> Sent(Ok())
333+ | Rejected -> Sent(Error "Message rejected by server")
334+ | Unauthorized -> Sent(Error "Not authorized to deliver message")
332 with ex ->
335 with ex ->
333− return Sent(Error ex.Message)
336+ return Sent(Error $"Send failed: {ex.Message}")
334 })
337 })
335
338
336 | CmdPoll(session, cursor) ->
339 | CmdPoll(session, cursor) ->
@@ -349,7 +352,7 @@ module App =
349 if not ackIds.IsEmpty then
352 if not ackIds.IsEmpty then
350 do! ackMessages session.Url session.Token ackIds
353 do! ackMessages session.Url session.Token ackIds
351
354
352− let now = DateTimeOffset.UtcNow.ToString("HH:mm:ss")
355+ let now = nowStr ()
353
356
354 let status =
357 let status =
355 $"[{now}] evts:{response.Events.Length} msgs:{messages.Length} errs:{errors.Length}"
358 $"[{now}] evts:{response.Events.Length} msgs:{messages.Length} errs:{errors.Length}"
@@ -360,7 +363,7 @@ module App =
360 | :? TimeoutException ->
363 | :? TimeoutException ->
361 return PollResult([], "polling...", cursor)
364 return PollResult([], "polling...", cursor)
362 | ex ->
365 | ex ->
363− let now = DateTimeOffset.UtcNow.ToString("HH:mm:ss")
366+ let now = nowStr ()
364 do! Async.Sleep 3000
367 do! Async.Sleep 3000
365 return PollResult([], $"[{now}] poll error: {ex.Message}", cursor)
368 return PollResult([], $"[{now}] poll error: {ex.Message}", cursor)
366 })
369 })