on master help sign in
Add newContact and tryGetJsonString helpers, safe DeliveryStatus deserialization, simplify profile display
e305f3diko
client/App.fs+21−24
@@ -165,6 +165,9 @@ module App =
165 | Some i -> contacts |> List.updateAt i contact
165 | Some i -> contacts |> List.updateAt i contact
166 | None -> contacts @ [ contact ]
166 | None -> contacts @ [ contact ]
167
167
168+ let private newContact pubkey nickname : Contact =
169+ { Pubkey = pubkey; Nickname = nickname; DisplayName = ""; Bio = ""; PhotoBase64 = "" }
170+
168 let private trySession model =
171 let private trySession model =
169 match model.Auth with
172 match model.Auth with
170 | Identified(id, Online token) -> Some { Url = model.ServerUrl; Token = token; Identity = id }
173 | Identified(id, Online token) -> Some { Url = model.ServerUrl; Token = token; Identity = id }
@@ -278,7 +281,7 @@ module App =
278 match evt with
281 match evt with
279 | IncomingChat(senderPubkey, message) ->
282 | IncomingChat(senderPubkey, message) ->
280 { m with
283 { m with
281− Contacts = m.Contacts |> addContactIfNew { Pubkey = senderPubkey; Nickname = truncKey senderPubkey; DisplayName = ""; Bio = ""; PhotoBase64 = "" }
284+ Contacts = m.Contacts |> addContactIfNew (newContact senderPubkey (truncKey senderPubkey))
282 Messages = m.Messages |> appendMessage senderPubkey message }
285 Messages = m.Messages |> appendMessage senderPubkey message }
283 | IncomingDeliveryAck(senderPubkey, ackIds) ->
286 | IncomingDeliveryAck(senderPubkey, ackIds) ->
284 { m with Messages = m.Messages |> markDelivered senderPubkey ackIds }
287 { m with Messages = m.Messages |> markDelivered senderPubkey ackIds }
@@ -308,7 +311,7 @@ module App =
308 let contact: Contact =
311 let contact: Contact =
309 match existing with
312 match existing with
310 | Some e -> { e with Nickname = cnn }
313 | Some e -> { e with Nickname = cnn }
311− | None -> { Pubkey = hex; Nickname = cnn; DisplayName = ""; Bio = ""; PhotoBase64 = "" }
314+ | None -> newContact hex cnn
312
315
313 let model' =
316 let model' =
314 { model with
317 { model with
@@ -400,6 +403,11 @@ module App =
400 return! sendMessage session.Url session.Token recipientHex (Crypto.toHex blob) ts
403 return! sendMessage session.Url session.Token recipientHex (Crypto.toHex blob) ts
401 }
404 }
402
405
406+ let private tryGetJsonString (el: JsonElement) (name: string) =
407+ match el.TryGetProperty(name) with
408+ | true, v when v.ValueKind <> JsonValueKind.Null -> Some(v.GetString())
409+ | _ -> None
410+
403 let private parseEnvelope (json: string) =
411 let private parseEnvelope (json: string) =
404 use doc = JsonDocument.Parse(json)
412 use doc = JsonDocument.Parse(json)
405 let root = doc.RootElement
413 let root = doc.RootElement
@@ -411,14 +419,8 @@ module App =
411 Some(DeliveryAck(root.GetProperty("id").GetString(), ackIds))
419 Some(DeliveryAck(root.GetProperty("id").GetString(), ackIds))
412 | "profile" ->
420 | "profile" ->
413 let displayName = root.GetProperty("display_name").GetString()
421 let displayName = root.GetProperty("display_name").GetString()
414− let bio =
422+ let bio = tryGetJsonString root "bio" |> Option.defaultValue ""
415− match root.TryGetProperty("bio") with
423+ let photo = tryGetJsonString root "photo"
416− | true, el when el.ValueKind <> JsonValueKind.Null -> el.GetString()
417− | _ -> ""
418− let photo =
419− match root.TryGetProperty("photo") with
420− | true, el when el.ValueKind <> JsonValueKind.Null -> Some(el.GetString())
421− | _ -> None
422 Some(ProfileMessage(root.GetProperty("id").GetString(), displayName, bio, photo))
424 Some(ProfileMessage(root.GetProperty("id").GetString(), displayName, bio, photo))
423 | _ -> None
425 | _ -> None
424
426
@@ -541,8 +543,7 @@ module App =
541 asyncCmd (async {
543 asyncCmd (async {
542 try
544 try
543 let! results = Microsoft.Maui.Media.MediaPicker.Default.PickPhotosAsync() |> Async.AwaitTask
545 let! results = Microsoft.Maui.Media.MediaPicker.Default.PickPhotosAsync() |> Async.AwaitTask
544− let file = results |> Seq.tryHead
546+ match results |> Seq.tryHead with
545− match file with
546 | None -> return PhotoPicked None
547 | None -> return PhotoPicked None
547 | Some file ->
548 | Some file ->
548 use! stream = file.OpenReadAsync() |> Async.AwaitTask
549 use! stream = file.OpenReadAsync() |> Async.AwaitTask
@@ -619,19 +620,15 @@ module App =
619 Button("Copy Public Key", CopyPubKey)
620 Button("Copy Public Key", CopyPubKey)
620
621
621 Label("Profile:").font(size = 18.)
622 Label("Profile:").font(size = 18.)
622− match model.Profile with
623+ let displayName, bio, photo =
623− | Some profile when profile.DisplayName <> "" ->
624− Label($"Name: {profile.DisplayName}").font(size = 14.)
625− | _ -> ()
626− match model.Profile with
627− | Some profile when profile.Bio <> "" ->
628− Label($"Bio: {profile.Bio}").font(size = 14.).textColor(Colors.DimGray)
629− | _ -> ()
630− let profilePage =
631 match model.Profile with
624 match model.Profile with
632− | Some p -> EditProfile(p.DisplayName, p.Bio, p.PhotoBase64)
625+ | Some p -> p.DisplayName, p.Bio, p.PhotoBase64
633− | None -> EditProfile("", "", None)
626+ | None -> "", "", None
627+ if displayName <> "" then
628+ Label($"Name: {displayName}").font(size = 14.)
629+ if bio <> "" then
630+ Label($"Bio: {bio}").font(size = 14.).textColor(Colors.DimGray)
634− Button("Edit Profile", SetPage profilePage)
631+ Button("Edit Profile", SetPage(EditProfile(displayName, bio, photo)))
635
632
636 Label("Server:")
633 Label("Server:")
637
634
client/Store.fs+1−1
@@ -60,7 +60,7 @@ module Store =
60
60
61 let private toChatMessage (d: MessageDoc) : ChatMessage =
61 let private toChatMessage (d: MessageDoc) : ChatMessage =
62 { Id = d.Id; Body = d.Body; Timestamp = DateTimeOffset.FromUnixTimeSeconds d.TimestampUnix; IsOutgoing = d.IsOutgoing
62 { Id = d.Id; Body = d.Body; Timestamp = DateTimeOffset.FromUnixTimeSeconds d.TimestampUnix; IsOutgoing = d.IsOutgoing
63− Status = match d.Status with 0 -> DeliveryStatus.Sent | 1 -> DeliveryStatus.Delivered | n -> failwith $"Unknown delivery status: {n}" }
63+ Status = match d.Status with 1 -> DeliveryStatus.Delivered | _ -> DeliveryStatus.Sent }
64
64
65 let private toMessageDoc convId (m: ChatMessage) : MessageDoc =
65 let private toMessageDoc convId (m: ChatMessage) : MessageDoc =
66 { Id = m.Id; ConversationId = convId; Body = m.Body; TimestampUnix = m.Timestamp.ToUnixTimeSeconds(); IsOutgoing = m.IsOutgoing
66 { Id = m.Id; ConversationId = convId; Body = m.Body; TimestampUnix = m.Timestamp.ToUnixTimeSeconds(); IsOutgoing = m.IsOutgoing
client/bin/Debug/net10.0-ios/iossimulator-arm64/Skrepka.app/Skrepka.dll

Binary file not shown.

client/bin/Debug/net10.0-ios/iossimulator-arm64/Skrepka.app/Skrepka.pdb

Binary file not shown.

client/bin/Debug/net10.0-ios/iossimulator-arm64/Skrepka.app/_CodeSignature/CodeResources+4−4
@@ -166,11 +166,11 @@
166 </data>
166 </data>
167 <key>Skrepka.dll</key>
167 <key>Skrepka.dll</key>
168 <data>
168 <data>
169− u3/Jli23brn1acnURBDMHQ032EY=
169+ XggCDQCHSf8dQC6LksWyNcwMo/0=
170 </data>
170 </data>
171 <key>Skrepka.pdb</key>
171 <key>Skrepka.pdb</key>
172 <data>
172 <data>
173− m9G0IzQJO1xJObAyLl6iRTGfI4Q=
173+ FRcfi2R+hf5HmuuoEB+4IrQgTRI=
174 </data>
174 </data>
175 <key>Sodium.Core.dll</key>
175 <key>Sodium.Core.dll</key>
176 <data>
176 <data>
@@ -1393,14 +1393,14 @@
1393 <dict>
1393 <dict>
1394 <key>hash2</key>
1394 <key>hash2</key>
1395 <data>
1395 <data>
1396− N4S21qMsbcdZoPSka8wm/OYfeytcN6be2i+NeNshbkM=
1396+ 4Obn19booe5w8nme/HekTocjkHnr5cKKZ7bpnmVCwZE=
1397 </data>
1397 </data>
1398 </dict>
1398 </dict>
1399 <key>Skrepka.pdb</key>
1399 <key>Skrepka.pdb</key>
1400 <dict>
1400 <dict>
1401 <key>hash2</key>
1401 <key>hash2</key>
1402 <data>
1402 <data>
1403− CZBydqM3QuDS2CPbFfJRWp0ybjMZr2cKEF/e4NllpY4=
1403+ 0QGn820sZRBznKRlggmNFzaLbJHqeqweO4QTDBDd6YE=
1404 </data>
1404 </data>
1405 </dict>
1405 </dict>
1406 <key>Sodium.Core.dll</key>
1406 <key>Sodium.Core.dll</key>
client/bin/Debug/net10.0-ios/iossimulator-arm64/Skrepka.dll

Binary file not shown.

client/bin/Debug/net10.0-ios/iossimulator-arm64/Skrepka.pdb

Binary file not shown.

client/bin/Debug/net10.0-maccatalyst/maccatalyst-arm64/Skrepka.app/Contents/MonoBundle/Skrepka.dll

Binary file not shown.

client/bin/Debug/net10.0-maccatalyst/maccatalyst-arm64/Skrepka.app/Contents/MonoBundle/Skrepka.pdb

Binary file not shown.

client/bin/Debug/net10.0-maccatalyst/maccatalyst-arm64/Skrepka.app/Contents/_CodeSignature/CodeResources+2−2
@@ -251,14 +251,14 @@
251 <dict>
251 <dict>
252 <key>hash2</key>
252 <key>hash2</key>
253 <data>
253 <data>
254− bun2DyiQNygihIIRw+/9Fz9gKTvkJ8OKN160J0nU8T4=
254+ P6Dn2mj+cOkqtrabVP1bG8x1eg30NhlSjO1UYUi+eKc=
255 </data>
255 </data>
256 </dict>
256 </dict>
257 <key>MonoBundle/Skrepka.pdb</key>
257 <key>MonoBundle/Skrepka.pdb</key>
258 <dict>
258 <dict>
259 <key>hash2</key>
259 <key>hash2</key>
260 <data>
260 <data>
261− o5yVSDk2KiZkgGHYl08aary/xPSlP2KvgKUPeV1GPE0=
261+ 3XVw9RVc9dugW7Y8G78UD4MMYYewWf/pYJJpWHzCq/c=
262 </data>
262 </data>
263 </dict>
263 </dict>
264 <key>MonoBundle/Sodium.Core.dll</key>
264 <key>MonoBundle/Sodium.Core.dll</key>
client/bin/Debug/net10.0-maccatalyst/maccatalyst-arm64/Skrepka.dll

Binary file not shown.

client/bin/Debug/net10.0-maccatalyst/maccatalyst-arm64/Skrepka.pdb

Binary file not shown.

client/obj/Debug/net10.0-ios/iossimulator-arm64/Skrepka.AssemblyInfo.fs+1−1
@@ -10,7 +10,7 @@ open System.Reflection
10[<assembly: System.Reflection.AssemblyCompanyAttribute("Skrepka")>]
10[<assembly: System.Reflection.AssemblyCompanyAttribute("Skrepka")>]
11[<assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")>]
11[<assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")>]
12[<assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")>]
12[<assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")>]
13−[<assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0+fec9263421fbac32ef5f434448cbad4cca707ffa")>]
13+[<assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0+50200f4e8cc7b94c2acf338b402efe56d4dce414")>]
14[<assembly: System.Reflection.AssemblyProductAttribute("Skrepka")>]
14[<assembly: System.Reflection.AssemblyProductAttribute("Skrepka")>]
15[<assembly: System.Reflection.AssemblyTitleAttribute("Skrepka")>]
15[<assembly: System.Reflection.AssemblyTitleAttribute("Skrepka")>]
16[<assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")>]
16[<assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")>]
client/obj/Debug/net10.0-ios/iossimulator-arm64/Skrepka.AssemblyInfoInputs.cache+1−1
@@ -1 +1 @@
1−14d65e38515f6fe609282787e3a83911d7f49a251ce309da041cf4a647d7c78c
1+e311e4b6d1989fb2125900b4d17724c47240c7e78f825d88678e9bf38444e433
client/obj/Debug/net10.0-ios/iossimulator-arm64/Skrepka.dll

Binary file not shown.

client/obj/Debug/net10.0-ios/iossimulator-arm64/Skrepka.fsproj.FileListAbsolute.txt+23
@@ -334,3 +334,26 @@
334/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/Skrepka.genruntimeconfig.cache
334/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/Skrepka.genruntimeconfig.cache
335/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/ref/Skrepka.dll
335/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/ref/Skrepka.dll
336/Users/iko/Developer/skrepka/client/bin/Debug/net10.0-ios/iossimulator-arm64/LiteDB.dll
336/Users/iko/Developer/skrepka/client/bin/Debug/net10.0-ios/iossimulator-arm64/LiteDB.dll
337+/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/resourcestamps/Fabulous.stamp
338+/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/resourcestamps/Fabulous.MauiControls.stamp
339+/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/resourcestamps/FSharp.Core.stamp
340+/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/resourcestamps/LiteDB.stamp
341+/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/resourcestamps/Microsoft.Extensions.Configuration.Abstractions.stamp
342+/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/resourcestamps/Microsoft.Extensions.Configuration.stamp
343+/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/resourcestamps/Microsoft.Extensions.DependencyInjection.Abstractions.stamp
344+/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/resourcestamps/Microsoft.Extensions.DependencyInjection.stamp
345+/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/resourcestamps/Microsoft.Extensions.Diagnostics.Abstractions.stamp
346+/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/resourcestamps/Microsoft.Extensions.FileProviders.Abstractions.stamp
347+/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/resourcestamps/Microsoft.Extensions.Hosting.Abstractions.stamp
348+/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/resourcestamps/Microsoft.Extensions.Logging.Abstractions.stamp
349+/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/resourcestamps/Microsoft.Extensions.Logging.stamp
350+/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/resourcestamps/Microsoft.Extensions.Options.stamp
351+/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/resourcestamps/Microsoft.Extensions.Primitives.stamp
352+/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/resourcestamps/Microsoft.Maui.Controls.Compatibility.stamp
353+/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/resourcestamps/Microsoft.Maui.Controls.stamp
354+/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/resourcestamps/Microsoft.Maui.Controls.Xaml.stamp
355+/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/resourcestamps/Microsoft.Maui.stamp
356+/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/resourcestamps/Microsoft.Maui.Essentials.stamp
357+/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/resourcestamps/Microsoft.Maui.Graphics.stamp
358+/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/resourcestamps/Sodium.Core.stamp
359+/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/unpack/Microsoft.Maui.Essentials/BundleResource/xml/microsoft_maui_essentials_fileprovider_file_paths.xml
client/obj/Debug/net10.0-ios/iossimulator-arm64/Skrepka.pdb

Binary file not shown.

client/obj/Debug/net10.0-ios/iossimulator-arm64/Skrepka.sourcelink.json+1−1
@@ -1 +1 @@
1−{"documents":{"/Users/iko/Developer/skrepka/*":"https://raw.githubusercontent.com/ilyakooo0/skrepka/fec9263421fbac32ef5f434448cbad4cca707ffa/*"}}
1+{"documents":{"/Users/iko/Developer/skrepka/*":"https://raw.githubusercontent.com/ilyakooo0/skrepka/50200f4e8cc7b94c2acf338b402efe56d4dce414/*"}}
client/obj/Debug/net10.0-ios/iossimulator-arm64/ref/Skrepka.dll

Binary file not shown.

client/obj/Debug/net10.0-ios/iossimulator-arm64/refint/Skrepka.dll

Binary file not shown.

client/obj/Debug/net10.0-maccatalyst/maccatalyst-arm64/Skrepka.AssemblyInfo.fs+1−1
@@ -10,7 +10,7 @@ open System.Reflection
10[<assembly: System.Reflection.AssemblyCompanyAttribute("Skrepka")>]
10[<assembly: System.Reflection.AssemblyCompanyAttribute("Skrepka")>]
11[<assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")>]
11[<assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")>]
12[<assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")>]
12[<assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")>]
13−[<assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0+4471c7ea728053f905aa06e4d51de8c7e2de1550")>]
13+[<assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0+50200f4e8cc7b94c2acf338b402efe56d4dce414")>]
14[<assembly: System.Reflection.AssemblyProductAttribute("Skrepka")>]
14[<assembly: System.Reflection.AssemblyProductAttribute("Skrepka")>]
15[<assembly: System.Reflection.AssemblyTitleAttribute("Skrepka")>]
15[<assembly: System.Reflection.AssemblyTitleAttribute("Skrepka")>]
16[<assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")>]
16[<assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")>]
client/obj/Debug/net10.0-maccatalyst/maccatalyst-arm64/Skrepka.AssemblyInfoInputs.cache+1−1
@@ -1 +1 @@
1−c25af9bb478fcf0a0ce68966144888db2fe1a3af16d82c8904c7a0f73a3d108d
1+8af8c70485fb6088d5df97530926c75e310135762195922457d0a7e470636584
client/obj/Debug/net10.0-maccatalyst/maccatalyst-arm64/Skrepka.dll

Binary file not shown.

client/obj/Debug/net10.0-maccatalyst/maccatalyst-arm64/Skrepka.pdb

Binary file not shown.

client/obj/Debug/net10.0-maccatalyst/maccatalyst-arm64/Skrepka.sourcelink.json+1−1
@@ -1 +1 @@
1−{"documents":{"/Users/iko/Developer/skrepka/*":"https://raw.githubusercontent.com/ilyakooo0/skrepka/4471c7ea728053f905aa06e4d51de8c7e2de1550/*"}}
1+{"documents":{"/Users/iko/Developer/skrepka/*":"https://raw.githubusercontent.com/ilyakooo0/skrepka/50200f4e8cc7b94c2acf338b402efe56d4dce414/*"}}
client/obj/Debug/net10.0-maccatalyst/maccatalyst-arm64/ref/Skrepka.dll

Binary file not shown.

client/obj/Debug/net10.0-maccatalyst/maccatalyst-arm64/refint/Skrepka.dll

Binary file not shown.