@@ -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 ]
168+ let private newContact pubkey nickname : Contact =
169+ { Pubkey = pubkey; Nickname = nickname; DisplayName = ""; Bio = ""; PhotoBase64 = "" }
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) ->
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
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
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())
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()
419− match root.TryGetProperty("photo") with
420− | true, el when el.ValueKind <> JsonValueKind.Null -> Some(el.GetString())
422 Some(ProfileMessage(root.GetProperty("id").GetString(), displayName, bio, photo))
424 Some(ProfileMessage(root.GetProperty("id").GetString(), displayName, bio, photo))
423 | _ -> None
425 | _ -> None
@@ -541,8 +543,7 @@ module App =
541 asyncCmd (async {
543 asyncCmd (async {
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
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)
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.)
626− match model.Profile with
627− | Some profile when profile.Bio <> "" ->
628− Label($"Bio: {profile.Bio}").font(size = 14.).textColor(Colors.DimGray)
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.)
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)))
636 Label("Server:")
633 Label("Server:")