Browse Source

Init profile page

develop
Apostolos Fanakis 6 years ago
parent
commit
5bd46fecc8
  1. 16
      app/src/components/LoadingSpinner.js
  2. 153
      app/src/components/ProfileInformation.js
  3. 217
      app/src/containers/ProfileContainer.js
  4. 4
      app/src/containers/TransactionsMonitorContainer.js
  5. 11
      app/src/containers/UsernameFormContainer.js
  6. 4
      app/src/router/routes.js

16
app/src/components/LoadingSpinner.js

@ -0,0 +1,16 @@
import React from 'react';
const LoadingSpinner = (props) => {
return(
<div className="vertical-center-children">
<div className={"center-in-parent " + (props.className ? props.className : "")}
style={props.style ? props.style : []}>
<p>
<i className="fas fa-spinner fa-3x fa-spin"></i>
</p>
</div>
</div>
);
}
export default LoadingSpinner;

153
app/src/components/ProfileInformation.js

@ -0,0 +1,153 @@
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { drizzle } from '../index';
import UserAvatar from 'react-user-avatar';
import epochTimeConverter from '../helpers/EpochTimeConverter';
import UsernameFormContainer from '../containers/UsernameFormContainer';
const callsInfo = [{
contract: 'Forum',
method: 'getUserDateOfRegister'
},{
contract: 'Forum',
method: 'getOrbitDBId'
}]
class ProfileInformation extends Component {
constructor(props) {
super(props);
this.dataKey = [];
var pageStatus = 'initialized';
if (this.props.drizzleStatus['initialized']) {
callsInfo.forEach((call, index) => {
this.dataKey[index] = drizzle.contracts[call.contract]
.methods[call.method].cacheCall(this.props.address);
})
pageStatus = 'loading';
}
if (this.dataKey.length !== 0) {
pageStatus = 'loaded';
callsInfo.forEach((call, index) => {
if (!this.props.contracts[call.contract][call.method][this.dataKey[index]]) {
pageStatus = 'loading';
return;
}
})
}
if (pageStatus === 'loaded'){
var dateOfRegister = '';
var orbitDBId = '';
let transaction = this.props.contracts[callsInfo[0].contract][callsInfo[0].method][this.dataKey[0]];
if (transaction){
dateOfRegister = transaction.value;
}
transaction = this.props.contracts[callsInfo[1].contract][callsInfo[1].method][this.dataKey[1]];
if (transaction){
orbitDBId = transaction.value;
}
}
this.state = {
pageStatus: pageStatus,
dateOfRegister: dateOfRegister ? dateOfRegister : '',
orbitDBId: orbitDBId ? orbitDBId : ''
};
}
componentDidUpdate(){
if (this.state.pageStatus === 'initialized' &&
this.props.drizzleStatus['initialized']) {
callsInfo.forEach((call, index) => {
this.dataKey[index] = drizzle.contracts[call.contract]
.methods[call.method].cacheCall(this.props.address);
})
this.setState({ pageStatus: 'loading' });
}
if (this.state.pageStatus === 'loading') {
var pageStatus = 'loaded';
callsInfo.forEach((call, index) => {
if (!this.props.contracts[call.contract][call.method][this.dataKey[index]]) {
pageStatus = 'loading';
return;
}
})
if (pageStatus === 'loaded') {
this.setState({ pageStatus: pageStatus });
}
}
if (this.state.pageStatus === 'loaded'){
if (this.state.dateOfRegister === ''){
let transaction = this.props.contracts[callsInfo[0].contract][callsInfo[0].method][this.dataKey[0]];
if (transaction){
this.setState({ dateOfRegister: transaction.value });
}
}
if (this.state.orbitDBId === ''){
let transaction = this.props.contracts[callsInfo[1].contract][callsInfo[1].method][this.dataKey[1]];
if (transaction){
this.setState({ orbitDBId: transaction.value });
}
}
}
}
render() {
return (
<div className="user-info">
{this.props.avatarUrl && <UserAvatar
size="40"
className="inline user-avatar"
src={this.props.avatarUrl}
name={this.props.username}/>}
<table className="highlight centered responsive-table">
<tbody>
<tr>
<td><strong>Username:</strong></td>
<td>{this.props.username}</td>
</tr>
<tr>
<td><strong>Account address:</strong></td>
<td>{this.props.address}</td>
</tr>
<tr>
<td><strong>OrbitDB:</strong></td>
<td>{this.state.orbitDBId}</td>
</tr>
<tr>
<td><strong>Number of topics created:</strong></td>
<td>{this.props.numberOfTopics}</td>
</tr>
<tr>
<td><strong>Number of posts:</strong></td>
<td>{this.props.numberOfPosts}</td>
</tr>
{this.state.dateOfRegister &&
<tr>
<td><strong>Member since:</strong></td>
<td>{epochTimeConverter(this.state.dateOfRegister)}</td>
</tr>
}
</tbody>
</table>
{this.props.self && <UsernameFormContainer/>}
</div>
);
}
};
const mapStateToProps = state => {
return {
drizzleStatus: state.drizzleStatus,
contracts: state.contracts,
user: state.user
}
};
export default connect(mapStateToProps)(ProfileInformation);

217
app/src/containers/ProfileContainer.js

@ -0,0 +1,217 @@
import React, { Component } from 'react';
import { bindActionCreators } from 'redux';
import { push } from 'connected-react-router'
import { connect } from 'react-redux';
import { drizzle } from '../index';
import { Tab } from 'semantic-ui-react'
import ProfileInformation from '../components/ProfileInformation';
import TopicList from '../components/TopicList';
import PostList from '../components/PostList';
import LoadingSpinner from '../components/LoadingSpinner';
import { setNavBarTitle } from '../redux/actions/userInterfaceActions';
const callsInfo = [{
contract: 'Forum',
method: 'getUsername'
},{
contract: 'Forum',
method: 'getUserTopics'
},{
contract: 'Forum',
method: 'getUserPosts'
}
];
class ProfileContainer extends Component {
constructor(props) {
super(props);
this.dataKey = [];
var address = this.props.match.params.address
? this.props.match.params.address
: this.props.user.address;
var pageStatus = 'initialized';
if (this.props.drizzleStatus['initialized']) {
callsInfo.forEach((call, index) => {
this.dataKey[index] = drizzle.contracts[call.contract]
.methods[call.method].cacheCall(address);
})
pageStatus = 'loading';
}
if (this.dataKey.length !== 0) {
pageStatus = 'loaded';
callsInfo.forEach((call, index) => {
if (!this.props.contracts[call.contract][call.method][this.dataKey[index]]) {
pageStatus = 'loading';
return;
}
})
}
if (pageStatus === 'loaded'){
var username = '';
var topicIDs = null;
var postIDs = null;
let transaction = this.props.contracts[callsInfo[0].contract][callsInfo[0].method][this.dataKey[0]];
if (transaction){
username = transaction.value;
this.props.setNavBarTitle(username);
}
transaction = this.props.contracts[callsInfo[1].contract][callsInfo[1].method][this.dataKey[1]];
if (transaction){
topicIDs = transaction.value;
}
transaction = this.props.contracts[callsInfo[2].contract][callsInfo[2].method][this.dataKey[2]];
if (transaction){
postIDs = transaction.value;
}
/*this.props.store.dispatch(hideProgressBar());*/
}
this.state = {
pageStatus: pageStatus,
userAddress: address,
username: username ? username : '',
topicIDs: topicIDs ? topicIDs : null,
postIDs: postIDs ? postIDs : null
};
}
componentDidUpdate(){
if (this.state.pageStatus === 'initialized' &&
this.props.drizzleStatus['initialized']) {
callsInfo.forEach((call, index) => {
this.dataKey[index] = drizzle.contracts[call.contract]
.methods[call.method].cacheCall(this.props.match.params.address);
})
this.setState({ pageStatus: 'loading' });
}
if (this.state.pageStatus === 'loading') {
var pageStatus = 'loaded';
callsInfo.forEach((call, index) => {
if (!this.props.contracts[call.contract][call.method][this.dataKey[index]]) {
pageStatus = 'loading';
return;
}
})
if (pageStatus === 'loaded') {
this.setState({ pageStatus: pageStatus });
}
}
if (this.state.pageStatus === 'loaded'){
if (this.state.username === ''){
let transaction = this.props.contracts[callsInfo[0].contract][callsInfo[0].method][this.dataKey[0]];
if (transaction){
var username = transaction.value;
this.props.setNavBarTitle(username);
this.setState({ username: username });
}
}
if (this.state.topicIDs === null){
let transaction = this.props.contracts[callsInfo[1].contract][callsInfo[1].method][this.dataKey[1]];
if (transaction){
this.setState({ topicIDs: transaction.value });
}
}
if (this.state.postIDs === null){
let transaction = this.props.contracts[callsInfo[2].contract][callsInfo[2].method][this.dataKey[2]];
if (transaction){
this.setState({ postIDs: transaction.value });
}
}
/*this.props.store.dispatch(hideProgressBar());*/
}
}
render() {
if (!this.props.user.hasSignedUp) {
this.props.navigateTo("/signup");
return(null);
}
var infoTab =
(<ProfileInformation
address={this.state.userAddress}
username={this.state.username}
numberOfTopics={this.state.topicIDs && this.state.topicIDs.length}
numberOfPosts={this.state.postIDs && this.state.postIDs.length}
self={this.state.userAddress === this.props.user.address}
key="profileInfo"
/>);
var topicsTab =
(<div className="profile-tab">
{this.state.topicIDs
? <TopicList topicIDs={this.state.topicIDs} />
: <LoadingSpinner />
}
</div>);
var postsTab =
(<div className="profile-tab">
{this.state.postIDs
? <PostList postIDs={this.state.postIDs} recentToTheTop />
: <LoadingSpinner />
}
</div>);
const profilePanes = [
{
menuItem: 'INFORMATION',
pane: {
key: 'INFORMATION',
content: (infoTab),
},
},
{
menuItem: 'TOPICS',
pane: {
key: 'TOPICS',
content: (topicsTab),
},
},
{
menuItem: 'POSTS',
pane: {
key: 'POSTS',
content: (postsTab),
},
},
]
return (
<div>
<Tab
menu={{ secondary: true, pointing: true }}
panes={profilePanes}
renderActiveOnly={false} />
</div>
);
}
componentWillUnmount() {
this.props.setNavBarTitle('');
}
}
const mapDispatchToProps = dispatch => bindActionCreators({
navigateTo: (location) => push(location),
setNavBarTitle: (navBarTitle) => setNavBarTitle(navBarTitle)
}, dispatch);
const mapStateToProps = state => {
return {
user: state.user,
drizzleStatus: state.drizzleStatus,
contracts: state.contracts,
orbitDB: state.orbitDB
}
};
export default connect(mapStateToProps, mapDispatchToProps)(ProfileContainer);

4
app/src/containers/TransactionsMonitorContainer.js

@ -29,6 +29,10 @@ class RightSideBar extends Component {
this.props.history.push("/profile");
this.handleMessageDismiss(null, index);
break;
case 'UsernameUpdated':
this.props.history.push("/profile");
this.handleMessageDismiss(null, index);
break;
case 'TopicCreated':
this.props.history.push("/topic/" +
this.props.transactions[transactionHash].receipt.events.TopicCreated.returnValues.topicID

11
app/src/containers/UsernameFormContainer.js

@ -5,7 +5,7 @@ import { Button, Message, Form, Dimmer, Loader, Header } from 'semantic-ui-react
import { drizzle } from '../index';
import { createDatabases } from '../orbit';
/*import { updateUsername } from '../redux/actions/transactionsMonitorActions';*/
import { updateUsername } from '../redux/actions/transactionsActions';
const contract = "Forum";
const checkUsernameTakenMethod = "isUserNameTaken";
@ -62,8 +62,7 @@ class UsernameFormContainer extends Component {
async completeAction() {
if(this.props.user.hasSignedUp){
//TODO
/*this.props.store.dispatch(updateUsername(...[this.state.usernameInput], null));*/
this.props.dispatch(updateUsername(...[this.state.usernameInput], null));
} else {
this.setState({ signingUp: true });
const orbitdbInfo = await createDatabases();
@ -79,13 +78,15 @@ class UsernameFormContainer extends Component {
orbitdbInfo.postsDB
], { from: this.props.account});
}
/*this.setState({ usernameInput: '' });*/
this.setState({ usernameInput: '' });
}
componentDidUpdate() {
if (this.state.signingUp) {
const txHash = this.props.transactionStack[this.stackId];
if (txHash && this.props.transactions[txHash].status === "error") {
if (txHash &&
this.props.transactions[txHash] &&
this.props.transactions[txHash].status === "error") {
this.setState({signingUp: false});
}
} else {

4
app/src/router/routes.js

@ -5,6 +5,7 @@ import HomeContainer from '../containers/HomeContainer'
import SignUpContainer from '../containers/SignUpContainer'
import StartTopicContainer from '../containers/StartTopicContainer'
import TopicContainer from '../containers/TopicContainer'
import ProfileContainer from '../containers/ProfileContainer'
import NotFound from '../components/NotFound'
const routes = (
@ -15,7 +16,8 @@ const routes = (
<Redirect from='/home' to="/" />
<Route path="/signup" component={SignUpContainer} />
<Route path="/startTopic" component={StartTopicContainer} />
<Route path="/topic/:topicId" component={TopicContainer} />
<Route path="/topic/:topicId/:postId?" component={TopicContainer} />
<Route path='/profile/:address?/:username?' component={ProfileContainer} />
<Route path='/404' component={NotFound} />
<Route component={NotFound} />
</Switch>

Loading…
Cancel
Save