Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -964,6 +964,7 @@ for (const accountComment of accountComments) {
console.log("comment", accountComment.index, "is status", accountComment.state);
}
// `state` becomes `failed` as soon as a pending local publish records terminal failure (`publishingState === "failed"` and `state === "stopped"`) or a publish error, instead of waiting for the 20-minute fallback.
// local account comments returned by useAccountComment and useAccountComments include the account author's address and shortAddress when an older cached account comment is missing author identity fields.
// note: accountComment.index can change after deletions; prefer commentCid for stable identifiers

// all my own votes
Expand Down
14 changes: 14 additions & 0 deletions llms-full.txt
Original file line number Diff line number Diff line change
Expand Up @@ -994,6 +994,7 @@ for (const accountComment of accountComments) {
console.log("comment", accountComment.index, "is status", accountComment.state);
}
// `state` becomes `failed` as soon as a pending local publish records terminal failure (`publishingState === "failed"` and `state === "stopped"`) or a publish error, instead of waiting for the 20-minute fallback.
// local account comments returned by useAccountComment and useAccountComments include the account author's address and shortAddress when an older cached account comment is missing author identity fields.
// note: accountComment.index can change after deletions; prefer commentCid for stable identifiers

// all my own votes
Expand Down Expand Up @@ -3163,6 +3164,19 @@ Avoid GitHub MCP and browser MCP servers for this project because they add signi
Source: https://github.com/bitsocialnet/bitsocial-react-hooks/blob/master/CHANGELOG.md

```markdown
## [0.1.19](https://github.com/bitsocialnet/bitsocial-react-hooks/compare/v0.1.18...v0.1.19) (2026-06-18)


### Bug Fixes

* resolve community name lookups ([ffef83c](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/ffef83cc7b27a59fca4b0788732ff0bfc213496e))



## [0.1.18](https://github.com/bitsocialnet/bitsocial-react-hooks/compare/v0.1.17...v0.1.18) (2026-06-15)



## [0.1.17](https://github.com/bitsocialnet/bitsocial-react-hooks/compare/v0.1.16...v0.1.17) (2026-06-12)


Expand Down
2 changes: 1 addition & 1 deletion llms.txt
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,5 @@ This file is generated by `scripts/generate-llms-files.mjs`. Do not hand-edit it

## Optional

- [Changelog](https://github.com/bitsocialnet/bitsocial-react-hooks/blob/master/CHANGELOG.md): * **actions:** adapt challenge answers for pkc-js ([20d89f0](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/20d89f07363f54c38b83e0f9425bd77174854f9f)) * **deps:** upgrade pkc-js and kubo ([9cb56c2](https...
- [Changelog](https://github.com/bitsocialnet/bitsocial-react-hooks/blob/master/CHANGELOG.md): * resolve community name lookups ([ffef83c](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/ffef83cc7b27a59fca4b0788732ff0bfc213496e))
- [TODO](https://github.com/bitsocialnet/bitsocial-react-hooks/blob/master/docs/TODO.md): - e2e test to publish to an electron sub - async useAuthorAddress hook (because resolving ETH address synchronously is too slow) - implement sort by active - implement showing your own pending replies in a comment (wh...
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"publishConfig": {
"access": "public"
},
"version": "0.1.19",
"version": "0.1.20",
"packageManager": "yarn@4.13.0",
"files": [
"CHANGELOG.md",
Expand Down
84 changes: 84 additions & 0 deletions src/hooks/accounts/accounts.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1655,6 +1655,75 @@ describe("accounts", () => {
expect(rendered2.result.current.index).toBe(undefined);
});

test("account comment hooks restore missing local author identity from the owning account", async () => {
const accountId = accountsStore.getState().activeAccountId!;
accountsStore.setState((state: any) => ({
...state,
accounts: {
...state.accounts,
[accountId]: {
...state.accounts[accountId],
author: {
...state.accounts[accountId].author,
displayName: "Account Author",
avatar: "account-avatar.png",
flair: { label: "account flair" },
},
},
},
accountsComments: {
...state.accountsComments,
[accountId]: state.accountsComments[accountId].map(
(accountComment: any, index: number) => {
if (index === 0) {
return {
...accountComment,
author: { displayName: "Anonymous", shortAddress: "stale-short-address" },
};
}
if (index === 1) {
return {
...accountComment,
author: { address: "existing author address", displayName: "Existing Author" },
};
}
return accountComment;
},
),
},
}));

const accountAuthor = accountsStore.getState().accounts[accountId].author;
const rendered2 = renderHook(() => {
const accountComment = useAccountComment({ commentIndex: 0 });
const accountComments = useAccountComments({ commentIndices: [0, 1] });
return { accountComment, accountComments };
});
const waitForRestoredAuthor = testUtils.createWaitFor(rendered2);

await waitForRestoredAuthor(
() => rendered2.result.current.accountComment.author?.address === accountAuthor.address,
);

const restoredComment = rendered2.result.current.accountComment;
expect(restoredComment.author.address).toBe(accountAuthor.address);
expect(typeof restoredComment.author.shortAddress).toBe("string");
expect(restoredComment.author.shortAddress).not.toBe("stale-short-address");
expect(restoredComment.author.displayName).toBe("Anonymous");
expect(restoredComment.author.avatar).toBe("account-avatar.png");
expect(restoredComment.author.flair).toEqual({ label: "account flair" });

const [restoredListComment, existingAuthorComment] =
rendered2.result.current.accountComments.accountComments;
expect(restoredListComment.author.address).toBe(accountAuthor.address);
expect(restoredListComment.author.displayName).toBe("Anonymous");
expect(existingAuthorComment.author.address).toBe("existing author address");
expect(existingAuthorComment.author.displayName).toBe("Existing Author");
expect(
accountsStore.getState().accountsComments[accountId][0].author.address,
).toBeUndefined();
});

test(`get all account comments`, async () => {
expect(rendered.result.current.accountComments.length).toBe(3);
expect(rendered.result.current.accountComments[0].content).toBe("content 1");
Expand Down Expand Up @@ -3927,6 +3996,21 @@ describe("accounts", () => {
expect(rendered.result.current.errors).toEqual([]);
});

test("useAccountComment ignores negative and fractional indexes", async () => {
const rendered = renderHook<any, any>((props) => useAccountComment(props));
const waitFor = testUtils.createWaitFor(rendered);

rendered.rerender({ commentIndex: -1 });
await waitFor(() => rendered.result.current.state !== undefined);
expect(rendered.result.current.content).toBeUndefined();
expect(rendered.result.current.errors).toEqual([]);

rendered.rerender({ commentIndex: 0.5 });
await waitFor(() => rendered.result.current.state !== undefined);
expect(rendered.result.current.content).toBeUndefined();
expect(rendered.result.current.errors).toEqual([]);
});

test("useAccountComment with nonexistent account has undefined accountComments", async () => {
const rendered = renderHook(() =>
useAccountComment({ commentIndex: 0, accountName: "NonExistentAccount" }),
Expand Down
70 changes: 53 additions & 17 deletions src/hooks/accounts/accounts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ import {
} from "../../lib/community-address";
import { addCommentModeration } from "../../lib/utils/comment-moderation";
import useInterval from "../utils/use-interval";
import PkcJs from "../../lib/pkc-js";

const getCommentEditPropertyValue = (comment: any, propertyName: string) => {
if (propertyName !== COMMENT_MODERATION_AUTHOR_SUMMARY_KEY) {
Expand Down Expand Up @@ -419,6 +420,35 @@ const getAccountHistorySortType = (
return order === "desc" ? "new" : "old";
};

const getAccountCommentWithAccountAuthor = (
accountComment: AccountComment,
account?: Account,
accountId?: string,
): AccountComment => {
const accountAuthor = account?.author;
if (
!accountId ||
accountComment.accountId !== accountId ||
!accountAuthor?.address ||
accountComment.author?.address
) {
return accountComment;
}

const accountShortAddress =
accountAuthor.shortAddress || PkcJs.PKC.getShortAddress({ address: accountAuthor.address });

return {
...accountComment,
author: {
...accountAuthor,
...accountComment.author,
address: accountAuthor.address,
...(accountShortAddress ? { shortAddress: accountShortAddress } : {}),
},
};
};

export function useAccountComments(options?: UseAccountCommentsOptions): UseAccountCommentsResult {
assert(
!options || typeof options === "object",
Expand Down Expand Up @@ -448,6 +478,7 @@ export function useAccountComments(options?: UseAccountCommentsOptions): UseAcco
const commentCidToAccountComment = useAccountsStore(
(state) => state.commentCidsToAccountsComments[commentCid || ""],
);
const account = useAccountsStore((state) => state.accounts[accountId || ""]);
const accountComments = useAccountsStore((state) => state.accountsComments[accountId || ""]);
const [accountCommentStates, setAccountCommentStates] = useState<string[]>([]);
const accountHistorySortType = getAccountHistorySortType(sortType, order);
Expand Down Expand Up @@ -538,10 +569,10 @@ export function useAccountComments(options?: UseAccountCommentsOptions): UseAcco
const filteredAccountCommentsWithStates = useMemo(() => {
const states = getAccountCommentsStates(filteredAccountComments);
return filteredAccountComments.map((comment, i) => ({
...comment,
...getAccountCommentWithAccountAuthor(comment, account, accountId || undefined),
state: states[i],
}));
}, [filteredAccountComments, accountCommentStates]);
}, [filteredAccountComments, accountCommentStates, account, accountId]);

if (options) {
log("useAccountComments", {
Expand Down Expand Up @@ -587,10 +618,13 @@ export function useAccountComment(options?: UseAccountCommentOptions): UseAccoun
const commentCidToAccountComment = useAccountsStore(
(state) => state.commentCidsToAccountsComments[commentCid || ""],
);
const account = useAccountsStore((state) => state.accounts[accountId || ""]);
const accountComments = useAccountsStore((state) => state.accountsComments[accountId || ""]);
const normalizedCommentIndex = commentIndex === undefined ? undefined : Number(commentIndex);
const resolvedCommentIndex =
typeof normalizedCommentIndex === "number" && !Number.isNaN(normalizedCommentIndex)
typeof normalizedCommentIndex === "number" &&
Number.isInteger(normalizedCommentIndex) &&
normalizedCommentIndex >= 0
? normalizedCommentIndex
: commentCidToAccountComment?.accountId === accountId
? commentCidToAccountComment.accountCommentIndex
Expand All @@ -601,24 +635,26 @@ export function useAccountComment(options?: UseAccountCommentOptions): UseAccoun
}
return accountComments?.[resolvedCommentIndex];
}, [accountComments, resolvedCommentIndex]);
const accountComment = (storedAccountComment || {}) as Partial<AccountComment> & {
error?: Error;
errors?: Error[];
};
const state = storedAccountComment
? getAccountCommentsStates([storedAccountComment])[0]
: "initializing";

return useMemo(
() =>
({
...accountComment,
state,
error: accountComment.error,
errors: accountComment.errors || [],
}) as UseAccountCommentResult,
[accountComment, state],
);
return useMemo(() => {
const accountComment = (
storedAccountComment
? getAccountCommentWithAccountAuthor(storedAccountComment, account, accountId || undefined)
: {}
) as Partial<AccountComment> & {
error?: Error;
errors?: Error[];
};
return {
...accountComment,
state,
error: accountComment.error,
errors: accountComment.errors || [],
} as UseAccountCommentResult;
}, [storedAccountComment, account, accountId, state]);
}

/**
Expand Down
Loading