@bitsocial/bitsocial-react-hooks 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +674 -0
- package/README.md +1365 -0
- package/dist/hooks/accounts/accounts.d.ts +64 -0
- package/dist/hooks/accounts/accounts.d.ts.map +1 -0
- package/dist/hooks/accounts/accounts.js +706 -0
- package/dist/hooks/accounts/accounts.js.map +1 -0
- package/dist/hooks/accounts/index.d.ts +2 -0
- package/dist/hooks/accounts/index.d.ts.map +1 -0
- package/dist/hooks/accounts/index.js +2 -0
- package/dist/hooks/accounts/index.js.map +1 -0
- package/dist/hooks/accounts/utils.d.ts +6 -0
- package/dist/hooks/accounts/utils.d.ts.map +1 -0
- package/dist/hooks/accounts/utils.js +226 -0
- package/dist/hooks/accounts/utils.js.map +1 -0
- package/dist/hooks/actions/actions.d.ts +19 -0
- package/dist/hooks/actions/actions.d.ts.map +1 -0
- package/dist/hooks/actions/actions.js +552 -0
- package/dist/hooks/actions/actions.js.map +1 -0
- package/dist/hooks/actions/index.d.ts +2 -0
- package/dist/hooks/actions/index.d.ts.map +1 -0
- package/dist/hooks/actions/index.js +2 -0
- package/dist/hooks/actions/index.js.map +1 -0
- package/dist/hooks/authors/author-avatars.d.ts +28 -0
- package/dist/hooks/authors/author-avatars.d.ts.map +1 -0
- package/dist/hooks/authors/author-avatars.js +191 -0
- package/dist/hooks/authors/author-avatars.js.map +1 -0
- package/dist/hooks/authors/authors.d.ts +37 -0
- package/dist/hooks/authors/authors.d.ts.map +1 -0
- package/dist/hooks/authors/authors.js +509 -0
- package/dist/hooks/authors/authors.js.map +1 -0
- package/dist/hooks/authors/index.d.ts +2 -0
- package/dist/hooks/authors/index.d.ts.map +1 -0
- package/dist/hooks/authors/index.js +2 -0
- package/dist/hooks/authors/index.js.map +1 -0
- package/dist/hooks/authors/utils.d.ts +4 -0
- package/dist/hooks/authors/utils.d.ts.map +1 -0
- package/dist/hooks/authors/utils.js +21 -0
- package/dist/hooks/authors/utils.js.map +1 -0
- package/dist/hooks/comments.d.ts +17 -0
- package/dist/hooks/comments.d.ts.map +1 -0
- package/dist/hooks/comments.js +351 -0
- package/dist/hooks/comments.js.map +1 -0
- package/dist/hooks/communities.d.ts +31 -0
- package/dist/hooks/communities.d.ts.map +1 -0
- package/dist/hooks/communities.js +389 -0
- package/dist/hooks/communities.js.map +1 -0
- package/dist/hooks/feeds/feeds.d.ts +18 -0
- package/dist/hooks/feeds/feeds.d.ts.map +1 -0
- package/dist/hooks/feeds/feeds.js +315 -0
- package/dist/hooks/feeds/feeds.js.map +1 -0
- package/dist/hooks/feeds/index.d.ts +2 -0
- package/dist/hooks/feeds/index.d.ts.map +1 -0
- package/dist/hooks/feeds/index.js +2 -0
- package/dist/hooks/feeds/index.js.map +1 -0
- package/dist/hooks/pkc-rpc.d.ts +7 -0
- package/dist/hooks/pkc-rpc.d.ts.map +1 -0
- package/dist/hooks/pkc-rpc.js +88 -0
- package/dist/hooks/pkc-rpc.js.map +1 -0
- package/dist/hooks/replies.d.ts +5 -0
- package/dist/hooks/replies.d.ts.map +1 -0
- package/dist/hooks/replies.js +155 -0
- package/dist/hooks/replies.js.map +1 -0
- package/dist/hooks/states.d.ts +15 -0
- package/dist/hooks/states.d.ts.map +1 -0
- package/dist/hooks/states.js +213 -0
- package/dist/hooks/states.js.map +1 -0
- package/dist/hooks/utils/use-interval.d.ts +3 -0
- package/dist/hooks/utils/use-interval.d.ts.map +1 -0
- package/dist/hooks/utils/use-interval.js +36 -0
- package/dist/hooks/utils/use-interval.js.map +1 -0
- package/dist/hooks/utils/use-previous.d.ts +1 -0
- package/dist/hooks/utils/use-previous.js +10 -0
- package/dist/index.d.ts +82 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +128 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/chain/chain.d.ts +36 -0
- package/dist/lib/chain/chain.d.ts.map +1 -0
- package/dist/lib/chain/chain.js +195 -0
- package/dist/lib/chain/chain.js.map +1 -0
- package/dist/lib/chain/index.d.ts +4 -0
- package/dist/lib/chain/index.d.ts.map +1 -0
- package/dist/lib/chain/index.js +4 -0
- package/dist/lib/chain/index.js.map +1 -0
- package/dist/lib/community-address.d.ts +6 -0
- package/dist/lib/community-address.d.ts.map +1 -0
- package/dist/lib/community-address.js +26 -0
- package/dist/lib/community-address.js.map +1 -0
- package/dist/lib/community-ref.d.ts +23 -0
- package/dist/lib/community-ref.d.ts.map +1 -0
- package/dist/lib/community-ref.js +113 -0
- package/dist/lib/community-ref.js.map +1 -0
- package/dist/lib/debug-utils.d.ts +9 -0
- package/dist/lib/debug-utils.d.ts.map +1 -0
- package/dist/lib/debug-utils.js +21 -0
- package/dist/lib/debug-utils.js.map +1 -0
- package/dist/lib/feed-sort-type.d.ts +2 -0
- package/dist/lib/feed-sort-type.d.ts.map +1 -0
- package/dist/lib/feed-sort-type.js +22 -0
- package/dist/lib/feed-sort-type.js.map +1 -0
- package/dist/lib/localforage-lru/index.d.ts +3 -0
- package/dist/lib/localforage-lru/index.d.ts.map +1 -0
- package/dist/lib/localforage-lru/index.js +46 -0
- package/dist/lib/localforage-lru/index.js.map +1 -0
- package/dist/lib/localforage-lru/localforage-lru.d.ts +6 -0
- package/dist/lib/localforage-lru/localforage-lru.d.ts.map +1 -0
- package/dist/lib/localforage-lru/localforage-lru.js +182 -0
- package/dist/lib/localforage-lru/localforage-lru.js.map +1 -0
- package/dist/lib/pkc-compat.d.ts +25 -0
- package/dist/lib/pkc-compat.d.ts.map +1 -0
- package/dist/lib/pkc-compat.js +131 -0
- package/dist/lib/pkc-compat.js.map +1 -0
- package/dist/lib/pkc-js/fixtures/markdown-example.d.ts +3 -0
- package/dist/lib/pkc-js/fixtures/markdown-example.d.ts.map +1 -0
- package/dist/lib/pkc-js/fixtures/markdown-example.js +280 -0
- package/dist/lib/pkc-js/fixtures/markdown-example.js.map +1 -0
- package/dist/lib/pkc-js/index.d.ts +11 -0
- package/dist/lib/pkc-js/index.d.ts.map +1 -0
- package/dist/lib/pkc-js/index.js +85 -0
- package/dist/lib/pkc-js/index.js.map +1 -0
- package/dist/lib/pkc-js/pkc-js-mock-content.d.ts +3 -0
- package/dist/lib/pkc-js/pkc-js-mock-content.d.ts.map +1 -0
- package/dist/lib/pkc-js/pkc-js-mock-content.js +1235 -0
- package/dist/lib/pkc-js/pkc-js-mock-content.js.map +1 -0
- package/dist/lib/pkc-js/pkc-js-mock.d.ts +137 -0
- package/dist/lib/pkc-js/pkc-js-mock.d.ts.map +1 -0
- package/dist/lib/pkc-js/pkc-js-mock.js +644 -0
- package/dist/lib/pkc-js/pkc-js-mock.js.map +1 -0
- package/dist/lib/polyfill.d.ts +3 -0
- package/dist/lib/polyfill.d.ts.map +1 -0
- package/dist/lib/polyfill.js +14 -0
- package/dist/lib/polyfill.js.map +1 -0
- package/dist/lib/protocol-compat.d.ts +14 -0
- package/dist/lib/protocol-compat.d.ts.map +1 -0
- package/dist/lib/protocol-compat.js +67 -0
- package/dist/lib/protocol-compat.js.map +1 -0
- package/dist/lib/test-utils.d.ts +29 -0
- package/dist/lib/test-utils.d.ts.map +1 -0
- package/dist/lib/test-utils.js +184 -0
- package/dist/lib/test-utils.js.map +1 -0
- package/dist/lib/utils/comment-moderation.d.ts +4 -0
- package/dist/lib/utils/comment-moderation.d.ts.map +1 -0
- package/dist/lib/utils/comment-moderation.js +56 -0
- package/dist/lib/utils/comment-moderation.js.map +1 -0
- package/dist/lib/utils/index.d.ts +4 -0
- package/dist/lib/utils/index.d.ts.map +1 -0
- package/dist/lib/utils/index.js +4 -0
- package/dist/lib/utils/index.js.map +1 -0
- package/dist/lib/utils/utils.d.ts +23 -0
- package/dist/lib/utils/utils.d.ts.map +1 -0
- package/dist/lib/utils/utils.js +375 -0
- package/dist/lib/utils/utils.js.map +1 -0
- package/dist/lib/validator.d.ts +30 -0
- package/dist/lib/validator.d.ts.map +1 -0
- package/dist/lib/validator.js +307 -0
- package/dist/lib/validator.js.map +1 -0
- package/dist/stores/accounts/account-generator.d.ts +51 -0
- package/dist/stores/accounts/account-generator.d.ts.map +1 -0
- package/dist/stores/accounts/account-generator.js +160 -0
- package/dist/stores/accounts/account-generator.js.map +1 -0
- package/dist/stores/accounts/accounts-actions-internal.d.ts +8 -0
- package/dist/stores/accounts/accounts-actions-internal.d.ts.map +1 -0
- package/dist/stores/accounts/accounts-actions-internal.js +403 -0
- package/dist/stores/accounts/accounts-actions-internal.js.map +1 -0
- package/dist/stores/accounts/accounts-actions.d.ts +46 -0
- package/dist/stores/accounts/accounts-actions.d.ts.map +1 -0
- package/dist/stores/accounts/accounts-actions.js +1341 -0
- package/dist/stores/accounts/accounts-actions.js.map +1 -0
- package/dist/stores/accounts/accounts-database.d.ts +34 -0
- package/dist/stores/accounts/accounts-database.d.ts.map +1 -0
- package/dist/stores/accounts/accounts-database.js +685 -0
- package/dist/stores/accounts/accounts-database.js.map +1 -0
- package/dist/stores/accounts/accounts-store.d.ts +32 -0
- package/dist/stores/accounts/accounts-store.d.ts.map +1 -0
- package/dist/stores/accounts/accounts-store.js +169 -0
- package/dist/stores/accounts/accounts-store.js.map +1 -0
- package/dist/stores/accounts/index.d.ts +4 -0
- package/dist/stores/accounts/index.d.ts.map +1 -0
- package/dist/stores/accounts/index.js +4 -0
- package/dist/stores/accounts/index.js.map +1 -0
- package/dist/stores/accounts/utils.d.ts +49 -0
- package/dist/stores/accounts/utils.d.ts.map +1 -0
- package/dist/stores/accounts/utils.js +419 -0
- package/dist/stores/accounts/utils.js.map +1 -0
- package/dist/stores/authors-comments/authors-comments-store.d.ts +37 -0
- package/dist/stores/authors-comments/authors-comments-store.d.ts.map +1 -0
- package/dist/stores/authors-comments/authors-comments-store.js +338 -0
- package/dist/stores/authors-comments/authors-comments-store.js.map +1 -0
- package/dist/stores/authors-comments/index.d.ts +4 -0
- package/dist/stores/authors-comments/index.d.ts.map +1 -0
- package/dist/stores/authors-comments/index.js +4 -0
- package/dist/stores/authors-comments/index.js.map +1 -0
- package/dist/stores/authors-comments/utils.d.ts +14 -0
- package/dist/stores/authors-comments/utils.d.ts.map +1 -0
- package/dist/stores/authors-comments/utils.js +81 -0
- package/dist/stores/authors-comments/utils.js.map +1 -0
- package/dist/stores/comments/comments-store.d.ts +19 -0
- package/dist/stores/comments/comments-store.d.ts.map +1 -0
- package/dist/stores/comments/comments-store.js +385 -0
- package/dist/stores/comments/comments-store.js.map +1 -0
- package/dist/stores/comments/index.d.ts +4 -0
- package/dist/stores/comments/index.d.ts.map +1 -0
- package/dist/stores/comments/index.js +4 -0
- package/dist/stores/comments/index.js.map +1 -0
- package/dist/stores/communities/communities-store.d.ts +17 -0
- package/dist/stores/communities/communities-store.d.ts.map +1 -0
- package/dist/stores/communities/communities-store.js +304 -0
- package/dist/stores/communities/communities-store.js.map +1 -0
- package/dist/stores/communities/index.d.ts +4 -0
- package/dist/stores/communities/index.d.ts.map +1 -0
- package/dist/stores/communities/index.js +4 -0
- package/dist/stores/communities/index.js.map +1 -0
- package/dist/stores/communities-pages/communities-pages-store.d.ts +23 -0
- package/dist/stores/communities-pages/communities-pages-store.d.ts.map +1 -0
- package/dist/stores/communities-pages/communities-pages-store.js +316 -0
- package/dist/stores/communities-pages/communities-pages-store.js.map +1 -0
- package/dist/stores/communities-pages/index.d.ts +4 -0
- package/dist/stores/communities-pages/index.d.ts.map +1 -0
- package/dist/stores/communities-pages/index.js +4 -0
- package/dist/stores/communities-pages/index.js.map +1 -0
- package/dist/stores/feeds/feed-sorter.d.ts +5 -0
- package/dist/stores/feeds/feed-sorter.d.ts.map +1 -0
- package/dist/stores/feeds/feed-sorter.js +135 -0
- package/dist/stores/feeds/feed-sorter.js.map +1 -0
- package/dist/stores/feeds/feeds-store.d.ts +25 -0
- package/dist/stores/feeds/feeds-store.d.ts.map +1 -0
- package/dist/stores/feeds/feeds-store.js +459 -0
- package/dist/stores/feeds/feeds-store.js.map +1 -0
- package/dist/stores/feeds/index.d.ts +4 -0
- package/dist/stores/feeds/index.d.ts.map +1 -0
- package/dist/stores/feeds/index.js +4 -0
- package/dist/stores/feeds/index.js.map +1 -0
- package/dist/stores/feeds/utils.d.ts +43 -0
- package/dist/stores/feeds/utils.d.ts.map +1 -0
- package/dist/stores/feeds/utils.js +736 -0
- package/dist/stores/feeds/utils.js.map +1 -0
- package/dist/stores/replies/index.d.ts +4 -0
- package/dist/stores/replies/index.d.ts.map +1 -0
- package/dist/stores/replies/index.js +4 -0
- package/dist/stores/replies/index.js.map +1 -0
- package/dist/stores/replies/replies-comments-store.d.ts +8 -0
- package/dist/stores/replies/replies-comments-store.d.ts.map +1 -0
- package/dist/stores/replies/replies-comments-store.js +23 -0
- package/dist/stores/replies/replies-comments-store.js.map +1 -0
- package/dist/stores/replies/replies-store.d.ts +29 -0
- package/dist/stores/replies/replies-store.d.ts.map +1 -0
- package/dist/stores/replies/replies-store.js +413 -0
- package/dist/stores/replies/replies-store.js.map +1 -0
- package/dist/stores/replies/utils.d.ts +25 -0
- package/dist/stores/replies/utils.d.ts.map +1 -0
- package/dist/stores/replies/utils.js +549 -0
- package/dist/stores/replies/utils.js.map +1 -0
- package/dist/stores/replies-pages/index.d.ts +4 -0
- package/dist/stores/replies-pages/index.d.ts.map +1 -0
- package/dist/stores/replies-pages/index.js +4 -0
- package/dist/stores/replies-pages/index.js.map +1 -0
- package/dist/stores/replies-pages/replies-pages-store.d.ts +20 -0
- package/dist/stores/replies-pages/replies-pages-store.d.ts.map +1 -0
- package/dist/stores/replies-pages/replies-pages-store.js +270 -0
- package/dist/stores/replies-pages/replies-pages-store.js.map +1 -0
- package/dist/stores/replies-pages/utils.d.ts +3 -0
- package/dist/stores/replies-pages/utils.d.ts.map +1 -0
- package/dist/stores/replies-pages/utils.js +43 -0
- package/dist/stores/replies-pages/utils.js.map +1 -0
- package/dist/types.d.ts +638 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +160 -0
|
@@ -0,0 +1,706 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { useMemo, useState, useEffect } from "react";
|
|
11
|
+
import isEqual from "lodash.isequal";
|
|
12
|
+
import useAccountsStore from "../../stores/accounts/index.js";
|
|
13
|
+
import useCommunitiesStore from "../../stores/communities/index.js";
|
|
14
|
+
import Logger from "@pkcprotocol/pkc-logger";
|
|
15
|
+
const log = Logger("bitsocial-react-hooks:accounts:hooks");
|
|
16
|
+
import assert from "assert";
|
|
17
|
+
import { useListCommunities, useCommunities } from "../communities.js";
|
|
18
|
+
import { useAccountsWithCalculatedProperties, useAccountWithCalculatedProperties, useCalculatedNotifications, } from "./utils.js";
|
|
19
|
+
import { getAccountEditPropertySummary } from "../../stores/accounts/utils.js";
|
|
20
|
+
import { getCanonicalCommunityAddress, getEquivalentCommunityAddressGroupKey, pickPreferredEquivalentCommunityAddress, } from "../../lib/community-address.js";
|
|
21
|
+
import { addCommentModeration } from "../../lib/utils/comment-moderation.js";
|
|
22
|
+
import useInterval from "../utils/use-interval.js";
|
|
23
|
+
/**
|
|
24
|
+
* @param accountName - The nickname of the account, e.g. 'Account 1'. If no accountName is provided, return
|
|
25
|
+
* the active account id.
|
|
26
|
+
*/
|
|
27
|
+
export function useAccountId(accountName) {
|
|
28
|
+
const accountId = useAccountsStore((state) => state.accountNamesToAccountIds[accountName || ""]);
|
|
29
|
+
// don't consider active account if account name is defined
|
|
30
|
+
const activeAccountId = useAccountsStore((state) => !accountName && state.activeAccountId);
|
|
31
|
+
const accountIdToUse = accountName ? accountId : activeAccountId;
|
|
32
|
+
return accountIdToUse;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* @param accountName - The nickname of the account, e.g. 'Account 1'. If no accountName is provided, return
|
|
36
|
+
* the active account.
|
|
37
|
+
*/
|
|
38
|
+
export function useAccount(options) {
|
|
39
|
+
assert(!options || typeof options === "object", `useAccount options argument '${options}' not an object`);
|
|
40
|
+
const { accountName } = options || {};
|
|
41
|
+
// get state
|
|
42
|
+
const accountId = useAccountId(accountName);
|
|
43
|
+
const accountStore = useAccountsStore((state) => state.accounts[accountId || ""]);
|
|
44
|
+
const accountComments = useAccountsStore((state) => state.accountsComments[accountId || ""]);
|
|
45
|
+
const accountCommentsReplies = useAccountsStore((state) => state.accountsCommentsReplies[accountId || ""]);
|
|
46
|
+
const account = useAccountWithCalculatedProperties(accountStore, accountComments, accountCommentsReplies);
|
|
47
|
+
log("useAccount", { accountId, account, accountName });
|
|
48
|
+
return account;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Return all accounts in the order of `accountsStore.accountIds`. To reorder, use `accountsActions.setAccountsOrder(accountNames)`.
|
|
52
|
+
*/
|
|
53
|
+
export function useAccounts() {
|
|
54
|
+
const accountIds = useAccountsStore((state) => state.accountIds);
|
|
55
|
+
const accountsStore = useAccountsStore((state) => state.accounts);
|
|
56
|
+
const accountsComments = useAccountsStore((state) => state.accountsComments);
|
|
57
|
+
const accountsCommentsReplies = useAccountsStore((state) => state.accountsCommentsReplies);
|
|
58
|
+
const accounts = useAccountsWithCalculatedProperties(accountsStore, accountsComments, accountsCommentsReplies);
|
|
59
|
+
const accountsArray = useMemo(() => {
|
|
60
|
+
const accountsArray = [];
|
|
61
|
+
if ((accountIds === null || accountIds === void 0 ? void 0 : accountIds.length) && accounts) {
|
|
62
|
+
for (const accountId of accountIds) {
|
|
63
|
+
accountsArray.push(accounts[accountId]);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return accountsArray;
|
|
67
|
+
}, [accounts, accountIds]);
|
|
68
|
+
log("useAccounts", { accounts, accountIds });
|
|
69
|
+
const state = (accountsArray === null || accountsArray === void 0 ? void 0 : accountsArray.length) ? "succeeded" : "initializing";
|
|
70
|
+
return useMemo(() => ({
|
|
71
|
+
accounts: accountsArray,
|
|
72
|
+
state,
|
|
73
|
+
error: undefined,
|
|
74
|
+
errors: [],
|
|
75
|
+
}), [accountsArray, state]);
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Returns all communities where the account is a creator or moderator
|
|
79
|
+
*/
|
|
80
|
+
export function useAccountCommunities(options) {
|
|
81
|
+
assert(!options || typeof options === "object", `useAccountCommunities options argument '${options}' not an object`);
|
|
82
|
+
const opts = options !== null && options !== void 0 ? options : {};
|
|
83
|
+
const { accountName, onlyIfCached } = opts;
|
|
84
|
+
const accountId = useAccountId(accountName);
|
|
85
|
+
const accountIdKey = accountId || "";
|
|
86
|
+
const accountsStoreAccountCommunities = useAccountsStore((state) => { var _a; return (_a = state.accounts[accountIdKey]) === null || _a === void 0 ? void 0 : _a.communities; });
|
|
87
|
+
// get all unique account community addresses
|
|
88
|
+
const ownerCommunityAddresses = useListCommunities(accountName);
|
|
89
|
+
const groupedCommunityAddresses = useMemo(() => {
|
|
90
|
+
const accountCommunityAddresses = [];
|
|
91
|
+
if (accountsStoreAccountCommunities) {
|
|
92
|
+
for (const communityAddress in accountsStoreAccountCommunities) {
|
|
93
|
+
accountCommunityAddresses.push(communityAddress);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
const allCommunityAddresses = [
|
|
97
|
+
...new Set([...ownerCommunityAddresses, ...accountCommunityAddresses]),
|
|
98
|
+
].sort();
|
|
99
|
+
const groupedAddresses = new Map();
|
|
100
|
+
for (const communityAddress of allCommunityAddresses) {
|
|
101
|
+
const groupKey = getEquivalentCommunityAddressGroupKey(communityAddress);
|
|
102
|
+
const addresses = groupedAddresses.get(groupKey);
|
|
103
|
+
if (addresses) {
|
|
104
|
+
addresses.push(communityAddress);
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
groupedAddresses.set(groupKey, [communityAddress]);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return [...groupedAddresses.entries()].map(([groupKey, addresses]) => ({
|
|
111
|
+
groupKey,
|
|
112
|
+
addresses,
|
|
113
|
+
preferredAddress: pickPreferredEquivalentCommunityAddress(addresses),
|
|
114
|
+
}));
|
|
115
|
+
}, [accountsStoreAccountCommunities, ownerCommunityAddresses]);
|
|
116
|
+
const uniqueCommunityAddresses = useMemo(() => groupedCommunityAddresses.map(({ preferredAddress }) => preferredAddress), [groupedCommunityAddresses]);
|
|
117
|
+
// fetch all community data
|
|
118
|
+
const { communities: communitiesArray, state: communitiesState, error: communitiesError, errors: communitiesErrors, } = useCommunities({
|
|
119
|
+
communities: uniqueCommunityAddresses.map((communityAddress) => ({ name: communityAddress })),
|
|
120
|
+
accountName,
|
|
121
|
+
onlyIfCached,
|
|
122
|
+
});
|
|
123
|
+
const communityFetchErrors = useCommunitiesStore((state) => uniqueCommunityAddresses.flatMap((communityAddress) => state.errors[communityAddress] || []));
|
|
124
|
+
const canonicalAddressByGroupKey = useMemo(() => {
|
|
125
|
+
var _a;
|
|
126
|
+
const canonicalAddresses = {};
|
|
127
|
+
for (const [i, { groupKey, preferredAddress }] of groupedCommunityAddresses.entries()) {
|
|
128
|
+
const fetchedAddress = (_a = communitiesArray[i]) === null || _a === void 0 ? void 0 : _a.address;
|
|
129
|
+
canonicalAddresses[groupKey] = getCanonicalCommunityAddress(fetchedAddress || preferredAddress);
|
|
130
|
+
}
|
|
131
|
+
return canonicalAddresses;
|
|
132
|
+
}, [groupedCommunityAddresses, communitiesArray]);
|
|
133
|
+
const communities = useMemo(() => {
|
|
134
|
+
const communities = {};
|
|
135
|
+
for (const [i, community] of communitiesArray.entries()) {
|
|
136
|
+
const { groupKey, preferredAddress } = groupedCommunityAddresses[i];
|
|
137
|
+
const canonicalAddress = canonicalAddressByGroupKey[groupKey];
|
|
138
|
+
communities[canonicalAddress] = Object.assign(Object.assign(Object.assign({}, communities[canonicalAddress]), community), {
|
|
139
|
+
// make sure the canonical address is defined even if the community hasn't fetched yet
|
|
140
|
+
address: canonicalAddress });
|
|
141
|
+
}
|
|
142
|
+
return communities;
|
|
143
|
+
}, [communitiesArray, groupedCommunityAddresses, canonicalAddressByGroupKey]);
|
|
144
|
+
// merged community data with account.communities data
|
|
145
|
+
const accountCommunities = useMemo(() => {
|
|
146
|
+
const accountCommunities = Object.assign({}, communities);
|
|
147
|
+
if (accountsStoreAccountCommunities) {
|
|
148
|
+
for (const communityAddress in accountsStoreAccountCommunities) {
|
|
149
|
+
const groupKey = getEquivalentCommunityAddressGroupKey(communityAddress);
|
|
150
|
+
const canonicalAddress = canonicalAddressByGroupKey[groupKey];
|
|
151
|
+
accountCommunities[canonicalAddress] = Object.assign(Object.assign(Object.assign({}, accountCommunities[canonicalAddress]), accountsStoreAccountCommunities[communityAddress]), { address: canonicalAddress });
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
// add pkc.communities data
|
|
155
|
+
for (const communityAddress of ownerCommunityAddresses) {
|
|
156
|
+
const groupKey = getEquivalentCommunityAddressGroupKey(communityAddress);
|
|
157
|
+
const canonicalAddress = canonicalAddressByGroupKey[groupKey];
|
|
158
|
+
accountCommunities[canonicalAddress] = Object.assign(Object.assign({}, accountCommunities[canonicalAddress]), { address: canonicalAddress, role: { role: "owner" } });
|
|
159
|
+
}
|
|
160
|
+
return accountCommunities;
|
|
161
|
+
}, [
|
|
162
|
+
accountsStoreAccountCommunities,
|
|
163
|
+
ownerCommunityAddresses,
|
|
164
|
+
communities,
|
|
165
|
+
canonicalAddressByGroupKey,
|
|
166
|
+
]);
|
|
167
|
+
if (accountId) {
|
|
168
|
+
log("useAccountCommunities", { accountCommunities });
|
|
169
|
+
}
|
|
170
|
+
const pendingAccountCommunities = Object.values(accountCommunities).some((community) => (community === null || community === void 0 ? void 0 : community.address) && !(community === null || community === void 0 ? void 0 : community.updatedAt));
|
|
171
|
+
const errors = communityFetchErrors.length ? communityFetchErrors : communitiesErrors;
|
|
172
|
+
const error = communitiesError || errors[errors.length - 1];
|
|
173
|
+
const state = !accountId
|
|
174
|
+
? "initializing"
|
|
175
|
+
: error
|
|
176
|
+
? "failed"
|
|
177
|
+
: pendingAccountCommunities
|
|
178
|
+
? "fetching-ipns"
|
|
179
|
+
: communitiesState;
|
|
180
|
+
return useMemo(() => ({
|
|
181
|
+
accountCommunities,
|
|
182
|
+
state,
|
|
183
|
+
error,
|
|
184
|
+
errors,
|
|
185
|
+
}), [accountCommunities, state, error, errors]);
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Returns an account's notifications in an array. Unread notifications have a field markedAsRead: false.
|
|
189
|
+
*
|
|
190
|
+
* @param accountName - The nickname of the account, e.g. 'Account 1'. If no accountName is provided, return
|
|
191
|
+
* the active account's notifications.
|
|
192
|
+
*/
|
|
193
|
+
export function useNotifications(options) {
|
|
194
|
+
assert(!options || typeof options === "object", `useNotifications options argument '${options}' not an object`);
|
|
195
|
+
const { accountName } = options || {};
|
|
196
|
+
// get state
|
|
197
|
+
const accountId = useAccountId(accountName);
|
|
198
|
+
const account = useAccountsStore((state) => state.accounts[accountId || ""]);
|
|
199
|
+
const accountCommentsReplies = useAccountsStore((state) => state.accountsCommentsReplies[accountId || ""]);
|
|
200
|
+
const accountsActionsInternal = useAccountsStore((state) => state.accountsActionsInternal);
|
|
201
|
+
const notifications = useCalculatedNotifications(account, accountCommentsReplies);
|
|
202
|
+
const [errors, setErrors] = useState([]);
|
|
203
|
+
const markAsRead = () => __awaiter(this, void 0, void 0, function* () {
|
|
204
|
+
try {
|
|
205
|
+
if (!account) {
|
|
206
|
+
throw Error("useNotifications cannot mark as read accounts not initalized yet");
|
|
207
|
+
}
|
|
208
|
+
accountsActionsInternal.markNotificationsAsRead(account);
|
|
209
|
+
}
|
|
210
|
+
catch (e) {
|
|
211
|
+
setErrors([...errors, e]);
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
if (account) {
|
|
215
|
+
log("useNotifications", { notifications });
|
|
216
|
+
}
|
|
217
|
+
const state = accountId ? "succeeded" : "initializing";
|
|
218
|
+
return useMemo(() => ({
|
|
219
|
+
notifications,
|
|
220
|
+
markAsRead,
|
|
221
|
+
state,
|
|
222
|
+
error: errors[errors.length - 1],
|
|
223
|
+
errors,
|
|
224
|
+
}), [notifications, errors]);
|
|
225
|
+
}
|
|
226
|
+
const getAccountCommentsStates = (accountComments) => {
|
|
227
|
+
// Without a cid, the account comment is still a local pending publish. pkc-js marks
|
|
228
|
+
// terminal publish failures when `publishingState === "failed"` and publication `state`
|
|
229
|
+
// is `"stopped"`, so we derive failed from that terminal pair or recorded publish errors.
|
|
230
|
+
const now = Math.round(Date.now() / 1000);
|
|
231
|
+
const expiryTime = now - 60 * 20;
|
|
232
|
+
const states = [];
|
|
233
|
+
for (const accountComment of accountComments) {
|
|
234
|
+
let state = "succeeded";
|
|
235
|
+
if (!accountComment.cid) {
|
|
236
|
+
const ac = accountComment;
|
|
237
|
+
const resolvedPublishFailed = (ac.publishingState === "failed" && ac.state === "stopped") ||
|
|
238
|
+
ac.error != null ||
|
|
239
|
+
(Array.isArray(ac.errors) && ac.errors.length > 0);
|
|
240
|
+
if (resolvedPublishFailed) {
|
|
241
|
+
state = "failed";
|
|
242
|
+
}
|
|
243
|
+
else if (accountComment.timestamp > expiryTime) {
|
|
244
|
+
state = "pending";
|
|
245
|
+
}
|
|
246
|
+
else {
|
|
247
|
+
state = "failed";
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
states.push(state);
|
|
251
|
+
}
|
|
252
|
+
return states;
|
|
253
|
+
};
|
|
254
|
+
export const haveAccountCommentStatesChanged = (nextStates, previousStates) => nextStates.toString() !== previousStates.toString();
|
|
255
|
+
const getAccountHistorySortType = (sortType, order) => {
|
|
256
|
+
if (sortType === "new" || sortType === "old") {
|
|
257
|
+
return sortType;
|
|
258
|
+
}
|
|
259
|
+
return order === "desc" ? "new" : "old";
|
|
260
|
+
};
|
|
261
|
+
export function useAccountComments(options) {
|
|
262
|
+
assert(!options || typeof options === "object", `useAccountComments options argument '${options}' not an object`);
|
|
263
|
+
const { accountName, filter, commentCid, commentIndices, communityAddress, parentCid, newerThan, page, pageSize, sortType, order, } = options || {};
|
|
264
|
+
assert(!filter || typeof filter === "function", `useAccountComments options.filter argument '${filter}' not an function`);
|
|
265
|
+
const accountId = useAccountId(accountName);
|
|
266
|
+
const accountCommentsIndexes = useAccountsStore((state) => state.accountsCommentsIndexes[accountId || ""]);
|
|
267
|
+
const commentCidToAccountComment = useAccountsStore((state) => state.commentCidsToAccountsComments[commentCid || ""]);
|
|
268
|
+
const accountComments = useAccountsStore((state) => state.accountsComments[accountId || ""]);
|
|
269
|
+
const [accountCommentStates, setAccountCommentStates] = useState([]);
|
|
270
|
+
const accountHistorySortType = getAccountHistorySortType(sortType, order);
|
|
271
|
+
const filteredAccountComments = useMemo(() => {
|
|
272
|
+
var _a, _b;
|
|
273
|
+
if (!accountComments) {
|
|
274
|
+
return [];
|
|
275
|
+
}
|
|
276
|
+
let scopedAccountComments = accountComments;
|
|
277
|
+
if (Array.isArray(commentIndices) && commentIndices.length > 0) {
|
|
278
|
+
const normalizedCommentIndices = commentIndices
|
|
279
|
+
.map((commentIndex) => Number(commentIndex))
|
|
280
|
+
.filter((commentIndex) => Number.isInteger(commentIndex) && commentIndex >= 0);
|
|
281
|
+
scopedAccountComments = normalizedCommentIndices
|
|
282
|
+
.map((commentIndex) => accountComments[commentIndex])
|
|
283
|
+
.filter(Boolean);
|
|
284
|
+
}
|
|
285
|
+
else if (commentCid) {
|
|
286
|
+
const mappedIndex = (commentCidToAccountComment === null || commentCidToAccountComment === void 0 ? void 0 : commentCidToAccountComment.accountId) === accountId
|
|
287
|
+
? commentCidToAccountComment.accountCommentIndex
|
|
288
|
+
: undefined;
|
|
289
|
+
scopedAccountComments =
|
|
290
|
+
typeof mappedIndex === "number" ? [accountComments[mappedIndex]].filter(Boolean) : [];
|
|
291
|
+
}
|
|
292
|
+
else if (parentCid) {
|
|
293
|
+
const parentIndexes = (_a = accountCommentsIndexes === null || accountCommentsIndexes === void 0 ? void 0 : accountCommentsIndexes.byParentCid) === null || _a === void 0 ? void 0 : _a[parentCid];
|
|
294
|
+
scopedAccountComments = (parentIndexes === null || parentIndexes === void 0 ? void 0 : parentIndexes.length)
|
|
295
|
+
? parentIndexes.map((index) => accountComments[index]).filter(Boolean)
|
|
296
|
+
: accountComments.filter((accountComment) => accountComment.parentCid === parentCid);
|
|
297
|
+
}
|
|
298
|
+
else if (communityAddress) {
|
|
299
|
+
const communityIndexes = (_b = accountCommentsIndexes === null || accountCommentsIndexes === void 0 ? void 0 : accountCommentsIndexes.byCommunityAddress) === null || _b === void 0 ? void 0 : _b[communityAddress];
|
|
300
|
+
scopedAccountComments = (communityIndexes === null || communityIndexes === void 0 ? void 0 : communityIndexes.length)
|
|
301
|
+
? communityIndexes.map((index) => accountComments[index]).filter(Boolean)
|
|
302
|
+
: accountComments.filter((accountComment) => accountComment.communityAddress === communityAddress);
|
|
303
|
+
}
|
|
304
|
+
if (typeof newerThan === "number") {
|
|
305
|
+
const newerThanTimestamp = newerThan === Infinity ? 0 : Math.floor(Date.now() / 1000) - newerThan;
|
|
306
|
+
scopedAccountComments = scopedAccountComments.filter((accountComment) => accountComment.timestamp > newerThanTimestamp);
|
|
307
|
+
}
|
|
308
|
+
if (filter) {
|
|
309
|
+
scopedAccountComments = scopedAccountComments.filter(filter);
|
|
310
|
+
}
|
|
311
|
+
if (accountHistorySortType === "new") {
|
|
312
|
+
scopedAccountComments = [...scopedAccountComments].reverse();
|
|
313
|
+
}
|
|
314
|
+
if (typeof pageSize === "number" && pageSize > 0) {
|
|
315
|
+
const pageNumber = Math.max(page || 0, 0);
|
|
316
|
+
const startIndex = pageNumber * pageSize;
|
|
317
|
+
return scopedAccountComments.slice(startIndex, startIndex + pageSize);
|
|
318
|
+
}
|
|
319
|
+
return scopedAccountComments;
|
|
320
|
+
}, [
|
|
321
|
+
accountComments,
|
|
322
|
+
accountCommentsIndexes,
|
|
323
|
+
accountId,
|
|
324
|
+
commentCid,
|
|
325
|
+
commentIndices,
|
|
326
|
+
commentCidToAccountComment,
|
|
327
|
+
communityAddress,
|
|
328
|
+
filter,
|
|
329
|
+
newerThan,
|
|
330
|
+
accountHistorySortType,
|
|
331
|
+
page,
|
|
332
|
+
pageSize,
|
|
333
|
+
parentCid,
|
|
334
|
+
]);
|
|
335
|
+
// Recheck periodically so the 20-minute “stale pending → failed” transition updates without other store events
|
|
336
|
+
const delay = 60000;
|
|
337
|
+
const immediate = false;
|
|
338
|
+
useInterval(() => {
|
|
339
|
+
const states = getAccountCommentsStates(filteredAccountComments);
|
|
340
|
+
if (haveAccountCommentStatesChanged(states, accountCommentStates)) {
|
|
341
|
+
setAccountCommentStates(states);
|
|
342
|
+
}
|
|
343
|
+
}, delay, immediate);
|
|
344
|
+
const filteredAccountCommentsWithStates = useMemo(() => {
|
|
345
|
+
const states = getAccountCommentsStates(filteredAccountComments);
|
|
346
|
+
return filteredAccountComments.map((comment, i) => (Object.assign(Object.assign({}, comment), { state: states[i] })));
|
|
347
|
+
}, [filteredAccountComments, accountCommentStates]);
|
|
348
|
+
if (options) {
|
|
349
|
+
log("useAccountComments", {
|
|
350
|
+
accountId,
|
|
351
|
+
filteredAccountCommentsWithStates,
|
|
352
|
+
accountComments,
|
|
353
|
+
commentCid,
|
|
354
|
+
commentIndices,
|
|
355
|
+
communityAddress,
|
|
356
|
+
filter,
|
|
357
|
+
newerThan,
|
|
358
|
+
sortType: accountHistorySortType,
|
|
359
|
+
page,
|
|
360
|
+
pageSize,
|
|
361
|
+
parentCid,
|
|
362
|
+
});
|
|
363
|
+
}
|
|
364
|
+
const state = accountId ? "succeeded" : "initializing";
|
|
365
|
+
return useMemo(() => ({
|
|
366
|
+
accountComments: filteredAccountCommentsWithStates,
|
|
367
|
+
state,
|
|
368
|
+
error: undefined,
|
|
369
|
+
errors: [],
|
|
370
|
+
}), [filteredAccountCommentsWithStates, state]);
|
|
371
|
+
}
|
|
372
|
+
/**
|
|
373
|
+
* Returns an account's single comment, e.g. a pending comment they published.
|
|
374
|
+
*/
|
|
375
|
+
export function useAccountComment(options) {
|
|
376
|
+
assert(!options || typeof options === "object", `useAccountComment options argument '${options}' not an object`);
|
|
377
|
+
const opts = options !== null && options !== void 0 ? options : {};
|
|
378
|
+
const { commentIndex, commentCid, accountName } = opts;
|
|
379
|
+
const accountId = useAccountId(accountName);
|
|
380
|
+
const commentCidToAccountComment = useAccountsStore((state) => state.commentCidsToAccountsComments[commentCid || ""]);
|
|
381
|
+
const accountComments = useAccountsStore((state) => state.accountsComments[accountId || ""]);
|
|
382
|
+
const normalizedCommentIndex = commentIndex === undefined ? undefined : Number(commentIndex);
|
|
383
|
+
const resolvedCommentIndex = typeof normalizedCommentIndex === "number" && !Number.isNaN(normalizedCommentIndex)
|
|
384
|
+
? normalizedCommentIndex
|
|
385
|
+
: (commentCidToAccountComment === null || commentCidToAccountComment === void 0 ? void 0 : commentCidToAccountComment.accountId) === accountId
|
|
386
|
+
? commentCidToAccountComment.accountCommentIndex
|
|
387
|
+
: undefined;
|
|
388
|
+
const storedAccountComment = useMemo(() => {
|
|
389
|
+
if (typeof resolvedCommentIndex !== "number") {
|
|
390
|
+
return undefined;
|
|
391
|
+
}
|
|
392
|
+
return accountComments === null || accountComments === void 0 ? void 0 : accountComments[resolvedCommentIndex];
|
|
393
|
+
}, [accountComments, resolvedCommentIndex]);
|
|
394
|
+
const accountComment = (storedAccountComment || {});
|
|
395
|
+
const state = storedAccountComment
|
|
396
|
+
? getAccountCommentsStates([storedAccountComment])[0]
|
|
397
|
+
: "initializing";
|
|
398
|
+
return useMemo(() => (Object.assign(Object.assign({}, accountComment), { state, error: accountComment.error, errors: accountComment.errors || [] })), [accountComment, state]);
|
|
399
|
+
}
|
|
400
|
+
/**
|
|
401
|
+
* Returns the own user's votes stored locally, even those not yet published by the community owner.
|
|
402
|
+
* Check UseAccountCommentsOptions type in types.tsx to filter them, e.g. filter = {communityAddresses: ['memes.eth']}.
|
|
403
|
+
*/
|
|
404
|
+
export function useAccountVotes(options) {
|
|
405
|
+
assert(!options || typeof options === "object", `useAccountVotes options argument '${options}' not an object`);
|
|
406
|
+
const opts = options !== null && options !== void 0 ? options : {};
|
|
407
|
+
const { accountName, filter, vote, commentCid, communityAddress, newerThan, page, pageSize, sortType, order, } = opts;
|
|
408
|
+
assert(!filter || typeof filter === "function", `useAccountVotes options.filter argument '${filter}' not an function`);
|
|
409
|
+
const accountId = useAccountId(accountName);
|
|
410
|
+
const accountVotes = useAccountsStore((state) => state.accountsVotes[accountId || ""]);
|
|
411
|
+
const accountHistorySortType = getAccountHistorySortType(sortType, order);
|
|
412
|
+
const filteredAccountVotesArray = useMemo(() => {
|
|
413
|
+
let accountVotesArray = [];
|
|
414
|
+
if (!accountVotes) {
|
|
415
|
+
return accountVotesArray;
|
|
416
|
+
}
|
|
417
|
+
for (const i in accountVotes) {
|
|
418
|
+
accountVotesArray.push(accountVotes[i]);
|
|
419
|
+
}
|
|
420
|
+
if (typeof vote === "number") {
|
|
421
|
+
accountVotesArray = accountVotesArray.filter((accountVote) => accountVote.vote === vote);
|
|
422
|
+
}
|
|
423
|
+
if (commentCid) {
|
|
424
|
+
accountVotesArray = accountVotesArray.filter((accountVote) => accountVote.commentCid === commentCid);
|
|
425
|
+
}
|
|
426
|
+
if (communityAddress) {
|
|
427
|
+
accountVotesArray = accountVotesArray.filter((accountVote) => accountVote.communityAddress === communityAddress);
|
|
428
|
+
}
|
|
429
|
+
if (typeof newerThan === "number") {
|
|
430
|
+
const newerThanTimestamp = newerThan === Infinity ? 0 : Math.floor(Date.now() / 1000) - newerThan;
|
|
431
|
+
accountVotesArray = accountVotesArray.filter((accountVote) => accountVote.timestamp > newerThanTimestamp);
|
|
432
|
+
}
|
|
433
|
+
if (filter) {
|
|
434
|
+
accountVotesArray = accountVotesArray.filter(filter);
|
|
435
|
+
}
|
|
436
|
+
accountVotesArray = [...accountVotesArray].sort((firstVote, secondVote) => (firstVote.timestamp || 0) - (secondVote.timestamp || 0));
|
|
437
|
+
if (accountHistorySortType === "new") {
|
|
438
|
+
accountVotesArray = [...accountVotesArray].reverse();
|
|
439
|
+
}
|
|
440
|
+
if (typeof pageSize === "number" && pageSize > 0) {
|
|
441
|
+
const pageNumber = Math.max(page || 0, 0);
|
|
442
|
+
const startIndex = pageNumber * pageSize;
|
|
443
|
+
accountVotesArray = accountVotesArray.slice(startIndex, startIndex + pageSize);
|
|
444
|
+
}
|
|
445
|
+
return accountVotesArray;
|
|
446
|
+
}, [
|
|
447
|
+
accountVotes,
|
|
448
|
+
accountHistorySortType,
|
|
449
|
+
commentCid,
|
|
450
|
+
communityAddress,
|
|
451
|
+
filter,
|
|
452
|
+
newerThan,
|
|
453
|
+
page,
|
|
454
|
+
pageSize,
|
|
455
|
+
vote,
|
|
456
|
+
]);
|
|
457
|
+
if (accountVotes && options) {
|
|
458
|
+
log("useAccountVotes", {
|
|
459
|
+
accountId,
|
|
460
|
+
filteredAccountVotesArray,
|
|
461
|
+
accountVotes,
|
|
462
|
+
commentCid,
|
|
463
|
+
communityAddress,
|
|
464
|
+
filter,
|
|
465
|
+
newerThan,
|
|
466
|
+
sortType: accountHistorySortType,
|
|
467
|
+
page,
|
|
468
|
+
pageSize,
|
|
469
|
+
vote,
|
|
470
|
+
});
|
|
471
|
+
}
|
|
472
|
+
// TODO: add failed / pending states
|
|
473
|
+
const state = accountId ? "succeeded" : "initializing";
|
|
474
|
+
return useMemo(() => ({
|
|
475
|
+
accountVotes: filteredAccountVotesArray,
|
|
476
|
+
state,
|
|
477
|
+
error: undefined,
|
|
478
|
+
errors: [],
|
|
479
|
+
}), [filteredAccountVotesArray, state]);
|
|
480
|
+
}
|
|
481
|
+
/**
|
|
482
|
+
* Returns an account's single vote on a comment, e.g. to know if you already voted on a comment.
|
|
483
|
+
*/
|
|
484
|
+
export function useAccountVote(options) {
|
|
485
|
+
assert(!options || typeof options === "object", `useAccountVote options argument '${options}' not an object`);
|
|
486
|
+
const opts = options !== null && options !== void 0 ? options : {};
|
|
487
|
+
const { commentCid, accountName } = opts;
|
|
488
|
+
const accountId = useAccountId(accountName);
|
|
489
|
+
const accountIdKey = accountId || "";
|
|
490
|
+
const commentCidKey = commentCid || "";
|
|
491
|
+
const accountVotes = useAccountsStore((state) => state.accountsVotes[accountIdKey]);
|
|
492
|
+
const accountVote = accountVotes === null || accountVotes === void 0 ? void 0 : accountVotes[commentCidKey];
|
|
493
|
+
const state = accountId && commentCid ? "succeeded" : "initializing";
|
|
494
|
+
// TODO: add failed / pending state
|
|
495
|
+
return useMemo(() => (Object.assign(Object.assign({}, accountVote), { state, error: undefined, errors: [] })), [accountVote, state]);
|
|
496
|
+
}
|
|
497
|
+
/**
|
|
498
|
+
* Returns all the comment and community edits published by an account.
|
|
499
|
+
*/
|
|
500
|
+
export function useAccountEdits(options) {
|
|
501
|
+
assert(!options || typeof options === "object", `useAccountEdits options argument '${options}' not an object`);
|
|
502
|
+
const opts = options !== null && options !== void 0 ? options : {};
|
|
503
|
+
const { filter, accountName } = opts;
|
|
504
|
+
assert(!filter || typeof filter === "function", `useAccountEdits options.filter argument '${filter}' not an function`);
|
|
505
|
+
const accountId = useAccountId(accountName);
|
|
506
|
+
const ensureAccountEditsLoaded = useAccountsStore((state) => state.accountsActionsInternal.ensureAccountEditsLoaded);
|
|
507
|
+
const accountEdits = useAccountsStore((state) => state.accountsEdits[accountId || ""]);
|
|
508
|
+
const accountEditsLoaded = useAccountsStore((state) => state.accountsEditsLoaded[accountId || ""]);
|
|
509
|
+
useEffect(() => {
|
|
510
|
+
if (!accountId || accountEditsLoaded) {
|
|
511
|
+
return;
|
|
512
|
+
}
|
|
513
|
+
ensureAccountEditsLoaded(accountId).catch((error) => log.error("useAccountEdits ensureAccountEditsLoaded error", { accountId, error }));
|
|
514
|
+
}, [accountEditsLoaded, accountId, ensureAccountEditsLoaded]);
|
|
515
|
+
const accountEditsArray = useMemo(() => {
|
|
516
|
+
const accountEditsArray = [];
|
|
517
|
+
for (const i in accountEdits || {}) {
|
|
518
|
+
accountEditsArray.push(...accountEdits[i]);
|
|
519
|
+
}
|
|
520
|
+
// sort by oldest first
|
|
521
|
+
return accountEditsArray.sort((a, b) => a.timestamp - b.timestamp);
|
|
522
|
+
}, [accountEdits]);
|
|
523
|
+
const filteredAccountEditsArray = useMemo(() => {
|
|
524
|
+
if (!filter) {
|
|
525
|
+
return accountEditsArray;
|
|
526
|
+
}
|
|
527
|
+
return accountEditsArray.filter(filter);
|
|
528
|
+
}, [accountEditsArray, filter]);
|
|
529
|
+
// TODO: add failed / pending states
|
|
530
|
+
const state = accountId ? (accountEditsLoaded ? "succeeded" : "initializing") : "initializing";
|
|
531
|
+
return useMemo(() => ({
|
|
532
|
+
accountEdits: filteredAccountEditsArray,
|
|
533
|
+
state,
|
|
534
|
+
error: undefined,
|
|
535
|
+
errors: [],
|
|
536
|
+
}), [filteredAccountEditsArray, state]);
|
|
537
|
+
}
|
|
538
|
+
/**
|
|
539
|
+
* Returns the comment edited (if has any edits), as well as the pending, succeeded or failed state of the edit.
|
|
540
|
+
*/
|
|
541
|
+
export function useEditedComment(options) {
|
|
542
|
+
assert(!options || typeof options === "object", `useEditedComment options argument '${options}' not an object`);
|
|
543
|
+
const opts = options !== null && options !== void 0 ? options : {};
|
|
544
|
+
const { comment, accountName } = opts;
|
|
545
|
+
const accountId = useAccountId(accountName);
|
|
546
|
+
const accountIdKey = accountId || "";
|
|
547
|
+
const commentCidKey = (comment && comment.cid) || "";
|
|
548
|
+
const commentEdits = useAccountsStore((state) => { var _a; return (_a = state.accountsEdits[accountIdKey]) === null || _a === void 0 ? void 0 : _a[commentCidKey]; });
|
|
549
|
+
const commentEditSummary = useAccountsStore((state) => { var _a; return (_a = state.accountsEditsSummaries[accountIdKey]) === null || _a === void 0 ? void 0 : _a[commentCidKey]; });
|
|
550
|
+
let initialState = "initializing";
|
|
551
|
+
if (accountId && comment && comment.cid) {
|
|
552
|
+
initialState = "unedited";
|
|
553
|
+
}
|
|
554
|
+
const editedResult = useMemo(() => {
|
|
555
|
+
const editedResult = {
|
|
556
|
+
editedComment: undefined,
|
|
557
|
+
succeededEdits: {},
|
|
558
|
+
pendingEdits: {},
|
|
559
|
+
failedEdits: {},
|
|
560
|
+
state: undefined,
|
|
561
|
+
};
|
|
562
|
+
// there are no edits
|
|
563
|
+
const propertyNameEdits = (commentEdits === null || commentEdits === void 0 ? void 0 : commentEdits.length) > 0 ? getAccountEditPropertySummary(commentEdits) : commentEditSummary;
|
|
564
|
+
if (!propertyNameEdits || Object.keys(propertyNameEdits).length === 0) {
|
|
565
|
+
return editedResult;
|
|
566
|
+
}
|
|
567
|
+
const now = Math.round(Date.now() / 1000);
|
|
568
|
+
// no longer consider an edit pending ater an expiry time of 20 minutes
|
|
569
|
+
const expiryTime = 60 * 20;
|
|
570
|
+
// iterate over propertyNameEdits and find if succeeded, pending or failed
|
|
571
|
+
for (const propertyName in propertyNameEdits) {
|
|
572
|
+
const propertyNameEdit = propertyNameEdits[propertyName];
|
|
573
|
+
const setPropertyNameEditState = (state) => {
|
|
574
|
+
// set propertyNameEdit e.g. editedResult.succeededEdits.removed = true
|
|
575
|
+
editedResult[`${state}Edits`][propertyName] = propertyNameEdit.value;
|
|
576
|
+
// if any propertyNameEdit failed, consider the commentEdit failed
|
|
577
|
+
if (state === "failed") {
|
|
578
|
+
editedResult.state = "failed";
|
|
579
|
+
}
|
|
580
|
+
// if all propertyNameEdit succeeded, consider the commentEdit succeeded
|
|
581
|
+
if (state === "succeeded" && !editedResult.state) {
|
|
582
|
+
editedResult.state = "succeeded";
|
|
583
|
+
}
|
|
584
|
+
// if any propertyNameEdit are pending, and none have failed, consider the commentEdit pending
|
|
585
|
+
if (state === "pending" && editedResult.state !== "failed") {
|
|
586
|
+
editedResult.state = "pending";
|
|
587
|
+
}
|
|
588
|
+
};
|
|
589
|
+
// Without a newer update we can only treat recent edits as pending. Older edits that never
|
|
590
|
+
// produced any update are effectively stale and should stop shadowing the live comment.
|
|
591
|
+
if (!(comment === null || comment === void 0 ? void 0 : comment.updatedAt)) {
|
|
592
|
+
if (isEqual(comment === null || comment === void 0 ? void 0 : comment[propertyName], propertyNameEdit.value)) {
|
|
593
|
+
setPropertyNameEditState("succeeded");
|
|
594
|
+
}
|
|
595
|
+
else if (propertyNameEdit.timestamp > now - expiryTime) {
|
|
596
|
+
setPropertyNameEditState("pending");
|
|
597
|
+
}
|
|
598
|
+
else {
|
|
599
|
+
setPropertyNameEditState("failed");
|
|
600
|
+
}
|
|
601
|
+
continue;
|
|
602
|
+
}
|
|
603
|
+
// comment.updatedAt is older than propertyNameEdit, propertyNameEdit is pending
|
|
604
|
+
// because we haven't received the update yet and can't evaluate
|
|
605
|
+
if (comment.updatedAt < propertyNameEdit.timestamp) {
|
|
606
|
+
setPropertyNameEditState("pending");
|
|
607
|
+
continue;
|
|
608
|
+
}
|
|
609
|
+
// comment.updatedAt is newer than propertyNameEdit, a comment update
|
|
610
|
+
// has been received after the edit was published so we can evaluate
|
|
611
|
+
else {
|
|
612
|
+
// comment has propertyNameEdit, propertyNameEdit succeeded
|
|
613
|
+
if (isEqual(comment[propertyName], propertyNameEdit.value)) {
|
|
614
|
+
setPropertyNameEditState("succeeded");
|
|
615
|
+
continue;
|
|
616
|
+
}
|
|
617
|
+
// comment does not have propertyNameEdit
|
|
618
|
+
else {
|
|
619
|
+
// propertyNameEdit is newer than 20min, it is too recent to evaluate
|
|
620
|
+
// so we should assume pending
|
|
621
|
+
if (propertyNameEdit.timestamp > now - expiryTime) {
|
|
622
|
+
setPropertyNameEditState("pending");
|
|
623
|
+
continue;
|
|
624
|
+
}
|
|
625
|
+
// propertyNameEdit is older than 20min, we can evaluate it
|
|
626
|
+
else {
|
|
627
|
+
// comment update was received too shortly after propertyNameEdit was
|
|
628
|
+
// published, assume pending until a more recent comment update is received
|
|
629
|
+
const timeSinceUpdate = comment.updatedAt - propertyNameEdit.timestamp;
|
|
630
|
+
if (timeSinceUpdate < expiryTime) {
|
|
631
|
+
setPropertyNameEditState("pending");
|
|
632
|
+
continue;
|
|
633
|
+
}
|
|
634
|
+
// comment update time is sufficiently distanced from propertyNameEdit
|
|
635
|
+
// and comment doesn't have propertyNameEdit, assume failed
|
|
636
|
+
else {
|
|
637
|
+
setPropertyNameEditState("failed");
|
|
638
|
+
continue;
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
// define editedComment
|
|
645
|
+
editedResult.editedComment = Object.assign({}, comment);
|
|
646
|
+
// add pending and succeeded props so the editor can see his changes right away
|
|
647
|
+
// don't add failed edits to reflect the current state of the edited comment
|
|
648
|
+
for (const propertyName in editedResult.pendingEdits) {
|
|
649
|
+
editedResult.editedComment[propertyName] = editedResult.pendingEdits[propertyName];
|
|
650
|
+
}
|
|
651
|
+
for (const propertyName in editedResult.succeededEdits) {
|
|
652
|
+
editedResult.editedComment[propertyName] = editedResult.succeededEdits[propertyName];
|
|
653
|
+
}
|
|
654
|
+
editedResult.editedComment = addCommentModeration(editedResult.editedComment);
|
|
655
|
+
return editedResult;
|
|
656
|
+
}, [comment, commentEditSummary, commentEdits]);
|
|
657
|
+
return useMemo(() => (Object.assign(Object.assign({}, editedResult), { state: editedResult.state || initialState, error: undefined, errors: [] })), [editedResult, initialState]);
|
|
658
|
+
}
|
|
659
|
+
/**
|
|
660
|
+
* This hook should be added to pages where the user is likely to publish something, i,e. the
|
|
661
|
+
* submit page and the /c/<commentCid> page, it improves the speed of publishing to the pubsub
|
|
662
|
+
* by subscribing to the pubsub right away.
|
|
663
|
+
*
|
|
664
|
+
* @param accountName - The nickname of the account, e.g. 'Account 1'.
|
|
665
|
+
* @param communityAddress - The community address to subscribe to, e.g. 'news.eth'.
|
|
666
|
+
*/
|
|
667
|
+
export function usePubsubSubscribe(options) {
|
|
668
|
+
assert(!options || typeof options === "object", `usePubsubSubscribe options argument '${options}' not an object`);
|
|
669
|
+
const opts = options !== null && options !== void 0 ? options : {};
|
|
670
|
+
const { accountName, communityAddress } = opts;
|
|
671
|
+
const accountId = useAccountId(accountName);
|
|
672
|
+
const accountIdKey = accountId || "";
|
|
673
|
+
const account = useAccountsStore((state) => state.accounts[accountIdKey]);
|
|
674
|
+
const [state, setState] = useState("initializing");
|
|
675
|
+
const [errors, setErrors] = useState([]);
|
|
676
|
+
useEffect(() => {
|
|
677
|
+
if (!(account === null || account === void 0 ? void 0 : account.pkc) || !communityAddress) {
|
|
678
|
+
return;
|
|
679
|
+
}
|
|
680
|
+
setState("subscribing");
|
|
681
|
+
account.pkc
|
|
682
|
+
.pubsubSubscribe(communityAddress)
|
|
683
|
+
.then(() => setState("succeeded"))
|
|
684
|
+
.catch((error) => {
|
|
685
|
+
setErrors([...errors, error]);
|
|
686
|
+
setState("failed");
|
|
687
|
+
log.error("usePubsubSubscribe pkc.pubsubSubscribe error", { communityAddress, error });
|
|
688
|
+
});
|
|
689
|
+
// unsub on component unmount
|
|
690
|
+
return function () {
|
|
691
|
+
account.pkc.pubsubUnsubscribe(communityAddress).catch((error) => {
|
|
692
|
+
setErrors([...errors, error]);
|
|
693
|
+
log.error("usePubsubSubscribe pkc.pubsubUnsubscribe error", {
|
|
694
|
+
communityAddress,
|
|
695
|
+
error,
|
|
696
|
+
});
|
|
697
|
+
});
|
|
698
|
+
};
|
|
699
|
+
}, [account === null || account === void 0 ? void 0 : account.pkc, communityAddress]);
|
|
700
|
+
return useMemo(() => ({
|
|
701
|
+
state,
|
|
702
|
+
error: errors[errors.length - 1],
|
|
703
|
+
errors,
|
|
704
|
+
}), [state, errors]);
|
|
705
|
+
}
|
|
706
|
+
//# sourceMappingURL=accounts.js.map
|