diff --git a/crates/core/src/node.rs b/crates/core/src/node.rs index 7c90407..8dd0d46 100644 --- a/crates/core/src/node.rs +++ b/crates/core/src/node.rs @@ -1793,6 +1793,20 @@ impl Node { } } } + // Keep posting_identities.display_name in sync with the + // profile post so the Personas list and any UI reading + // PostingIdentity sees the current name (not the original + // empty/auto-gen one). The upsert preserves the persona's + // secret_seed / created_at; only display_name changes. + if let Ok(Some(existing)) = storage.get_posting_identity(&posting_id) { + let updated = crate::types::PostingIdentity { + node_id: existing.node_id, + secret_seed: existing.secret_seed, + display_name: display_name.clone(), + created_at: existing.created_at, + }; + let _ = storage.upsert_posting_identity(&updated); + } } // Propagate via neighbor-manifest header diffs like any other post. diff --git a/frontend/app.js b/frontend/app.js index 1840b8e..5bf2922 100644 --- a/frontend/app.js +++ b/frontend/app.js @@ -1687,12 +1687,13 @@ async function openBioModal(nodeId, preloadedName) { ${bio ? `

${escapeHtml(bio)}

` : '

No bio.

'}
- ${following - ? `` - : ``} - ${isVouched - ? `` - : ``} + ${(following && isVouched) + ? `` + : (following + ? ` + ` + : ` + `)} ${isIgnored ? `` @@ -1749,16 +1750,34 @@ async function openBioModal(nodeId, preloadedName) { } catch (e) { toast('Error: ' + e); } finally { vouch.disabled = false; } }; - const revokeVouch = document.getElementById('bio-revoke-vouch'); - if (revokeVouch) revokeVouch.onclick = async () => { - if (!confirm(`Revoke vouch for ${name}? This rotates your vouch key — they keep access to existing posts but not future ones.`)) return; - revokeVouch.disabled = true; + // Friend = follow + vouch in one click. Default action per v0.7.x UX. + const friend = document.getElementById('bio-friend'); + if (friend) friend.onclick = async () => { + friend.disabled = true; + try { + await invoke('follow_node', { nodeIdHex: nodeId }); + await invoke('vouch_for_peer', { nodeIdHex: nodeId }); + toast(`Friended ${name}`); + close(); + loadFollows(); + loadFeed(true); + } catch (e) { toast('Error: ' + e); } + finally { friend.disabled = false; } + }; + // Unfriend = revoke vouch + unfollow. Rotation cost is real; confirm. + const unfriend = document.getElementById('bio-unfriend'); + if (unfriend) unfriend.onclick = async () => { + if (!confirm(`Unfriend ${name}? This revokes your vouch (rotates your vouch key — they keep access to existing posts but not future ones) AND unfollows them.`)) return; + unfriend.disabled = true; try { await invoke('revoke_vouch_for_peer', { nodeIdHex: nodeId }); - toast('Revoked and rotated'); + await invoke('unfollow_node', { nodeIdHex: nodeId }); + toast(`Unfriended ${name}`); close(); + loadFollows(); + loadFeed(true); } catch (e) { toast('Error: ' + e); } - finally { revokeVouch.disabled = false; } + finally { unfriend.disabled = false; } }; } catch (e) { bodyEl.innerHTML = `

Error: ${e}

`; @@ -4041,14 +4060,14 @@ $('#export-btn').addEventListener('click', () => { overlay.className = 'image-lightbox'; overlay.style.cursor = 'default'; overlay.innerHTML = ` -
-

Export Data

-

Choose what to include in the export ZIP.

+
+

Export your personas

+

Save your personas + (optionally) your posts to a ZIP file so you can import them on another device.

- - - - + + + +
@@ -4118,8 +4137,8 @@ $('#import-btn').addEventListener('click', () => { overlay.style.cursor = 'default'; overlay.innerHTML = `
-

Import Data

-

Select an ItsGoin export ZIP file.

+

Import from another device

+

Select an ItsGoin export ZIP. Default action restores the exported personas onto this device so you can post as them.

diff --git a/frontend/index.html b/frontend/index.html index e415fd8..ba80394 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -231,13 +231,13 @@
-
-

Identities

-
-
- - -
+
+

Your data on this device

+

+ Personas are who you are to peers — the keys you post and message with. Most people only need one. To move your account to a new device, you export your personas from this device and import them on the new one. +

+ Identities below are this device's own network address — usually not what you want to move. Leave them alone unless you know why you're touching them. +

@@ -248,9 +248,25 @@
+

Move to another device

+

+ Export creates a ZIP containing your personas (and optionally posts/follows). Import on the other device's Settings > Move to another device. +

- - + + +
+
+ +
+

Identities (advanced)

+

+ This device's network address. Changing this is rarely useful — it lets you move the device's QUIC endpoint, NOT your posting identity. +

+
+
+ +