Browse Source

Fix Routes, Add other users profiles view, Other minor fixes

develop
Apostolos Fanakis 7 years ago
parent
commit
64d95f8d94
  1. 16
      src/components/Post.js
  2. 17
      src/components/PostList.js
  3. 4
      src/components/TopicList.js
  4. 41
      src/containers/PrivateRouteContainer.js
  5. 49
      src/containers/ProfileContainer.js
  6. 2
      src/containers/StartTopicContainer.js
  7. 39
      src/containers/TopicContainer.js
  8. 18
      src/index.js

16
src/components/Post.js

@ -1,4 +1,5 @@
import React from 'react';
import { Link, withRouter } from 'react-router';
import UserAvatar from 'react-user-avatar';
import TimeAgo from 'react-timeago';
import ReactMarkdown from 'react-markdown';
@ -9,11 +10,14 @@ const Post = (props) => {
? <div className="pure-u-1-1 post card">
<div className="post-header">
<div className="vertical-center-children">
<UserAvatar
size="40"
className="inline user-avatar"
src={props.post.avatarUrl}
name={props.post.username}/>
<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}
@ -60,4 +64,4 @@ const Post = (props) => {
);
};
export default Post;
export default withRouter(Post);

17
src/components/PostList.js

@ -1,6 +1,5 @@
import { drizzleConnect } from 'drizzle-react';
import React, { Component } from 'react';
import { Link } from 'react-router';
import PropTypes from 'prop-types';
import Post from './Post';
@ -45,12 +44,15 @@ class PostList extends Component {
const posts = this.postsData.map((post, index) => {
if (post) {
return (
<Link to={"/topic/" + post[4] + "/" +
((this.orbitPostsData[index] !== undefined) ? this.orbitPostsData[index].subject + "/" +
this.props.postIDs[index] : "")}
<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]),
@ -59,7 +61,7 @@ class PostList extends Component {
}}
id={index}
key={index}/>
</Link>
</div>
);
} else {
return (
@ -94,13 +96,14 @@ class PostList extends Component {
};
PostList.contextTypes = {
drizzle: PropTypes.object
drizzle: PropTypes.object,
router: PropTypes.object
};
const mapStateToProps = state => {
return {
user: state.user, //Needed!!
orbitDB: state.orbitDB,
orbitDB: state.orbitDB
}
};

4
src/components/TopicList.js

@ -56,7 +56,7 @@ class TopicList extends Component {
const topics = this.topicsData.map((topic, index) => {
if (topic){
return (
<Link to={"/topic/" + index + "/" +
<Link to={"/topic/" + this.props.topicIDs[index] + "/" +
((this.topicsSubjects[index] !== undefined) ? this.topicsSubjects[index] + "/" + 0 : "")}
key={index}>
<Topic topic={{
@ -71,7 +71,7 @@ class TopicList extends Component {
);
} else {
return (
<Link to={"/topic/" + index + "/"}
<Link to={"/topic/" + this.props.topicIDs[index] + "/"}
key={index}>
<Topic topic={null}
id={index}

41
src/containers/PrivateRouteContainer.js

@ -2,45 +2,24 @@ import React from 'react';
import { drizzleConnect } from 'drizzle-react';
import { Route } from "react-router";
import { Redirect } from "react-router-dom";
import { withRouter } from 'react-router-dom';
import { connect } from 'react-redux'
const PrivateRoute = ({ component, redirectTo, user, ...rest }) => {
console.log("rest");
console.log(JSON.stringify(component));
const PrivateRoute = (props) => {
return (
<Route
{...rest} render={routeProps => {
return user.hasSignedUp
? (renderMergedProps(component, routeProps, rest))
: (<Redirect
to={{
pathname: redirectTo,
state: { from: routeProps.location }
}}
/>);
}}/>
props.user.hasSignedUp
? <Route path={props.path} component={props.component} />
: <Redirect
from={props.path}
to="/login"
/>
);
};
const renderMergedProps = (component, ...rest) => {
const finalProps = Object.assign({}, ...rest);
return (
React.createElement(component, finalProps)
);
}
const PrivateRouteContainer = withRouter(connect(state => ({
hasSignedUp: state.user.hasSignedUp
}))(PrivateRoute));
/*const mapStateToProps = state => {
const mapStateToProps = state => {
return {
user: state.user
}
};*/
};
/*const PrivateRouteContainer = withRouter(drizzleConnect(PrivateRoute, mapStateToProps));*/
const PrivateRouteContainer = drizzleConnect(PrivateRoute, mapStateToProps);
export default PrivateRouteContainer;

49
src/containers/ProfileContainer.js

@ -10,6 +10,7 @@ import epochTimeConverter from '../helpers/EpochTimeConverter';
const contract = "Forum";
const contractMethods = {
getUsername: "getUsername",
getDateOfRegister: "getUserDateOfRegister",
getOrbitDB: "getOrbitDBId",
getUserTopics: "getUserTopics",
@ -20,10 +21,20 @@ class Profile extends Component {
constructor(props, context) {
super(props);
//THIS WILL CHANGE WITH ACTUAL DATA
this.match = {
username: this.props.user.username,
userAddress: this.props.user.address
if (this.props.params.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);
@ -32,12 +43,13 @@ class Profile extends Component {
this.state = {
viewSelected: "topics",
username: this.match.username, // TODO actually get them from match
userAddress: this.match.userAddress, // when router is fixed
username: this.profile.username,
userAddress: this.profile.userAddress,
dateOfRegister: null,
orbitDBId: this.match.address === this.props.user.address ? this.props.orbitDB.id : "",
orbitDBId: this.profile.orbitId,
getUsernameTransactionState: null,
getDateOfRegisterTransactionState: null,
getOrbitDBTransactionState: this.match.address === this.props.user.address ? "SUCCESS" : null,
getOrbitDBTransactionState: this.profile.orbitId ? "SUCCESS" : null,
getTopicsTransactionState: null,
getPostsTransactionState: null,
topicIDs: [],
@ -58,7 +70,7 @@ class Profile extends Component {
numberOfTopics={this.state.topicIDs.length}
numberOfPosts={this.state.postIDs.length}
dateOfRegister={this.state.dateOfRegister}
self/>
self={this.profile.self}/>
<div className="pure-u-1-1 profile-tabs-header">
<p onClick={() => (this.handleTabClick("topics"))}
className={this.state.viewSelected === "topics" ? "profile-tab-selected" : ""}>
@ -88,6 +100,25 @@ 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]

2
src/containers/StartTopicContainer.js

@ -235,6 +235,8 @@ class StartTopic extends Component {
'savingToOrbitDB': null,
'transactionOutputTimerActive': false
});
this.props.router.push("/topic/" + this.topicIDFetched + "/"
+ this.state.topicSubjectInput);
}, 5000);
}
else if (this.state.savingToOrbitDB === "ERROR"){

39
src/containers/TopicContainer.js

@ -14,6 +14,10 @@ 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);
@ -21,21 +25,25 @@ class Topic extends Component {
this.drizzle = context.drizzle;
this.state = {
topicID: this.props.params.topicId,
topicSubject: this.props.params.topicSubject ? this.props.params.topicSubject : null,
postFocus: this.props.params.postId && /^[0-9]+$/.test(this.props.params.postId)
? this.props.params.postId
: null,
getPostsTransactionState: null,
posting: false,
topicSubject: null
posting: false
};
}
async fetchTopicSubject(orbitDBAddress, topicID) {
/*const fullAddress = this.topicsData[topicID][1];
async fetchTopicSubject(orbitDBAddress) {
/*const fullAddress = this.topicsData[this.state.topicID][1];
const store = await this.props.orbitDB.orbitdb.keyvalue(JSON.stringify(fullAddress));
await store.load();
var som = store.get(JSON.stringify(topicID));
this.topicsSubjects[topicID] = som['subject'];
this.topicsSubjectsFetchStatus[topicID] = "fetched";*/
var som = store.get(JSON.stringify(this.state.topicID));
this.topicsSubjects[this.state.topicID] = som['subject'];
this.topicsSubjectsFetchStatus[this.state.topicID] = "fetched";*/
var som =this.props.orbitDB.topicsDB.get(JSON.stringify(topicID));
var som =this.props.orbitDB.topicsDB.get(JSON.stringify(this.state.topicID));
this.setState({'topicSubject': som['subject']});
}
@ -65,7 +73,7 @@ class Topic extends Component {
topicContents = (
(<div style={{marginBottom: '100px'}}>
{this.state.posting &&
<NewPost topicID={1}
<NewPost topicID={this.state.topicID}
subject={this.state.topicSubject}
onCancelClick={() => {this.handleClick()}}
onPostCreated={() => {this.postCreated()}}
@ -90,7 +98,8 @@ class Topic extends Component {
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(1);
this.getPostsDataKey = this.drizzle.contracts[contract].methods[contractMethod]
.cacheCall(this.state.topicID);
this.setState({'getPostsTransactionState': "IN_PROGRESS"});
}
}
@ -98,9 +107,13 @@ class Topic extends Component {
let currentDrizzleState = this.drizzle.store.getState();
let dataFetched = (currentDrizzleState.contracts[contract][contractMethod])[this.getPostsDataKey];
if (dataFetched){
this.posts = dataFetched.value[4];
this.setState({'getPostsTransactionState': "SUCCESS"});
this.fetchTopicSubject(dataFetched.value[0], 1);
if (dataFetched.value){
this.posts = dataFetched.value[4];
this.setState({'getPostsTransactionState': "SUCCESS"});
this.fetchTopicSubject(dataFetched.value[0]);
} else if (dataFetched.error){
//TODO
}
}
}
}

18
src/index.js

@ -31,9 +31,12 @@ render((
<Router history={history}>
<Route path="/" component={CoreLayout}>
<IndexRoute component={HomeContainer} />
<PrivateRouteContainer path="/topic/:topicId/:topicSubject/:postId" component={TopicContainer} redirectTo="/" />
<PrivateRouteContainer path='/profile' component={ProfileContainer} redirectTo="/" />
<PrivateRouteContainer path='/startTopic' component={StartTopicContainer} redirectTo="/" />
<Route path="/topic/:topicId(/:topicSubject)(/:postId)"
component={TopicContainer} />
<Route path='/profile(/:address)(/:username)'
component={ProfileContainer} />
<Route path='/startTopic'
component={StartTopicContainer} />
<Route path='/404' component={NotFoundView} />
<Route path='*' component={NotFoundView} />
</Route>
@ -42,4 +45,11 @@ render((
</DrizzleProvider>
),
document.getElementById('root')
);
);
/*<PrivateRouteContainer path="/topic/:topicId(/:topicSubject)(/:postId)"
component={TopicContainer} />
<PrivateRouteContainer path='/profile(/:address)(/:username)'
component={ProfileContainer} />
<PrivateRouteContainer path='/startTopic'
component={StartTopicContainer} />*/
Loading…
Cancel
Save