-
-
-
-
-
Username
-
Number of replies:
-
+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 (
+
+
+
+
+
+ {topic.topicSubject !== null ? topic.topicSubject : "Subject"}
+
+
+
+
+
+ {this.props.blockchainData[0].returnData !== null
+ ?this.props.blockchainData[0].returnData[2]
+ :"Username"
+ }
+
+
+ {"Number of replies: " + (this.props.blockchainData[0].returnData !== null
+ ?this.props.blockchainData[0].returnData[4].length
+ :"")
+ }
+
+
+ Started {this.props.blockchainData[0].returnData !== null &&
+
+ }
+
+
-
- );
+
+ );
+ }
+
+ componentDidUpdate(){
+ if (this.props.blockchainData[0].returnData !== null && this.topicSubjectFetchStatus === "pending") {
+ this.fetchSubject(this.props.topicID);
+ }
+ }
};
-export default Topic;
\ No newline at end of file
+const mapStateToProps = state => {
+ return {
+ user: state.user,
+ orbitDB: state.orbitDB
+ }
+}
+
+export default drizzleConnect(Topic, mapStateToProps);
\ No newline at end of file
diff --git a/src/components/TopicList.js b/src/components/TopicList.js
index de24078..4f64066 100644
--- a/src/components/TopicList.js
+++ b/src/components/TopicList.js
@@ -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 (
-
-
-
- );
- } else {
- return (
-
-
-
- );
- }
- });
+import Topic from './Topic';
+const TopicList = (props) => {
+ const topics = props.topicIDs.map((topicID) => {
return (
-
- {topics.slice(0).reverse()}
-
+
);
- }
-
- 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 (
+
+ {topics.slice(0).reverse()}
+
+ );
};
-export default drizzleConnect(TopicList, mapStateToProps);
\ No newline at end of file
+export default TopicList;
\ No newline at end of file
diff --git a/src/components/WithBlockchainData.js b/src/components/WithBlockchainData.js
new file mode 100644
index 0000000..640e5da
--- /dev/null
+++ b/src/components/WithBlockchainData.js
@@ -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 (
+
+ );
+ }
+
+ 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;
\ No newline at end of file
diff --git a/src/containers/BoardContainer.js b/src/containers/BoardContainer.js
index d329940..ba00557 100644
--- a/src/containers/BoardContainer.js
+++ b/src/containers/BoardContainer.js
@@ -2,32 +2,28 @@ import { drizzleConnect } from 'drizzle-react';
import React, { Component } from 'react';
import PropTypes from 'prop-types';
+import WithBlockchainData from '../components/WithBlockchainData';
import TopicList from '../components/TopicList';
import FloatingButton from '../components/FloatingButton';
import LoadingSpinner from '../components/LoadingSpinner';
-const contract = "Forum";
-const contractMethod = "getNumberOfTopics";
-
class Board extends Component {
constructor(props, context) {
super(props);
-
- this.drizzle = context.drizzle;
-
- this.state = {
- transactionState: null
- };
}
render() {
var boardContents;
- if (this.state.transactionState !== "SUCCESS") {
+ if (!this.props.blockchainData[0].returnData) {
boardContents = (
);
} else {
- boardContents = ;
+ this.topicIDs = [];
+ for (var i = 0; i < this.props.blockchainData[0].returnData; i++) {
+ this.topicIDs.push(i);
+ }
+ boardContents =
}
return (
@@ -37,28 +33,6 @@ class Board extends Component {
);
}
-
- componentWillReceiveProps() {
- if (this.state.transactionState === null){
- if (this.drizzle.contracts[contract]){ //Waits until drizzle is initialized
- //This gets called only once but should be called every time someone posts
- this.dataKey = this.drizzle.contracts[contract].methods[contractMethod].cacheCall();
- this.setState({'transactionState': "IN_PROGRESS"});
- }
- }
- if (!this.numberOfTopics) {
- let currentDrizzleState = this.drizzle.store.getState();
- let dataFetched = (currentDrizzleState.contracts[contract][contractMethod])[this.dataKey];
- if (dataFetched){
- this.numberOfTopics = dataFetched.value;
- this.topicIDs = [];
- for (var i = 0; i < this.numberOfTopics; i++) {
- this.topicIDs.push(i);
- }
- this.setState({'transactionState': "SUCCESS"});
- }
- }
- }
}
Board.contextTypes = {
@@ -71,6 +45,23 @@ const mapStateToProps = state => {
}
};
-const BoardContainer = drizzleConnect(Board, mapStateToProps);
+class BoardContainer extends Component {
+ constructor(props){
+ super(props);
+
+ this.board =
;
+ }
+
+ render() {
+ return(this.board);
+ }
+}
export default BoardContainer;
\ No newline at end of file
diff --git a/src/containers/ProfileContainer.js b/src/containers/ProfileContainer.js
index c0e61d2..264bb34 100644
--- a/src/containers/ProfileContainer.js
+++ b/src/containers/ProfileContainer.js
@@ -3,47 +3,20 @@ import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import PropTypes from 'prop-types';
+import WithBlockchainData from '../components/WithBlockchainData';
import ProfileInformation from '../components/ProfileInformation';
import TopicList from '../components/TopicList';
import PostList from '../components/PostList';
import LoadingSpinner from '../components/LoadingSpinner';
-import epochTimeConverter from '../helpers/EpochTimeConverter';
import '../assets/css/materialTabs.css';
-const contract = "Forum";
-const contractMethods = {
- getUsername: "getUsername",
- getDateOfRegister: "getUserDateOfRegister",
- getOrbitDB: "getOrbitDBId",
- getUserTopics: "getUserTopics",
- getUserPosts: "getUserPosts"
-};
-
class Profile extends Component {
constructor(props, context) {
super(props);
- /*console.log(this.props.params.address);
- console.log(this.props.user.address);*/
-
- if (this.props.params.address == this.props.user.address){
- this.profile = {
- userAddress: this.props.params.address,
- username: this.props.params.username ? this.props.params.username : "",
- orbitId: "",
- self: false
- }
- } else {
- this.profile = {
- userAddress: this.props.user.address,
- username: this.props.user.username,
- orbitId: this.props.orbitDB.id,
- self: true
- }
- }
-
this.handleTabClick = this.handleTabClick.bind(this);
+ this.propsToView = this.propsToView.bind(this);
this.drizzle = context.drizzle;
this.underlineBarRef = React.createRef();
@@ -53,17 +26,7 @@ class Profile extends Component {
this.state = {
viewSelected: "profile-info-tab",
- username: this.profile.username,
- userAddress: this.profile.userAddress,
- dateOfRegister: null,
- orbitDBId: this.profile.orbitId,
- getUsernameTransactionState: null,
- getDateOfRegisterTransactionState: null,
- getOrbitDBTransactionState: this.profile.orbitId ? "SUCCESS" : null,
- getTopicsTransactionState: null,
- getPostsTransactionState: null,
- topicIDs: [],
- postIDs: []
+ userAddress: this.profile.userAddress
};
}
@@ -85,26 +48,40 @@ class Profile extends Component {
}
render() {
+ this.propsToView();
var infoTab =
- (
);
+ (
);
var topicsTab =
(
- {this.state.getTopicsTransactionState === "SUCCESS"
- ?
+ {this.topicIDs
+ ?
:
}
);
var postsTab =
(
- {this.state.getPostsTransactionState === "SUCCESS"
- ?
+ {this.postIDs
+ ?
:
}
);
@@ -152,99 +129,19 @@ class Profile extends Component {
);
}
- componentWillReceiveProps() {
- if (this.state.getUsernameTransactionState === null){
- if (this.drizzle.contracts[contract]){ //Waits until drizzle is initialized
- this.usernameKey = this.drizzle.contracts[contract]
- .methods[contractMethods.getUsername].cacheCall(this.state.userAddress);
- this.setState({'getUsernameTransactionState': "IN_PROGRESS"});
- }
- }
- if (this.state.getUsernameTransactionState === "IN_PROGRESS") {
- let currentDrizzleState = this.drizzle.store.getState();
- let dataFetched = (currentDrizzleState
- .contracts[contract][contractMethods.getUsername])[this.usernameKey];
- if (dataFetched){
- this.setState({
- 'username': dataFetched.value,
- 'getUsernameTransactionState': "SUCCESS"
- });
- }
- }
-
- if (this.state.getDateOfRegisterTransactionState === null){
- if (this.drizzle.contracts[contract]){ //Waits until drizzle is initialized
- this.dateOfRegisterKey = this.drizzle.contracts[contract]
- .methods[contractMethods.getDateOfRegister].cacheCall(this.state.userAddress);
- this.setState({'getDateOfRegisterTransactionState': "IN_PROGRESS"});
- }
- }
- if (this.state.getDateOfRegisterTransactionState === "IN_PROGRESS") {
- let currentDrizzleState = this.drizzle.store.getState();
- let dataFetched = (currentDrizzleState
- .contracts[contract][contractMethods.getDateOfRegister])[this.dateOfRegisterKey];
- if (dataFetched){
- this.setState({
- 'dateOfRegister': epochTimeConverter(dataFetched.value),
- 'getDateOfRegisterTransactionState': "SUCCESS"
- });
- }
- }
-
- if (this.state.getOrbitDBTransactionState === null){
- if (this.drizzle.contracts[contract]){ //Waits until drizzle is initialized
- this.orbitDBIdKey = this.drizzle.contracts[contract]
- .methods[contractMethods.getOrbitDB].cacheCall(this.state.userAddress);
- this.setState({'getOrbitDBTransactionState': "IN_PROGRESS"});
- }
- }
- if (this.state.getOrbitDBTransactionState === "IN_PROGRESS") {
- let currentDrizzleState = this.drizzle.store.getState();
- let dataFetched = (currentDrizzleState
- .contracts[contract][contractMethods.getOrbitDB])[this.orbitDBIdKey];
- if (dataFetched){
- this.setState({
- 'orbitDBId': dataFetched.value,
- 'getOrbitDBTransactionState': "SUCCESS"
- });
- }
- }
-
- if (this.state.getTopicsTransactionState === null){
- if (this.drizzle.contracts[contract]){ //Waits until drizzle is initialized
- this.getTopicsKey = this.drizzle.contracts[contract]
- .methods[contractMethods.getUserTopics].cacheCall(this.state.userAddress);
- this.setState({'getTopicsTransactionState': "IN_PROGRESS"});
- }
- }
- if (this.state.getTopicsTransactionState === "IN_PROGRESS") {
- let currentDrizzleState = this.drizzle.store.getState();
- let dataFetched = (currentDrizzleState
- .contracts[contract][contractMethods.getUserTopics])[this.getTopicsKey];
- if (dataFetched){
- this.setState({
- 'topicIDs': dataFetched.value,
- 'getTopicsTransactionState': "SUCCESS"
- });
+ propsToView(){
+ if (!this.topicIDs){
+ let transaction = this.props.blockchainData
+ .find(transaction => transaction.callInfo.method === "getUserTopics");
+ if (transaction.returnData){
+ this.topicIDs = transaction.returnData;
}
}
-
- if (this.state.getPostsTransactionState === null){
- if (this.drizzle.contracts[contract]){ //Waits until drizzle is initialized
- this.getPostsKey = this.drizzle.contracts[contract]
- .methods[contractMethods.getUserPosts].cacheCall(this.state.userAddress);
- this.setState({'getPostsTransactionState': "IN_PROGRESS"});
- }
- }
- if (this.state.getPostsTransactionState === "IN_PROGRESS") {
- let currentDrizzleState = this.drizzle.store.getState();
- let dataFetched = (currentDrizzleState
- .contracts[contract][contractMethods.getUserPosts])[this.getPostsKey];
- if (dataFetched){
- this.setState({
- 'postIDs': dataFetched.value,
- 'getPostsTransactionState': "SUCCESS"
- });
+ if (!this.postIDs){
+ let transaction = this.props.blockchainData
+ .find(transaction => transaction.callInfo.method === "getUserPosts");
+ if (transaction.returnData){
+ this.postIDs = transaction.returnData;
}
}
}
@@ -260,14 +157,46 @@ Profile.contextTypes = {
const mapStateToProps = state => {
return {
- accounts: state.accounts,
- Forum: state.contracts.Forum,
user: state.user,
- orbitDB: state.orbitDB,
- drizzleStatus: state.drizzleStatus
+ orbitDB: state.orbitDB
}
};
-const ProfileContainer = drizzleConnect(Profile, mapStateToProps);
+class ProfileContainer extends Component {
+ constructor(props){
+ super(props);
+
+ let userAddress;
+ if (this.props.params.address){
+ userAddress = this.props.params.address;
+ } else {
+ userAddress = this.props.user.address;
+ }
+
+ this.profile =
+ }
+
+ render() {
+ return(this.profile);
+ }
+}
+
+const containerProps = state => {
+ return {
+ user: state.user
+ }
+};
-export default ProfileContainer;
\ No newline at end of file
+export default drizzleConnect(ProfileContainer, containerProps);
\ No newline at end of file
diff --git a/src/containers/StartTopicContainer.js b/src/containers/StartTopicContainer.js
index 4b590a6..62f32a5 100644
--- a/src/containers/StartTopicContainer.js
+++ b/src/containers/StartTopicContainer.js
@@ -237,8 +237,7 @@ class StartTopic extends Component {
'savingToOrbitDB': null,
'transactionOutputTimerActive': false
});
- this.props.router.push("/topic/" + this.topicIDFetched + "/"
- + this.state.topicSubjectInput);
+ this.props.router.push("/topic/" + this.topicIDFetched);
}, 5000);
}
else if (this.state.savingToOrbitDB === "ERROR"){
diff --git a/src/containers/TopicContainer.js b/src/containers/TopicContainer.js
index bdb2e2c..eeae87a 100644
--- a/src/containers/TopicContainer.js
+++ b/src/containers/TopicContainer.js
@@ -2,22 +2,16 @@ import { drizzleConnect } from 'drizzle-react';
import React, { Component } from 'react';
import PropTypes from 'prop-types';
+import WithBlockchainData from '../components/WithBlockchainData';
import PostList from '../components/PostList';
import NewPost from '../components/NewPost';
import FloatingButton from '../components/FloatingButton';
import LoadingSpinner from '../components/LoadingSpinner';
-const contract = "Forum";
-const contractMethod = "getTopic";
-
class Topic extends Component {
constructor(props, context) {
super(props);
- if (!/^[0-9]+$/.test(this.props.params.topicId)){
- this.props.router.push("/404");
- }
-
this.fetchTopicSubject = this.fetchTopicSubject.bind(this);
this.handleClick = this.handleClick.bind(this);
this.postCreated = this.postCreated.bind(this);
@@ -43,7 +37,7 @@ class Topic extends Component {
this.topicsSubjects[this.state.topicID] = som['subject'];
this.topicsSubjectsFetchStatus[this.state.topicID] = "fetched";*/
- var som =this.props.orbitDB.topicsDB.get(JSON.stringify(this.state.topicID));
+ var som =this.props.orbitDB.topicsDB.get(this.state.topicID);
this.setState({'topicSubject': som['subject']});
}
@@ -79,7 +73,7 @@ class Topic extends Component {
onPostCreated={() => {this.postCreated()}}
/>
}
-
+ {this.postList}
{!this.state.posting &&
}
@@ -95,25 +89,22 @@ class Topic extends Component {
}
componentWillReceiveProps() {
- if (this.state.getPostsTransactionState === null){
- if (this.drizzle.contracts[contract]){ //Waits until drizzle is initialized
- //This gets called only once but should be called every time someone posts
- this.getPostsDataKey = this.drizzle.contracts[contract].methods[contractMethod]
- .cacheCall(this.state.topicID);
- this.setState({'getPostsTransactionState': "IN_PROGRESS"});
- }
- }
- if (this.state.getPostsTransactionState === "IN_PROGRESS") {
- let currentDrizzleState = this.drizzle.store.getState();
- let dataFetched = (currentDrizzleState.contracts[contract][contractMethod])[this.getPostsDataKey];
- if (dataFetched){
- if (dataFetched.value){
- this.posts = dataFetched.value[4];
- this.setState({'getPostsTransactionState': "SUCCESS"});
- this.fetchTopicSubject(dataFetched.value[0]);
- } else if (dataFetched.error){
- //TODO
- }
+ if (this.props.blockchainData[0].status === "success") {
+ if (this.state.getPostsTransactionState !== "SUCCESS"){
+ this.postList = {
+ return {
+ contract: 'Forum',
+ method: 'getPost',
+ params: [postID]
+ }
+ })}
+ postIDs={this.props.blockchainData[0].returnData[4]}
+ />
+
+ this.setState({'getPostsTransactionState': "SUCCESS"});
+ this.fetchTopicSubject(this.props.blockchainData[0].returnData[0]);
}
}
}
@@ -130,6 +121,28 @@ const mapStateToProps = state => {
}
};
-const TopicContainer = drizzleConnect(Topic, mapStateToProps);
+class TopicContainer extends Component {
+ constructor(props){
+ super(props);
+
+ if (!/^[0-9]+$/.test(props.params.topicId)){ //Topic ID should be a positive integer
+ this.props.router.push("/404");
+ }
+
+ this.topic = ;
+ }
+
+ render() {
+ return(this.topic);
+ }
+}
export default TopicContainer;
\ No newline at end of file
diff --git a/src/index.js b/src/index.js
index 59864e9..b551365 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,6 +1,7 @@
import React from 'react';
import { render } from 'react-dom';
-import { Router, Route, IndexRoute, browserHistory } from 'react-router';
+import { Router, IndexRoute, browserHistory } from 'react-router';
+import { Route } from 'react-router-dom';
import { syncHistoryWithStore } from 'react-router-redux';
import { DrizzleProvider } from 'drizzle-react';
@@ -31,7 +32,7 @@ render((
-