diff --git a/api/src/types/fragments.js b/api/src/types/fragments.js
index 252f8086..e64d6a9c 100644
--- a/api/src/types/fragments.js
+++ b/api/src/types/fragments.js
@@ -22,6 +22,12 @@ export const appBundleFragment = `
Index_updatedAt: updatedAt
Index_deletedAt: deletedAt
}
+ ... on Article {
+ Article_id: id
+ Article_title: title
+ Article_url: url
+ Article_createdAt: createdAt
+ }
... on WebPage {
WebPage_title: title
WebPage_favicon: favicon
diff --git a/web-app/public/images/article.svg b/web-app/public/images/article.svg
new file mode 100644
index 00000000..1e92c8b7
--- /dev/null
+++ b/web-app/public/images/article.svg
@@ -0,0 +1,7 @@
+
diff --git a/web-app/src/components/site/index-details/ArticleItem/index.tsx b/web-app/src/components/site/index-details/ArticleItem/index.tsx
new file mode 100644
index 00000000..c0eac08f
--- /dev/null
+++ b/web-app/src/components/site/index-details/ArticleItem/index.tsx
@@ -0,0 +1,116 @@
+import Freizeit from "@/fonts/loader";
+import { shortStr } from "@/utils/helper";
+import Button from "components/base/Button";
+import IconContextMenu from "components/base/Icon/IconContextMenu";
+import Text from "components/base/Text";
+import Col from "components/layout/base/Grid/Col";
+import FlexRow from "components/layout/base/Grid/FlexRow";
+import IndexDetailItemPopup from "components/site/popup/IndexDetailItemPopup";
+import { useRole } from "hooks/useRole";
+import moment from "moment";
+import React from "react";
+import sanitize from "sanitize-html";
+import { ArticleIndexNodeItem, DefaultIndexNodeItem } from "types/entity";
+
+export interface ArticleItemProps {
+ item: ArticleIndexNodeItem;
+ onChange?(val: DefaultIndexNodeItem[]): void;
+ search?: boolean;
+ handleRemove?(): void;
+}
+
+const ArticleItem: React.FC = ({
+ item,
+ search = false,
+ handleRemove,
+}) => {
+ const { node } = item;
+
+ const { isCreator } = useRole();
+
+ return (
+
+
+
+
+
+ ) => {
+ const target = e.target as HTMLImageElement;
+ target.onerror = null; // Prevents infinite loop in case fallback image also fails
+ target.src = "/images/article.svg";
+ }}
+ style={{
+ verticalAlign: "middle",
+ }}
+ />
+
+
+
+
+ {!search && isCreator ? (
+
+
+
+
+
+
+
+
+
+
+ ) : (
+
+
+
+
+
+
+
+
+ )}
+
+
+
+
+ {item.type}
+ {" • "}
+
+ {node.url}
+
+ {" • "}
+
+
+
+ {node?.createdAt
+ ? `Published ${moment(new Date(node.createdAt)).fromNow()}`
+ : ""}
+
+
+
+
+ );
+};
+export default ArticleItem;
diff --git a/web-app/src/components/site/index-details/IndexItemList/index.tsx b/web-app/src/components/site/index-details/IndexItemList/index.tsx
index 21621d4f..df2c2723 100644
--- a/web-app/src/components/site/index-details/IndexItemList/index.tsx
+++ b/web-app/src/components/site/index-details/IndexItemList/index.tsx
@@ -9,6 +9,7 @@ import {
IndexItem,
IndexTeamNodeItem,
IndexWebPageItem,
+ ArticleIndexNodeItem,
} from "types/entity";
import NoLinks from "../../indexes/NoLinks";
@@ -17,6 +18,7 @@ import TeamItem from "../TeamItem";
import IndexIndexItem from "../IndexIndexItem";
import DefaultIndexItem from "../DefaultIndexItem";
import CastItem from "../CastItem";
+import ArticleItem from "../ArticleItem";
export interface IndexItemListProps {
search: string;
@@ -31,6 +33,7 @@ const MemoTeamItem = memo(TeamItem);
const MemoIndexItem = memo(IndexIndexItem);
const MemoDefaultIndexItem = memo(DefaultIndexItem);
const MemoCastItem = memo(CastItem);
+const MemoArticleItem = memo(ArticleItem);
const IndexItemList: FC = ({
search,
@@ -62,6 +65,16 @@ const IndexItemList: FC = ({
);
}
+ if (item.type === "Article") {
+ return (
+ removeItem(item)}
+ search={!!search}
+ item={item as ArticleIndexNodeItem}
+ />
+ );
+ }
+
if (item.type === "Index") {
return (
{
const profileData = {
name: values.name,
bio: values.bio,
- avatar: (avatar || userProfile.avatar).replace(
+ avatar: undefined,
+ };
+
+ if (avatar || userProfile.avatar) {
+ profileData.avatar = (avatar || userProfile.avatar).replace(
`${appConfig.ipfsProxy}/`,
"",
- ),
- };
+ );
+ }
await dispatch(updateProfile({ profile: profileData, api })).unwrap();
toast.success("Profile updated successfully");
diff --git a/web-app/src/types/entity.ts b/web-app/src/types/entity.ts
index 2606afaf..3a6d48bb 100644
--- a/web-app/src/types/entity.ts
+++ b/web-app/src/types/entity.ts
@@ -74,6 +74,12 @@ export type CastIndexNode = {
username: string;
};
};
+export type ArticleIndexNode = {
+ id: string;
+ title: string;
+ url: string;
+ createdAt: string;
+};
export type IndexWebPageItem = {
id: string;
@@ -105,11 +111,18 @@ export type CastIndexNodeItem = {
node: CastIndexNode;
};
+export type ArticleIndexNodeItem = {
+ id: string;
+ type: string;
+ node: ArticleIndexNode;
+};
+
export type IndexItem =
| IndexWebPageItem
| IndexTeamNodeItem
| IndexIndexNodeItem
| DefaultIndexNodeItem
+ | ArticleIndexNodeItem
| CastIndexNodeItem;
export type IndexLink = {