diff --git a/apps/builddao/widget/Bookmarks.jsx b/apps/builddao/widget/Bookmarks.jsx
new file mode 100644
index 00000000..6c399cc8
--- /dev/null
+++ b/apps/builddao/widget/Bookmarks.jsx
@@ -0,0 +1,69 @@
+const { Post } = VM.require("buildhub.near/widget/components") || (() => <>>);
+
+const accountId = props.accountId ?? context.accountId;
+
+const bookmarks = Social.getr(`${accountId}/graph/bookmark`, "final", {
+ withBlockHeight: true,
+});
+
+const StorageKey = "order";
+const order = Storage.privateGet(StorageKey);
+const apps = useMemo(() => {
+ if (bookmarks === null || order === null) {
+ return [];
+ }
+ const starredApps = new Map();
+ const path = [];
+
+ const buildSrc = (node) => {
+ if (node.hasOwnProperty("")) {
+ starredApps.set(path.join("/"), node[":block"]);
+ }
+ Object.entries(node).forEach(([key, value]) => {
+ if (typeof value === "object") {
+ path.push(key);
+ buildSrc(value);
+ path.pop();
+ }
+ });
+ };
+
+ buildSrc(bookmarks ?? {}, [], starredApps);
+ let apps = [...starredApps.entries()];
+ apps.sort((a, b) => b[1] - a[1]);
+ apps = apps.map((a) => a[0]);
+ apps.sort((a, b) => (order?.[a] || 0) - (order?.[b] || 0));
+ Storage.privateSet(
+ StorageKey,
+ Object.fromEntries(apps.map((a, i) => [a, i + 1]))
+ );
+ return apps;
+}, [bookmarks, order]);
+
+let transformedArray = apps.map((item) => {
+ let splitParts = item.split("/");
+ let accountId = splitParts[0];
+ let lastPart = splitParts[splitParts.length - 1];
+ let blockHeight = isNaN(lastPart) ? null : parseInt(lastPart);
+
+ return { accountId, blockHeight };
+});
+
+let filteredArray = transformedArray.filter(
+ (item) => item.blockHeight !== null
+);
+
+return (
+ <>
+ {(filteredArray ?? []).map((item) => (
+
+ ))}
+ {filteredArray.length === 0 && (
+
No Bookmarks Yet!
+ )}
+ >
+);
diff --git a/apps/builddao/widget/Feed.jsx b/apps/builddao/widget/Feed.jsx
index cb893808..b711cec5 100644
--- a/apps/builddao/widget/Feed.jsx
+++ b/apps/builddao/widget/Feed.jsx
@@ -139,6 +139,11 @@ const feeds = {
- [Provide any context or details]
`,
},
+ bookmarks: {
+ label: "Bookmarks",
+ icon: "bi-bookmark",
+ name: "bookmark",
+ },
};
const [activeFeed, setActiveFeed] = useState(type || "resolutions");
@@ -158,42 +163,48 @@ return (
{context.accountId ? (
-
+ activeFeed !== "bookmarks" ? (
+
+ ) : (
+
+ )
) : (
)}
- (
-
- )}
- />
+ ]}
+ Item={(p) => (
+
+ )}
+ />
+ )}
);
diff --git a/apps/builddao/widget/components/post/BookmarkButton.jsx b/apps/builddao/widget/components/post/BookmarkButton.jsx
index 693f3e3c..5ddf89d9 100644
--- a/apps/builddao/widget/components/post/BookmarkButton.jsx
+++ b/apps/builddao/widget/components/post/BookmarkButton.jsx
@@ -12,54 +12,51 @@ const bookmarks = Social.index("bookmark", item);
const dataLoading = bookmarks === null;
-const bookmarksByUsers = {};
+const bookmarksByUser = {};
(bookmarks || []).forEach((bookmark) => {
if (bookmark.value.type === "bookmark") {
- bookmarksByUsers[bookmark.accountId] = bookmark;
+ bookmarksByUser[bookmark.accountId] = bookmark;
} else if (bookmark.value.type === "unbookmark") {
- delete bookmarksByUsers[bookmark.accountId];
+ delete bookmarksByUser[bookmark.accountId];
}
});
+
if (state.hasBookmark === true) {
- bookmarksByUsers[context.accountId] = {
+ bookmarksByUser[context.accountId] = {
accountId: context.accountId,
};
} else if (state.hasBookmark === false) {
- delete bookmarksByUsers[context.accountId];
+ delete bookmarksByUser[context.accountId];
}
-const accountsWithBookmarks = Object.keys(bookmarksByUsers);
-const likeCount = accountsWithBookmarks.length;
-const hasBookmark = context.accountId && !!bookmarksByUsers[context.accountId];
+const accountsWithBookmarks = Object.keys(bookmarksByUser);
+const bookmarkCount = accountsWithBookmarks.length;
+const hasBookmark = context.accountId && !!bookmarksByUser[context.accountId];
const bookmarkSvg = (
);
const bookmarkFillSvg = (
);
@@ -128,38 +125,66 @@ const BookmarkButton = styled.div`
}
`;
-const likeClick = () => {
+const bookmarkClick = () => {
if (state.loading || dataLoading || !context.accountId) {
return;
}
State.update({
loading: true,
});
+ const type = hasBookmark ? "unbookmark" : "bookmark";
const data = {
index: {
bookmark: JSON.stringify({
key: item,
value: {
- type: hasBookmark ? "unbookmark" : "bookmark",
+ type,
},
}),
},
};
+ if (item.type === "social" && typeof item.path === "string") {
+ const keys = item.path.split("/");
+ keys.push(item.blockHeight);
+ if (keys.length > 0) {
+ data.graph = {
+ bookmark: {},
+ };
+ let root = data.graph.bookmark;
+ keys.slice(0, -1).forEach((key) => {
+ root = root[key] = {};
+ });
+ root[keys[keys.length - 1]] = hasBookmark ? null : "";
+ }
+ }
+
+ if (!hasBookmark && props.notifyAccountId) {
+ data.index.notify = JSON.stringify({
+ key: props.notifyAccountId,
+ value: {
+ type,
+ item,
+ },
+ });
+ }
+
Social.set(data, {
onCommit: () => State.update({ loading: false, hasBookmark: !hasBookmark }),
onCancel: () => State.update({ loading: false }),
});
};
-const title = hasBookmark ? "Unbookmark" : "Bookmark";
+const title = hasBookmark
+ ? props.titleUnbookmark ?? "Unbookmark"
+ : props.titleBookmark ?? "Bookmark";
-return (
+const inner = (
{hasBookmark ? bookmarkFillSvg : bookmarkSvg}
+ {bookmarkCount > 0 && (
+
+
+
+ )}
);
+
+return props.tooltip ? (
+ {title}}
+ >
+ {inner}
+
+) : (
+ inner
+);