@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.
Files changed (269) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +1365 -0
  3. package/dist/hooks/accounts/accounts.d.ts +64 -0
  4. package/dist/hooks/accounts/accounts.d.ts.map +1 -0
  5. package/dist/hooks/accounts/accounts.js +706 -0
  6. package/dist/hooks/accounts/accounts.js.map +1 -0
  7. package/dist/hooks/accounts/index.d.ts +2 -0
  8. package/dist/hooks/accounts/index.d.ts.map +1 -0
  9. package/dist/hooks/accounts/index.js +2 -0
  10. package/dist/hooks/accounts/index.js.map +1 -0
  11. package/dist/hooks/accounts/utils.d.ts +6 -0
  12. package/dist/hooks/accounts/utils.d.ts.map +1 -0
  13. package/dist/hooks/accounts/utils.js +226 -0
  14. package/dist/hooks/accounts/utils.js.map +1 -0
  15. package/dist/hooks/actions/actions.d.ts +19 -0
  16. package/dist/hooks/actions/actions.d.ts.map +1 -0
  17. package/dist/hooks/actions/actions.js +552 -0
  18. package/dist/hooks/actions/actions.js.map +1 -0
  19. package/dist/hooks/actions/index.d.ts +2 -0
  20. package/dist/hooks/actions/index.d.ts.map +1 -0
  21. package/dist/hooks/actions/index.js +2 -0
  22. package/dist/hooks/actions/index.js.map +1 -0
  23. package/dist/hooks/authors/author-avatars.d.ts +28 -0
  24. package/dist/hooks/authors/author-avatars.d.ts.map +1 -0
  25. package/dist/hooks/authors/author-avatars.js +191 -0
  26. package/dist/hooks/authors/author-avatars.js.map +1 -0
  27. package/dist/hooks/authors/authors.d.ts +37 -0
  28. package/dist/hooks/authors/authors.d.ts.map +1 -0
  29. package/dist/hooks/authors/authors.js +509 -0
  30. package/dist/hooks/authors/authors.js.map +1 -0
  31. package/dist/hooks/authors/index.d.ts +2 -0
  32. package/dist/hooks/authors/index.d.ts.map +1 -0
  33. package/dist/hooks/authors/index.js +2 -0
  34. package/dist/hooks/authors/index.js.map +1 -0
  35. package/dist/hooks/authors/utils.d.ts +4 -0
  36. package/dist/hooks/authors/utils.d.ts.map +1 -0
  37. package/dist/hooks/authors/utils.js +21 -0
  38. package/dist/hooks/authors/utils.js.map +1 -0
  39. package/dist/hooks/comments.d.ts +17 -0
  40. package/dist/hooks/comments.d.ts.map +1 -0
  41. package/dist/hooks/comments.js +351 -0
  42. package/dist/hooks/comments.js.map +1 -0
  43. package/dist/hooks/communities.d.ts +31 -0
  44. package/dist/hooks/communities.d.ts.map +1 -0
  45. package/dist/hooks/communities.js +389 -0
  46. package/dist/hooks/communities.js.map +1 -0
  47. package/dist/hooks/feeds/feeds.d.ts +18 -0
  48. package/dist/hooks/feeds/feeds.d.ts.map +1 -0
  49. package/dist/hooks/feeds/feeds.js +315 -0
  50. package/dist/hooks/feeds/feeds.js.map +1 -0
  51. package/dist/hooks/feeds/index.d.ts +2 -0
  52. package/dist/hooks/feeds/index.d.ts.map +1 -0
  53. package/dist/hooks/feeds/index.js +2 -0
  54. package/dist/hooks/feeds/index.js.map +1 -0
  55. package/dist/hooks/pkc-rpc.d.ts +7 -0
  56. package/dist/hooks/pkc-rpc.d.ts.map +1 -0
  57. package/dist/hooks/pkc-rpc.js +88 -0
  58. package/dist/hooks/pkc-rpc.js.map +1 -0
  59. package/dist/hooks/replies.d.ts +5 -0
  60. package/dist/hooks/replies.d.ts.map +1 -0
  61. package/dist/hooks/replies.js +155 -0
  62. package/dist/hooks/replies.js.map +1 -0
  63. package/dist/hooks/states.d.ts +15 -0
  64. package/dist/hooks/states.d.ts.map +1 -0
  65. package/dist/hooks/states.js +213 -0
  66. package/dist/hooks/states.js.map +1 -0
  67. package/dist/hooks/utils/use-interval.d.ts +3 -0
  68. package/dist/hooks/utils/use-interval.d.ts.map +1 -0
  69. package/dist/hooks/utils/use-interval.js +36 -0
  70. package/dist/hooks/utils/use-interval.js.map +1 -0
  71. package/dist/hooks/utils/use-previous.d.ts +1 -0
  72. package/dist/hooks/utils/use-previous.js +10 -0
  73. package/dist/index.d.ts +82 -0
  74. package/dist/index.d.ts.map +1 -0
  75. package/dist/index.js +128 -0
  76. package/dist/index.js.map +1 -0
  77. package/dist/lib/chain/chain.d.ts +36 -0
  78. package/dist/lib/chain/chain.d.ts.map +1 -0
  79. package/dist/lib/chain/chain.js +195 -0
  80. package/dist/lib/chain/chain.js.map +1 -0
  81. package/dist/lib/chain/index.d.ts +4 -0
  82. package/dist/lib/chain/index.d.ts.map +1 -0
  83. package/dist/lib/chain/index.js +4 -0
  84. package/dist/lib/chain/index.js.map +1 -0
  85. package/dist/lib/community-address.d.ts +6 -0
  86. package/dist/lib/community-address.d.ts.map +1 -0
  87. package/dist/lib/community-address.js +26 -0
  88. package/dist/lib/community-address.js.map +1 -0
  89. package/dist/lib/community-ref.d.ts +23 -0
  90. package/dist/lib/community-ref.d.ts.map +1 -0
  91. package/dist/lib/community-ref.js +113 -0
  92. package/dist/lib/community-ref.js.map +1 -0
  93. package/dist/lib/debug-utils.d.ts +9 -0
  94. package/dist/lib/debug-utils.d.ts.map +1 -0
  95. package/dist/lib/debug-utils.js +21 -0
  96. package/dist/lib/debug-utils.js.map +1 -0
  97. package/dist/lib/feed-sort-type.d.ts +2 -0
  98. package/dist/lib/feed-sort-type.d.ts.map +1 -0
  99. package/dist/lib/feed-sort-type.js +22 -0
  100. package/dist/lib/feed-sort-type.js.map +1 -0
  101. package/dist/lib/localforage-lru/index.d.ts +3 -0
  102. package/dist/lib/localforage-lru/index.d.ts.map +1 -0
  103. package/dist/lib/localforage-lru/index.js +46 -0
  104. package/dist/lib/localforage-lru/index.js.map +1 -0
  105. package/dist/lib/localforage-lru/localforage-lru.d.ts +6 -0
  106. package/dist/lib/localforage-lru/localforage-lru.d.ts.map +1 -0
  107. package/dist/lib/localforage-lru/localforage-lru.js +182 -0
  108. package/dist/lib/localforage-lru/localforage-lru.js.map +1 -0
  109. package/dist/lib/pkc-compat.d.ts +25 -0
  110. package/dist/lib/pkc-compat.d.ts.map +1 -0
  111. package/dist/lib/pkc-compat.js +131 -0
  112. package/dist/lib/pkc-compat.js.map +1 -0
  113. package/dist/lib/pkc-js/fixtures/markdown-example.d.ts +3 -0
  114. package/dist/lib/pkc-js/fixtures/markdown-example.d.ts.map +1 -0
  115. package/dist/lib/pkc-js/fixtures/markdown-example.js +280 -0
  116. package/dist/lib/pkc-js/fixtures/markdown-example.js.map +1 -0
  117. package/dist/lib/pkc-js/index.d.ts +11 -0
  118. package/dist/lib/pkc-js/index.d.ts.map +1 -0
  119. package/dist/lib/pkc-js/index.js +85 -0
  120. package/dist/lib/pkc-js/index.js.map +1 -0
  121. package/dist/lib/pkc-js/pkc-js-mock-content.d.ts +3 -0
  122. package/dist/lib/pkc-js/pkc-js-mock-content.d.ts.map +1 -0
  123. package/dist/lib/pkc-js/pkc-js-mock-content.js +1235 -0
  124. package/dist/lib/pkc-js/pkc-js-mock-content.js.map +1 -0
  125. package/dist/lib/pkc-js/pkc-js-mock.d.ts +137 -0
  126. package/dist/lib/pkc-js/pkc-js-mock.d.ts.map +1 -0
  127. package/dist/lib/pkc-js/pkc-js-mock.js +644 -0
  128. package/dist/lib/pkc-js/pkc-js-mock.js.map +1 -0
  129. package/dist/lib/polyfill.d.ts +3 -0
  130. package/dist/lib/polyfill.d.ts.map +1 -0
  131. package/dist/lib/polyfill.js +14 -0
  132. package/dist/lib/polyfill.js.map +1 -0
  133. package/dist/lib/protocol-compat.d.ts +14 -0
  134. package/dist/lib/protocol-compat.d.ts.map +1 -0
  135. package/dist/lib/protocol-compat.js +67 -0
  136. package/dist/lib/protocol-compat.js.map +1 -0
  137. package/dist/lib/test-utils.d.ts +29 -0
  138. package/dist/lib/test-utils.d.ts.map +1 -0
  139. package/dist/lib/test-utils.js +184 -0
  140. package/dist/lib/test-utils.js.map +1 -0
  141. package/dist/lib/utils/comment-moderation.d.ts +4 -0
  142. package/dist/lib/utils/comment-moderation.d.ts.map +1 -0
  143. package/dist/lib/utils/comment-moderation.js +56 -0
  144. package/dist/lib/utils/comment-moderation.js.map +1 -0
  145. package/dist/lib/utils/index.d.ts +4 -0
  146. package/dist/lib/utils/index.d.ts.map +1 -0
  147. package/dist/lib/utils/index.js +4 -0
  148. package/dist/lib/utils/index.js.map +1 -0
  149. package/dist/lib/utils/utils.d.ts +23 -0
  150. package/dist/lib/utils/utils.d.ts.map +1 -0
  151. package/dist/lib/utils/utils.js +375 -0
  152. package/dist/lib/utils/utils.js.map +1 -0
  153. package/dist/lib/validator.d.ts +30 -0
  154. package/dist/lib/validator.d.ts.map +1 -0
  155. package/dist/lib/validator.js +307 -0
  156. package/dist/lib/validator.js.map +1 -0
  157. package/dist/stores/accounts/account-generator.d.ts +51 -0
  158. package/dist/stores/accounts/account-generator.d.ts.map +1 -0
  159. package/dist/stores/accounts/account-generator.js +160 -0
  160. package/dist/stores/accounts/account-generator.js.map +1 -0
  161. package/dist/stores/accounts/accounts-actions-internal.d.ts +8 -0
  162. package/dist/stores/accounts/accounts-actions-internal.d.ts.map +1 -0
  163. package/dist/stores/accounts/accounts-actions-internal.js +403 -0
  164. package/dist/stores/accounts/accounts-actions-internal.js.map +1 -0
  165. package/dist/stores/accounts/accounts-actions.d.ts +46 -0
  166. package/dist/stores/accounts/accounts-actions.d.ts.map +1 -0
  167. package/dist/stores/accounts/accounts-actions.js +1341 -0
  168. package/dist/stores/accounts/accounts-actions.js.map +1 -0
  169. package/dist/stores/accounts/accounts-database.d.ts +34 -0
  170. package/dist/stores/accounts/accounts-database.d.ts.map +1 -0
  171. package/dist/stores/accounts/accounts-database.js +685 -0
  172. package/dist/stores/accounts/accounts-database.js.map +1 -0
  173. package/dist/stores/accounts/accounts-store.d.ts +32 -0
  174. package/dist/stores/accounts/accounts-store.d.ts.map +1 -0
  175. package/dist/stores/accounts/accounts-store.js +169 -0
  176. package/dist/stores/accounts/accounts-store.js.map +1 -0
  177. package/dist/stores/accounts/index.d.ts +4 -0
  178. package/dist/stores/accounts/index.d.ts.map +1 -0
  179. package/dist/stores/accounts/index.js +4 -0
  180. package/dist/stores/accounts/index.js.map +1 -0
  181. package/dist/stores/accounts/utils.d.ts +49 -0
  182. package/dist/stores/accounts/utils.d.ts.map +1 -0
  183. package/dist/stores/accounts/utils.js +419 -0
  184. package/dist/stores/accounts/utils.js.map +1 -0
  185. package/dist/stores/authors-comments/authors-comments-store.d.ts +37 -0
  186. package/dist/stores/authors-comments/authors-comments-store.d.ts.map +1 -0
  187. package/dist/stores/authors-comments/authors-comments-store.js +338 -0
  188. package/dist/stores/authors-comments/authors-comments-store.js.map +1 -0
  189. package/dist/stores/authors-comments/index.d.ts +4 -0
  190. package/dist/stores/authors-comments/index.d.ts.map +1 -0
  191. package/dist/stores/authors-comments/index.js +4 -0
  192. package/dist/stores/authors-comments/index.js.map +1 -0
  193. package/dist/stores/authors-comments/utils.d.ts +14 -0
  194. package/dist/stores/authors-comments/utils.d.ts.map +1 -0
  195. package/dist/stores/authors-comments/utils.js +81 -0
  196. package/dist/stores/authors-comments/utils.js.map +1 -0
  197. package/dist/stores/comments/comments-store.d.ts +19 -0
  198. package/dist/stores/comments/comments-store.d.ts.map +1 -0
  199. package/dist/stores/comments/comments-store.js +385 -0
  200. package/dist/stores/comments/comments-store.js.map +1 -0
  201. package/dist/stores/comments/index.d.ts +4 -0
  202. package/dist/stores/comments/index.d.ts.map +1 -0
  203. package/dist/stores/comments/index.js +4 -0
  204. package/dist/stores/comments/index.js.map +1 -0
  205. package/dist/stores/communities/communities-store.d.ts +17 -0
  206. package/dist/stores/communities/communities-store.d.ts.map +1 -0
  207. package/dist/stores/communities/communities-store.js +304 -0
  208. package/dist/stores/communities/communities-store.js.map +1 -0
  209. package/dist/stores/communities/index.d.ts +4 -0
  210. package/dist/stores/communities/index.d.ts.map +1 -0
  211. package/dist/stores/communities/index.js +4 -0
  212. package/dist/stores/communities/index.js.map +1 -0
  213. package/dist/stores/communities-pages/communities-pages-store.d.ts +23 -0
  214. package/dist/stores/communities-pages/communities-pages-store.d.ts.map +1 -0
  215. package/dist/stores/communities-pages/communities-pages-store.js +316 -0
  216. package/dist/stores/communities-pages/communities-pages-store.js.map +1 -0
  217. package/dist/stores/communities-pages/index.d.ts +4 -0
  218. package/dist/stores/communities-pages/index.d.ts.map +1 -0
  219. package/dist/stores/communities-pages/index.js +4 -0
  220. package/dist/stores/communities-pages/index.js.map +1 -0
  221. package/dist/stores/feeds/feed-sorter.d.ts +5 -0
  222. package/dist/stores/feeds/feed-sorter.d.ts.map +1 -0
  223. package/dist/stores/feeds/feed-sorter.js +135 -0
  224. package/dist/stores/feeds/feed-sorter.js.map +1 -0
  225. package/dist/stores/feeds/feeds-store.d.ts +25 -0
  226. package/dist/stores/feeds/feeds-store.d.ts.map +1 -0
  227. package/dist/stores/feeds/feeds-store.js +459 -0
  228. package/dist/stores/feeds/feeds-store.js.map +1 -0
  229. package/dist/stores/feeds/index.d.ts +4 -0
  230. package/dist/stores/feeds/index.d.ts.map +1 -0
  231. package/dist/stores/feeds/index.js +4 -0
  232. package/dist/stores/feeds/index.js.map +1 -0
  233. package/dist/stores/feeds/utils.d.ts +43 -0
  234. package/dist/stores/feeds/utils.d.ts.map +1 -0
  235. package/dist/stores/feeds/utils.js +736 -0
  236. package/dist/stores/feeds/utils.js.map +1 -0
  237. package/dist/stores/replies/index.d.ts +4 -0
  238. package/dist/stores/replies/index.d.ts.map +1 -0
  239. package/dist/stores/replies/index.js +4 -0
  240. package/dist/stores/replies/index.js.map +1 -0
  241. package/dist/stores/replies/replies-comments-store.d.ts +8 -0
  242. package/dist/stores/replies/replies-comments-store.d.ts.map +1 -0
  243. package/dist/stores/replies/replies-comments-store.js +23 -0
  244. package/dist/stores/replies/replies-comments-store.js.map +1 -0
  245. package/dist/stores/replies/replies-store.d.ts +29 -0
  246. package/dist/stores/replies/replies-store.d.ts.map +1 -0
  247. package/dist/stores/replies/replies-store.js +413 -0
  248. package/dist/stores/replies/replies-store.js.map +1 -0
  249. package/dist/stores/replies/utils.d.ts +25 -0
  250. package/dist/stores/replies/utils.d.ts.map +1 -0
  251. package/dist/stores/replies/utils.js +549 -0
  252. package/dist/stores/replies/utils.js.map +1 -0
  253. package/dist/stores/replies-pages/index.d.ts +4 -0
  254. package/dist/stores/replies-pages/index.d.ts.map +1 -0
  255. package/dist/stores/replies-pages/index.js +4 -0
  256. package/dist/stores/replies-pages/index.js.map +1 -0
  257. package/dist/stores/replies-pages/replies-pages-store.d.ts +20 -0
  258. package/dist/stores/replies-pages/replies-pages-store.d.ts.map +1 -0
  259. package/dist/stores/replies-pages/replies-pages-store.js +270 -0
  260. package/dist/stores/replies-pages/replies-pages-store.js.map +1 -0
  261. package/dist/stores/replies-pages/utils.d.ts +3 -0
  262. package/dist/stores/replies-pages/utils.d.ts.map +1 -0
  263. package/dist/stores/replies-pages/utils.js +43 -0
  264. package/dist/stores/replies-pages/utils.js.map +1 -0
  265. package/dist/types.d.ts +638 -0
  266. package/dist/types.d.ts.map +1 -0
  267. package/dist/types.js +3 -0
  268. package/dist/types.js.map +1 -0
  269. 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