From dfcb139e3ce181319c8b7611384c8a6245024817 Mon Sep 17 00:00:00 2001 From: Apostolof Date: Fri, 8 Jun 2018 02:57:47 +0300 Subject: [PATCH] Add contract and OrbitDB interaction in StartTopic, BoardContainer and TopicList --- contracts/Forum.sol | 33 ++++++- src/assets/css/App.css | 33 +++++++ src/components/FloatingButton.js | 4 +- src/components/StartTopic.js | 124 +++++++++++++++++++----- src/components/Topic.js | 28 ++++-- src/components/TopicList.js | 159 ++++++++++++++++++++++--------- src/containers/BoardContainer.js | 61 +++++++++--- src/util/drizzleOptions.js | 7 +- src/util/orbit.js | 53 +++++++++-- src/util/orbitReducer.js | 12 +++ 10 files changed, 408 insertions(+), 106 deletions(-) diff --git a/contracts/Forum.sol b/contracts/Forum.sol index cbd2470..acea856 100644 --- a/contracts/Forum.sol +++ b/contracts/Forum.sol @@ -55,7 +55,7 @@ contract Forum { return false; } - //---------OrbitDB--------- + //----------------------------------------OrbitDB---------------------------------------- struct OrbitDB { string id; // TODO: set an upper bound instead of arbitrary string string topicsDB; //TODO: not sure yet which of these are actually needed @@ -123,11 +123,17 @@ contract Forum { mapping (uint => Topic) topics; mapping (uint => Post) posts; + event TopicCreated(uint topicID); + event PostCreated(uint postID, uint topicID); + event NumberOfTopicsReceived(uint numTopics); + event TopicReceived(string orbitTopicsDB, address author, string username, uint timestamp, uint[] postIDs); + function createTopic() public returns (uint) { require(hasUserSignedUp(msg.sender)); // Only registered users can create topics uint topicID = numTopics++; topics[topicID] = Topic(topicID, msg.sender, block.timestamp, new uint[](0)); users[msg.sender].topicIDs.push(topicID); + emit TopicCreated(topicID); return topicID; } @@ -138,10 +144,33 @@ contract Forum { posts[postID] = Post(postID, msg.sender, block.timestamp); topics[topicID].postIDs.push(postID); users[msg.sender].postIDs.push(postID); + emit PostCreated(postID, topicID); return postID; } - function getTopicPosts (uint topicID) public view returns (uint[]) { + function getNumberOfTopics() public view returns (uint) { + emit NumberOfTopicsReceived(numTopics); + return numTopics; + } + + function getTopic(uint topicID) public view returns (string, address, string, uint, uint[]) { + //require(hasUserSignedUp(msg.sender)); needed? + require(topicID { return ( -
-

+

+

diff --git a/src/components/StartTopic.js b/src/components/StartTopic.js index 5785a7d..464eda5 100644 --- a/src/components/StartTopic.js +++ b/src/components/StartTopic.js @@ -1,10 +1,11 @@ import { drizzleConnect } from 'drizzle-react' import React, { Component } from 'react' import PropTypes from 'prop-types' + import Post from './Post' const contract = "Forum"; -const startTopicMethod = "createTopic"; +const contractMethod = "createTopic"; class StartTopic extends Component { constructor(props, context) { @@ -12,28 +13,49 @@ class StartTopic extends Component { this.handleInputChange = this.handleInputChange.bind(this); this.handlePreviewToggle = this.handlePreviewToggle.bind(this); - this.handleSubmit = this.handleSubmit.bind(this); + this.validateAndPost = this.validateAndPost.bind(this); + this.pushToDatabase = this.pushToDatabase.bind(this); + this.transactionProgressText = []; this.drizzle = context.drizzle; - this.drizzleState = this.drizzle.store.getState(); - this.contracts = this.drizzle.contracts; - this.abi = this.contracts[contract].abi; + this.state = { topicSubjectInput: '', topicMessageInput: '', + topicSubjectInputEmptySubmit: false, + topicMessageInputEmptySubmit: false, previewEnabled: false, - previewDate: "" + previewDate: "", + creatingTopic: false, + transactionState: null, + savingToOrbitDB: null }; } - async handleSubmit() { - console.log("contracts:"); - console.log(this.contracts); - console.log("DS contracts:"); - console.log(this.drizzleState.contracts); + async validateAndPost() { + if (this.state.topicSubjectInput === '' || this.state.topicMessageInput === ''){ + this.setState({ + topicSubjectInputEmptySubmit: this.state.topicSubjectInput === '', + topicMessageInputEmptySubmit: this.state.topicMessageInput === '' + }); + return; + } + + this.stackId = this.drizzle.contracts[contract].methods[contractMethod].cacheSend(); + this.transactionProgressText.push(
); + this.transactionProgressText.push("Waiting for transaction acceptance..."); + this.setState({ + 'creatingTopic': true, + 'transactionState': "ACCEPTANCE_PENDING" + }); + } - this.dataKey = this.drizzleState.contracts[contract].methods[startTopicMethod].cacheCall(); - //TODO get return value and pass it to orbit + async pushToDatabase() { + await this.props.orbitDB.topicsDB.put(this.topicIDFetched, { + subject: this.state.topicSubjectInput, + content: this.state.topicMessageInput + }); + this.setState({'savingToOrbitDB': "SUCCESS"}); } handleInputChange(event) { @@ -49,23 +71,25 @@ class StartTopic extends Component { getDate() { const currentdate = new Date(); - return ((currentdate.getMonth() + 1) + " " + return ((currentdate.getMonth() + 1) + " " + currentdate.getDate() + ", " - + currentdate.getFullYear() + ", " - + currentdate.getHours() + ":" - + currentdate.getMinutes() + ":" + + currentdate.getFullYear() + ", " + + currentdate.getHours() + ":" + + currentdate.getMinutes() + ":" + currentdate.getSeconds()); } render() { - if(this.dataKey) { - /*console.log(this.drizzleState);*/ - if (this.drizzleState.contracts[contract]) { - console.log(this.drizzleState.contracts[contract].storedData[this.dataKey].value); - } - } return(
+ {this.state.creatingTopic &&
+
+

+
+ {this.transactionProgressText} +
+
+ }

@@ -83,6 +107,7 @@ class StartTopic extends Component { [ ,