feat(fof-layer2): Tauri commands + frontend compose/comment routing
Three new Tauri commands surface Layer 2 to the frontend:
- create_post_with_fof_comments(content) → { postId }
Builds the FoF gating block from the default persona's keyring and
publishes a Mode 2 post (public body, FoF-gated comments).
- comment_on_fof_post(post_id_hex, body)
Backwards-compat wrapper: comment_on_post now auto-detects FoF
gating on the parent post and dispatches internally. Existing
comment-send UI works unchanged.
- revoke_fof_commenter(post_id_hex, pub_x_index, reason_code)
Wraps the Node helper. UI for per-comment revocation can hang off
this without further Node changes.
Node::comment_on_post now branches on parent post fof_gating presence
— this is the central routing point so neither the frontend nor
existing comment-send code needs to know about FoF specifics. FoF
posts get FoF comments automatically; non-FoF posts get the legacy
path. Same Tauri command, same frontend handler.
Frontend:
- Compose: comment-perm-select gains a "Friends of Friends" option.
When picked, compose dispatches to create_post_with_fof_comments
instead of the standard create_post. Standard set_comment_policy
diff fires after so receivers' four-check accept rule activates.
- Attachments + non-default-persona FoF posts are out-of-v1; compose
reports + aborts rather than silently producing a non-FoF post.
Layer 2 backend + minimal-viable UI complete. Granular per-comment
revoke UI and access-grant UI deferred — Node + Tauri primitives
exist; the surfaces can be added without further crypto work.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
96118d7ce8
commit
10de3f6108
4 changed files with 144 additions and 4 deletions
|
|
@ -2629,8 +2629,29 @@ async function doPost() {
|
|||
}
|
||||
}
|
||||
|
||||
const commentPerm = document.getElementById('comment-perm-select').value;
|
||||
const reactPerm = document.getElementById('react-perm-select').value;
|
||||
|
||||
let result;
|
||||
if (selectedFiles.length > 0) {
|
||||
if (commentPerm === 'friends_of_friends') {
|
||||
// FoF Layer 2: body is still public (Mode 2) but the post
|
||||
// carries a fof_gating block built from the author's
|
||||
// keyring. Routed through a dedicated command because the
|
||||
// gating block is signed at publish time (can't be added
|
||||
// via SetPolicy after the fact).
|
||||
// Attachments + non-default-persona FoF posts are not yet
|
||||
// supported by the v1 command — fall through to the
|
||||
// standard path with a warning if either applies.
|
||||
if (selectedFiles.length > 0 || params.postingIdHex) {
|
||||
toast('FoF posts with attachments or non-default persona require Mode 1 (later).');
|
||||
postBtn.disabled = false;
|
||||
return;
|
||||
}
|
||||
const created = await invoke('create_post_with_fof_comments', {
|
||||
content: params.content,
|
||||
});
|
||||
result = { id: created.postId };
|
||||
} else if (selectedFiles.length > 0) {
|
||||
// Convert ArrayBuffers to base64 strings
|
||||
const files = selectedFiles.map(f => {
|
||||
const bytes = new Uint8Array(f.data);
|
||||
|
|
@ -2644,9 +2665,9 @@ async function doPost() {
|
|||
result = await invoke('create_post', params);
|
||||
}
|
||||
|
||||
// Set engagement policy if non-default
|
||||
const commentPerm = document.getElementById('comment-perm-select').value;
|
||||
const reactPerm = document.getElementById('react-perm-select').value;
|
||||
// Set engagement policy if non-default (FoF posts also publish
|
||||
// the policy diff so receivers route the comment-receive path
|
||||
// through the FoF four-check verify gate).
|
||||
if ((commentPerm !== 'public' || reactPerm !== 'both') && result && result.id) {
|
||||
try {
|
||||
await invoke('set_comment_policy', {
|
||||
|
|
|
|||
|
|
@ -104,6 +104,7 @@
|
|||
<select id="comment-perm-select" title="Comment permission">
|
||||
<option value="public">Comments: All</option>
|
||||
<option value="followers_only">Comments: Followers</option>
|
||||
<option value="friends_of_friends">Comments: Friends of Friends</option>
|
||||
<option value="none">Comments: Off</option>
|
||||
</select>
|
||||
<select id="react-perm-select" title="React permission">
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue