mirror of https://gitlab.com/ecentrics/concordia
Apostolos Fanakis
7 years ago
12 changed files with 525 additions and 544 deletions
@ -1,67 +1,117 @@ |
|||
import React from 'react'; |
|||
import React, { Component } from 'react'; |
|||
import { Link, withRouter } from 'react-router'; |
|||
import UserAvatar from 'react-user-avatar'; |
|||
import { drizzleConnect } from 'drizzle-react'; |
|||
import PropTypes from 'prop-types'; |
|||
|
|||
import TimeAgo from 'react-timeago'; |
|||
import epochTimeConverter from '../helpers/EpochTimeConverter' |
|||
import UserAvatar from 'react-user-avatar'; |
|||
import ReactMarkdown from 'react-markdown'; |
|||
|
|||
const Post = (props) => { |
|||
return ( |
|||
props.post !== null |
|||
? <div className="pure-u-1-1 post card"> |
|||
<div className="post-header"> |
|||
<div className="vertical-center-children"> |
|||
<Link to={"/profile/" + props.post.userAddress + "/" + props.post.username} |
|||
onClick={(event) => {event.stopPropagation()}}> |
|||
<UserAvatar |
|||
size="40" |
|||
className="inline user-avatar" |
|||
src={props.post.avatarUrl} |
|||
name={props.post.username}/> |
|||
</Link> |
|||
<p className="inline no-margin"> |
|||
<strong> |
|||
{props.post.username} |
|||
<br/> |
|||
Subject: {props.post.subject} |
|||
</strong> |
|||
</p> |
|||
class Post extends Component { |
|||
constructor(props, context) { |
|||
super(props); |
|||
|
|||
this.fetchPost = this.fetchPost.bind(this); |
|||
|
|||
this.orbitPostData = { |
|||
content: "", |
|||
subject: "" |
|||
}; |
|||
this.orbitPostDataFetchStatus = "pending"; |
|||
} |
|||
|
|||
async fetchPost(postID) { |
|||
this.orbitPostDataFetchStatus = "fetching"; |
|||
|
|||
var som = this.props.orbitDB.postsDB.get(postID); |
|||
if (som){ |
|||
this.orbitPostData = som; |
|||
} |
|||
this.orbitPostDataFetchStatus = "fetched"; |
|||
} |
|||
|
|||
render(){ |
|||
let avatarView = (this.props.blockchainData[0].returnData |
|||
? <UserAvatar |
|||
size="40" |
|||
className="inline user-avatar" |
|||
src={this.props.avatarUrl} |
|||
name={this.props.blockchainData[0].returnData[2]}/> |
|||
: <div className="user-avatar" style={{width: "40px"}}></div> |
|||
); |
|||
|
|||
return ( |
|||
<div className="pure-u-1-1 post card" |
|||
onClick={() => { this.context.router.push("/topic/" |
|||
+ this.props.blockchainData[0].returnData[4] + "/" |
|||
+ this.props.postID)}}> |
|||
<div className="post-header"> |
|||
<div className="vertical-center-children"> |
|||
{this.props.blockchainData[0].returnData !== null |
|||
?<Link to={"/profile/" + this.props.blockchainData[0].returnData[1] |
|||
+ "/" + this.props.blockchainData[0].returnData[2]} |
|||
onClick={(event) => {event.stopPropagation()}}> |
|||
{avatarView} |
|||
</Link> |
|||
:avatarView |
|||
} |
|||
<p className="inline no-margin"> |
|||
<strong> |
|||
<span style={{color: this.props.blockchainData[0].returnData !== null ? "" : "grey"}}> |
|||
{this.props.blockchainData[0].returnData !== null |
|||
?this.props.blockchainData[0].returnData[2] |
|||
:"Username" |
|||
} |
|||
</span> |
|||
<br/> |
|||
<span style={{color: this.orbitPostData.subject ? "" : "grey"}}> |
|||
Subject: {this.orbitPostData.subject} |
|||
</span> |
|||
</strong> |
|||
</p> |
|||
</div> |
|||
<div className="post-info"> |
|||
<span> |
|||
Posted {this.props.blockchainData[0].returnData !== null && |
|||
<TimeAgo date={epochTimeConverter(this.props.blockchainData[0].returnData[3])}/> |
|||
} |
|||
</span> |
|||
<span>#{this.props.postIndex}</span> |
|||
</div> |
|||
</div> |
|||
<div className="post-info"> |
|||
<span>Posted <TimeAgo date={props.post.date}/></span> |
|||
<span>#{props.post.postIndex}</span> |
|||
<hr/> |
|||
<div className="post-content"> |
|||
{this.orbitPostData.content |
|||
? <ReactMarkdown source={this.orbitPostData.content} /> |
|||
: <p style={{color: 'grey'}}>Post content...</p> |
|||
} |
|||
</div> |
|||
</div> |
|||
<hr/> |
|||
<div className="post-content"> |
|||
{props.post.postContent |
|||
? <ReactMarkdown source={props.post.postContent} /> |
|||
: <p style={{color: 'grey'}}>Post content...</p> |
|||
} |
|||
</div> |
|||
<hr/> |
|||
<div className="post-meta"> |
|||
Maybe add buttons for upvote etc here... |
|||
</div> |
|||
</div> |
|||
: <div className="pure-u-1-1 post card" style={{color: 'grey'}}> |
|||
<div className="post-header"> |
|||
<p className="inline no-margin"> |
|||
<strong>Subject</strong> |
|||
</p> |
|||
<div className="post-info"> |
|||
<span>Posted </span> |
|||
<hr/> |
|||
<div className="post-meta"> |
|||
Maybe add buttons for upvote etc here... |
|||
</div> |
|||
</div> |
|||
<hr/> |
|||
<div className="post-content"> |
|||
<p>Post content...</p> |
|||
</div> |
|||
<hr/> |
|||
<div className="post-meta"> |
|||
Maybe add buttons for upvote etc here... |
|||
</div> |
|||
</div> |
|||
); |
|||
); |
|||
} |
|||
|
|||
componentDidUpdate() { |
|||
if (this.props.blockchainData[0].status === "success" |
|||
&& this.orbitPostDataFetchStatus === "pending") { |
|||
this.fetchPost(this.props.postID); |
|||
} |
|||
} |
|||
}; |
|||
|
|||
Post.contextTypes = { |
|||
router: PropTypes.object |
|||
}; |
|||
|
|||
const mapStateToProps = state => { |
|||
return { |
|||
user: state.user, |
|||
orbitDB: state.orbitDB |
|||
} |
|||
}; |
|||
|
|||
export default withRouter(Post); |
|||
export default drizzleConnect(withRouter(Post), mapStateToProps); |
@ -1,110 +1,35 @@ |
|||
import { drizzleConnect } from 'drizzle-react'; |
|||
import React, { Component } from 'react'; |
|||
import PropTypes from 'prop-types'; |
|||
import React from 'react'; |
|||
|
|||
import Post from './Post'; |
|||
|
|||
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); |
|||
|
|||
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";*/ |
|||
import WithBlockchainData from './WithBlockchainData'; |
|||
|
|||
var som = this.props.orbitDB.postsDB.get(this.props.postIDs[index]); |
|||
this.orbitPostsData[index] = som; |
|||
this.orbitPostsDataFetchStatus[index] = "fetched"; |
|||
} |
|||
|
|||
render (){ |
|||
const posts = this.postsData.map((post, index) => { |
|||
if (post) { |
|||
return ( |
|||
<div onClick={() => { |
|||
this.context.router.push("/topic/" + post[4] + "/" + |
|||
((this.orbitPostsData[index] !== undefined) |
|||
? this.orbitPostsData[index].subject + "/" + this.props.postIDs[index] |
|||
: ""))}} |
|||
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 |
|||
}} |
|||
id={index} |
|||
key={index}/> |
|||
</div> |
|||
); |
|||
} else { |
|||
return ( |
|||
<Post post={null} |
|||
id={index} |
|||
key={index}/> |
|||
); |
|||
} |
|||
}); |
|||
import Post from './Post'; |
|||
|
|||
const PostList = (props) => { |
|||
const posts = props.postIDs.map((postID, index) => { |
|||
return ( |
|||
<div className="posts-list"> |
|||
{posts} |
|||
</div> |
|||
<WithBlockchainData |
|||
component={Post} |
|||
callsInfo={[{ |
|||
contract: 'Forum', |
|||
method: 'getPost', |
|||
params: [postID] |
|||
}]} |
|||
avatarUrl={""} |
|||
postIndex={index} |
|||
postID={postID} |
|||
key={postID} |
|||
/> |
|||
); |
|||
} |
|||
}); |
|||
|
|||
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); |
|||
return ( |
|||
<div className="posts-list"> |
|||
{props.recentToTheTop |
|||
?posts.slice(0).reverse() |
|||
:posts |
|||
} |
|||
} |
|||
} |
|||
}; |
|||
|
|||
PostList.contextTypes = { |
|||
drizzle: PropTypes.object, |
|||
router: PropTypes.object |
|||
}; |
|||
|
|||
const mapStateToProps = state => { |
|||
return { |
|||
user: state.user, //Needed!!
|
|||
orbitDB: state.orbitDB |
|||
} |
|||
</div> |
|||
); |
|||
}; |
|||
|
|||
export default drizzleConnect(PostList, mapStateToProps); |
|||
export default PostList; |
@ -1,38 +1,51 @@ |
|||
import React from 'react'; |
|||
import UserAvatar from 'react-user-avatar'; |
|||
|
|||
import epochTimeConverter from '../helpers/EpochTimeConverter'; |
|||
|
|||
import UsernameFormContainer from '../containers/UsernameFormContainer'; |
|||
|
|||
const ProfileInformation = (props) => { |
|||
return ( |
|||
<div className="pure-u-1-1 user-info card"> |
|||
{props.avatarUrl && <UserAvatar |
|||
size="40" |
|||
className="inline user-avatar" |
|||
src={props.avatarUrl} |
|||
name={props.username}/>} |
|||
<p className="no-margin inline"> |
|||
<strong>Username:</strong> {props.username} |
|||
</p> |
|||
<p className="no-margin"> |
|||
<strong>Account address:</strong> {props.address} |
|||
</p> |
|||
<p className="no-margin"> |
|||
<strong>OrbitDB:</strong> {props.orbitAddress} |
|||
</p> |
|||
<p className="no-margin"> |
|||
<strong>Number of topics created:</strong> {props.numberOfTopics} |
|||
</p> |
|||
<p className="no-margin"> |
|||
<strong>Number of posts:</strong> {props.numberOfPosts} |
|||
</p> |
|||
{props.dateOfRegister && |
|||
<p className="no-margin"> |
|||
<strong>Member since:</strong> {props.dateOfRegister} |
|||
</p> |
|||
} |
|||
{props.self && <UsernameFormContainer/>} |
|||
</div> |
|||
); |
|||
let transaction = props.blockchainData |
|||
.find(transaction => transaction.callInfo.method === "getUsername"); |
|||
let username = transaction ? transaction.returnData : ""; |
|||
|
|||
transaction = props.blockchainData |
|||
.find(transaction => transaction.callInfo.method === "getUserDateOfRegister"); |
|||
let dateOfRegister = transaction ? transaction.returnData : ""; |
|||
|
|||
transaction = props.blockchainData |
|||
.find(transaction => transaction.callInfo.method === "getOrbitDBId") |
|||
let orbitDBId = transaction ? transaction.returnData : ""; |
|||
|
|||
return ( |
|||
<div className="pure-u-1-1 user-info card"> |
|||
{props.avatarUrl && <UserAvatar |
|||
size="40" |
|||
className="inline user-avatar" |
|||
src={props.avatarUrl} |
|||
name={username}/>} |
|||
<p className="no-margin inline"> |
|||
<strong>Username:</strong> {username} |
|||
</p> |
|||
<p className="no-margin"> |
|||
<strong>Account address:</strong> {props.address} |
|||
</p> |
|||
<p className="no-margin"> |
|||
<strong>OrbitDB:</strong> {orbitDBId} |
|||
</p> |
|||
<p className="no-margin"> |
|||
<strong>Number of topics created:</strong> {props.numberOfTopics} |
|||
</p> |
|||
<p className="no-margin"> |
|||
<strong>Number of posts:</strong> {props.numberOfPosts} |
|||
</p> |
|||
<p className="no-margin"> |
|||
<strong>Member since:</strong> {epochTimeConverter(dateOfRegister)} |
|||
</p> |
|||
{props.self && <UsernameFormContainer/>} |
|||
</div> |
|||
); |
|||
}; |
|||
|
|||
export default ProfileInformation; |
@ -1,30 +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 epochTimeConverter from '../helpers/EpochTimeConverter' |
|||
|
|||
const Topic = (props) => { |
|||
return ( |
|||
props.topic !== null |
|||
? <div className={"pure-u-1-1 topic card"}> |
|||
<p className="topic-subject" style={{color: props.topic.topicSubject ? "" : "grey"}}> |
|||
<strong>{props.topic.topicSubject ? props.topic.topicSubject : "Subject"}</strong> |
|||
</p> |
|||
<hr/> |
|||
<div className="topic-meta"> |
|||
<p className="no-margin">{props.topic.topicStarter}</p> |
|||
<p className="no-margin">Number of replies: {props.topic.numberOfReplies}</p> |
|||
<p className="topic-date">Started <TimeAgo date={props.topic.date}/></p> |
|||
</div> |
|||
</div> |
|||
: <div className={"pure-u-1-1 topic card"} style={{color: 'grey'}}> |
|||
<p className="topic-subject"><strong>Subject</strong></p> |
|||
<hr/> |
|||
<div className="topic-meta"> |
|||
<p className="no-margin">Username</p> |
|||
<p className="no-margin">Number of replies: </p> |
|||
<p className="topic-date">Started </p> |
|||
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"; |
|||
|
|||
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 ( |
|||
<Link to={"/topic/" + this.props.topicID}> |
|||
<div className={"pure-u-1-1 topic card"}> |
|||
<p className="topic-subject" style={{color: this.topicSubject ? "" : "grey"}}> |
|||
<strong>{this.topicSubject !== null ? this.topicSubject : "Subject"}</strong> |
|||
</p> |
|||
<hr/> |
|||
<div className="topic-meta"> |
|||
<p className="no-margin" style={{ |
|||
color: this.props.blockchainData[0].returnData !== null ? "" : "grey" |
|||
}}> |
|||
{this.props.blockchainData[0].returnData !== null |
|||
?this.props.blockchainData[0].returnData[2] |
|||
:"Username" |
|||
} |
|||
</p> |
|||
<p className="no-margin" style={{ |
|||
color: this.props.blockchainData[0].returnData !== null ? "" : "grey" |
|||
}}> |
|||
{"Number of replies: " + (this.props.blockchainData[0].returnData !== null |
|||
?this.props.blockchainData[0].returnData[4].length |
|||
:"") |
|||
} |
|||
</p> |
|||
<p className="topic-date"> |
|||
Started {this.props.blockchainData[0].returnData !== null && |
|||
<TimeAgo date={epochTimeConverter(this.props.blockchainData[0].returnData[3])}/> |
|||
} |
|||
</p> |
|||
</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); |
@ -1,118 +1,30 @@ |
|||
import { drizzleConnect } from 'drizzle-react'; |
|||
import React, { Component } from 'react'; |
|||
import { Link } from 'react-router'; |
|||
import PropTypes from 'prop-types'; |
|||
import React from 'react'; |
|||
|
|||
import Topic from './Topic'; |
|||
|
|||
import epochTimeConverter from '../helpers/EpochTimeConverter' |
|||
|
|||
const contract = "Forum"; |
|||
const contractMethod = "getTopic"; |
|||
|
|||
class TopicList extends Component { |
|||
constructor(props, context) { |
|||
super(props); |
|||
|
|||
this.fetchSubject = this.fetchSubject.bind(this); |
|||
|
|||
this.drizzle = context.drizzle; |
|||
this.dataKeys = []; |
|||
this.topicsData = new Array(parseInt(this.props.topicIDs.length, 10)).fill(undefined); |
|||
this.topicsSubjects = []; |
|||
this.topicsSubjectsFetchStatus = new Array(parseInt(this.props.topicIDs.length, 10)).fill("pending"); |
|||
|
|||
for (var i = 0; i < this.props.topicIDs.length; ++i){ |
|||
this.dataKeys[i] = this.drizzle.contracts[contract].methods[contractMethod] |
|||
.cacheCall(this.props.topicIDs[i]); |
|||
} |
|||
|
|||
this.state = { |
|||
}; |
|||
} |
|||
import WithBlockchainData from './WithBlockchainData'; |
|||
|
|||
async fetchSubject(topicIndex) { |
|||
if (this.topicsData[topicIndex][1] === this.props.user.address){ |
|||
let som =this.props.orbitDB.topicsDB.get(this.props.topicIDs[topicIndex]); |
|||
this.topicsSubjects[topicIndex] = som['subject']; |
|||
this.topicsSubjectsFetchStatus[topicIndex] = "fetched"; |
|||
} else { |
|||
const fullAddress = "/orbitdb" + this.topicsData[topicIndex][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(this.props.topicIDs[topicIndex]); |
|||
this.topicsSubjects[topicIndex] = som['subject']; |
|||
this.topicsSubjectsFetchStatus[topicIndex] = "fetched"; |
|||
} |
|||
} |
|||
|
|||
render (){ |
|||
const topics = this.topicsData.map((topic, index) => { |
|||
if (topic){ |
|||
return ( |
|||
<Link to={"/topic/" + this.props.topicIDs[index] + "/" + |
|||
((this.topicsSubjects[index] !== undefined) ? this.topicsSubjects[index] + "/" + 0 : "")} |
|||
key={index}> |
|||
<Topic topic={{ |
|||
topicSubject: ((this.topicsSubjects[index] !== undefined) && this.topicsSubjects[index]), |
|||
topicStarter: topic[2], |
|||
numberOfReplies: topic[4].length, |
|||
date: epochTimeConverter(topic[3]) |
|||
}} |
|||
id={index} |
|||
key={index}/> |
|||
</Link> |
|||
); |
|||
} else { |
|||
return ( |
|||
<Link to={"/topic/" + this.props.topicIDs[index] + "/"} |
|||
key={index}> |
|||
<Topic topic={null} |
|||
id={index} |
|||
key={index}/> |
|||
</Link> |
|||
); |
|||
} |
|||
}); |
|||
import Topic from './Topic'; |
|||
|
|||
const TopicList = (props) => { |
|||
const topics = props.topicIDs.map((topicID) => { |
|||
return ( |
|||
<div className="topics-list"> |
|||
{topics.slice(0).reverse()} |
|||
</div> |
|||
<WithBlockchainData |
|||
component={Topic} |
|||
callsInfo={[{ |
|||
contract: 'Forum', |
|||
method: 'getTopic', |
|||
params: [topicID] |
|||
}]} |
|||
topicID={topicID} |
|||
key={topicID} |
|||
/> |
|||
); |
|||
} |
|||
|
|||
componentWillReceiveProps() { |
|||
for (var i = 0; i < this.props.topicIDs.length; ++i){ |
|||
if (this.topicsData[i] === undefined) { |
|||
let currentDrizzleState = this.drizzle.store.getState(); |
|||
let dataFetched = (currentDrizzleState.contracts[contract][contractMethod])[this.dataKeys[i]]; |
|||
if (dataFetched){ |
|||
this.topicsData[i] = dataFetched.value; |
|||
} |
|||
} else if (!this.topicsSubjects[i] && this.topicsSubjectsFetchStatus[i] === "pending") { |
|||
this.topicsSubjectsFetchStatus[i] = "fetching"; |
|||
this.fetchSubject(i); |
|||
} |
|||
} |
|||
} |
|||
}; |
|||
|
|||
TopicList.contextTypes = { |
|||
drizzle: PropTypes.object |
|||
}; |
|||
}); |
|||
|
|||
const mapStateToProps = state => { |
|||
return { |
|||
user: state.user, //Needed!!
|
|||
orbitDB: state.orbitDB, |
|||
} |
|||
return ( |
|||
<div className="topics-list"> |
|||
{topics.slice(0).reverse()} |
|||
</div> |
|||
); |
|||
}; |
|||
|
|||
export default drizzleConnect(TopicList, mapStateToProps); |
|||
export default TopicList; |
@ -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