@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,1341 @@
|
|
|
1
|
+
// public accounts actions that are called by the user
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
import accountsStore, { listeners } from "./accounts-store.js";
|
|
12
|
+
import communitiesStore from "../communities/index.js";
|
|
13
|
+
import accountsDatabase from "./accounts-database.js";
|
|
14
|
+
import accountGenerator from "./account-generator.js";
|
|
15
|
+
import Logger from "@pkcprotocol/pkc-logger";
|
|
16
|
+
import validator from "../../lib/validator.js";
|
|
17
|
+
import chain from "../../lib/chain/index.js";
|
|
18
|
+
import assert from "assert";
|
|
19
|
+
const log = Logger("bitsocial-react-hooks:accounts:stores");
|
|
20
|
+
import * as accountsActionsInternal from "./accounts-actions-internal.js";
|
|
21
|
+
import { backfillPublicationCommunityAddress, createPkcCommunityEdit, getPkcCommunityAddresses, normalizeCommunityEditOptionsForPkc, normalizePublicationOptionsForStore, normalizePublicationOptionsForPkc, } from "../../lib/pkc-compat.js";
|
|
22
|
+
import { getAccountCommentsIndex, getAccountCommunities, getCommentCidsToAccountsComments, getAccountEditPropertySummary, fetchCommentLinkDimensions, getAccountCommentDepth, addShortAddressesToAccountComment, sanitizeAccountCommentForState, sanitizeStoredAccountComment, } from "./utils.js";
|
|
23
|
+
import isEqual from "lodash.isequal";
|
|
24
|
+
import { v4 as uuid } from "uuid";
|
|
25
|
+
import utils from "../../lib/utils/index.js";
|
|
26
|
+
// Active publish-session tracking for pending comments (Task 3)
|
|
27
|
+
const activePublishSessions = new Map();
|
|
28
|
+
const abandonedPublishSessionIds = new Set();
|
|
29
|
+
const getClientsSnapshotForState = (clients) => {
|
|
30
|
+
if (!clients || typeof clients !== "object") {
|
|
31
|
+
return undefined;
|
|
32
|
+
}
|
|
33
|
+
if (typeof clients.on === "function" || "state" in clients) {
|
|
34
|
+
return { state: clients.state };
|
|
35
|
+
}
|
|
36
|
+
const snapshot = {};
|
|
37
|
+
for (const key in clients) {
|
|
38
|
+
const childSnapshot = getClientsSnapshotForState(clients[key]);
|
|
39
|
+
if (childSnapshot !== undefined) {
|
|
40
|
+
snapshot[key] = childSnapshot;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return Object.keys(snapshot).length > 0 ? snapshot : undefined;
|
|
44
|
+
};
|
|
45
|
+
const syncCommentClientsSnapshot = (publishSessionId, accountId, publication) => {
|
|
46
|
+
const session = getPublishSession(publishSessionId);
|
|
47
|
+
if ((session === null || session === void 0 ? void 0 : session.currentIndex) === undefined) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
const snapshot = getClientsSnapshotForState(publication === null || publication === void 0 ? void 0 : publication.clients);
|
|
51
|
+
accountsStore.setState(({ accountsComments }) => maybeUpdateAccountComment(accountsComments, accountId, session.currentIndex, (ac, acc) => {
|
|
52
|
+
const updatedAccountComment = Object.assign({}, acc);
|
|
53
|
+
if (snapshot === undefined) {
|
|
54
|
+
delete updatedAccountComment.clients;
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
updatedAccountComment.clients = snapshot;
|
|
58
|
+
}
|
|
59
|
+
ac[session.currentIndex] = updatedAccountComment;
|
|
60
|
+
}));
|
|
61
|
+
};
|
|
62
|
+
const accountOwnsCommunityLocally = (account, communityAddress) => {
|
|
63
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
64
|
+
const localCommunityAddresses = getPkcCommunityAddresses(account.pkc);
|
|
65
|
+
if (localCommunityAddresses.includes(communityAddress)) {
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
const storedCommunity = communitiesStore.getState().communities[communityAddress];
|
|
69
|
+
if (((_b = (_a = storedCommunity === null || storedCommunity === void 0 ? void 0 : storedCommunity.roles) === null || _a === void 0 ? void 0 : _a[account.author.address]) === null || _b === void 0 ? void 0 : _b.role) === "owner") {
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
if (((_c = storedCommunity === null || storedCommunity === void 0 ? void 0 : storedCommunity.signer) === null || _c === void 0 ? void 0 : _c.address) &&
|
|
73
|
+
storedCommunity.signer.address === ((_d = account.signer) === null || _d === void 0 ? void 0 : _d.address)) {
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
76
|
+
return ((_g = (_f = (_e = account.communities) === null || _e === void 0 ? void 0 : _e[communityAddress]) === null || _f === void 0 ? void 0 : _f.role) === null || _g === void 0 ? void 0 : _g.role) === "owner";
|
|
77
|
+
};
|
|
78
|
+
const createPublishSession = (accountId, index) => {
|
|
79
|
+
const sessionId = uuid();
|
|
80
|
+
activePublishSessions.set(sessionId, {
|
|
81
|
+
accountId,
|
|
82
|
+
originalIndex: index,
|
|
83
|
+
currentIndex: index,
|
|
84
|
+
});
|
|
85
|
+
return sessionId;
|
|
86
|
+
};
|
|
87
|
+
const updatePublishSessionComment = (sessionId, comment) => {
|
|
88
|
+
const session = activePublishSessions.get(sessionId);
|
|
89
|
+
if (!session) {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
activePublishSessions.set(sessionId, Object.assign(Object.assign({}, session), { comment }));
|
|
93
|
+
};
|
|
94
|
+
const abandonAndStopPublishSession = (accountId, index) => {
|
|
95
|
+
var _a, _b;
|
|
96
|
+
const session = getPublishSessionByCurrentIndex(accountId, index);
|
|
97
|
+
if (!session)
|
|
98
|
+
return;
|
|
99
|
+
abandonedPublishSessionIds.add(session.sessionId);
|
|
100
|
+
try {
|
|
101
|
+
const stop = (_b = (_a = session.comment) === null || _a === void 0 ? void 0 : _a.stop) === null || _b === void 0 ? void 0 : _b.bind(session.comment);
|
|
102
|
+
if (typeof stop === "function")
|
|
103
|
+
stop();
|
|
104
|
+
}
|
|
105
|
+
catch (e) {
|
|
106
|
+
log.error("comment.stop() error during abandon", { accountId, index, error: e });
|
|
107
|
+
}
|
|
108
|
+
activePublishSessions.delete(session.sessionId);
|
|
109
|
+
};
|
|
110
|
+
const isPublishSessionAbandoned = (sessionId) => abandonedPublishSessionIds.has(sessionId);
|
|
111
|
+
const getPublishSession = (sessionId) => activePublishSessions.get(sessionId);
|
|
112
|
+
/** Returns state update or {} when accountComment not yet in state (no-op). Exported for coverage. */
|
|
113
|
+
export const maybeUpdateAccountComment = (accountsComments, accountId, index, updater) => {
|
|
114
|
+
const accountComments = [...(accountsComments[accountId] || [])];
|
|
115
|
+
const accountComment = accountComments[index];
|
|
116
|
+
if (!accountComment)
|
|
117
|
+
return {};
|
|
118
|
+
updater(accountComments, accountComment);
|
|
119
|
+
return { accountsComments: Object.assign(Object.assign({}, accountsComments), { [accountId]: accountComments }) };
|
|
120
|
+
};
|
|
121
|
+
const getPublishSessionByCurrentIndex = (accountId, index) => {
|
|
122
|
+
for (const [key, session] of activePublishSessions) {
|
|
123
|
+
if (session.accountId === accountId && session.currentIndex === index) {
|
|
124
|
+
return Object.assign({ sessionId: key }, session);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return undefined;
|
|
128
|
+
};
|
|
129
|
+
const shiftPublishSessionIndicesAfterDelete = (accountId, deletedIndex) => {
|
|
130
|
+
for (const session of activePublishSessions.values()) {
|
|
131
|
+
if (session.accountId === accountId && session.currentIndex > deletedIndex) {
|
|
132
|
+
session.currentIndex -= 1;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
const cleanupPublishSessionOnTerminal = (sessionId) => {
|
|
137
|
+
activePublishSessions.delete(sessionId);
|
|
138
|
+
abandonedPublishSessionIds.delete(sessionId);
|
|
139
|
+
};
|
|
140
|
+
export const doesStoredAccountEditMatch = (storedAccountEdit, targetStoredAccountEdit) => (storedAccountEdit === null || storedAccountEdit === void 0 ? void 0 : storedAccountEdit.clientId) && (targetStoredAccountEdit === null || targetStoredAccountEdit === void 0 ? void 0 : targetStoredAccountEdit.clientId)
|
|
141
|
+
? storedAccountEdit.clientId === targetStoredAccountEdit.clientId
|
|
142
|
+
: isEqual(storedAccountEdit, targetStoredAccountEdit);
|
|
143
|
+
export const sanitizeStoredAccountEdit = (storedAccountEdit) => {
|
|
144
|
+
const sanitizedStoredAccountEdit = Object.assign({}, storedAccountEdit);
|
|
145
|
+
delete sanitizedStoredAccountEdit.signer;
|
|
146
|
+
delete sanitizedStoredAccountEdit.author;
|
|
147
|
+
return sanitizedStoredAccountEdit;
|
|
148
|
+
};
|
|
149
|
+
const accountEditNonPropertyNames = new Set([
|
|
150
|
+
"author",
|
|
151
|
+
"signer",
|
|
152
|
+
"clientId",
|
|
153
|
+
"commentCid",
|
|
154
|
+
"communityAddress",
|
|
155
|
+
"communityAddress",
|
|
156
|
+
"communityEdit",
|
|
157
|
+
"communityEdit",
|
|
158
|
+
"timestamp",
|
|
159
|
+
]);
|
|
160
|
+
const normalizeStoredAccountEditForSummary = (storedAccountEdit) => {
|
|
161
|
+
var _a;
|
|
162
|
+
const normalizedEdit = storedAccountEdit.commentModeration
|
|
163
|
+
? Object.assign(Object.assign(Object.assign({}, storedAccountEdit), storedAccountEdit.commentModeration), { commentModeration: undefined }) : Object.assign({}, storedAccountEdit);
|
|
164
|
+
const communityEdit = (_a = normalizedEdit.communityEdit) !== null && _a !== void 0 ? _a : normalizedEdit.communityEdit;
|
|
165
|
+
if (communityEdit && typeof communityEdit === "object") {
|
|
166
|
+
Object.assign(normalizedEdit, communityEdit);
|
|
167
|
+
}
|
|
168
|
+
delete normalizedEdit.communityEdit;
|
|
169
|
+
delete normalizedEdit.communityEdit;
|
|
170
|
+
return normalizedEdit;
|
|
171
|
+
};
|
|
172
|
+
const getStoredAccountEditTarget = (storedAccountEdit) => storedAccountEdit.commentCid ||
|
|
173
|
+
storedAccountEdit.communityAddress ||
|
|
174
|
+
storedAccountEdit.communityAddress;
|
|
175
|
+
export const addStoredAccountEditSummaryToState = (accountsEditsSummaries, accountId, storedAccountEdit) => {
|
|
176
|
+
var _a;
|
|
177
|
+
const editTarget = getStoredAccountEditTarget(storedAccountEdit);
|
|
178
|
+
if (!editTarget) {
|
|
179
|
+
return { accountsEditsSummaries };
|
|
180
|
+
}
|
|
181
|
+
const accountEditsSummary = accountsEditsSummaries[accountId] || {};
|
|
182
|
+
const targetSummary = accountEditsSummary[editTarget] || {};
|
|
183
|
+
const nextSummary = Object.assign({}, targetSummary);
|
|
184
|
+
const normalizedEdit = normalizeStoredAccountEditForSummary(storedAccountEdit);
|
|
185
|
+
for (const propertyName in normalizedEdit) {
|
|
186
|
+
if (normalizedEdit[propertyName] === undefined ||
|
|
187
|
+
accountEditNonPropertyNames.has(propertyName)) {
|
|
188
|
+
continue;
|
|
189
|
+
}
|
|
190
|
+
const previousTimestamp = ((_a = nextSummary[propertyName]) === null || _a === void 0 ? void 0 : _a.timestamp) || 0;
|
|
191
|
+
if ((normalizedEdit.timestamp || 0) >= previousTimestamp) {
|
|
192
|
+
nextSummary[propertyName] = {
|
|
193
|
+
timestamp: normalizedEdit.timestamp,
|
|
194
|
+
value: normalizedEdit[propertyName],
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
return {
|
|
199
|
+
accountsEditsSummaries: Object.assign(Object.assign({}, accountsEditsSummaries), { [accountId]: Object.assign(Object.assign({}, accountEditsSummary), { [editTarget]: nextSummary }) }),
|
|
200
|
+
};
|
|
201
|
+
};
|
|
202
|
+
export const removeStoredAccountEditSummaryFromState = (accountsEditsSummaries, accountsEdits, accountId, storedAccountEdit) => {
|
|
203
|
+
var _a;
|
|
204
|
+
const editTarget = getStoredAccountEditTarget(storedAccountEdit);
|
|
205
|
+
if (!editTarget) {
|
|
206
|
+
return { accountsEditsSummaries };
|
|
207
|
+
}
|
|
208
|
+
let deletedEdit = false;
|
|
209
|
+
const editsForTarget = (((_a = accountsEdits[accountId]) === null || _a === void 0 ? void 0 : _a[editTarget]) || []).filter((storedEdit) => {
|
|
210
|
+
if (!deletedEdit && doesStoredAccountEditMatch(storedEdit, storedAccountEdit)) {
|
|
211
|
+
deletedEdit = true;
|
|
212
|
+
return false;
|
|
213
|
+
}
|
|
214
|
+
return true;
|
|
215
|
+
});
|
|
216
|
+
const nextTargetSummary = getAccountEditPropertySummary(editsForTarget);
|
|
217
|
+
const nextAccountSummary = Object.assign({}, (accountsEditsSummaries[accountId] || {}));
|
|
218
|
+
if (Object.keys(nextTargetSummary).length > 0) {
|
|
219
|
+
nextAccountSummary[editTarget] = nextTargetSummary;
|
|
220
|
+
}
|
|
221
|
+
else {
|
|
222
|
+
delete nextAccountSummary[editTarget];
|
|
223
|
+
}
|
|
224
|
+
return {
|
|
225
|
+
accountsEditsSummaries: Object.assign(Object.assign({}, accountsEditsSummaries), { [accountId]: nextAccountSummary }),
|
|
226
|
+
};
|
|
227
|
+
};
|
|
228
|
+
export const hasTerminalChallengeVerificationError = (challengeVerification) => {
|
|
229
|
+
const challengeErrors = challengeVerification === null || challengeVerification === void 0 ? void 0 : challengeVerification.challengeErrors;
|
|
230
|
+
const hasChallengeErrors = Array.isArray(challengeErrors)
|
|
231
|
+
? challengeErrors.length > 0
|
|
232
|
+
: challengeErrors && typeof challengeErrors === "object"
|
|
233
|
+
? Object.keys(challengeErrors).length > 0
|
|
234
|
+
: Boolean(challengeErrors);
|
|
235
|
+
return (!(challengeVerification === null || challengeVerification === void 0 ? void 0 : challengeVerification.challengeSuccess) &&
|
|
236
|
+
(hasChallengeErrors || Boolean(challengeVerification === null || challengeVerification === void 0 ? void 0 : challengeVerification.reason)));
|
|
237
|
+
};
|
|
238
|
+
export const addStoredAccountEditToState = (accountsEdits, accountId, storedAccountEdit) => {
|
|
239
|
+
const accountEdits = accountsEdits[accountId] || {};
|
|
240
|
+
const editTarget = getStoredAccountEditTarget(storedAccountEdit);
|
|
241
|
+
if (!editTarget) {
|
|
242
|
+
return { accountsEdits };
|
|
243
|
+
}
|
|
244
|
+
const commentEdits = accountEdits[editTarget] || [];
|
|
245
|
+
return {
|
|
246
|
+
accountsEdits: Object.assign(Object.assign({}, accountsEdits), { [accountId]: Object.assign(Object.assign({}, accountEdits), { [editTarget]: [...commentEdits, storedAccountEdit] }) }),
|
|
247
|
+
};
|
|
248
|
+
};
|
|
249
|
+
export const removeStoredAccountEditFromState = (accountsEdits, accountId, storedAccountEdit) => {
|
|
250
|
+
const accountEdits = accountsEdits[accountId] || {};
|
|
251
|
+
const editTarget = getStoredAccountEditTarget(storedAccountEdit);
|
|
252
|
+
if (!editTarget) {
|
|
253
|
+
return { accountsEdits };
|
|
254
|
+
}
|
|
255
|
+
const commentEdits = accountEdits[editTarget] || [];
|
|
256
|
+
let deletedEdit = false;
|
|
257
|
+
const nextCommentEdits = commentEdits.filter((commentEdit) => {
|
|
258
|
+
if (!deletedEdit && doesStoredAccountEditMatch(commentEdit, storedAccountEdit)) {
|
|
259
|
+
deletedEdit = true;
|
|
260
|
+
return false;
|
|
261
|
+
}
|
|
262
|
+
return true;
|
|
263
|
+
});
|
|
264
|
+
const nextAccountEdits = nextCommentEdits.length > 0
|
|
265
|
+
? Object.assign(Object.assign({}, accountEdits), { [editTarget]: nextCommentEdits }) : Object.fromEntries(Object.entries(accountEdits).filter(([target]) => target !== editTarget));
|
|
266
|
+
return {
|
|
267
|
+
accountsEdits: Object.assign(Object.assign({}, accountsEdits), { [accountId]: nextAccountEdits }),
|
|
268
|
+
};
|
|
269
|
+
};
|
|
270
|
+
const addNewAccountToDatabaseAndState = (newAccount) => __awaiter(void 0, void 0, void 0, function* () {
|
|
271
|
+
// add to database first to init the account
|
|
272
|
+
yield accountsDatabase.addAccount(newAccount);
|
|
273
|
+
// use database data for these because it's easier
|
|
274
|
+
const [newAccountIds, newAccountNamesToAccountIds] = yield Promise.all([
|
|
275
|
+
accountsDatabase.accountsMetadataDatabase.getItem("accountIds"),
|
|
276
|
+
accountsDatabase.accountsMetadataDatabase.getItem("accountNamesToAccountIds"),
|
|
277
|
+
]);
|
|
278
|
+
// set the new state
|
|
279
|
+
const { accounts, accountsComments, accountsCommentsIndexes, accountsVotes, accountsEdits, accountsEditsSummaries, accountsEditsLoaded, accountsCommentsReplies, } = accountsStore.getState();
|
|
280
|
+
const newAccounts = Object.assign(Object.assign({}, accounts), { [newAccount.id]: newAccount });
|
|
281
|
+
const newState = {
|
|
282
|
+
accounts: newAccounts,
|
|
283
|
+
accountIds: newAccountIds,
|
|
284
|
+
accountNamesToAccountIds: newAccountNamesToAccountIds,
|
|
285
|
+
accountsComments: Object.assign(Object.assign({}, accountsComments), { [newAccount.id]: [] }),
|
|
286
|
+
accountsCommentsIndexes: Object.assign(Object.assign({}, accountsCommentsIndexes), { [newAccount.id]: getAccountCommentsIndex([]) }),
|
|
287
|
+
accountsVotes: Object.assign(Object.assign({}, accountsVotes), { [newAccount.id]: {} }),
|
|
288
|
+
accountsEdits: Object.assign(Object.assign({}, accountsEdits), { [newAccount.id]: {} }),
|
|
289
|
+
accountsEditsSummaries: Object.assign(Object.assign({}, accountsEditsSummaries), { [newAccount.id]: {} }),
|
|
290
|
+
accountsEditsLoaded: Object.assign(Object.assign({}, accountsEditsLoaded), { [newAccount.id]: false }),
|
|
291
|
+
accountsCommentsReplies: Object.assign(Object.assign({}, accountsCommentsReplies), { [newAccount.id]: {} }),
|
|
292
|
+
};
|
|
293
|
+
// if there is only 1 account, make it active
|
|
294
|
+
// otherwise stay on the same active account
|
|
295
|
+
if (newAccountIds.length === 1) {
|
|
296
|
+
newState.activeAccountId = newAccount.id;
|
|
297
|
+
}
|
|
298
|
+
accountsStore.setState(newState);
|
|
299
|
+
});
|
|
300
|
+
export const createAccount = (accountName) => __awaiter(void 0, void 0, void 0, function* () {
|
|
301
|
+
const newAccount = yield accountGenerator.generateDefaultAccount();
|
|
302
|
+
if (accountName) {
|
|
303
|
+
newAccount.name = accountName;
|
|
304
|
+
}
|
|
305
|
+
yield addNewAccountToDatabaseAndState(newAccount);
|
|
306
|
+
log("accountsActions.createAccount", { accountName, account: newAccount });
|
|
307
|
+
});
|
|
308
|
+
export const deleteAccount = (accountName) => __awaiter(void 0, void 0, void 0, function* () {
|
|
309
|
+
const { accounts, accountNamesToAccountIds, activeAccountId, accountsComments, accountsCommentsIndexes, accountsVotes, accountsEdits, accountsEditsSummaries, accountsEditsLoaded, } = accountsStore.getState();
|
|
310
|
+
assert(accounts && accountNamesToAccountIds && activeAccountId, `can't use accountsStore.accountActions before initialized`);
|
|
311
|
+
let account = accounts[activeAccountId];
|
|
312
|
+
if (accountName) {
|
|
313
|
+
const accountId = accountNamesToAccountIds[accountName];
|
|
314
|
+
account = accounts[accountId];
|
|
315
|
+
}
|
|
316
|
+
assert(account === null || account === void 0 ? void 0 : account.id, `accountsActions.deleteAccount account.id '${account === null || account === void 0 ? void 0 : account.id}' doesn't exist, activeAccountId '${activeAccountId}' accountName '${accountName}'`);
|
|
317
|
+
yield accountsDatabase.removeAccount(account);
|
|
318
|
+
const newAccounts = Object.assign({}, accounts);
|
|
319
|
+
delete newAccounts[account.id];
|
|
320
|
+
const [newAccountIds, newActiveAccountId, newAccountNamesToAccountIds] = yield Promise.all([
|
|
321
|
+
accountsDatabase.accountsMetadataDatabase.getItem("accountIds"),
|
|
322
|
+
accountsDatabase.accountsMetadataDatabase.getItem("activeAccountId"),
|
|
323
|
+
accountsDatabase.accountsMetadataDatabase.getItem("accountNamesToAccountIds"),
|
|
324
|
+
]);
|
|
325
|
+
const newAccountsComments = Object.assign({}, accountsComments);
|
|
326
|
+
delete newAccountsComments[account.id];
|
|
327
|
+
const newAccountsCommentsIndexes = Object.assign({}, accountsCommentsIndexes);
|
|
328
|
+
delete newAccountsCommentsIndexes[account.id];
|
|
329
|
+
const newCommentCidsToAccountsComments = getCommentCidsToAccountsComments(newAccountsComments);
|
|
330
|
+
const newAccountsVotes = Object.assign({}, accountsVotes);
|
|
331
|
+
delete newAccountsVotes[account.id];
|
|
332
|
+
const newAccountsEdits = Object.assign({}, accountsEdits);
|
|
333
|
+
delete newAccountsEdits[account.id];
|
|
334
|
+
const newAccountsEditsSummaries = Object.assign({}, accountsEditsSummaries);
|
|
335
|
+
delete newAccountsEditsSummaries[account.id];
|
|
336
|
+
const newAccountsEditsLoaded = Object.assign({}, accountsEditsLoaded);
|
|
337
|
+
delete newAccountsEditsLoaded[account.id];
|
|
338
|
+
accountsStore.setState({
|
|
339
|
+
accounts: newAccounts,
|
|
340
|
+
accountIds: newAccountIds,
|
|
341
|
+
activeAccountId: newActiveAccountId,
|
|
342
|
+
accountNamesToAccountIds: newAccountNamesToAccountIds,
|
|
343
|
+
accountsComments: newAccountsComments,
|
|
344
|
+
accountsCommentsIndexes: newAccountsCommentsIndexes,
|
|
345
|
+
commentCidsToAccountsComments: newCommentCidsToAccountsComments,
|
|
346
|
+
accountsVotes: newAccountsVotes,
|
|
347
|
+
accountsEdits: newAccountsEdits,
|
|
348
|
+
accountsEditsSummaries: newAccountsEditsSummaries,
|
|
349
|
+
accountsEditsLoaded: newAccountsEditsLoaded,
|
|
350
|
+
});
|
|
351
|
+
});
|
|
352
|
+
export const setActiveAccount = (accountName) => __awaiter(void 0, void 0, void 0, function* () {
|
|
353
|
+
const { accountNamesToAccountIds } = accountsStore.getState();
|
|
354
|
+
assert(accountNamesToAccountIds, `can't use accountsStore.accountActions before initialized`);
|
|
355
|
+
validator.validateAccountsActionsSetActiveAccountArguments(accountName);
|
|
356
|
+
const accountId = accountNamesToAccountIds[accountName];
|
|
357
|
+
yield accountsDatabase.accountsMetadataDatabase.setItem("activeAccountId", accountId);
|
|
358
|
+
log("accountsActions.setActiveAccount", { accountName, accountId });
|
|
359
|
+
accountsStore.setState({ activeAccountId: accountId });
|
|
360
|
+
});
|
|
361
|
+
export const setAccount = (account) => __awaiter(void 0, void 0, void 0, function* () {
|
|
362
|
+
var _a;
|
|
363
|
+
const { accounts } = accountsStore.getState();
|
|
364
|
+
validator.validateAccountsActionsSetAccountArguments(account);
|
|
365
|
+
assert(accounts === null || accounts === void 0 ? void 0 : accounts[account.id], `cannot set account with account.id '${account.id}' id does not exist in database`);
|
|
366
|
+
// if author.address has changed, add new community roles of author.address found in communities store
|
|
367
|
+
// TODO: add test to check if roles get added
|
|
368
|
+
if (account.author.address !== accounts[account.id].author.address) {
|
|
369
|
+
const communities = getAccountCommunities(account, communitiesStore.getState().communities);
|
|
370
|
+
account = Object.assign(Object.assign({}, account), { communities });
|
|
371
|
+
// wallet.signature changes if author.address changes
|
|
372
|
+
if ((_a = account.author.wallets) === null || _a === void 0 ? void 0 : _a.eth) {
|
|
373
|
+
const pkcSignerWalletWithNewAuthorAddress = yield chain.getEthWalletFromPkcPrivateKey(account.signer.privateKey, account.author.address);
|
|
374
|
+
// wallet is using pkc signer, redo signature with new author.address
|
|
375
|
+
if (account.author.wallets.eth.address === (pkcSignerWalletWithNewAuthorAddress === null || pkcSignerWalletWithNewAuthorAddress === void 0 ? void 0 : pkcSignerWalletWithNewAuthorAddress.address)) {
|
|
376
|
+
account.author.wallets = Object.assign(Object.assign({}, account.author.wallets), { eth: pkcSignerWalletWithNewAuthorAddress });
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
// use this function to serialize and update all databases
|
|
381
|
+
yield accountsDatabase.addAccount(account);
|
|
382
|
+
const [newAccount, newAccountNamesToAccountIds] = yield Promise.all([
|
|
383
|
+
// use this function to deserialize
|
|
384
|
+
accountsDatabase.getAccount(account.id),
|
|
385
|
+
accountsDatabase.accountsMetadataDatabase.getItem("accountNamesToAccountIds"),
|
|
386
|
+
]);
|
|
387
|
+
const newAccounts = Object.assign(Object.assign({}, accounts), { [newAccount.id]: newAccount });
|
|
388
|
+
log("accountsActions.setAccount", { account: newAccount });
|
|
389
|
+
accountsStore.setState({
|
|
390
|
+
accounts: newAccounts,
|
|
391
|
+
accountNamesToAccountIds: newAccountNamesToAccountIds,
|
|
392
|
+
});
|
|
393
|
+
});
|
|
394
|
+
export const setAccountsOrder = (newOrderedAccountNames) => __awaiter(void 0, void 0, void 0, function* () {
|
|
395
|
+
const { accounts, accountNamesToAccountIds } = accountsStore.getState();
|
|
396
|
+
assert(accounts && accountNamesToAccountIds, `can't use accountsStore.accountActions before initialized`);
|
|
397
|
+
const accountIds = [];
|
|
398
|
+
const accountNames = [];
|
|
399
|
+
for (const accountName of newOrderedAccountNames) {
|
|
400
|
+
const accountId = accountNamesToAccountIds[accountName];
|
|
401
|
+
accountIds.push(accountId);
|
|
402
|
+
accountNames.push(accounts[accountId].name);
|
|
403
|
+
}
|
|
404
|
+
validator.validateAccountsActionsSetAccountsOrderArguments(newOrderedAccountNames, accountNames);
|
|
405
|
+
log("accountsActions.setAccountsOrder", {
|
|
406
|
+
previousAccountNames: accountNames,
|
|
407
|
+
newAccountNames: newOrderedAccountNames,
|
|
408
|
+
});
|
|
409
|
+
yield accountsDatabase.accountsMetadataDatabase.setItem("accountIds", accountIds);
|
|
410
|
+
accountsStore.setState({ accountIds });
|
|
411
|
+
});
|
|
412
|
+
export const importAccount = (serializedAccount) => __awaiter(void 0, void 0, void 0, function* () {
|
|
413
|
+
var _a, _b;
|
|
414
|
+
const { accounts, accountNamesToAccountIds, activeAccountId } = accountsStore.getState();
|
|
415
|
+
assert(accounts && accountNamesToAccountIds && activeAccountId, `can't use accountsStore.accountActions before initialized`);
|
|
416
|
+
let imported;
|
|
417
|
+
try {
|
|
418
|
+
imported = JSON.parse(serializedAccount);
|
|
419
|
+
}
|
|
420
|
+
catch (e) { }
|
|
421
|
+
assert((imported === null || imported === void 0 ? void 0 : imported.account) && ((_a = imported === null || imported === void 0 ? void 0 : imported.account) === null || _a === void 0 ? void 0 : _a.id) && ((_b = imported === null || imported === void 0 ? void 0 : imported.account) === null || _b === void 0 ? void 0 : _b.name), `accountsActions.importAccount failed JSON.stringify json serializedAccount '${serializedAccount}'`);
|
|
422
|
+
// add community roles already in communities store to imported account
|
|
423
|
+
// TODO: add test to check if roles get added
|
|
424
|
+
const communities = getAccountCommunities(imported.account, communitiesStore.getState().communities);
|
|
425
|
+
// if imported.account.name already exists, add ' 2', don't overwrite
|
|
426
|
+
if (accountNamesToAccountIds[imported.account.name]) {
|
|
427
|
+
imported.account.name += " 2";
|
|
428
|
+
}
|
|
429
|
+
// generate new account
|
|
430
|
+
const generatedAccount = yield accountGenerator.generateDefaultAccount();
|
|
431
|
+
// use generatedAccount to init properties like .pkc and .id on a new account
|
|
432
|
+
// overwrite account.id to avoid duplicate ids
|
|
433
|
+
const newAccount = Object.assign(Object.assign(Object.assign({}, generatedAccount), imported.account), { communities, id: generatedAccount.id });
|
|
434
|
+
// add account to database
|
|
435
|
+
yield accountsDatabase.addAccount(newAccount);
|
|
436
|
+
// add account comments, votes, edits to database
|
|
437
|
+
for (const accountComment of imported.accountComments || []) {
|
|
438
|
+
yield accountsDatabase.addAccountComment(newAccount.id, accountComment);
|
|
439
|
+
}
|
|
440
|
+
for (const accountVote of imported.accountVotes || []) {
|
|
441
|
+
yield accountsDatabase.addAccountVote(newAccount.id, accountVote);
|
|
442
|
+
}
|
|
443
|
+
for (const accountEdit of imported.accountEdits || []) {
|
|
444
|
+
yield accountsDatabase.addAccountEdit(newAccount.id, accountEdit);
|
|
445
|
+
}
|
|
446
|
+
// set new state
|
|
447
|
+
// get new state data from database because it's easier
|
|
448
|
+
const [accountComments, accountVotes, accountEditsSummary, accountIds, newAccountNamesToAccountIds,] = yield Promise.all([
|
|
449
|
+
accountsDatabase.getAccountComments(newAccount.id),
|
|
450
|
+
accountsDatabase.getAccountVotes(newAccount.id),
|
|
451
|
+
accountsDatabase.getAccountEditsSummary(newAccount.id),
|
|
452
|
+
accountsDatabase.accountsMetadataDatabase.getItem("accountIds"),
|
|
453
|
+
accountsDatabase.accountsMetadataDatabase.getItem("accountNamesToAccountIds"),
|
|
454
|
+
]);
|
|
455
|
+
accountsStore.setState((state) => ({
|
|
456
|
+
accounts: Object.assign(Object.assign({}, state.accounts), { [newAccount.id]: newAccount }),
|
|
457
|
+
accountIds,
|
|
458
|
+
accountNamesToAccountIds: newAccountNamesToAccountIds,
|
|
459
|
+
accountsComments: Object.assign(Object.assign({}, state.accountsComments), { [newAccount.id]: accountComments }),
|
|
460
|
+
accountsCommentsIndexes: Object.assign(Object.assign({}, state.accountsCommentsIndexes), { [newAccount.id]: getAccountCommentsIndex(accountComments) }),
|
|
461
|
+
commentCidsToAccountsComments: getCommentCidsToAccountsComments(Object.assign(Object.assign({}, state.accountsComments), { [newAccount.id]: accountComments })),
|
|
462
|
+
accountsVotes: Object.assign(Object.assign({}, state.accountsVotes), { [newAccount.id]: accountVotes }),
|
|
463
|
+
accountsEdits: Object.assign(Object.assign({}, state.accountsEdits), { [newAccount.id]: {} }),
|
|
464
|
+
accountsEditsSummaries: Object.assign(Object.assign({}, state.accountsEditsSummaries), { [newAccount.id]: accountEditsSummary }),
|
|
465
|
+
accountsEditsLoaded: Object.assign(Object.assign({}, state.accountsEditsLoaded), { [newAccount.id]: false }),
|
|
466
|
+
// don't import/export replies to own comments, those are just cached and can be refetched
|
|
467
|
+
accountsCommentsReplies: Object.assign(Object.assign({}, state.accountsCommentsReplies), { [newAccount.id]: {} }),
|
|
468
|
+
}));
|
|
469
|
+
log("accountsActions.importAccount", {
|
|
470
|
+
account: newAccount,
|
|
471
|
+
accountComments,
|
|
472
|
+
accountVotes,
|
|
473
|
+
accountEditsSummary,
|
|
474
|
+
});
|
|
475
|
+
// start looking for updates for all accounts comments in database
|
|
476
|
+
for (const accountComment of accountComments) {
|
|
477
|
+
accountsStore
|
|
478
|
+
.getState()
|
|
479
|
+
.accountsActionsInternal.startUpdatingAccountCommentOnCommentUpdateEvents(accountComment, newAccount, accountComment.index)
|
|
480
|
+
.catch((error) => log.error("accountsActions.importAccount startUpdatingAccountCommentOnCommentUpdateEvents error", {
|
|
481
|
+
accountComment,
|
|
482
|
+
accountCommentIndex: accountComment.index,
|
|
483
|
+
importedAccount: newAccount,
|
|
484
|
+
error,
|
|
485
|
+
}));
|
|
486
|
+
}
|
|
487
|
+
// TODO: add options to only import private key, account settings, or include all account comments/votes history
|
|
488
|
+
});
|
|
489
|
+
export const exportAccount = (accountName) => __awaiter(void 0, void 0, void 0, function* () {
|
|
490
|
+
const { accounts, accountNamesToAccountIds, activeAccountId } = accountsStore.getState();
|
|
491
|
+
assert(accounts && accountNamesToAccountIds && activeAccountId, `can't use accountsStore.accountActions before initialized`);
|
|
492
|
+
let account = accounts[activeAccountId];
|
|
493
|
+
if (accountName) {
|
|
494
|
+
const accountId = accountNamesToAccountIds[accountName];
|
|
495
|
+
account = accounts[accountId];
|
|
496
|
+
}
|
|
497
|
+
assert(account === null || account === void 0 ? void 0 : account.id, `accountsActions.exportAccount account.id '${account === null || account === void 0 ? void 0 : account.id}' doesn't exist, activeAccountId '${activeAccountId}' accountName '${accountName}'`);
|
|
498
|
+
const exportedAccountJson = yield accountsDatabase.getExportedAccountJson(account.id);
|
|
499
|
+
log("accountsActions.exportAccount", { exportedAccountJson });
|
|
500
|
+
return exportedAccountJson;
|
|
501
|
+
});
|
|
502
|
+
export const subscribe = (communityAddress, accountName) => __awaiter(void 0, void 0, void 0, function* () {
|
|
503
|
+
const { accounts, accountNamesToAccountIds, activeAccountId } = accountsStore.getState();
|
|
504
|
+
assert(communityAddress && typeof communityAddress === "string", `accountsActions.subscribe invalid communityAddress '${communityAddress}'`);
|
|
505
|
+
assert(accounts && accountNamesToAccountIds && activeAccountId, `can't use accountsStore.accountActions before initialized`);
|
|
506
|
+
let account = accounts[activeAccountId];
|
|
507
|
+
if (accountName) {
|
|
508
|
+
const accountId = accountNamesToAccountIds[accountName];
|
|
509
|
+
account = accounts[accountId];
|
|
510
|
+
}
|
|
511
|
+
assert(account === null || account === void 0 ? void 0 : account.id, `accountsActions.subscribe account.id '${account === null || account === void 0 ? void 0 : account.id}' doesn't exist, activeAccountId '${activeAccountId}' accountName '${accountName}'`);
|
|
512
|
+
let subscriptions = account.subscriptions || [];
|
|
513
|
+
if (subscriptions.includes(communityAddress)) {
|
|
514
|
+
throw Error(`account '${account.id}' already subscribed to '${communityAddress}'`);
|
|
515
|
+
}
|
|
516
|
+
subscriptions = [...subscriptions, communityAddress];
|
|
517
|
+
const updatedAccount = Object.assign(Object.assign({}, account), { subscriptions });
|
|
518
|
+
// update account in db async for instant feedback speed
|
|
519
|
+
accountsDatabase.addAccount(updatedAccount);
|
|
520
|
+
const updatedAccounts = Object.assign(Object.assign({}, accounts), { [updatedAccount.id]: updatedAccount });
|
|
521
|
+
log("accountsActions.subscribe", { account: updatedAccount, accountName, communityAddress });
|
|
522
|
+
accountsStore.setState({ accounts: updatedAccounts });
|
|
523
|
+
});
|
|
524
|
+
export const unsubscribe = (communityAddress, accountName) => __awaiter(void 0, void 0, void 0, function* () {
|
|
525
|
+
const { accounts, accountNamesToAccountIds, activeAccountId } = accountsStore.getState();
|
|
526
|
+
assert(communityAddress && typeof communityAddress === "string", `accountsActions.unsubscribe invalid communityAddress '${communityAddress}'`);
|
|
527
|
+
assert(accounts && accountNamesToAccountIds && activeAccountId, `can't use accountsStore.accountActions before initialized`);
|
|
528
|
+
let account = accounts[activeAccountId];
|
|
529
|
+
if (accountName) {
|
|
530
|
+
const accountId = accountNamesToAccountIds[accountName];
|
|
531
|
+
account = accounts[accountId];
|
|
532
|
+
}
|
|
533
|
+
assert(account === null || account === void 0 ? void 0 : account.id, `accountsActions.unsubscribe account.id '${account === null || account === void 0 ? void 0 : account.id}' doesn't exist, activeAccountId '${activeAccountId}' accountName '${accountName}'`);
|
|
534
|
+
let subscriptions = account.subscriptions || [];
|
|
535
|
+
if (!subscriptions.includes(communityAddress)) {
|
|
536
|
+
throw Error(`account '${account.id}' already unsubscribed from '${communityAddress}'`);
|
|
537
|
+
}
|
|
538
|
+
// remove communityAddress
|
|
539
|
+
subscriptions = subscriptions.filter((address) => address !== communityAddress);
|
|
540
|
+
const updatedAccount = Object.assign(Object.assign({}, account), { subscriptions });
|
|
541
|
+
// update account in db async for instant feedback speed
|
|
542
|
+
accountsDatabase.addAccount(updatedAccount);
|
|
543
|
+
const updatedAccounts = Object.assign(Object.assign({}, accounts), { [updatedAccount.id]: updatedAccount });
|
|
544
|
+
log("accountsActions.unsubscribe", { account: updatedAccount, accountName, communityAddress });
|
|
545
|
+
accountsStore.setState({ accounts: updatedAccounts });
|
|
546
|
+
});
|
|
547
|
+
export const blockAddress = (address, accountName) => __awaiter(void 0, void 0, void 0, function* () {
|
|
548
|
+
const { accounts, accountNamesToAccountIds, activeAccountId } = accountsStore.getState();
|
|
549
|
+
assert(address && typeof address === "string", `accountsActions.blockAddress invalid address '${address}'`);
|
|
550
|
+
assert(accounts && accountNamesToAccountIds && activeAccountId, `can't use accountsStore.accountActions before initialized`);
|
|
551
|
+
let account = accounts[activeAccountId];
|
|
552
|
+
if (accountName) {
|
|
553
|
+
const accountId = accountNamesToAccountIds[accountName];
|
|
554
|
+
account = accounts[accountId];
|
|
555
|
+
}
|
|
556
|
+
assert(account === null || account === void 0 ? void 0 : account.id, `accountsActions.blockAddress account.id '${account === null || account === void 0 ? void 0 : account.id}' doesn't exist, activeAccountId '${activeAccountId}' accountName '${accountName}'`);
|
|
557
|
+
const blockedAddresses = Object.assign({}, account.blockedAddresses);
|
|
558
|
+
if (blockedAddresses[address] === true) {
|
|
559
|
+
throw Error(`account '${account.id}' already blocked address '${address}'`);
|
|
560
|
+
}
|
|
561
|
+
blockedAddresses[address] = true;
|
|
562
|
+
const updatedAccount = Object.assign(Object.assign({}, account), { blockedAddresses });
|
|
563
|
+
// update account in db async for instant feedback speed
|
|
564
|
+
accountsDatabase.addAccount(updatedAccount);
|
|
565
|
+
const updatedAccounts = Object.assign(Object.assign({}, accounts), { [updatedAccount.id]: updatedAccount });
|
|
566
|
+
log("accountsActions.blockAddress", { account: updatedAccount, accountName, address });
|
|
567
|
+
accountsStore.setState({ accounts: updatedAccounts });
|
|
568
|
+
});
|
|
569
|
+
export const unblockAddress = (address, accountName) => __awaiter(void 0, void 0, void 0, function* () {
|
|
570
|
+
const { accounts, accountNamesToAccountIds, activeAccountId } = accountsStore.getState();
|
|
571
|
+
assert(address && typeof address === "string", `accountsActions.unblockAddress invalid address '${address}'`);
|
|
572
|
+
assert(accounts && accountNamesToAccountIds && activeAccountId, `can't use accountsStore.accountActions before initialized`);
|
|
573
|
+
let account = accounts[activeAccountId];
|
|
574
|
+
if (accountName) {
|
|
575
|
+
const accountId = accountNamesToAccountIds[accountName];
|
|
576
|
+
account = accounts[accountId];
|
|
577
|
+
}
|
|
578
|
+
assert(account === null || account === void 0 ? void 0 : account.id, `accountsActions.unblockAddress account.id '${account === null || account === void 0 ? void 0 : account.id}' doesn't exist, activeAccountId '${activeAccountId}' accountName '${accountName}'`);
|
|
579
|
+
const blockedAddresses = Object.assign({}, account.blockedAddresses);
|
|
580
|
+
if (!blockedAddresses[address]) {
|
|
581
|
+
throw Error(`account '${account.id}' already unblocked address '${address}'`);
|
|
582
|
+
}
|
|
583
|
+
delete blockedAddresses[address];
|
|
584
|
+
const updatedAccount = Object.assign(Object.assign({}, account), { blockedAddresses });
|
|
585
|
+
// update account in db async for instant feedback speed
|
|
586
|
+
accountsDatabase.addAccount(updatedAccount);
|
|
587
|
+
const updatedAccounts = Object.assign(Object.assign({}, accounts), { [updatedAccount.id]: updatedAccount });
|
|
588
|
+
log("accountsActions.unblockAddress", { account: updatedAccount, accountName, address });
|
|
589
|
+
accountsStore.setState({ accounts: updatedAccounts });
|
|
590
|
+
});
|
|
591
|
+
export const blockCid = (cid, accountName) => __awaiter(void 0, void 0, void 0, function* () {
|
|
592
|
+
const { accounts, accountNamesToAccountIds, activeAccountId } = accountsStore.getState();
|
|
593
|
+
assert(cid && typeof cid === "string", `accountsActions.blockCid invalid cid '${cid}'`);
|
|
594
|
+
assert(accounts && accountNamesToAccountIds && activeAccountId, `can't use accountsStore.accountActions before initialized`);
|
|
595
|
+
let account = accounts[activeAccountId];
|
|
596
|
+
if (accountName) {
|
|
597
|
+
const accountId = accountNamesToAccountIds[accountName];
|
|
598
|
+
account = accounts[accountId];
|
|
599
|
+
}
|
|
600
|
+
assert(account === null || account === void 0 ? void 0 : account.id, `accountsActions.blockCid account.id '${account === null || account === void 0 ? void 0 : account.id}' doesn't exist, activeAccountId '${activeAccountId}' accountName '${accountName}'`);
|
|
601
|
+
const blockedCids = Object.assign({}, account.blockedCids);
|
|
602
|
+
if (blockedCids[cid] === true) {
|
|
603
|
+
throw Error(`account '${account.id}' already blocked cid '${cid}'`);
|
|
604
|
+
}
|
|
605
|
+
blockedCids[cid] = true;
|
|
606
|
+
const updatedAccount = Object.assign(Object.assign({}, account), { blockedCids });
|
|
607
|
+
// update account in db async for instant feedback speed
|
|
608
|
+
accountsDatabase.addAccount(updatedAccount);
|
|
609
|
+
const updatedAccounts = Object.assign(Object.assign({}, accounts), { [updatedAccount.id]: updatedAccount });
|
|
610
|
+
log("accountsActions.blockCid", { account: updatedAccount, accountName, cid });
|
|
611
|
+
accountsStore.setState({ accounts: updatedAccounts });
|
|
612
|
+
});
|
|
613
|
+
export const unblockCid = (cid, accountName) => __awaiter(void 0, void 0, void 0, function* () {
|
|
614
|
+
const { accounts, accountNamesToAccountIds, activeAccountId } = accountsStore.getState();
|
|
615
|
+
assert(cid && typeof cid === "string", `accountsActions.unblockCid invalid cid '${cid}'`);
|
|
616
|
+
assert(accounts && accountNamesToAccountIds && activeAccountId, `can't use accountsStore.accountActions before initialized`);
|
|
617
|
+
let account = accounts[activeAccountId];
|
|
618
|
+
if (accountName) {
|
|
619
|
+
const accountId = accountNamesToAccountIds[accountName];
|
|
620
|
+
account = accounts[accountId];
|
|
621
|
+
}
|
|
622
|
+
assert(account === null || account === void 0 ? void 0 : account.id, `accountsActions.unblockCid account.id '${account === null || account === void 0 ? void 0 : account.id}' doesn't exist, activeAccountId '${activeAccountId}' accountName '${accountName}'`);
|
|
623
|
+
const blockedCids = Object.assign({}, account.blockedCids);
|
|
624
|
+
if (!blockedCids[cid]) {
|
|
625
|
+
throw Error(`account '${account.id}' already unblocked cid '${cid}'`);
|
|
626
|
+
}
|
|
627
|
+
delete blockedCids[cid];
|
|
628
|
+
const updatedAccount = Object.assign(Object.assign({}, account), { blockedCids });
|
|
629
|
+
// update account in db async for instant feedback speed
|
|
630
|
+
accountsDatabase.addAccount(updatedAccount);
|
|
631
|
+
const updatedAccounts = Object.assign(Object.assign({}, accounts), { [updatedAccount.id]: updatedAccount });
|
|
632
|
+
log("accountsActions.unblockCid", { account: updatedAccount, accountName, cid });
|
|
633
|
+
accountsStore.setState({ accounts: updatedAccounts });
|
|
634
|
+
});
|
|
635
|
+
export const publishComment = (publishCommentOptions, accountName) => __awaiter(void 0, void 0, void 0, function* () {
|
|
636
|
+
var _a, _b, _c;
|
|
637
|
+
const { accounts, accountsComments, accountNamesToAccountIds, activeAccountId } = accountsStore.getState();
|
|
638
|
+
assert(accounts && accountNamesToAccountIds && activeAccountId, `can't use accountsStore.accountActions before initialized`);
|
|
639
|
+
let account = accounts[activeAccountId];
|
|
640
|
+
if (accountName) {
|
|
641
|
+
const accountId = accountNamesToAccountIds[accountName];
|
|
642
|
+
account = accounts[accountId];
|
|
643
|
+
}
|
|
644
|
+
validator.validateAccountsActionsPublishCommentArguments({
|
|
645
|
+
publishCommentOptions,
|
|
646
|
+
accountName,
|
|
647
|
+
account,
|
|
648
|
+
});
|
|
649
|
+
// find author.previousCommentCid if any
|
|
650
|
+
const accountCommentsWithCids = accountsComments[account.id]
|
|
651
|
+
.filter((comment) => comment.cid)
|
|
652
|
+
// author can change his address, his previousCommentCid becomes invalid
|
|
653
|
+
.filter((comment) => { var _a, _b; return ((_a = comment.author) === null || _a === void 0 ? void 0 : _a.address) === ((_b = account.author) === null || _b === void 0 ? void 0 : _b.address); });
|
|
654
|
+
const previousCommentCid = (_a = accountCommentsWithCids[accountCommentsWithCids.length - 1]) === null || _a === void 0 ? void 0 : _a.cid;
|
|
655
|
+
const author = Object.assign({}, account.author);
|
|
656
|
+
if (previousCommentCid) {
|
|
657
|
+
author.previousCommentCid = previousCommentCid;
|
|
658
|
+
}
|
|
659
|
+
let createCommentOptions = normalizePublicationOptionsForPkc(account.pkc, Object.assign({ timestamp: Math.floor(Date.now() / 1000), author, signer: account.signer }, publishCommentOptions));
|
|
660
|
+
delete createCommentOptions.onChallenge;
|
|
661
|
+
delete createCommentOptions.onChallengeVerification;
|
|
662
|
+
delete createCommentOptions.onError;
|
|
663
|
+
delete createCommentOptions.onPublishingStateChange;
|
|
664
|
+
delete createCommentOptions._onPendingCommentIndex;
|
|
665
|
+
const storedCreateCommentOptions = normalizePublicationOptionsForStore(createCommentOptions);
|
|
666
|
+
// make sure the options dont throw
|
|
667
|
+
yield account.pkc.createComment(createCommentOptions);
|
|
668
|
+
// try to get comment depth needed for custom depth flat account replies
|
|
669
|
+
const depth = getAccountCommentDepth(createCommentOptions);
|
|
670
|
+
// set fetching link dimensions state
|
|
671
|
+
let fetchingLinkDimensionsStates;
|
|
672
|
+
if (publishCommentOptions.link) {
|
|
673
|
+
(_b = publishCommentOptions.onPublishingStateChange) === null || _b === void 0 ? void 0 : _b.call(publishCommentOptions, "fetching-link-dimensions");
|
|
674
|
+
fetchingLinkDimensionsStates = {
|
|
675
|
+
state: "publishing",
|
|
676
|
+
publishingState: "fetching-link-dimensions",
|
|
677
|
+
};
|
|
678
|
+
}
|
|
679
|
+
// save comment to db
|
|
680
|
+
let accountCommentIndex = accountsComments[account.id].length;
|
|
681
|
+
const publishSessionId = createPublishSession(account.id, accountCommentIndex);
|
|
682
|
+
let savedOnce = false;
|
|
683
|
+
const saveCreatedAccountComment = (accountComment) => __awaiter(void 0, void 0, void 0, function* () {
|
|
684
|
+
var _a;
|
|
685
|
+
if (isPublishSessionAbandoned(publishSessionId)) {
|
|
686
|
+
return;
|
|
687
|
+
}
|
|
688
|
+
const isUpdate = savedOnce;
|
|
689
|
+
const session = getPublishSession(publishSessionId);
|
|
690
|
+
const currentIndex = (_a = session === null || session === void 0 ? void 0 : session.currentIndex) !== null && _a !== void 0 ? _a : accountCommentIndex;
|
|
691
|
+
const persistedAccountComment = addShortAddressesToAccountComment(sanitizeStoredAccountComment(accountComment));
|
|
692
|
+
const liveAccountComment = addShortAddressesToAccountComment(sanitizeAccountCommentForState(accountComment));
|
|
693
|
+
const liveAccountComments = accountsStore.getState().accountsComments[account.id] || [];
|
|
694
|
+
if (isUpdate && !liveAccountComments[currentIndex]) {
|
|
695
|
+
return;
|
|
696
|
+
}
|
|
697
|
+
yield accountsDatabase.addAccountComment(account.id, persistedAccountComment, isUpdate ? currentIndex : undefined);
|
|
698
|
+
savedOnce = true;
|
|
699
|
+
accountsStore.setState(({ accountsComments, accountsCommentsIndexes }) => {
|
|
700
|
+
const accountComments = [...accountsComments[account.id]];
|
|
701
|
+
if (isUpdate && !accountComments[currentIndex]) {
|
|
702
|
+
return {};
|
|
703
|
+
}
|
|
704
|
+
accountComments[currentIndex] = Object.assign(Object.assign({}, liveAccountComment), { index: currentIndex, accountId: account.id });
|
|
705
|
+
return {
|
|
706
|
+
accountsComments: Object.assign(Object.assign({}, accountsComments), { [account.id]: accountComments }),
|
|
707
|
+
accountsCommentsIndexes: Object.assign(Object.assign({}, accountsCommentsIndexes), { [account.id]: getAccountCommentsIndex(accountComments) }),
|
|
708
|
+
};
|
|
709
|
+
});
|
|
710
|
+
});
|
|
711
|
+
let createdAccountComment = Object.assign(Object.assign({}, storedCreateCommentOptions), { depth, index: accountCommentIndex, accountId: account.id });
|
|
712
|
+
createdAccountComment = addShortAddressesToAccountComment(sanitizeAccountCommentForState(createdAccountComment));
|
|
713
|
+
yield saveCreatedAccountComment(createdAccountComment);
|
|
714
|
+
(_c = publishCommentOptions._onPendingCommentIndex) === null || _c === void 0 ? void 0 : _c.call(publishCommentOptions, accountCommentIndex, createdAccountComment);
|
|
715
|
+
let comment;
|
|
716
|
+
(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
717
|
+
// fetch comment.link dimensions
|
|
718
|
+
if (publishCommentOptions.link) {
|
|
719
|
+
const commentLinkDimensions = yield fetchCommentLinkDimensions(publishCommentOptions.link);
|
|
720
|
+
createCommentOptions = Object.assign(Object.assign({}, createCommentOptions), commentLinkDimensions);
|
|
721
|
+
// save dimensions to db
|
|
722
|
+
createdAccountComment = Object.assign(Object.assign({}, createdAccountComment), commentLinkDimensions);
|
|
723
|
+
yield saveCreatedAccountComment(createdAccountComment);
|
|
724
|
+
}
|
|
725
|
+
if (isPublishSessionAbandoned(publishSessionId)) {
|
|
726
|
+
return;
|
|
727
|
+
}
|
|
728
|
+
comment = backfillPublicationCommunityAddress(yield account.pkc.createComment(createCommentOptions), createCommentOptions);
|
|
729
|
+
syncCommentClientsSnapshot(publishSessionId, account.id, comment);
|
|
730
|
+
publishAndRetryFailedChallengeVerification();
|
|
731
|
+
log("accountsActions.publishComment", { createCommentOptions });
|
|
732
|
+
}))();
|
|
733
|
+
let lastChallenge;
|
|
734
|
+
let lastReportedPublishError;
|
|
735
|
+
const normalizePublishError = (error) => error instanceof Error ? error : new Error(String(error));
|
|
736
|
+
const getActiveSessionForComment = (activeComment) => {
|
|
737
|
+
const session = getPublishSession(publishSessionId);
|
|
738
|
+
if (!session ||
|
|
739
|
+
isPublishSessionAbandoned(publishSessionId) ||
|
|
740
|
+
session.comment !== activeComment) {
|
|
741
|
+
return undefined;
|
|
742
|
+
}
|
|
743
|
+
return session;
|
|
744
|
+
};
|
|
745
|
+
const queueCleanupFailedPublishSession = (activeComment) => {
|
|
746
|
+
if (!getActiveSessionForComment(activeComment))
|
|
747
|
+
return;
|
|
748
|
+
queueMicrotask(() => {
|
|
749
|
+
if (getActiveSessionForComment(activeComment)) {
|
|
750
|
+
cleanupPublishSessionOnTerminal(publishSessionId);
|
|
751
|
+
}
|
|
752
|
+
});
|
|
753
|
+
};
|
|
754
|
+
const recordPublishCommentError = (rawError, activeComment) => {
|
|
755
|
+
const error = normalizePublishError(rawError);
|
|
756
|
+
if (lastReportedPublishError === error) {
|
|
757
|
+
return error;
|
|
758
|
+
}
|
|
759
|
+
lastReportedPublishError = error;
|
|
760
|
+
const session = getActiveSessionForComment(activeComment);
|
|
761
|
+
if (!session)
|
|
762
|
+
return error;
|
|
763
|
+
const currentIndex = session.currentIndex;
|
|
764
|
+
accountsStore.setState(({ accountsComments }) => maybeUpdateAccountComment(accountsComments, account.id, currentIndex, (ac, acc) => {
|
|
765
|
+
const previousErrors = Array.isArray(acc.errors) ? acc.errors : [];
|
|
766
|
+
const errors = previousErrors[previousErrors.length - 1] === error
|
|
767
|
+
? previousErrors
|
|
768
|
+
: [...previousErrors, error];
|
|
769
|
+
ac[currentIndex] = Object.assign(Object.assign({}, acc), { errors, error });
|
|
770
|
+
}));
|
|
771
|
+
return error;
|
|
772
|
+
};
|
|
773
|
+
const reportActivePublishCommentError = (rawError, activeComment) => {
|
|
774
|
+
var _a;
|
|
775
|
+
if (!getActiveSessionForComment(activeComment))
|
|
776
|
+
return;
|
|
777
|
+
const error = recordPublishCommentError(rawError, activeComment);
|
|
778
|
+
queueCleanupFailedPublishSession(activeComment);
|
|
779
|
+
(_a = publishCommentOptions.onError) === null || _a === void 0 ? void 0 : _a.call(publishCommentOptions, error, activeComment);
|
|
780
|
+
};
|
|
781
|
+
function publishAndRetryFailedChallengeVerification() {
|
|
782
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
783
|
+
if (isPublishSessionAbandoned(publishSessionId)) {
|
|
784
|
+
return;
|
|
785
|
+
}
|
|
786
|
+
const activeComment = comment;
|
|
787
|
+
updatePublishSessionComment(publishSessionId, activeComment);
|
|
788
|
+
activeComment.once("challenge", (challenge) => __awaiter(this, void 0, void 0, function* () {
|
|
789
|
+
lastChallenge = challenge;
|
|
790
|
+
publishCommentOptions.onChallenge(challenge, activeComment);
|
|
791
|
+
}));
|
|
792
|
+
activeComment.once("challengeverification", (challengeVerification) => __awaiter(this, void 0, void 0, function* () {
|
|
793
|
+
var _a, _b;
|
|
794
|
+
publishCommentOptions.onChallengeVerification(challengeVerification, activeComment);
|
|
795
|
+
if (!challengeVerification.challengeSuccess && lastChallenge) {
|
|
796
|
+
// publish again automatically on fail
|
|
797
|
+
const timestamp = Math.floor(Date.now() / 1000);
|
|
798
|
+
createCommentOptions = Object.assign(Object.assign({}, createCommentOptions), { timestamp });
|
|
799
|
+
createdAccountComment = Object.assign(Object.assign({}, createdAccountComment), { timestamp });
|
|
800
|
+
updatePublishSessionComment(publishSessionId, undefined);
|
|
801
|
+
yield saveCreatedAccountComment(createdAccountComment);
|
|
802
|
+
if (isPublishSessionAbandoned(publishSessionId)) {
|
|
803
|
+
return;
|
|
804
|
+
}
|
|
805
|
+
comment = backfillPublicationCommunityAddress(yield account.pkc.createComment(createCommentOptions), createCommentOptions);
|
|
806
|
+
syncCommentClientsSnapshot(publishSessionId, account.id, comment);
|
|
807
|
+
lastChallenge = undefined;
|
|
808
|
+
publishAndRetryFailedChallengeVerification();
|
|
809
|
+
}
|
|
810
|
+
else {
|
|
811
|
+
// the challengeverification message of a comment publication should in theory send back the CID
|
|
812
|
+
// of the published comment which is needed to resolve it for replies, upvotes, etc
|
|
813
|
+
const session = getPublishSession(publishSessionId);
|
|
814
|
+
const currentIndex = (_a = session === null || session === void 0 ? void 0 : session.currentIndex) !== null && _a !== void 0 ? _a : accountCommentIndex;
|
|
815
|
+
if (!session || isPublishSessionAbandoned(publishSessionId))
|
|
816
|
+
return;
|
|
817
|
+
queueMicrotask(() => cleanupPublishSessionOnTerminal(publishSessionId));
|
|
818
|
+
if ((_b = challengeVerification === null || challengeVerification === void 0 ? void 0 : challengeVerification.commentUpdate) === null || _b === void 0 ? void 0 : _b.cid) {
|
|
819
|
+
const persistedCommentWithCid = addShortAddressesToAccountComment(sanitizeStoredAccountComment(normalizePublicationOptionsForStore(comment)));
|
|
820
|
+
const liveCommentWithCid = addShortAddressesToAccountComment(sanitizeAccountCommentForState(normalizePublicationOptionsForStore(comment)));
|
|
821
|
+
delete persistedCommentWithCid.clients;
|
|
822
|
+
delete persistedCommentWithCid.publishingState;
|
|
823
|
+
delete persistedCommentWithCid.error;
|
|
824
|
+
delete persistedCommentWithCid.errors;
|
|
825
|
+
delete liveCommentWithCid.clients;
|
|
826
|
+
delete liveCommentWithCid.publishingState;
|
|
827
|
+
delete liveCommentWithCid.error;
|
|
828
|
+
delete liveCommentWithCid.errors;
|
|
829
|
+
yield accountsDatabase.addAccountComment(account.id, persistedCommentWithCid, currentIndex);
|
|
830
|
+
accountsStore.setState(({ accountsComments, accountsCommentsIndexes, commentCidsToAccountsComments }) => {
|
|
831
|
+
var _a;
|
|
832
|
+
const updatedAccountComments = [...accountsComments[account.id]];
|
|
833
|
+
const updatedAccountComment = Object.assign(Object.assign({}, liveCommentWithCid), { index: currentIndex, accountId: account.id });
|
|
834
|
+
updatedAccountComments[currentIndex] = updatedAccountComment;
|
|
835
|
+
return {
|
|
836
|
+
accountsComments: Object.assign(Object.assign({}, accountsComments), { [account.id]: updatedAccountComments }),
|
|
837
|
+
accountsCommentsIndexes: Object.assign(Object.assign({}, accountsCommentsIndexes), { [account.id]: getAccountCommentsIndex(updatedAccountComments) }),
|
|
838
|
+
commentCidsToAccountsComments: Object.assign(Object.assign({}, commentCidsToAccountsComments), { [(_a = challengeVerification === null || challengeVerification === void 0 ? void 0 : challengeVerification.commentUpdate) === null || _a === void 0 ? void 0 : _a.cid]: {
|
|
839
|
+
accountId: account.id,
|
|
840
|
+
accountCommentIndex: currentIndex,
|
|
841
|
+
} }),
|
|
842
|
+
};
|
|
843
|
+
});
|
|
844
|
+
// clone the comment or it bugs publishing callbacks
|
|
845
|
+
const updatingComment = yield account.pkc.createComment(normalizePublicationOptionsForPkc(account.pkc, Object.assign({}, comment)));
|
|
846
|
+
accountsActionsInternal
|
|
847
|
+
.startUpdatingAccountCommentOnCommentUpdateEvents(updatingComment, account, currentIndex)
|
|
848
|
+
.catch((error) => log.error("accountsActions.publishComment startUpdatingAccountCommentOnCommentUpdateEvents error", { comment, account, accountCommentIndex, error }));
|
|
849
|
+
}
|
|
850
|
+
}
|
|
851
|
+
}));
|
|
852
|
+
activeComment.on("error", (error) => {
|
|
853
|
+
reportActivePublishCommentError(error, activeComment);
|
|
854
|
+
});
|
|
855
|
+
activeComment.on("statechange", (state) => {
|
|
856
|
+
const session = getActiveSessionForComment(activeComment);
|
|
857
|
+
if (!session)
|
|
858
|
+
return;
|
|
859
|
+
const currentIndex = session.currentIndex;
|
|
860
|
+
let hasTerminalFailedState = false;
|
|
861
|
+
accountsStore.setState(({ accountsComments }) => maybeUpdateAccountComment(accountsComments, account.id, currentIndex, (ac, acc) => {
|
|
862
|
+
const nextAccountComment = Object.assign(Object.assign({}, acc), { state });
|
|
863
|
+
ac[currentIndex] = nextAccountComment;
|
|
864
|
+
hasTerminalFailedState =
|
|
865
|
+
nextAccountComment.state === "stopped" &&
|
|
866
|
+
nextAccountComment.publishingState === "failed";
|
|
867
|
+
}));
|
|
868
|
+
if (hasTerminalFailedState) {
|
|
869
|
+
queueCleanupFailedPublishSession(activeComment);
|
|
870
|
+
}
|
|
871
|
+
});
|
|
872
|
+
activeComment.on("publishingstatechange", (publishingState) => __awaiter(this, void 0, void 0, function* () {
|
|
873
|
+
var _a;
|
|
874
|
+
const session = getActiveSessionForComment(activeComment);
|
|
875
|
+
if (!session)
|
|
876
|
+
return;
|
|
877
|
+
const currentIndex = session.currentIndex;
|
|
878
|
+
let hasTerminalFailedState = false;
|
|
879
|
+
accountsStore.setState(({ accountsComments }) => maybeUpdateAccountComment(accountsComments, account.id, currentIndex, (ac, acc) => {
|
|
880
|
+
const nextAccountComment = Object.assign(Object.assign({}, acc), { publishingState });
|
|
881
|
+
ac[currentIndex] = nextAccountComment;
|
|
882
|
+
hasTerminalFailedState =
|
|
883
|
+
nextAccountComment.state === "stopped" &&
|
|
884
|
+
nextAccountComment.publishingState === "failed";
|
|
885
|
+
}));
|
|
886
|
+
if (hasTerminalFailedState) {
|
|
887
|
+
queueCleanupFailedPublishSession(activeComment);
|
|
888
|
+
}
|
|
889
|
+
(_a = publishCommentOptions.onPublishingStateChange) === null || _a === void 0 ? void 0 : _a.call(publishCommentOptions, publishingState);
|
|
890
|
+
}));
|
|
891
|
+
// set clients on account comment so the frontend can display it, dont persist in db because a reload cancels publishing
|
|
892
|
+
utils.clientsOnStateChange(activeComment.clients, (clientState, clientType, clientUrl, chainTicker) => {
|
|
893
|
+
const session = getActiveSessionForComment(activeComment);
|
|
894
|
+
if (!session)
|
|
895
|
+
return;
|
|
896
|
+
const currentIndex = session.currentIndex;
|
|
897
|
+
accountsStore.setState(({ accountsComments }) => maybeUpdateAccountComment(accountsComments, account.id, currentIndex, (ac, acc) => {
|
|
898
|
+
const clients = getClientsSnapshotForState(activeComment.clients) || {};
|
|
899
|
+
const client = { state: clientState };
|
|
900
|
+
if (chainTicker) {
|
|
901
|
+
const chainProviders = Object.assign(Object.assign({}, clients[clientType][chainTicker]), { [clientUrl]: client });
|
|
902
|
+
clients[clientType] = Object.assign(Object.assign({}, clients[clientType]), { [chainTicker]: chainProviders });
|
|
903
|
+
}
|
|
904
|
+
else {
|
|
905
|
+
clients[clientType] = Object.assign(Object.assign({}, clients[clientType]), { [clientUrl]: client });
|
|
906
|
+
}
|
|
907
|
+
ac[currentIndex] = Object.assign(Object.assign({}, acc), { clients });
|
|
908
|
+
}));
|
|
909
|
+
});
|
|
910
|
+
listeners.push(activeComment);
|
|
911
|
+
try {
|
|
912
|
+
// publish will resolve after the challenge request
|
|
913
|
+
// if it fails before, like failing to resolve ENS, we can emit the error
|
|
914
|
+
yield activeComment.publish();
|
|
915
|
+
}
|
|
916
|
+
catch (error) {
|
|
917
|
+
reportActivePublishCommentError(error, activeComment);
|
|
918
|
+
}
|
|
919
|
+
});
|
|
920
|
+
}
|
|
921
|
+
return createdAccountComment;
|
|
922
|
+
});
|
|
923
|
+
export const deleteComment = (commentCidOrAccountCommentIndex, accountName) => __awaiter(void 0, void 0, void 0, function* () {
|
|
924
|
+
const { accounts, accountsComments, accountNamesToAccountIds, activeAccountId, commentCidsToAccountsComments, } = accountsStore.getState();
|
|
925
|
+
assert(accounts && accountNamesToAccountIds && activeAccountId, `can't use accountsStore.accountActions before initialized`);
|
|
926
|
+
let account = accounts[activeAccountId];
|
|
927
|
+
if (accountName) {
|
|
928
|
+
const accountId = accountNamesToAccountIds[accountName];
|
|
929
|
+
account = accounts[accountId];
|
|
930
|
+
}
|
|
931
|
+
assert(account === null || account === void 0 ? void 0 : account.id, `accountsActions.deleteComment account.id '${account === null || account === void 0 ? void 0 : account.id}' doesn't exist`);
|
|
932
|
+
const accountComments = accountsComments[account.id] || [];
|
|
933
|
+
assert(accountComments.length > 0, `accountsActions.deleteComment no comments for account`);
|
|
934
|
+
let accountCommentIndex;
|
|
935
|
+
if (typeof commentCidOrAccountCommentIndex === "number") {
|
|
936
|
+
accountCommentIndex = commentCidOrAccountCommentIndex;
|
|
937
|
+
}
|
|
938
|
+
else {
|
|
939
|
+
const mapping = commentCidsToAccountsComments[commentCidOrAccountCommentIndex];
|
|
940
|
+
assert(mapping && mapping.accountId === account.id, `accountsActions.deleteComment cid '${commentCidOrAccountCommentIndex}' not found for account`);
|
|
941
|
+
accountCommentIndex = mapping.accountCommentIndex;
|
|
942
|
+
}
|
|
943
|
+
assert(accountCommentIndex >= 0 && accountCommentIndex < accountComments.length, `accountsActions.deleteComment index '${accountCommentIndex}' out of range`);
|
|
944
|
+
abandonAndStopPublishSession(account.id, accountCommentIndex);
|
|
945
|
+
shiftPublishSessionIndicesAfterDelete(account.id, accountCommentIndex);
|
|
946
|
+
const spliced = [...accountComments];
|
|
947
|
+
spliced.splice(accountCommentIndex, 1);
|
|
948
|
+
const reindexed = spliced.map((c, i) => (Object.assign(Object.assign({}, c), { index: i, accountId: account.id })));
|
|
949
|
+
const newAccountsComments = Object.assign(Object.assign({}, accountsComments), { [account.id]: reindexed });
|
|
950
|
+
const newCommentCidsToAccountsComments = getCommentCidsToAccountsComments(newAccountsComments);
|
|
951
|
+
accountsStore.setState(({ accountsCommentsIndexes }) => ({
|
|
952
|
+
accountsComments: newAccountsComments,
|
|
953
|
+
accountsCommentsIndexes: Object.assign(Object.assign({}, accountsCommentsIndexes), { [account.id]: getAccountCommentsIndex(reindexed) }),
|
|
954
|
+
commentCidsToAccountsComments: newCommentCidsToAccountsComments,
|
|
955
|
+
}));
|
|
956
|
+
yield accountsDatabase.deleteAccountComment(account.id, accountCommentIndex);
|
|
957
|
+
log("accountsActions.deleteComment", { accountId: account.id, accountCommentIndex });
|
|
958
|
+
});
|
|
959
|
+
export const publishVote = (publishVoteOptions, accountName) => __awaiter(void 0, void 0, void 0, function* () {
|
|
960
|
+
const { accounts, accountNamesToAccountIds, activeAccountId } = accountsStore.getState();
|
|
961
|
+
assert(accounts && accountNamesToAccountIds && activeAccountId, `can't use accountsStore.accountActions before initialized`);
|
|
962
|
+
let account = accounts[activeAccountId];
|
|
963
|
+
if (accountName) {
|
|
964
|
+
const accountId = accountNamesToAccountIds[accountName];
|
|
965
|
+
account = accounts[accountId];
|
|
966
|
+
}
|
|
967
|
+
validator.validateAccountsActionsPublishVoteArguments({
|
|
968
|
+
publishVoteOptions,
|
|
969
|
+
accountName,
|
|
970
|
+
account,
|
|
971
|
+
});
|
|
972
|
+
let createVoteOptions = normalizePublicationOptionsForPkc(account.pkc, Object.assign({ timestamp: Math.floor(Date.now() / 1000), author: account.author, signer: account.signer }, publishVoteOptions));
|
|
973
|
+
delete createVoteOptions.onChallenge;
|
|
974
|
+
delete createVoteOptions.onChallengeVerification;
|
|
975
|
+
delete createVoteOptions.onError;
|
|
976
|
+
delete createVoteOptions.onPublishingStateChange;
|
|
977
|
+
const storedCreateVoteOptions = normalizePublicationOptionsForStore(createVoteOptions);
|
|
978
|
+
let vote = backfillPublicationCommunityAddress(yield account.pkc.createVote(createVoteOptions), createVoteOptions);
|
|
979
|
+
let lastChallenge;
|
|
980
|
+
const publishAndRetryFailedChallengeVerification = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
981
|
+
var _a;
|
|
982
|
+
vote.once("challenge", (challenge) => __awaiter(void 0, void 0, void 0, function* () {
|
|
983
|
+
lastChallenge = challenge;
|
|
984
|
+
publishVoteOptions.onChallenge(challenge, vote);
|
|
985
|
+
}));
|
|
986
|
+
vote.once("challengeverification", (challengeVerification) => __awaiter(void 0, void 0, void 0, function* () {
|
|
987
|
+
publishVoteOptions.onChallengeVerification(challengeVerification, vote);
|
|
988
|
+
if (!challengeVerification.challengeSuccess && lastChallenge) {
|
|
989
|
+
// publish again automatically on fail
|
|
990
|
+
createVoteOptions = Object.assign(Object.assign({}, createVoteOptions), { timestamp: Math.floor(Date.now() / 1000) });
|
|
991
|
+
vote = backfillPublicationCommunityAddress(yield account.pkc.createVote(createVoteOptions), createVoteOptions);
|
|
992
|
+
lastChallenge = undefined;
|
|
993
|
+
publishAndRetryFailedChallengeVerification();
|
|
994
|
+
}
|
|
995
|
+
}));
|
|
996
|
+
vote.on("error", (error) => { var _a; return (_a = publishVoteOptions.onError) === null || _a === void 0 ? void 0 : _a.call(publishVoteOptions, error, vote); });
|
|
997
|
+
// TODO: add publishingState to account votes
|
|
998
|
+
vote.on("publishingstatechange", (publishingState) => { var _a; return (_a = publishVoteOptions.onPublishingStateChange) === null || _a === void 0 ? void 0 : _a.call(publishVoteOptions, publishingState); });
|
|
999
|
+
listeners.push(vote);
|
|
1000
|
+
try {
|
|
1001
|
+
// publish will resolve after the challenge request
|
|
1002
|
+
// if it fails before, like failing to resolve ENS, we can emit the error
|
|
1003
|
+
yield vote.publish();
|
|
1004
|
+
}
|
|
1005
|
+
catch (error) {
|
|
1006
|
+
(_a = publishVoteOptions.onError) === null || _a === void 0 ? void 0 : _a.call(publishVoteOptions, error, vote);
|
|
1007
|
+
}
|
|
1008
|
+
});
|
|
1009
|
+
publishAndRetryFailedChallengeVerification();
|
|
1010
|
+
yield accountsDatabase.addAccountVote(account.id, storedCreateVoteOptions);
|
|
1011
|
+
log("accountsActions.publishVote", { createVoteOptions });
|
|
1012
|
+
accountsStore.setState(({ accountsVotes }) => ({
|
|
1013
|
+
accountsVotes: Object.assign(Object.assign({}, accountsVotes), { [account.id]: Object.assign(Object.assign({}, accountsVotes[account.id]), { [storedCreateVoteOptions.commentCid]: Object.assign(Object.assign({}, storedCreateVoteOptions), { signer: undefined, author: undefined }) }) }),
|
|
1014
|
+
}));
|
|
1015
|
+
});
|
|
1016
|
+
export const publishCommentEdit = (publishCommentEditOptions, accountName) => __awaiter(void 0, void 0, void 0, function* () {
|
|
1017
|
+
const { accounts, accountNamesToAccountIds, activeAccountId } = accountsStore.getState();
|
|
1018
|
+
assert(accounts && accountNamesToAccountIds && activeAccountId, `can't use accountsStore.accountActions before initialized`);
|
|
1019
|
+
let account = accounts[activeAccountId];
|
|
1020
|
+
if (accountName) {
|
|
1021
|
+
const accountId = accountNamesToAccountIds[accountName];
|
|
1022
|
+
account = accounts[accountId];
|
|
1023
|
+
}
|
|
1024
|
+
validator.validateAccountsActionsPublishCommentEditArguments({
|
|
1025
|
+
publishCommentEditOptions,
|
|
1026
|
+
accountName,
|
|
1027
|
+
account,
|
|
1028
|
+
});
|
|
1029
|
+
let createCommentEditOptions = normalizePublicationOptionsForPkc(account.pkc, Object.assign({ timestamp: Math.floor(Date.now() / 1000), author: account.author, signer: account.signer }, publishCommentEditOptions));
|
|
1030
|
+
delete createCommentEditOptions.onChallenge;
|
|
1031
|
+
delete createCommentEditOptions.onChallengeVerification;
|
|
1032
|
+
delete createCommentEditOptions.onError;
|
|
1033
|
+
delete createCommentEditOptions.onPublishingStateChange;
|
|
1034
|
+
const storedCreateCommentEditOptions = Object.assign(Object.assign({}, normalizePublicationOptionsForStore(createCommentEditOptions)), { clientId: uuid() });
|
|
1035
|
+
const storedCommentEdit = sanitizeStoredAccountEdit(storedCreateCommentEditOptions);
|
|
1036
|
+
let commentEdit = backfillPublicationCommunityAddress(yield account.pkc.createCommentEdit(createCommentEditOptions), createCommentEditOptions);
|
|
1037
|
+
let lastChallenge;
|
|
1038
|
+
let challengeSucceeded = false;
|
|
1039
|
+
let rollbackPendingEditPromise;
|
|
1040
|
+
const rollbackStoredCommentEdit = () => {
|
|
1041
|
+
if (!rollbackPendingEditPromise && !challengeSucceeded) {
|
|
1042
|
+
rollbackPendingEditPromise = Promise.all([
|
|
1043
|
+
accountsDatabase.deleteAccountEdit(account.id, storedCommentEdit),
|
|
1044
|
+
Promise.resolve(accountsStore.setState(({ accountsEdits, accountsEditsSummaries }) => {
|
|
1045
|
+
const nextState = removeStoredAccountEditSummaryFromState(accountsEditsSummaries, accountsEdits, account.id, storedCommentEdit);
|
|
1046
|
+
Object.assign(nextState, removeStoredAccountEditFromState(accountsEdits, account.id, storedCommentEdit));
|
|
1047
|
+
return nextState;
|
|
1048
|
+
})),
|
|
1049
|
+
]).then(() => { });
|
|
1050
|
+
}
|
|
1051
|
+
return rollbackPendingEditPromise;
|
|
1052
|
+
};
|
|
1053
|
+
yield accountsDatabase.addAccountEdit(account.id, storedCreateCommentEditOptions);
|
|
1054
|
+
log("accountsActions.publishCommentEdit", { createCommentEditOptions });
|
|
1055
|
+
accountsStore.setState(({ accountsEdits, accountsEditsSummaries }) => {
|
|
1056
|
+
const nextState = addStoredAccountEditSummaryToState(accountsEditsSummaries, account.id, storedCommentEdit);
|
|
1057
|
+
Object.assign(nextState, addStoredAccountEditToState(accountsEdits, account.id, storedCommentEdit));
|
|
1058
|
+
return nextState;
|
|
1059
|
+
});
|
|
1060
|
+
const publishAndRetryFailedChallengeVerification = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
1061
|
+
var _a;
|
|
1062
|
+
commentEdit.once("challenge", (challenge) => __awaiter(void 0, void 0, void 0, function* () {
|
|
1063
|
+
lastChallenge = challenge;
|
|
1064
|
+
publishCommentEditOptions.onChallenge(challenge, commentEdit);
|
|
1065
|
+
}));
|
|
1066
|
+
commentEdit.once("challengeverification", (challengeVerification) => __awaiter(void 0, void 0, void 0, function* () {
|
|
1067
|
+
publishCommentEditOptions.onChallengeVerification(challengeVerification, commentEdit);
|
|
1068
|
+
if (challengeVerification.challengeSuccess) {
|
|
1069
|
+
challengeSucceeded = true;
|
|
1070
|
+
}
|
|
1071
|
+
if (hasTerminalChallengeVerificationError(challengeVerification)) {
|
|
1072
|
+
lastChallenge = undefined;
|
|
1073
|
+
yield rollbackStoredCommentEdit();
|
|
1074
|
+
return;
|
|
1075
|
+
}
|
|
1076
|
+
if (!challengeVerification.challengeSuccess && lastChallenge) {
|
|
1077
|
+
// publish again automatically on fail
|
|
1078
|
+
createCommentEditOptions = Object.assign(Object.assign({}, createCommentEditOptions), { timestamp: Math.floor(Date.now() / 1000) });
|
|
1079
|
+
commentEdit = backfillPublicationCommunityAddress(yield account.pkc.createCommentEdit(createCommentEditOptions), createCommentEditOptions);
|
|
1080
|
+
lastChallenge = undefined;
|
|
1081
|
+
publishAndRetryFailedChallengeVerification();
|
|
1082
|
+
}
|
|
1083
|
+
}));
|
|
1084
|
+
commentEdit.on("error", (error) => __awaiter(void 0, void 0, void 0, function* () {
|
|
1085
|
+
var _a;
|
|
1086
|
+
yield rollbackStoredCommentEdit();
|
|
1087
|
+
(_a = publishCommentEditOptions.onError) === null || _a === void 0 ? void 0 : _a.call(publishCommentEditOptions, error, commentEdit);
|
|
1088
|
+
}));
|
|
1089
|
+
// TODO: add publishingState to account edits
|
|
1090
|
+
commentEdit.on("publishingstatechange", (publishingState) => { var _a; return (_a = publishCommentEditOptions.onPublishingStateChange) === null || _a === void 0 ? void 0 : _a.call(publishCommentEditOptions, publishingState); });
|
|
1091
|
+
listeners.push(commentEdit);
|
|
1092
|
+
try {
|
|
1093
|
+
// publish will resolve after the challenge request
|
|
1094
|
+
// if it fails before, like failing to resolve ENS, we can emit the error
|
|
1095
|
+
yield commentEdit.publish();
|
|
1096
|
+
}
|
|
1097
|
+
catch (error) {
|
|
1098
|
+
yield rollbackStoredCommentEdit();
|
|
1099
|
+
(_a = publishCommentEditOptions.onError) === null || _a === void 0 ? void 0 : _a.call(publishCommentEditOptions, error, commentEdit);
|
|
1100
|
+
}
|
|
1101
|
+
});
|
|
1102
|
+
publishAndRetryFailedChallengeVerification();
|
|
1103
|
+
});
|
|
1104
|
+
export const publishCommentModeration = (publishCommentModerationOptions, accountName) => __awaiter(void 0, void 0, void 0, function* () {
|
|
1105
|
+
const { accounts, accountNamesToAccountIds, activeAccountId } = accountsStore.getState();
|
|
1106
|
+
assert(accounts && accountNamesToAccountIds && activeAccountId, `can't use accountsStore.accountActions before initialized`);
|
|
1107
|
+
let account = accounts[activeAccountId];
|
|
1108
|
+
if (accountName) {
|
|
1109
|
+
const accountId = accountNamesToAccountIds[accountName];
|
|
1110
|
+
account = accounts[accountId];
|
|
1111
|
+
}
|
|
1112
|
+
validator.validateAccountsActionsPublishCommentModerationArguments({
|
|
1113
|
+
publishCommentModerationOptions,
|
|
1114
|
+
accountName,
|
|
1115
|
+
account,
|
|
1116
|
+
});
|
|
1117
|
+
let createCommentModerationOptions = normalizePublicationOptionsForPkc(account.pkc, Object.assign({ timestamp: Math.floor(Date.now() / 1000), author: account.author, signer: account.signer }, publishCommentModerationOptions));
|
|
1118
|
+
delete createCommentModerationOptions.onChallenge;
|
|
1119
|
+
delete createCommentModerationOptions.onChallengeVerification;
|
|
1120
|
+
delete createCommentModerationOptions.onError;
|
|
1121
|
+
delete createCommentModerationOptions.onPublishingStateChange;
|
|
1122
|
+
const storedCreateCommentModerationOptions = Object.assign(Object.assign({}, normalizePublicationOptionsForStore(createCommentModerationOptions)), { clientId: uuid() });
|
|
1123
|
+
const storedCommentModeration = sanitizeStoredAccountEdit(storedCreateCommentModerationOptions);
|
|
1124
|
+
let commentModeration = backfillPublicationCommunityAddress(yield account.pkc.createCommentModeration(createCommentModerationOptions), createCommentModerationOptions);
|
|
1125
|
+
let lastChallenge;
|
|
1126
|
+
let challengeSucceeded = false;
|
|
1127
|
+
let storedCommentModerationAdded = false;
|
|
1128
|
+
let rollbackStoredCommentModerationRequested = false;
|
|
1129
|
+
let rollbackPendingEditPromise;
|
|
1130
|
+
const rollbackStoredCommentModeration = () => {
|
|
1131
|
+
rollbackStoredCommentModerationRequested = true;
|
|
1132
|
+
if (!storedCommentModerationAdded) {
|
|
1133
|
+
return Promise.resolve();
|
|
1134
|
+
}
|
|
1135
|
+
if (!rollbackPendingEditPromise && !challengeSucceeded) {
|
|
1136
|
+
rollbackPendingEditPromise = Promise.all([
|
|
1137
|
+
accountsDatabase.deleteAccountEdit(account.id, storedCommentModeration),
|
|
1138
|
+
Promise.resolve(accountsStore.setState(({ accountsEdits, accountsEditsSummaries }) => {
|
|
1139
|
+
const nextState = removeStoredAccountEditSummaryFromState(accountsEditsSummaries, accountsEdits, account.id, storedCommentModeration);
|
|
1140
|
+
Object.assign(nextState, removeStoredAccountEditFromState(accountsEdits, account.id, storedCommentModeration));
|
|
1141
|
+
return nextState;
|
|
1142
|
+
})),
|
|
1143
|
+
]).then(() => { });
|
|
1144
|
+
}
|
|
1145
|
+
return rollbackPendingEditPromise || Promise.resolve();
|
|
1146
|
+
};
|
|
1147
|
+
const publishAndRetryFailedChallengeVerification = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
1148
|
+
var _a;
|
|
1149
|
+
commentModeration.once("challenge", (challenge) => __awaiter(void 0, void 0, void 0, function* () {
|
|
1150
|
+
lastChallenge = challenge;
|
|
1151
|
+
publishCommentModerationOptions.onChallenge(challenge, commentModeration);
|
|
1152
|
+
}));
|
|
1153
|
+
commentModeration.once("challengeverification", (challengeVerification) => __awaiter(void 0, void 0, void 0, function* () {
|
|
1154
|
+
publishCommentModerationOptions.onChallengeVerification(challengeVerification, commentModeration);
|
|
1155
|
+
if (challengeVerification.challengeSuccess) {
|
|
1156
|
+
challengeSucceeded = true;
|
|
1157
|
+
}
|
|
1158
|
+
if (hasTerminalChallengeVerificationError(challengeVerification)) {
|
|
1159
|
+
lastChallenge = undefined;
|
|
1160
|
+
yield rollbackStoredCommentModeration();
|
|
1161
|
+
return;
|
|
1162
|
+
}
|
|
1163
|
+
if (!challengeVerification.challengeSuccess && lastChallenge) {
|
|
1164
|
+
// publish again automatically on fail
|
|
1165
|
+
createCommentModerationOptions = Object.assign(Object.assign({}, createCommentModerationOptions), { timestamp: Math.floor(Date.now() / 1000) });
|
|
1166
|
+
commentModeration = backfillPublicationCommunityAddress(yield account.pkc.createCommentModeration(createCommentModerationOptions), createCommentModerationOptions);
|
|
1167
|
+
lastChallenge = undefined;
|
|
1168
|
+
publishAndRetryFailedChallengeVerification();
|
|
1169
|
+
}
|
|
1170
|
+
}));
|
|
1171
|
+
commentModeration.on("error", (error) => __awaiter(void 0, void 0, void 0, function* () {
|
|
1172
|
+
var _a;
|
|
1173
|
+
yield rollbackStoredCommentModeration();
|
|
1174
|
+
(_a = publishCommentModerationOptions.onError) === null || _a === void 0 ? void 0 : _a.call(publishCommentModerationOptions, error, commentModeration);
|
|
1175
|
+
}));
|
|
1176
|
+
// TODO: add publishingState to account edits
|
|
1177
|
+
commentModeration.on("publishingstatechange", (publishingState) => { var _a; return (_a = publishCommentModerationOptions.onPublishingStateChange) === null || _a === void 0 ? void 0 : _a.call(publishCommentModerationOptions, publishingState); });
|
|
1178
|
+
listeners.push(commentModeration);
|
|
1179
|
+
try {
|
|
1180
|
+
// publish will resolve after the challenge request
|
|
1181
|
+
// if it fails before, like failing to resolve ENS, we can emit the error
|
|
1182
|
+
yield commentModeration.publish();
|
|
1183
|
+
}
|
|
1184
|
+
catch (error) {
|
|
1185
|
+
yield rollbackStoredCommentModeration();
|
|
1186
|
+
(_a = publishCommentModerationOptions.onError) === null || _a === void 0 ? void 0 : _a.call(publishCommentModerationOptions, error, commentModeration);
|
|
1187
|
+
}
|
|
1188
|
+
});
|
|
1189
|
+
publishAndRetryFailedChallengeVerification();
|
|
1190
|
+
yield accountsDatabase.addAccountEdit(account.id, storedCreateCommentModerationOptions);
|
|
1191
|
+
log("accountsActions.publishCommentModeration", { createCommentModerationOptions });
|
|
1192
|
+
accountsStore.setState(({ accountsEdits, accountsEditsSummaries }) => {
|
|
1193
|
+
const nextState = addStoredAccountEditSummaryToState(accountsEditsSummaries, account.id, storedCommentModeration);
|
|
1194
|
+
Object.assign(nextState, addStoredAccountEditToState(accountsEdits, account.id, storedCommentModeration));
|
|
1195
|
+
return nextState;
|
|
1196
|
+
});
|
|
1197
|
+
storedCommentModerationAdded = true;
|
|
1198
|
+
if (rollbackStoredCommentModerationRequested) {
|
|
1199
|
+
yield rollbackStoredCommentModeration();
|
|
1200
|
+
}
|
|
1201
|
+
});
|
|
1202
|
+
export const publishCommunityEdit = (communityAddress, publishCommunityEditOptions, accountName) => __awaiter(void 0, void 0, void 0, function* () {
|
|
1203
|
+
var _a;
|
|
1204
|
+
const { accounts, accountNamesToAccountIds, activeAccountId } = accountsStore.getState();
|
|
1205
|
+
assert(accounts && accountNamesToAccountIds && activeAccountId, `can't use accountsStore.accountActions before initialized`);
|
|
1206
|
+
let account = accounts[activeAccountId];
|
|
1207
|
+
if (accountName) {
|
|
1208
|
+
const accountId = accountNamesToAccountIds[accountName];
|
|
1209
|
+
account = accounts[accountId];
|
|
1210
|
+
}
|
|
1211
|
+
validator.validateAccountsActionsPublishCommunityEditArguments({
|
|
1212
|
+
communityAddress,
|
|
1213
|
+
publishCommunityEditOptions,
|
|
1214
|
+
accountName,
|
|
1215
|
+
account,
|
|
1216
|
+
});
|
|
1217
|
+
const communityEditOptions = Object.assign({}, publishCommunityEditOptions);
|
|
1218
|
+
delete communityEditOptions.onChallenge;
|
|
1219
|
+
delete communityEditOptions.onChallengeVerification;
|
|
1220
|
+
delete communityEditOptions.onError;
|
|
1221
|
+
delete communityEditOptions.onPublishingStateChange;
|
|
1222
|
+
let createCommunityEditOptions = normalizeCommunityEditOptionsForPkc(account.pkc, {
|
|
1223
|
+
timestamp: Math.floor(Date.now() / 1000),
|
|
1224
|
+
author: account.author,
|
|
1225
|
+
signer: account.signer,
|
|
1226
|
+
// not possible to edit community.address over pubsub, only locally
|
|
1227
|
+
communityAddress,
|
|
1228
|
+
communityEdit: communityEditOptions,
|
|
1229
|
+
});
|
|
1230
|
+
const storedCreateCommunityEditOptions = Object.assign(Object.assign({}, normalizePublicationOptionsForStore(createCommunityEditOptions)), { clientId: uuid() });
|
|
1231
|
+
const storedCommunityEdit = sanitizeStoredAccountEdit(storedCreateCommunityEditOptions);
|
|
1232
|
+
let challengeSucceeded = false;
|
|
1233
|
+
let rollbackPendingEditPromise;
|
|
1234
|
+
const rollbackStoredCommunityEdit = () => {
|
|
1235
|
+
if (!rollbackPendingEditPromise && !challengeSucceeded) {
|
|
1236
|
+
rollbackPendingEditPromise = Promise.all([
|
|
1237
|
+
accountsDatabase.deleteAccountEdit(account.id, storedCommunityEdit),
|
|
1238
|
+
Promise.resolve(accountsStore.setState(({ accountsEdits, accountsEditsSummaries }) => {
|
|
1239
|
+
const nextState = removeStoredAccountEditSummaryFromState(accountsEditsSummaries, accountsEdits, account.id, storedCommunityEdit);
|
|
1240
|
+
Object.assign(nextState, removeStoredAccountEditFromState(accountsEdits, account.id, storedCommunityEdit));
|
|
1241
|
+
return nextState;
|
|
1242
|
+
})),
|
|
1243
|
+
]).then(() => { });
|
|
1244
|
+
}
|
|
1245
|
+
return rollbackPendingEditPromise;
|
|
1246
|
+
};
|
|
1247
|
+
const storePublishedCommunityEdit = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
1248
|
+
yield accountsDatabase.addAccountEdit(account.id, storedCreateCommunityEditOptions);
|
|
1249
|
+
accountsStore.setState(({ accountsEdits, accountsEditsSummaries }) => {
|
|
1250
|
+
const nextState = addStoredAccountEditSummaryToState(accountsEditsSummaries, account.id, storedCommunityEdit);
|
|
1251
|
+
Object.assign(nextState, addStoredAccountEditToState(accountsEdits, account.id, storedCommunityEdit));
|
|
1252
|
+
return nextState;
|
|
1253
|
+
});
|
|
1254
|
+
});
|
|
1255
|
+
// account is the owner of the community and can edit it locally, no need to publish
|
|
1256
|
+
if (accountOwnsCommunityLocally(account, communityAddress)) {
|
|
1257
|
+
yield communitiesStore
|
|
1258
|
+
.getState()
|
|
1259
|
+
.editCommunity(communityAddress, communityEditOptions, account);
|
|
1260
|
+
yield storePublishedCommunityEdit();
|
|
1261
|
+
// create fake success challenge verification for consistent behavior with remote community edit
|
|
1262
|
+
publishCommunityEditOptions.onChallengeVerification({ challengeSuccess: true });
|
|
1263
|
+
(_a = publishCommunityEditOptions.onPublishingStateChange) === null || _a === void 0 ? void 0 : _a.call(publishCommunityEditOptions, "succeeded");
|
|
1264
|
+
return;
|
|
1265
|
+
}
|
|
1266
|
+
assert(!publishCommunityEditOptions.address ||
|
|
1267
|
+
publishCommunityEditOptions.address === communityAddress, `accountsActions.publishCommunityEdit can't edit address of a remote community`);
|
|
1268
|
+
let communityEdit = backfillPublicationCommunityAddress(yield createPkcCommunityEdit(account.pkc, createCommunityEditOptions), createCommunityEditOptions);
|
|
1269
|
+
let lastChallenge;
|
|
1270
|
+
const publishAndRetryFailedChallengeVerification = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
1271
|
+
var _a;
|
|
1272
|
+
communityEdit.once("challenge", (challenge) => __awaiter(void 0, void 0, void 0, function* () {
|
|
1273
|
+
lastChallenge = challenge;
|
|
1274
|
+
publishCommunityEditOptions.onChallenge(challenge, communityEdit);
|
|
1275
|
+
}));
|
|
1276
|
+
communityEdit.once("challengeverification", (challengeVerification) => __awaiter(void 0, void 0, void 0, function* () {
|
|
1277
|
+
publishCommunityEditOptions.onChallengeVerification(challengeVerification, communityEdit);
|
|
1278
|
+
if (challengeVerification.challengeSuccess) {
|
|
1279
|
+
challengeSucceeded = true;
|
|
1280
|
+
}
|
|
1281
|
+
if (hasTerminalChallengeVerificationError(challengeVerification)) {
|
|
1282
|
+
lastChallenge = undefined;
|
|
1283
|
+
yield rollbackStoredCommunityEdit();
|
|
1284
|
+
return;
|
|
1285
|
+
}
|
|
1286
|
+
if (!challengeVerification.challengeSuccess && lastChallenge) {
|
|
1287
|
+
// publish again automatically on fail
|
|
1288
|
+
createCommunityEditOptions = Object.assign(Object.assign({}, createCommunityEditOptions), { timestamp: Math.floor(Date.now() / 1000) });
|
|
1289
|
+
communityEdit = backfillPublicationCommunityAddress(yield createPkcCommunityEdit(account.pkc, createCommunityEditOptions), createCommunityEditOptions);
|
|
1290
|
+
lastChallenge = undefined;
|
|
1291
|
+
publishAndRetryFailedChallengeVerification();
|
|
1292
|
+
}
|
|
1293
|
+
}));
|
|
1294
|
+
communityEdit.on("error", (error) => __awaiter(void 0, void 0, void 0, function* () {
|
|
1295
|
+
var _a;
|
|
1296
|
+
yield rollbackStoredCommunityEdit();
|
|
1297
|
+
(_a = publishCommunityEditOptions.onError) === null || _a === void 0 ? void 0 : _a.call(publishCommunityEditOptions, error, communityEdit);
|
|
1298
|
+
}));
|
|
1299
|
+
// TODO: add publishingState to account edits
|
|
1300
|
+
communityEdit.on("publishingstatechange", (publishingState) => { var _a; return (_a = publishCommunityEditOptions.onPublishingStateChange) === null || _a === void 0 ? void 0 : _a.call(publishCommunityEditOptions, publishingState); });
|
|
1301
|
+
listeners.push(communityEdit);
|
|
1302
|
+
try {
|
|
1303
|
+
// publish will resolve after the challenge request
|
|
1304
|
+
// if it fails before, like failing to resolve ENS, we can emit the error
|
|
1305
|
+
yield communityEdit.publish();
|
|
1306
|
+
}
|
|
1307
|
+
catch (error) {
|
|
1308
|
+
yield rollbackStoredCommunityEdit();
|
|
1309
|
+
(_a = publishCommunityEditOptions.onError) === null || _a === void 0 ? void 0 : _a.call(publishCommunityEditOptions, error, communityEdit);
|
|
1310
|
+
}
|
|
1311
|
+
});
|
|
1312
|
+
yield storePublishedCommunityEdit();
|
|
1313
|
+
publishAndRetryFailedChallengeVerification();
|
|
1314
|
+
log("accountsActions.publishCommunityEdit", { createCommunityEditOptions });
|
|
1315
|
+
});
|
|
1316
|
+
export const createCommunity = (createCommunityOptions, accountName) => __awaiter(void 0, void 0, void 0, function* () {
|
|
1317
|
+
const { accounts, accountNamesToAccountIds, activeAccountId } = accountsStore.getState();
|
|
1318
|
+
assert(accounts && accountNamesToAccountIds && activeAccountId, `can't use accountsStore.accountsActions before initialized`);
|
|
1319
|
+
let account = accounts[activeAccountId];
|
|
1320
|
+
if (accountName) {
|
|
1321
|
+
const accountId = accountNamesToAccountIds[accountName];
|
|
1322
|
+
account = accounts[accountId];
|
|
1323
|
+
}
|
|
1324
|
+
const community = yield communitiesStore
|
|
1325
|
+
.getState()
|
|
1326
|
+
.createCommunity(createCommunityOptions, account);
|
|
1327
|
+
log("accountsActions.createCommunity", { createCommunityOptions, community });
|
|
1328
|
+
return community;
|
|
1329
|
+
});
|
|
1330
|
+
export const deleteCommunity = (communityAddress, accountName) => __awaiter(void 0, void 0, void 0, function* () {
|
|
1331
|
+
const { accounts, accountNamesToAccountIds, activeAccountId } = accountsStore.getState();
|
|
1332
|
+
assert(accounts && accountNamesToAccountIds && activeAccountId, `can't use accountsStore.accountsActions before initialized`);
|
|
1333
|
+
let account = accounts[activeAccountId];
|
|
1334
|
+
if (accountName) {
|
|
1335
|
+
const accountId = accountNamesToAccountIds[accountName];
|
|
1336
|
+
account = accounts[accountId];
|
|
1337
|
+
}
|
|
1338
|
+
yield communitiesStore.getState().deleteCommunity(communityAddress, account);
|
|
1339
|
+
log("accountsActions.deleteCommunity", { communityAddress });
|
|
1340
|
+
});
|
|
1341
|
+
//# sourceMappingURL=accounts-actions.js.map
|