mirror of https://gitlab.com/ecentrics/concordia
				
				
			
			
			
				Browse Source
			
			
			
			
				
		# Conflicts: # src/components/Post.js # src/components/PostList.js # src/components/ProfileInformation.js # src/components/Topic.js # src/containers/ProfileContainer.jsdevelop
				 12 changed files with 502 additions and 548 deletions
			
			
		| @ -1,116 +1,35 @@ | |||||
| import { drizzleConnect } from 'drizzle-react'; | import React from 'react'; | ||||
| import React, { Component } from 'react'; |  | ||||
| import PropTypes from 'prop-types'; |  | ||||
| 
 | 
 | ||||
| import Post from './Post'; | import WithBlockchainData from './WithBlockchainData'; | ||||
| 
 |  | ||||
| import epochTimeConverter from '../helpers/EpochTimeConverter' |  | ||||
| 
 |  | ||||
| const contract = "Forum"; |  | ||||
| const contractMethod = "getPost"; |  | ||||
| 
 |  | ||||
| class PostList extends Component { |  | ||||
|     constructor(props, context) { |  | ||||
|         super(props); |  | ||||
| 
 | 
 | ||||
|         this.fetchPost = this.fetchPost.bind(this); | import Post from './Post'; | ||||
|         this.onHrefHandle = this.onHrefHandle.bind(this); |  | ||||
| 
 |  | ||||
|         this.drizzle = context.drizzle; |  | ||||
|         this.dataKeys = []; |  | ||||
|         this.postsData = new Array(parseInt(this.props.postIDs.length, 10)).fill(undefined); |  | ||||
|         this.orbitPostsData = new Array(parseInt(this.props.postIDs.length, 10)).fill(undefined); |  | ||||
|         this.orbitPostsDataFetchStatus = new Array(parseInt(this.props.postIDs.length, 10)).fill("pending"); |  | ||||
| 
 |  | ||||
|         for (var i = 0; i < this.props.postIDs.length; ++i){ |  | ||||
|             this.dataKeys[i] = this.drizzle.contracts[contract].methods[contractMethod] |  | ||||
|                 .cacheCall(this.props.postIDs[i]); |  | ||||
|         } |  | ||||
|     } |  | ||||
| 
 |  | ||||
|     async fetchPost(index) { |  | ||||
|         /*const fullAddress = this.postsData[postID][1]; |  | ||||
|         const store = await this.props.orbitDB.orbitdb.keyvalue(JSON.stringify(fullAddress)); |  | ||||
|         await store.load(); |  | ||||
|         var som = store.get(JSON.stringify(postID)); |  | ||||
|         this.orbitPostsData[postID] = som['subject']; |  | ||||
|         this.orbitPostsDataFetchStatus[postID] = "fetched";*/ |  | ||||
| 
 |  | ||||
|         var som = this.props.orbitDB.postsDB.get(this.props.postIDs[index]); |  | ||||
|         this.orbitPostsData[index] = som; |  | ||||
|         this.orbitPostsDataFetchStatus[index] = "fetched"; |  | ||||
|     } |  | ||||
| 
 |  | ||||
|     onHrefHandle(postIndex){ |  | ||||
|         this.context.router.push("/topic/" + this.postsData[postIndex][4] + "/" +  |  | ||||
|             ((this.orbitPostsData[postIndex] !== undefined) |  | ||||
|                 ? this.orbitPostsData[postIndex].subject + "/" + this.props.postIDs[postIndex] |  | ||||
|                 : "")) |  | ||||
|     } |  | ||||
| 
 | 
 | ||||
|     render (){ | const PostList = (props) => { | ||||
|         const posts = this.postsData.map((post, index) => { |     const posts = props.postIDs.map((postID, index) => { | ||||
|             if (post) { |  | ||||
|                 return ( |  | ||||
|                     <div key={index}> |  | ||||
|                         <Post post={{ |  | ||||
|                                 avatarUrl:post.avatarUrl, |  | ||||
|                                 userAddress:post[1], |  | ||||
|                                 username:post[2], |  | ||||
|                                 subject:(this.orbitPostsData[index] !== undefined) && |  | ||||
|                                     this.orbitPostsData[index].subject, |  | ||||
|                                 date:epochTimeConverter(post[3]), |  | ||||
|                                 postIndex:index, |  | ||||
|                                 postContent:(this.orbitPostsData[index] !== undefined) && |  | ||||
|                                     this.orbitPostsData[index].content, |  | ||||
|                             }} |  | ||||
|                             onHrefClick={() => this.onHrefHandle(index)} |  | ||||
|                             id={index} |  | ||||
|                             key={index}/> |  | ||||
|                     </div> |  | ||||
|                 ); |  | ||||
|             } else { |  | ||||
|         return ( |         return ( | ||||
|                     <Post post={null} |             <WithBlockchainData | ||||
|                         id={index} |                 component={Post} | ||||
|                         key={index}/> |                 callsInfo={[{ | ||||
|  |                         contract: 'Forum', | ||||
|  |                         method: 'getPost', | ||||
|  |                         params: [postID] | ||||
|  |                 }]} | ||||
|  |                 avatarUrl={""} | ||||
|  |                 postIndex={index} | ||||
|  |                 postID={postID} | ||||
|  |                 key={postID} | ||||
|  |             /> | ||||
|         ); |         ); | ||||
|             } |  | ||||
|     }); |     }); | ||||
| 
 | 
 | ||||
|     return ( |     return ( | ||||
|         <div className="posts-list"> |         <div className="posts-list"> | ||||
|                 {posts} |             {props.recentToTheTop | ||||
|  |                 ?posts.slice(0).reverse() | ||||
|  |                 :posts | ||||
|  |             } | ||||
|         </div> |         </div> | ||||
|     ); |     ); | ||||
|     } |  | ||||
| 
 |  | ||||
|     componentWillReceiveProps() { |  | ||||
|         for (var i = 0; i < this.props.postIDs.length; ++i){ |  | ||||
|             if (this.postsData[i] === undefined) { |  | ||||
|                 let currentDrizzleState = this.drizzle.store.getState(); |  | ||||
|                 let dataFetched = (currentDrizzleState.contracts[contract][contractMethod])[this.dataKeys[i]]; |  | ||||
|                 if (dataFetched){ |  | ||||
|                     this.postsData[i] = dataFetched.value; |  | ||||
|                 } |  | ||||
|             } else if (!this.orbitPostsData[i] && this.orbitPostsDataFetchStatus[i] === "pending") { |  | ||||
|                 this.orbitPostsDataFetchStatus[i] = "fetching"; |  | ||||
|                 this.fetchPost(i); |  | ||||
|             } |  | ||||
|         } |  | ||||
|     } |  | ||||
| }; |  | ||||
| 
 |  | ||||
| PostList.contextTypes = { |  | ||||
|     drizzle: PropTypes.object, |  | ||||
|     router: PropTypes.object |  | ||||
| }; |  | ||||
| 
 |  | ||||
| const mapStateToProps = state => { |  | ||||
|     return { |  | ||||
|         user: state.user, //Needed!!
 |  | ||||
|         orbitDB: state.orbitDB |  | ||||
|     } |  | ||||
| }; | }; | ||||
| 
 | 
 | ||||
| export default drizzleConnect(PostList, mapStateToProps); | export default PostList; | ||||
| @ -1,38 +1,91 @@ | |||||
| import React from 'react'; | import React, { Component } from 'react'; | ||||
|  | import { Link } from 'react-router'; | ||||
|  | import { drizzleConnect } from 'drizzle-react'; | ||||
|  | 
 | ||||
| import TimeAgo from 'react-timeago'; | import TimeAgo from 'react-timeago'; | ||||
|  | import epochTimeConverter from '../helpers/EpochTimeConverter' | ||||
|  | 
 | ||||
|  | class Topic extends Component { | ||||
|  |     constructor(props){ | ||||
|  |         super(props); | ||||
|  | 
 | ||||
|  |         this.fetchSubject = this.fetchSubject.bind(this); | ||||
|  | 
 | ||||
|  |         this.topicSubject = null; | ||||
|  |         this.topicSubjectFetchStatus = "pending"; | ||||
|  |     } | ||||
|  | 
 | ||||
|  |     async fetchSubject(topicID) { | ||||
|  |         this.topicSubjectFetchStatus = "fetching"; | ||||
| 
 | 
 | ||||
| const Topic = (props) => { |         if (this.props.blockchainData[0].returnData[1] === this.props.user.address) { | ||||
|  |             let som = this.props.orbitDB.topicsDB.get(topicID); | ||||
|  |             this.topicSubject = som['subject']; | ||||
|  |             this.topicSubjectFetchStatus = "fetched"; | ||||
|  |         } else { | ||||
|  |             const fullAddress = "/orbitdb" + this.props.blockchainData[0].returnData[0] + "/topics"; | ||||
|  |             const store = await this.props.orbitDB.orbitdb.keyvalue(fullAddress); | ||||
|  | 
 | ||||
|  |             /*store.events.on('replicated', () => { | ||||
|  |               const result = store.iterator({ limit: -1 }).collect().map(e => e.payload.value) | ||||
|  |               console.log(result.join('\n')) | ||||
|  |             })*/ | ||||
|  | 
 | ||||
|  |             await store.load(); | ||||
|  |             let som = store.get(topicID); | ||||
|  |             this.topicSubject = som['subject']; | ||||
|  |             this.topicSubjectFetchStatus = "fetched"; | ||||
|  |         } | ||||
|  |     } | ||||
|  | 
 | ||||
|  |     render(){ | ||||
|         return ( |         return ( | ||||
|         props.topic !== null |             <Link to={"/topic/" + this.props.topicID}> | ||||
|             ? <div className="topic card white hoverable"> |                 <div className="topic card white hoverable"> | ||||
|                     <div className="card-content"> |                     <div className="card-content"> | ||||
|                     <div className="topic-subject"> |                         <div className={"topic-subject" + (this.topicSubject ? "" : "grey-text")}> | ||||
|                         <p style={{color: props.topic.topicSubject ? "" : "grey"}}> |                             <p> | ||||
|                             {props.topic.topicSubject ? props.topic.topicSubject : "Subject"} |                                 {topic.topicSubject !== null ? topic.topicSubject : "Subject"} | ||||
|                             </p> |                             </p> | ||||
|                         </div> |                         </div> | ||||
|                         <hr/> |                         <hr/> | ||||
|                         <div className="topic-meta"> |                         <div className="topic-meta"> | ||||
|                         <p className="no-margin">{props.topic.topicStarter}</p> |                             <p className={"no-margin" + (this.topicSubject ? "" : "grey-text")}> | ||||
|                         <p className="no-margin">Number of replies: {props.topic.numberOfReplies}</p> |                                 {this.props.blockchainData[0].returnData !== null | ||||
|                         <p className="topic-date grey-text darken-3">Started <TimeAgo date={props.topic.date}/></p> |                                     ?this.props.blockchainData[0].returnData[2] | ||||
|                     </div> |                                     :"Username" | ||||
|                 </div> |                                 } | ||||
|             </div> |                             </p> | ||||
|             : <div className="topic card white hoverable"> |                             <p className={"no-margin" + (this.props.blockchainData[0].returnData !== null ? "" : "grey-text")}> | ||||
|                 <div className="card-content grey-text"> |                                 {"Number of replies: " + (this.props.blockchainData[0].returnData !== null | ||||
|                     <div className="topic-subject"> |                                     ?this.props.blockchainData[0].returnData[4].length | ||||
|                         <p>Subject</p> |                                     :"") | ||||
|                     </div> |                                 } | ||||
|                     <hr/> |                             </p> | ||||
|                     <div className="topic-meta"> |                             <p className="topic-date grey-text darken-3"> | ||||
|                         <p className="no-margin">Username</p> |                                 Started {this.props.blockchainData[0].returnData !== null && | ||||
|                         <p className="no-margin">Number of replies: </p> |                                     <TimeAgo date={epochTimeConverter(this.props.blockchainData[0].returnData[3])}/> | ||||
|                         <p className="topic-date grey-text darken-3"></p> |                                 } | ||||
|  |                             </p> | ||||
|                         </div> |                         </div> | ||||
|                     </div> |                     </div> | ||||
|                 </div> |                 </div> | ||||
|  |             </Link> | ||||
|         ); |         ); | ||||
|  |     } | ||||
|  | 
 | ||||
|  |     componentDidUpdate(){ | ||||
|  |         if (this.props.blockchainData[0].returnData !== null && this.topicSubjectFetchStatus === "pending") { | ||||
|  |             this.fetchSubject(this.props.topicID); | ||||
|  |         } | ||||
|  |     } | ||||
| }; | }; | ||||
| 
 | 
 | ||||
| export default Topic; | const mapStateToProps = state => { | ||||
|  |     return { | ||||
|  |         user: state.user, | ||||
|  |         orbitDB: state.orbitDB | ||||
|  |     } | ||||
|  | } | ||||
|  | 
 | ||||
|  | export default drizzleConnect(Topic, mapStateToProps); | ||||
| @ -0,0 +1,81 @@ | |||||
|  | import React, { Component } from 'react'; | ||||
|  | import PropTypes from 'prop-types'; | ||||
|  | 
 | ||||
|  | class WithBlockchainData extends Component { | ||||
|  |     constructor(props, context) { | ||||
|  |         super(props); | ||||
|  | 
 | ||||
|  |         { | ||||
|  |             let {component, callsInfo, ...rest } = this.props; | ||||
|  |             this.component = component; | ||||
|  |             this.callsInfo = callsInfo; | ||||
|  |             this.forwardedProps = rest; | ||||
|  |         } | ||||
|  | 
 | ||||
|  |         this.checkContractUpdates = this.checkContractUpdates.bind(this); | ||||
|  | 
 | ||||
|  |         this.drizzle = context.drizzle; | ||||
|  |         this.dataKeys = []; | ||||
|  |         this.blockchainData = this.callsInfo.map((call) => { | ||||
|  |             return ({ | ||||
|  |                 callInfo: call, | ||||
|  |                 status: "initialized", | ||||
|  |                 returnData: null | ||||
|  |             }); | ||||
|  |         }); | ||||
|  | 
 | ||||
|  |         for (var i = 0; i < this.callsInfo.length; ++i){ | ||||
|  |             this.dataKeys[i] = this.drizzle | ||||
|  |                 .contracts[this.callsInfo[i].contract] | ||||
|  |                 .methods[this.callsInfo[i].method] | ||||
|  |                 .cacheCall(...(this.callsInfo[i].params)); | ||||
|  |             this.blockchainData[i].status = "pending"; | ||||
|  |         } | ||||
|  | 
 | ||||
|  |         this.state = { | ||||
|  |             transactionsState: new Array(this.callsInfo.length).fill("pending") | ||||
|  |         } | ||||
|  |     } | ||||
|  | 
 | ||||
|  |     render() { | ||||
|  |         let {component, callsInfo, ...rest } = this.props; | ||||
|  |         return ( | ||||
|  |             <this.component blockchainData={this.blockchainData} {...rest}/> | ||||
|  |         ); | ||||
|  |     } | ||||
|  | 
 | ||||
|  |     componentDidMount() { | ||||
|  |         this.intervalChecker = setInterval(this.checkContractUpdates, 10); //HOWMUCHMUCHACHO???
 | ||||
|  |     } | ||||
|  | 
 | ||||
|  |     componentWillUnmount() { | ||||
|  |         clearInterval(this.intervalChecker); | ||||
|  |     } | ||||
|  | 
 | ||||
|  |     checkContractUpdates() { | ||||
|  |         for (var i = 0; i < this.callsInfo.length; ++i){ | ||||
|  |             let currentDrizzleState = this.drizzle.store.getState(); | ||||
|  |             if (this.state.transactionsState[i] === "pending") { | ||||
|  |                 let dataFetched = (currentDrizzleState | ||||
|  |                     .contracts[this.callsInfo[i].contract][this.callsInfo[i].method][this.dataKeys[i]]); | ||||
|  |                 if (dataFetched){ | ||||
|  |                     this.blockchainData[i].returnData = dataFetched.value; | ||||
|  |                     this.blockchainData[i].status = "success"; | ||||
|  |                     this.setState((prevState) => ({ | ||||
|  |                         transactionsState: [ | ||||
|  |                             ...prevState.transactionsState.slice(0, i), | ||||
|  |                             "success", | ||||
|  |                             ...prevState.transactionsState.slice(i) | ||||
|  |                         ] | ||||
|  |                     })); | ||||
|  |                 } | ||||
|  |             } //TODO cover errors!!
 | ||||
|  |         } | ||||
|  |     } | ||||
|  | } | ||||
|  | 
 | ||||
|  | WithBlockchainData.contextTypes = { | ||||
|  |     drizzle: PropTypes.object | ||||
|  | }; | ||||
|  | 
 | ||||
|  | export default WithBlockchainData; | ||||
					Loading…
					
					
				
		Reference in new issue