mirror of https://gitlab.com/ecentrics/concordia
Apostolos Fanakis
4 years ago
28 changed files with 748 additions and 707 deletions
@ -1,34 +1,33 @@ |
|||||
import React from 'react' |
import React from 'react'; |
||||
import { Provider } from 'react-redux' |
import { Provider } from 'react-redux'; |
||||
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom' |
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom'; |
||||
import LoadingContainer from './LoadingContainer' |
import PropTypes from 'prop-types'; |
||||
import PropTypes from 'prop-types' |
import LoadingContainer from './LoadingContainer'; |
||||
|
|
||||
// CSS |
// CSS |
||||
import '../assets/css/app.css'; |
import '../assets/css/app.css'; |
||||
|
|
||||
import CoreLayoutContainer from './CoreLayoutContainer'; |
import CoreLayoutContainer from './CoreLayoutContainer'; |
||||
import HomeContainer from './HomeContainer'; |
import HomeContainer from './HomeContainer'; |
||||
import NotFound from '../components/NotFound'; |
import NotFound from './NotFound'; |
||||
|
|
||||
|
|
||||
const App = ({ store }) => ( |
const App = ({ store }) => ( |
||||
<Provider store={store}> |
<Provider store={store}> |
||||
<LoadingContainer> |
<LoadingContainer> |
||||
<Router> |
<Router> |
||||
<CoreLayoutContainer> |
<CoreLayoutContainer> |
||||
<Switch> |
<Switch> |
||||
<Route exact path="/" component={HomeContainer} /> |
<Route exact path="/" component={HomeContainer} /> |
||||
<Route component={NotFound} /> |
<Route component={NotFound} /> |
||||
</Switch> |
</Switch> |
||||
</CoreLayoutContainer> |
</CoreLayoutContainer> |
||||
</Router> |
</Router> |
||||
</LoadingContainer> |
</LoadingContainer> |
||||
</Provider> |
</Provider> |
||||
) |
); |
||||
|
|
||||
App.propTypes = { |
App.propTypes = { |
||||
store: PropTypes.object.isRequired |
store: PropTypes.object.isRequired, |
||||
} |
}; |
||||
|
|
||||
export default App |
export default App; |
||||
|
@ -1,72 +0,0 @@ |
|||||
// Modified version of https://github.com/trufflesuite/drizzle/blob/develop/packages/react-plugin/src/DrizzleContext.js
|
|
||||
import React from "react"; |
|
||||
|
|
||||
const Context = React.createContext(); |
|
||||
|
|
||||
class Provider extends React.Component { |
|
||||
state = { |
|
||||
drizzleState: null, |
|
||||
drizzleInitialized: false, |
|
||||
breezeState: null, |
|
||||
breezeInitialized: false |
|
||||
}; |
|
||||
|
|
||||
componentDidMount() { |
|
||||
const { drizzle, breeze } = this.props; |
|
||||
// subscribe to changes in the store, keep state up-to-date
|
|
||||
this.unsubscribe = drizzle.store.subscribe(() => { |
|
||||
const drizzleState = drizzle.store.getState(); |
|
||||
const breezeState = breeze.store.getState(); |
|
||||
|
|
||||
if (drizzleState.drizzleStatus.initialized) { |
|
||||
this.setState({ |
|
||||
drizzleState, |
|
||||
drizzleInitialized: true |
|
||||
}); |
|
||||
} |
|
||||
if (breezeState.breezeStatus.initialized) { |
|
||||
this.setState({ |
|
||||
breezeState: breezeState, |
|
||||
breezeInitialized: true |
|
||||
}); |
|
||||
} |
|
||||
}); |
|
||||
|
|
||||
this.unsubscribe = breeze.store.subscribe(() => { |
|
||||
const breezeState = breeze.store.getState(); |
|
||||
if (breezeState.breezeStatus.initialized) { |
|
||||
this.setState({ |
|
||||
breezeState: breezeState, |
|
||||
breezeInitialized: true |
|
||||
}); |
|
||||
} |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
componentWillUnmount() { |
|
||||
this.unsubscribe(); |
|
||||
} |
|
||||
|
|
||||
render() { |
|
||||
return ( |
|
||||
<Context.Provider |
|
||||
value={{ |
|
||||
drizzle: this.props.drizzle, |
|
||||
drizzleState: this.state.drizzleState, |
|
||||
drizzleInitialized: this.state.drizzleInitialized, |
|
||||
breeze: this.props.breeze, |
|
||||
breezeState: this.state.breezeState, |
|
||||
breezeInitialized: this.state.breezeInitialized |
|
||||
}} |
|
||||
> |
|
||||
{this.props.children} |
|
||||
</Context.Provider> |
|
||||
); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
export default { |
|
||||
Context: Context, |
|
||||
Consumer: Context.Consumer, |
|
||||
Provider |
|
||||
}; |
|
@ -0,0 +1,81 @@ |
|||||
|
// Modified version of https://github.com/trufflesuite/drizzle/blob/develop/packages/react-plugin/src/DrizzleContext.js |
||||
|
import React from 'react'; |
||||
|
|
||||
|
const Context = React.createContext(); |
||||
|
|
||||
|
class Provider extends React.Component { |
||||
|
constructor(props) { |
||||
|
super(props); |
||||
|
|
||||
|
this.state = { |
||||
|
drizzleState: null, |
||||
|
drizzleInitialized: false, |
||||
|
breezeState: null, |
||||
|
breezeInitialized: false, |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
componentDidMount() { |
||||
|
const { drizzle, breeze } = this.props; |
||||
|
// subscribe to changes in the store, keep state up-to-date |
||||
|
this.unsubscribe = drizzle.store.subscribe(() => { |
||||
|
const drizzleState = drizzle.store.getState(); |
||||
|
const breezeState = breeze.store.getState(); |
||||
|
|
||||
|
if (drizzleState.drizzleStatus.initialized) { |
||||
|
this.setState({ |
||||
|
drizzleState, |
||||
|
drizzleInitialized: true, |
||||
|
}); |
||||
|
} |
||||
|
if (breezeState.breezeStatus.initialized) { |
||||
|
this.setState({ |
||||
|
breezeState, |
||||
|
breezeInitialized: true, |
||||
|
}); |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
this.unsubscribe = breeze.store.subscribe(() => { |
||||
|
const breezeState = breeze.store.getState(); |
||||
|
if (breezeState.breezeStatus.initialized) { |
||||
|
this.setState({ |
||||
|
breezeState, |
||||
|
breezeInitialized: true, |
||||
|
}); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
componentWillUnmount() { |
||||
|
this.unsubscribe(); |
||||
|
} |
||||
|
|
||||
|
render() { |
||||
|
const { |
||||
|
drizzleState, drizzleInitialized, breezeState, breezeInitialized, |
||||
|
} = this.state; |
||||
|
const { drizzle, breeze, children } = this.props; |
||||
|
|
||||
|
return ( |
||||
|
<Context.Provider |
||||
|
value={{ |
||||
|
drizzle, |
||||
|
drizzleState, |
||||
|
drizzleInitialized, |
||||
|
breeze, |
||||
|
breezeState, |
||||
|
breezeInitialized, |
||||
|
}} |
||||
|
> |
||||
|
{children} |
||||
|
</Context.Provider> |
||||
|
); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
export default { |
||||
|
Context, |
||||
|
Consumer: Context.Consumer, |
||||
|
Provider, |
||||
|
}; |
@ -1,19 +1,21 @@ |
|||||
import React, { Component } from 'react'; |
import React from 'react'; |
||||
import PropTypes from 'prop-types'; |
import PropTypes from 'prop-types'; |
||||
|
|
||||
import MenuComponent from './MenuComponent'; |
import MenuComponent from './MenuComponent'; |
||||
|
|
||||
export default class CoreLayout extends Component { |
const CoreLayout = (props) => { |
||||
render() { |
const { children } = props; |
||||
return ( |
|
||||
<div> |
return ( |
||||
<MenuComponent/> |
<div> |
||||
{this.props.children} |
<MenuComponent /> |
||||
</div> |
{children} |
||||
) |
</div> |
||||
} |
); |
||||
} |
}; |
||||
|
|
||||
CoreLayout.propTypes = { |
CoreLayout.propTypes = { |
||||
children: PropTypes.element.isRequired |
children: PropTypes.element.isRequired, |
||||
}; |
}; |
||||
|
|
||||
|
export default CoreLayout; |
||||
|
@ -1,9 +1,5 @@ |
|||||
import React, { Component } from 'react'; |
import React from 'react'; |
||||
|
|
||||
class HomeContainer extends Component { |
const HomeContainer = () => (<p>TODO: Home Container</p>); |
||||
render() { |
|
||||
return(<p>TODO: Home Container</p>); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
export default HomeContainer; |
export default HomeContainer; |
||||
|
@ -1,38 +1,35 @@ |
|||||
import React, { Component } from 'react'; |
import React from 'react'; |
||||
import { withRouter } from "react-router"; |
import { withRouter } from 'react-router'; |
||||
import { Menu } from 'semantic-ui-react'; |
import { Menu } from 'semantic-ui-react'; |
||||
|
|
||||
import AppContext from "./AppContext"; |
import AppContext from './AppContext'; |
||||
|
|
||||
import app_logo from '../assets/images/app_logo.png'; |
import appLogo from '../assets/images/app_logo.png'; |
||||
import SignUpForm from './SignUpForm'; |
import SignUpForm from './SignUpForm'; |
||||
|
|
||||
class MenuComponent extends Component { |
const MenuComponent = (props) => { |
||||
render() { |
const { history: { push } } = props; |
||||
return ( |
|
||||
<AppContext.Consumer> |
|
||||
{context => { |
|
||||
return( |
|
||||
<div> |
|
||||
<Menu color='black' inverted> |
|
||||
<Menu.Item |
|
||||
link |
|
||||
name='home' |
|
||||
onClick={() => { this.props.history.push("/"); }} |
|
||||
> |
|
||||
<img src={app_logo} alt="app_logo"/> |
|
||||
</Menu.Item> |
|
||||
|
|
||||
<SignUpForm/> |
return ( |
||||
|
<AppContext.Consumer> |
||||
|
{() => ( |
||||
|
<div> |
||||
|
<Menu color="black" inverted> |
||||
|
<Menu.Item |
||||
|
link |
||||
|
name="home" |
||||
|
onClick={() => { push('/'); }} |
||||
|
> |
||||
|
<img src={appLogo} alt="app_logo" /> |
||||
|
</Menu.Item> |
||||
|
|
||||
</Menu> |
<SignUpForm /> |
||||
</div> |
|
||||
) |
</Menu> |
||||
} |
</div> |
||||
} |
)} |
||||
</AppContext.Consumer> |
</AppContext.Consumer> |
||||
) |
); |
||||
} |
}; |
||||
} |
|
||||
|
|
||||
export default withRouter(MenuComponent); |
export default withRouter(MenuComponent); |
||||
|
@ -1,139 +1,144 @@ |
|||||
import React, { Component } from 'react'; |
import React, { Component } from 'react'; |
||||
import { Button, Form, Menu, Message, Modal } from 'semantic-ui-react'; |
import { |
||||
|
Button, Form, Menu, Message, Modal, |
||||
|
} from 'semantic-ui-react'; |
||||
|
|
||||
import AppContext from "./AppContext"; |
|
||||
import { connect } from 'react-redux'; |
import { connect } from 'react-redux'; |
||||
|
import AppContext from './AppContext'; |
||||
|
|
||||
const contractName = 'Forum'; |
const contractName = 'Forum'; |
||||
const checkUsernameTakenMethod = 'isUserNameTaken'; |
const checkUsernameTakenMethod = 'isUserNameTaken'; |
||||
const signUpMethod = 'signUp'; |
const signUpMethod = 'signUp'; |
||||
|
|
||||
class SignUpForm extends Component { |
class SignUpForm extends Component { |
||||
constructor(props, context) { |
constructor(props, context) { |
||||
super(props, context); |
super(props, context); |
||||
|
|
||||
// For quick access |
// For quick access |
||||
this.contract = this.context.drizzle.contracts[contractName]; |
this.contract = this.context.drizzle.contracts[contractName]; |
||||
|
|
||||
this.handleInputChange = this.handleInputChange.bind(this); |
this.handleInputChange = this.handleInputChange.bind(this); |
||||
this.handleSubmit = this.handleSubmit.bind(this); |
this.handleSubmit = this.handleSubmit.bind(this); |
||||
this.completeAction = this.completeAction.bind(this); |
this.completeAction = this.completeAction.bind(this); |
||||
|
|
||||
this.checkedUsernames = []; |
this.checkedUsernames = []; |
||||
|
|
||||
this.state = { |
this.state = { |
||||
usernameInput: '', |
usernameInput: '', |
||||
error: false, |
error: false, |
||||
errorHeader: '', |
errorHeader: '', |
||||
errorMessage: '', |
errorMessage: '', |
||||
signingUp: false, |
signingUp: false, |
||||
}; |
}; |
||||
|
} |
||||
|
|
||||
|
componentDidUpdate() { |
||||
|
// TODO |
||||
|
} |
||||
|
|
||||
|
handleSubmit() { |
||||
|
const { usernameInput, error } = this.state; |
||||
|
|
||||
|
if (usernameInput === '') { |
||||
|
this.setState({ |
||||
|
error: true, |
||||
|
errorHeader: 'Data Incomplete', |
||||
|
errorMessage: 'You need to provide a username', |
||||
|
}); |
||||
|
} else if (!error) { |
||||
|
// TODO |
||||
|
// // Makes sure current input username has been checked for availability |
||||
|
// if (this.checkedUsernames.some((e) => e.usernameChecked === usernameInput)) { |
||||
|
// this.completeAction(); |
||||
|
// } |
||||
|
this.completeAction(); |
||||
} |
} |
||||
|
} |
||||
handleInputChange(e, { name, value }) { |
|
||||
this.setState({ |
handleInputChange(e, { name, value }) { |
||||
[name]: value, |
this.setState({ |
||||
error: false, |
[name]: value, |
||||
}); |
error: false, |
||||
if (value !== '') { |
}); |
||||
if (this.checkedUsernames.length > 0) { |
if (value !== '') { |
||||
if (this.checkedUsernames.some((e) => e.usernameChecked === value)) { |
if (this.checkedUsernames.length > 0) { |
||||
return; |
if (this.checkedUsernames.some((e) => e.usernameChecked === value)) { |
||||
} |
return; |
||||
} |
|
||||
|
|
||||
this.contract.methods[checkUsernameTakenMethod].cacheCall( |
|
||||
value, |
|
||||
); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
handleSubmit() { |
|
||||
const { usernameInput, error } = this.state; |
|
||||
|
|
||||
if (usernameInput === '') { |
|
||||
this.setState({ |
|
||||
error: true, |
|
||||
errorHeader: 'Data Incomplete', |
|
||||
errorMessage: 'You need to provide a username', |
|
||||
}); |
|
||||
} else if (!error) { |
|
||||
// TODO |
|
||||
// // Makes sure current input username has been checked for availability |
|
||||
// if (this.checkedUsernames.some((e) => e.usernameChecked === usernameInput)) { |
|
||||
// this.completeAction(); |
|
||||
// } |
|
||||
this.completeAction(); |
|
||||
} |
} |
||||
} |
} |
||||
|
|
||||
componentDidUpdate() { |
this.contract.methods[checkUsernameTakenMethod].cacheCall( |
||||
// TODO |
value, |
||||
|
); |
||||
} |
} |
||||
|
} |
||||
completeAction() { |
|
||||
const { usernameInput } = this.state; |
completeAction() { |
||||
const { user, account } = this.props; |
const { usernameInput } = this.state; |
||||
|
const { user, account } = this.props; |
||||
if (user.hasSignedUp) { |
|
||||
console.log('Signing up..') |
if (user.hasSignedUp) { |
||||
this.contract.methods['signUp'].cacheSend(usernameInput); |
console.log('Signing up..'); |
||||
} else { |
this.contract.methods.signUp.cacheSend(usernameInput); |
||||
this.setState({ |
} else { |
||||
signingUp: true, |
this.setState({ |
||||
}); |
signingUp: true, |
||||
this.contract.methods[signUpMethod].cacheSend( |
}); |
||||
...[usernameInput], { from: account }, |
this.contract.methods[signUpMethod].cacheSend( |
||||
); |
...[usernameInput], { from: account }, |
||||
} |
); |
||||
this.setState({ |
|
||||
usernameInput: '', |
|
||||
}); |
|
||||
} |
} |
||||
|
this.setState({ |
||||
render() { |
usernameInput: '', |
||||
const { |
}); |
||||
error, usernameInput, errorHeader, errorMessage, signingUp, |
} |
||||
} = this.state; |
|
||||
|
render() { |
||||
return( |
const { |
||||
<Modal as={Form} onSubmit={e => this.handleSubmit(e)} trigger={ |
error, usernameInput, errorHeader, errorMessage, signingUp, |
||||
<Menu.Item |
} = this.state; |
||||
name='signup' |
|
||||
position='right' |
return ( |
||||
content='Sign Up' |
<Modal |
||||
/> |
as={Form} |
||||
}> |
onSubmit={(e) => this.handleSubmit(e)} |
||||
<Modal.Header>Sign Up</Modal.Header> |
trigger={( |
||||
<Modal.Content> |
<Menu.Item |
||||
|
name="signup" |
||||
<Form.Field required> |
position="right" |
||||
<label>Username</label> |
content="Sign Up" |
||||
<Form.Input |
/> |
||||
placeholder='Username' |
)} |
||||
name="usernameInput" |
> |
||||
value={usernameInput} |
<Modal.Header>Sign Up</Modal.Header> |
||||
onChange={this.handleInputChange} |
<Modal.Content> |
||||
/> |
|
||||
</Form.Field> |
<Form.Field required> |
||||
<Message |
<label>Username</label> |
||||
error |
<Form.Input |
||||
header={errorHeader} |
placeholder="Username" |
||||
content={errorMessage} |
name="usernameInput" |
||||
|
value={usernameInput} |
||||
|
onChange={this.handleInputChange} |
||||
/> |
/> |
||||
<Button type="submit" color="black" content="Sign Up" /> |
</Form.Field> |
||||
|
<Message |
||||
</Modal.Content> |
error |
||||
</Modal> |
header={errorHeader} |
||||
) |
content={errorMessage} |
||||
|
/> |
||||
|
<Button type="submit" color="black" content="Sign Up" /> |
||||
|
|
||||
} |
</Modal.Content> |
||||
|
</Modal> |
||||
|
); |
||||
|
} |
||||
} |
} |
||||
|
|
||||
SignUpForm.contextType = AppContext.Context; |
SignUpForm.contextType = AppContext.Context; |
||||
|
|
||||
const mapStateToProps = (state) => ({ |
const mapStateToProps = (state) => ({ |
||||
user: state.user |
user: state.user, |
||||
}); |
}); |
||||
|
|
||||
export default connect(mapStateToProps)(SignUpForm); |
export default connect(mapStateToProps)(SignUpForm); |
||||
|
@ -1,45 +1,45 @@ |
|||||
|
import { orbitConstants } from '@ezerous/breeze'; |
||||
import web3Options from './web3Options'; |
import web3Options from './web3Options'; |
||||
import EthereumIdentityProvider from '../orbit/ΕthereumIdentityProvider'; |
import EthereumIdentityProvider from '../orbit/ΕthereumIdentityProvider'; |
||||
import { orbitConstants } from '@ezerous/breeze' |
|
||||
|
|
||||
const { web3 } = web3Options; |
const { web3 } = web3Options; |
||||
EthereumIdentityProvider.setWeb3(web3); |
EthereumIdentityProvider.setWeb3(web3); |
||||
|
|
||||
const breezeOptions = { |
const breezeOptions = { |
||||
ipfs: { |
ipfs: { |
||||
config: { |
config: { |
||||
Addresses: { |
Addresses: { |
||||
Swarm: [ |
Swarm: [ |
||||
// Use local signaling server (see also rendezvous script in package.json)
|
// Use local signaling server (see also rendezvous script in package.json)
|
||||
// For more information: https://github.com/libp2p/js-libp2p-webrtc-star
|
// For more information: https://github.com/libp2p/js-libp2p-webrtc-star
|
||||
'/ip4/127.0.0.1/tcp/9090/wss/p2p-webrtc-star' |
'/ip4/127.0.0.1/tcp/9090/wss/p2p-webrtc-star', |
||||
|
|
||||
// Use the following public servers if needed
|
// Use the following public servers if needed
|
||||
// '/dns4/wrtc-star1.par.dwebops.pub/tcp/443/wss/p2p-webrtc-star',
|
// '/dns4/wrtc-star1.par.dwebops.pub/tcp/443/wss/p2p-webrtc-star',
|
||||
// '/dns4/ wrtc-star2.sjc.dwebops.pub/tcp/443/wss/p2p-webrtc-star'
|
// '/dns4/ wrtc-star2.sjc.dwebops.pub/tcp/443/wss/p2p-webrtc-star'
|
||||
] |
], |
||||
}, |
}, |
||||
}, |
|
||||
preload: { |
|
||||
enabled: false |
|
||||
}, |
|
||||
init: { |
|
||||
emptyRepo: true |
|
||||
} |
|
||||
}, |
}, |
||||
orbit: { |
preload: { |
||||
identityProvider: EthereumIdentityProvider, |
enabled: false, |
||||
databases: [ |
}, |
||||
{ |
init: { |
||||
name: 'topics', |
emptyRepo: true, |
||||
type: orbitConstants.ORBIT_TYPE_KEYVALUE |
}, |
||||
}, |
}, |
||||
{ |
orbit: { |
||||
name: 'posts', |
identityProvider: EthereumIdentityProvider, |
||||
type: orbitConstants.ORBIT_TYPE_KEYVALUE |
databases: [ |
||||
} |
{ |
||||
] |
name: 'topics', |
||||
} |
type: orbitConstants.ORBIT_TYPE_KEYVALUE, |
||||
|
}, |
||||
|
{ |
||||
|
name: 'posts', |
||||
|
type: orbitConstants.ORBIT_TYPE_KEYVALUE, |
||||
|
}, |
||||
|
], |
||||
|
}, |
||||
}; |
}; |
||||
|
|
||||
export default breezeOptions; |
export default breezeOptions; |
||||
|
@ -1,7 +1,11 @@ |
|||||
// https://github.com/orbitdb/orbit-db/blob/master/GUIDE.md#address
|
// https://github.com/orbitdb/orbit-db/blob/master/GUIDE.md#address
|
||||
export async function determineDBAddress({orbit, dbName, type, identityId}) { |
async function determineDBAddress({ |
||||
const ipfsMultihash = (await orbit.determineAddress(dbName, type, { |
orbit, dbName, type, identityId, |
||||
accessController: { write: [identityId] }, |
}) { |
||||
})).root; |
const ipfsMultihash = (await orbit.determineAddress(dbName, type, { |
||||
return `/orbitdb/${ipfsMultihash}/${dbName}`; |
accessController: { write: [identityId] }, |
||||
|
})).root; |
||||
|
return `/orbitdb/${ipfsMultihash}/${dbName}`; |
||||
} |
} |
||||
|
|
||||
|
export default determineDBAddress; |
||||
|
@ -1,31 +1,31 @@ |
|||||
import { USER_DATA_UPDATED } from '../actions/userActions'; |
import { USER_DATA_UPDATED } from '../actions/userActions'; |
||||
|
|
||||
const initialState = { |
const initialState = { |
||||
username: '', |
username: '', |
||||
address: null, |
address: null, |
||||
hasSignedUp: false, |
hasSignedUp: false, |
||||
}; |
}; |
||||
|
|
||||
const userReducer = (state = initialState, action) => { |
const userReducer = (state = initialState, action) => { |
||||
const { type } = action; |
const { type } = action; |
||||
|
|
||||
if(type === USER_DATA_UPDATED) { |
if (type === USER_DATA_UPDATED) { |
||||
const { address, username } = action; |
const { address, username } = action; |
||||
if(username){ |
if (username) { |
||||
return { |
return { |
||||
username: username, |
username, |
||||
address: address, |
address, |
||||
hasSignedUp: true, |
hasSignedUp: true, |
||||
}; |
}; |
||||
} |
|
||||
return { |
|
||||
username: '', |
|
||||
address, |
|
||||
hasSignedUp: false, |
|
||||
}; |
|
||||
} |
} |
||||
|
return { |
||||
|
username: '', |
||||
|
address, |
||||
|
hasSignedUp: false, |
||||
|
}; |
||||
|
} |
||||
|
|
||||
return state; |
return state; |
||||
}; |
}; |
||||
|
|
||||
export default userReducer; |
export default userReducer; |
||||
|
@ -1,22 +1,21 @@ |
|||||
import { put, all, take } from 'redux-saga/effects' |
import { put, all, take } from 'redux-saga/effects'; |
||||
|
|
||||
import { breezeActions } from '@ezerous/breeze' |
import { breezeActions } from '@ezerous/breeze'; |
||||
import { drizzleActions } from '@ezerous/drizzle' |
import { drizzleActions } from '@ezerous/drizzle'; |
||||
|
|
||||
function * initOrbitDatabases (action) { |
function* initOrbitDatabases(action) { |
||||
const { account, breeze} = action; |
const { account, breeze } = action; |
||||
yield put(breezeActions.orbit.orbitInit(breeze, account)); //same as breeze.initOrbit(account);
|
yield put(breezeActions.orbit.orbitInit(breeze, account)); // same as breeze.initOrbit(account);
|
||||
} |
} |
||||
|
|
||||
function * orbitSaga () { |
function* orbitSaga() { |
||||
const res = yield all([ |
const res = yield all([ |
||||
take(drizzleActions.drizzle.DRIZZLE_INITIALIZED), |
take(drizzleActions.drizzle.DRIZZLE_INITIALIZED), |
||||
take(breezeActions.breeze.BREEZE_INITIALIZED), |
take(breezeActions.breeze.BREEZE_INITIALIZED), |
||||
take(drizzleActions.account.ACCOUNTS_FETCHED) |
take(drizzleActions.account.ACCOUNTS_FETCHED), |
||||
]); |
]); |
||||
|
|
||||
yield initOrbitDatabases({breeze:res[1].breeze, account: res[2].accounts[0]}); |
yield initOrbitDatabases({ breeze: res[1].breeze, account: res[2].accounts[0] }); |
||||
} |
} |
||||
|
|
||||
export default orbitSaga |
export default orbitSaga; |
||||
|
|
||||
|
@ -1,17 +1,17 @@ |
|||||
import { all, fork } from 'redux-saga/effects'; |
import { all, fork } from 'redux-saga/effects'; |
||||
import { drizzleSagas } from '@ezerous/drizzle'; |
import { drizzleSagas } from '@ezerous/drizzle'; |
||||
import { breezeSagas } from '@ezerous/breeze' |
import { breezeSagas } from '@ezerous/breeze'; |
||||
import orbitSaga from './orbitSaga' |
import orbitSaga from './orbitSaga'; |
||||
import userSaga from './userSaga' |
import userSaga from './userSaga'; |
||||
|
|
||||
export default function* root() { |
export default function* root() { |
||||
const sagas = [ |
const sagas = [ |
||||
...drizzleSagas, |
...drizzleSagas, |
||||
...breezeSagas, |
...breezeSagas, |
||||
orbitSaga, |
orbitSaga, |
||||
userSaga |
userSaga, |
||||
]; |
]; |
||||
yield all( |
yield all( |
||||
sagas.map((saga) => fork(saga)), |
sagas.map((saga) => fork(saga)), |
||||
); |
); |
||||
} |
} |
||||
|
@ -1,42 +1,43 @@ |
|||||
import { all, call, put, take } from 'redux-saga/effects'; |
/* eslint-disable no-console */ |
||||
|
import { |
||||
|
all, call, put, take, |
||||
|
} from 'redux-saga/effects'; |
||||
|
|
||||
import { drizzleActions } from '@ezerous/drizzle'; |
import { drizzleActions } from '@ezerous/drizzle'; |
||||
import { USER_DATA_UPDATED, USER_DATA_ERROR } from '../actions/userActions'; |
import { USER_DATA_UPDATED, USER_DATA_ERROR } from '../actions/userActions'; |
||||
|
|
||||
function * fetchUserData ({drizzle, account}) { |
function* fetchUserData({ drizzle, account }) { |
||||
const contract = drizzle.contracts['Forum']; |
const contract = drizzle.contracts.Forum; |
||||
const transaction = yield call(contract.methods.hasUserSignedUp, account); |
const transaction = yield call(contract.methods.hasUserSignedUp, account); |
||||
|
|
||||
try { |
try { |
||||
const dispatchArgs = { address: account }; |
const dispatchArgs = { address: account }; |
||||
const callResult = yield call(transaction.call, { address: account }); |
const callResult = yield call(transaction.call, { address: account }); |
||||
|
|
||||
// User has signed up, fetch his username
|
// User has signed up, fetch his username
|
||||
if (callResult) { |
if (callResult) { |
||||
const txObj2 = yield call(contract.methods.getUsername, account); |
const txObj2 = yield call(contract.methods.getUsername, account); |
||||
dispatchArgs.username = yield call(txObj2.call, { |
dispatchArgs.username = yield call(txObj2.call, { |
||||
address: account |
address: account, |
||||
}); |
}); |
||||
} |
|
||||
|
|
||||
yield put({ |
|
||||
type: USER_DATA_UPDATED, ...dispatchArgs |
|
||||
}); |
|
||||
|
|
||||
} catch (error) { |
|
||||
console.error(error); |
|
||||
yield put({ type: USER_DATA_ERROR }); |
|
||||
} |
} |
||||
} |
|
||||
|
|
||||
|
yield put({ |
||||
|
type: USER_DATA_UPDATED, ...dispatchArgs, |
||||
|
}); |
||||
|
} catch (error) { |
||||
|
console.error(error); |
||||
|
yield put({ type: USER_DATA_ERROR }); |
||||
|
} |
||||
|
} |
||||
|
|
||||
function * userSaga () { |
function* userSaga() { |
||||
const res = yield all([ |
const res = yield all([ |
||||
take(drizzleActions.drizzle.DRIZZLE_INITIALIZED), |
take(drizzleActions.drizzle.DRIZZLE_INITIALIZED), |
||||
take(drizzleActions.account.ACCOUNTS_FETCHED) |
take(drizzleActions.account.ACCOUNTS_FETCHED), |
||||
]); |
]); |
||||
|
|
||||
yield fetchUserData({drizzle:res[0].drizzle, account: res[1].accounts[0]}); |
yield fetchUserData({ drizzle: res[0].drizzle, account: res[1].accounts[0] }); |
||||
} |
} |
||||
|
|
||||
export default userSaga |
export default userSaga; |
||||
|
@ -1,24 +1,25 @@ |
|||||
import { configureStore, getDefaultMiddleware } from '@reduxjs/toolkit'; |
import { configureStore, getDefaultMiddleware } from '@reduxjs/toolkit'; |
||||
import { drizzleReducers, drizzleMiddlewares, generateContractsInitialState } from '@ezerous/drizzle'; |
import { drizzleReducers, drizzleMiddlewares, generateContractsInitialState } from '@ezerous/drizzle'; |
||||
import { breezeReducers } from '@ezerous/breeze' |
import { breezeReducers } from '@ezerous/breeze'; |
||||
import userReducer from './reducers/userReducer' |
|
||||
import createSagaMiddleware from 'redux-saga'; |
import createSagaMiddleware from 'redux-saga'; |
||||
|
import userReducer from './reducers/userReducer'; |
||||
import rootSaga from './sagas/rootSaga'; |
import rootSaga from './sagas/rootSaga'; |
||||
import drizzleOptions from '../options/drizzleOptions'; |
import drizzleOptions from '../options/drizzleOptions'; |
||||
|
|
||||
const initialState = { |
const initialState = { |
||||
contracts: generateContractsInitialState(drizzleOptions), |
contracts: generateContractsInitialState(drizzleOptions), |
||||
}; |
}; |
||||
|
|
||||
const sagaMiddleware = createSagaMiddleware(); |
const sagaMiddleware = createSagaMiddleware(); |
||||
|
|
||||
const store = configureStore({ |
const store = configureStore({ |
||||
reducer: {...drizzleReducers, ...breezeReducers, user: userReducer }, |
reducer: { ...drizzleReducers, ...breezeReducers, user: userReducer }, |
||||
middleware: getDefaultMiddleware({ |
middleware: getDefaultMiddleware({ |
||||
serializableCheck: false, //https://redux.js.org/style-guide/style-guide/#do-not-put-non-serializable-values-in-state-or-actions
|
// https://redux.js.org/style-guide/style-guide/#do-not-put-non-serializable-values-in-state-or-actions
|
||||
}).concat(drizzleMiddlewares).concat(sagaMiddleware), |
serializableCheck: false, |
||||
preloadedState: initialState |
}).concat(drizzleMiddlewares).concat(sagaMiddleware), |
||||
}) |
preloadedState: initialState, |
||||
|
}); |
||||
|
|
||||
sagaMiddleware.run(rootSaga); |
sagaMiddleware.run(rootSaga); |
||||
export default store; |
export default store; |
||||
|
@ -1,13 +1,13 @@ |
|||||
let Forum; |
let Forum; |
||||
|
|
||||
try { |
try { |
||||
// eslint-disable-next-line global-require
|
// eslint-disable-next-line global-require
|
||||
Forum = require('./build/Forum.json'); |
Forum = require('./build/Forum.json'); |
||||
} catch (e) { |
} catch (e) { |
||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||
console.error("Could not require contract artifacts. Haven't you run compile yet?"); |
console.error("Could not require contract artifacts. Haven't you run compile yet?"); |
||||
} |
} |
||||
|
|
||||
module.exports = { |
module.exports = { |
||||
contracts: [Forum], |
contracts: [Forum], |
||||
}; |
}; |
||||
|
Loading…
Reference in new issue