@@ -46,7 +46,8 @@ module App =
4646 ComposeText: string
4747 NewPubkey: string
4848 NewNickname: string
49− Error: string option }
49+ Error: string option
50+ PollCursor: int64 }
5051
5152 // ── Msg ──
5253
@@ -66,7 +67,7 @@ module App =
6667 | SetNewNickname of string
6768 | DoSaveContact
6869 | DoDeleteContact of string
69− | PollResult of (string * string * int64 * string) list * string
70+ | PollResult of (string * string * int64 * string) list * string * int64
7071 | DoPoll
7172 | CopyPubKey
7273 | DismissError
@@ -84,7 +85,7 @@ module App =
8485 pubKeyHex: string *
8586 recipPubHex: string *
8687 text: string
87− | CmdPoll of url: string * token: string * privKey: byte[]
88+ | CmdPoll of url: string * token: string * privKey: byte[] * cursor: int64
8889 | CmdCopyToClipboard of string
8990
9091 // ── Helpers ──
@@ -112,7 +113,8 @@ module App =
112113 ComposeText = ""
113114 NewPubkey = ""
114115 NewNickname = ""
115− Error = None },
116+ Error = None
117+ PollCursor = 0L },
116118 []
117119
118120 // ── Update ──
@@ -143,7 +145,7 @@ module App =
143145 Conn = Online token
144146 Page = Conversations
145147 Error = None },
146− [ CmdPoll(model.ServerUrl, token, model.PrivKey.Value) ]
148+ [ CmdPoll(model.ServerUrl, token, model.PrivKey.Value, model.PollCursor) ]
147149
148150 | AuthErr err -> { model with Conn = Offline; Error = Some err }, []
149151
@@ -170,7 +172,7 @@ module App =
170172
171173 | Sent _ -> model, []
172174
173− | PollResult(incoming, status) ->
175+ | PollResult(incoming, status, newCursor) ->
174176 let model' =
175177 incoming
176178 |> List.fold
@@ -195,15 +197,15 @@ module App =
195197 { m with
196198 Contacts = contacts
197199 Messages = m.Messages |> Map.add fromPk (msgs @ [ newMsg ]) })
198− { model with PollStatus = status }
200+ { model with PollStatus = status; PollCursor = newCursor }
199201
200202 match model'.Conn with
201− | Online token -> model', [ CmdPoll(model'.ServerUrl, token, model'.PrivKey.Value) ]
203+ | Online token -> model', [ CmdPoll(model'.ServerUrl, token, model'.PrivKey.Value, model'.PollCursor) ]
202204 | _ -> model', []
203205
204206 | DoPoll ->
205207 match model.Conn, model.PrivKey with
206− | Online token, Some priv -> model, [ CmdPoll(model.ServerUrl, token, priv) ]
208+ | Online token, Some priv -> model, [ CmdPoll(model.ServerUrl, token, priv, model.PollCursor) ]
207209 | _ -> model, []
208210
209211 | SetNewPubkey pk -> { model with NewPubkey = pk }, []
@@ -294,10 +296,10 @@ module App =
294296 return DismissError // TODO: show send errors properly
295297 })
296298
297− | CmdPoll(url, token, privKey) ->
299+ | CmdPoll(url, token, privKey, cursor) ->
298300 asyncCmd (async {
299301 try
300− let! (events, _) = ApiClient.poll url token
302+ let! (events, newCursor) = ApiClient.poll url token cursor
301303 let messages = ResizeArray()
302304 let ackIds = ResizeArray()
303305 let errors = ResizeArray()
@@ -335,15 +337,15 @@ module App =
335337 $"[{now}] evts:{events.Length} msgs:{messages.Count} errs:{errors.Count}"
336338 + (if errors.Count > 0 then $" [{errors.[0]}]" else "")
337339
338− return PollResult(Seq.toList messages, status)
340+ return PollResult(Seq.toList messages, status, newCursor)
339341 with
340342 | :? System.Threading.Tasks.TaskCanceledException ->
341343 // Normal timeout from long poll — just retry
342− return PollResult([], "polling...")
344+ return PollResult([], "polling...", cursor)
343345 | ex ->
344346 let now = DateTimeOffset.UtcNow.ToString("HH:mm:ss")
345347 do! Async.Sleep 3000
346− return PollResult([], $"[{now}] poll error: {ex.Message}")
348+ return PollResult([], $"[{now}] poll error: {ex.Message}", cursor)
347349 })
348350
349351 | CmdCopyToClipboard text ->