Joystream Stats hace 3 años
padre
commit
efd7b978ee

+ 7 - 7
package.json

@@ -4,13 +4,6 @@
   "license": "GPL-3.0-or-later",
   "repository": "https://github.com/Joystream/community-repo",
   "dependencies": {
-    "@joystream/types": "^0.14.0",
-    "@types/jest": "^26.0.15",
-    "@types/node": "^12.0.0",
-    "@types/node-fetch": "^2.5.7",
-    "@types/react": "^16.9.53",
-    "@types/react-calendar-timeline": "^0.26.3",
-    "@types/react-dom": "^16.9.8",
     "axios": "^0.21.1",
     "bootstrap": "^4.5.3",
     "d3-timeline": "^1.0.1",
@@ -55,8 +48,15 @@
     ]
   },
   "devDependencies": {
+    "@joystream/types": "^0.14.0",
+    "@types/jest": "^26.0.15",
+    "@types/node": "^12.0.0",
+    "@types/node-fetch": "^2.5.7",
+    "@types/react": "^16.9.53",
     "@types/bootstrap": "^5.0.1",
     "@types/react-bootstrap": "^0.32.25",
+    "@types/react-calendar-timeline": "^0.26.3",
+    "@types/react-dom": "^16.9.8",
     "@types/react-router-dom": "^5.1.6"
   }
 }

+ 1 - 2
src/App.tsx

@@ -435,8 +435,7 @@ class App extends React.Component<IProps, IState> {
 
         const data = await api.query.staking.erasStakers(era, validator);
         let { total, own, others } = data.toJSON();
-        let { stakes } = this.state;
-        if (!stakes) stakes = {};
+        let { stakes = {} } = this.state;
 
         stakes[validator] = { total, own, others, commission };
         this.save("stakes", stakes);

+ 2 - 0
src/components/Forum/Categories.tsx

@@ -19,6 +19,8 @@ const Categories = (props: {
     return props.latest.find((i) => i === id) ? "bg-secondary" : "";
   };
 
+  if (!categories.length) return <div />;
+
   return (
     <div className="overflow-auto" style={{ maxHeight: "30%" }}>
       <div className="box">

+ 33 - 16
src/components/Forum/Content.tsx

@@ -17,6 +17,9 @@ const Content = (props: {
   selectThread: (id: number) => void;
   startTime: number;
   latest: { threads: number[]; categories: number[]; posts: Post[] };
+  searchTerm: string;
+  filterPosts: (posts: Post[], s: string) => Post[];
+  filterThreads: (list: any[], s: string) => any[];
 }) => {
   const {
     selectCategory,
@@ -29,13 +32,18 @@ const Content = (props: {
     handles,
     startTime,
     latest,
+    filterPosts,
+    filterThreads,
   } = props;
 
   if (thread)
     return (
       <Posts
         thread={thread}
-        posts={posts.filter((p) => p.threadId === thread.id)}
+        posts={filterPosts(
+          posts.filter((p) => p.threadId === thread.id),
+          props.searchTerm
+        )}
         handles={handles}
         startTime={startTime}
       />
@@ -46,7 +54,10 @@ const Content = (props: {
       <Threads
         latest={latest.threads}
         selectThread={selectThread}
-        threads={threads.filter((t) => t.categoryId === category.id)}
+        threads={filterThreads(
+          threads.filter((t) => t.categoryId === category.id),
+          props.searchTerm
+        )}
         posts={posts}
       />
     );
@@ -56,22 +67,28 @@ const Content = (props: {
       <Categories
         latest={latest.categories}
         selectCategory={selectCategory}
-        categories={categories}
+        categories={filterThreads(categories, props.searchTerm)}
         threads={threads}
       />
-      <h2 className="text-center text-light my-2">Latest</h2>
-      <div className="overflow-auto" style={{ height: "90%" }}>
-        {latest.posts.map((p) => (
-          <LatestPost
-            key={p.id}
-            selectThread={selectThread}
-            startTime={startTime}
-            handles={handles}
-            thread={threads.find((t) => t.id === p.threadId)}
-            post={p}
-          />
-        ))}
-      </div>
+      {!latest.posts.length ? (
+        <h2 className="text-center text-light my-2">Nothing found</h2>
+      ) : (
+        <div>
+          <h2 className="text-center text-light my-2">Latest</h2>
+          <div className="overflow-auto" style={{ height: "90%" }}>
+            {latest.posts.map((p) => (
+              <LatestPost
+                key={p.id}
+                selectThread={selectThread}
+                startTime={startTime}
+                handles={handles}
+                thread={threads.find((t) => t.id === p.threadId)}
+                post={p}
+              />
+            ))}
+          </div>
+        </div>
+      )}
     </div>
   );
 };

+ 1 - 1
src/components/Forum/LatestPost.tsx

@@ -23,7 +23,7 @@ const LatestPost = (props: {
       className="box d-flex flex-row"
       onClick={() => thread && props.selectThread(thread.id)}
     >
-      <div className="mr-3">
+      <div className="col-2 mr-3">
         <User key={authorId} id={authorId} handle={handles[authorId]} />
         <div>{moment(startTime + createdAt.block * 6000).fromNow()}</div>
         <a href={`${domain}/#/forum/threads/${threadId}`}>reply</a>

+ 18 - 1
src/components/Forum/NavBar.tsx

@@ -1,5 +1,5 @@
 import React from "react";
-import { Navbar } from "react-bootstrap";
+import { Form, Nav, Navbar } from "react-bootstrap";
 import { Link } from "react-router-dom";
 
 import { ChevronRight } from "react-feather";
@@ -39,6 +39,8 @@ const NavBar = (props: {
   threads: Thread[];
   thread?: Thread;
   posts: Post[];
+  searchTerm: string;
+  handleChange: (e: any) => void;
 }) => {
   const {
     selectCategory,
@@ -49,6 +51,8 @@ const NavBar = (props: {
     posts,
     category,
     thread,
+    searchTerm,
+    handleChange,
   } = props;
 
   return (
@@ -73,6 +77,19 @@ const NavBar = (props: {
         threads={threads}
         posts={posts}
       />
+      <Nav className="ml-auto">
+        <Form>
+          <input
+            type="search"
+            name="searchTerm"
+            value={searchTerm}
+            placeholder="Search"
+            className="bg-dark text-light "
+            onChange={handleChange}
+            ref={(i) => i && i.focus()}
+          />
+        </Form>
+      </Nav>
     </Navbar>
   );
 };

+ 34 - 3
src/components/Forum/index.tsx

@@ -16,15 +16,19 @@ interface IState {
   categoryId: number;
   threadId: number;
   postId: number;
+  searchTerm: string;
 }
 
 class Forum extends React.Component<IProps, IState> {
   constructor(props: IProps) {
     super(props);
-    this.state = { categoryId: 0, threadId: 0, postId: 0 };
+    this.state = { categoryId: 0, threadId: 0, postId: 0, searchTerm: "" };
     this.selectCategory = this.selectCategory.bind(this);
     this.selectThread = this.selectThread.bind(this);
     this.handleKeyDown = this.handleKeyDown.bind(this);
+    this.handleChange = this.handleChange.bind(this);
+    this.filterPosts = this.filterPosts.bind(this);
+    this.filterThreads = this.filterThreads.bind(this);
   }
 
   componentDidMount() {
@@ -41,6 +45,10 @@ class Forum extends React.Component<IProps, IState> {
     if (this.state.categoryId) return this.selectCategory(0);
   }
 
+  handleChange(e: { target: { value: string } }) {
+    this.setState({ searchTerm: e.target.value.toLowerCase() });
+  }
+
   selectCategory(categoryId: number) {
     this.setState({ categoryId });
   }
@@ -57,10 +65,28 @@ class Forum extends React.Component<IProps, IState> {
     if (id > 1) return id;
   }
 
+  filterPosts(posts: Post[], s: string) {
+    return s === ""
+      ? posts
+      : posts.filter(
+          (p) =>
+            p.text.toLowerCase().includes(s) ||
+            this.props.handles[p.authorId].includes(s)
+        );
+  }
+
+  filterThreads(list: any[], s: string) {
+    return s === ""
+      ? list
+      : list.filter((i) => i.title.toLowerCase().includes(s));
+  }
+
   getLatest() {
     let threads: number[] = [];
     let categories: number[] = [];
-    let posts = this.props.posts.sort((a, b) => b.id - a.id).slice(0, 20);
+    let posts = this.filterPosts(this.props.posts, this.state.searchTerm)
+      .sort((a, b) => b.id - a.id)
+      .slice(0, 20);
     posts.forEach((p) => {
       const thread = this.props.threads.find((t) => t.id === p.threadId);
       if (!thread) return;
@@ -72,7 +98,7 @@ class Forum extends React.Component<IProps, IState> {
 
   render() {
     const { block, now, handles, categories, posts, threads } = this.props;
-    const { categoryId, threadId } = this.state;
+    const { categoryId, threadId, searchTerm } = this.state;
 
     const startTime: number = now - block * 6000;
 
@@ -94,6 +120,8 @@ class Forum extends React.Component<IProps, IState> {
           threads={threads}
           thread={thread}
           posts={posts}
+          handleChange={this.handleChange}
+          searchTerm={searchTerm}
         />
         <Content
           latest={this.getLatest()}
@@ -106,6 +134,9 @@ class Forum extends React.Component<IProps, IState> {
           thread={thread}
           handles={handles}
           startTime={startTime}
+          searchTerm={searchTerm}
+          filterPosts={this.filterPosts}
+          filterThreads={this.filterThreads}
         />
       </div>
     );