mirror of
https://github.com/fazo96/ipfs-boards
synced 2025-03-11 21:38:38 +01:00
eslint fix
This commit is contained in:
parent
bc32ede2b5
commit
4e880f8864
@ -1,23 +1,23 @@
|
||||
|
||||
export const ADD_POST = 'ADD_POST'
|
||||
export const EDIT_POST = 'EDIT_POST'
|
||||
export const HIDE_POST = 'HIDE_POST'
|
||||
export const UPDATE_BOARD_METADATA = 'UPDATE_BOARD_METADATA'
|
||||
export const ADD_POST = 'ADD_POST';
|
||||
export const EDIT_POST = 'EDIT_POST';
|
||||
export const HIDE_POST = 'HIDE_POST';
|
||||
export const UPDATE_BOARD_METADATA = 'UPDATE_BOARD_METADATA';
|
||||
|
||||
export const ADD_COMMENT = 'ADD_COMMENT'
|
||||
export const EDIT_COMMENT = 'EDIT_COMMENT'
|
||||
export const HIDE_COMMENT = 'HIDE_COMMENT'
|
||||
export const ADD_COMMENT = 'ADD_COMMENT';
|
||||
export const EDIT_COMMENT = 'EDIT_COMMENT';
|
||||
export const HIDE_COMMENT = 'HIDE_COMMENT';
|
||||
|
||||
export const OPEN_BOARD = 'OPEN_BOARD'
|
||||
export const OPENED_BOARD = 'OPENED_BOARD'
|
||||
export const CLOSE_BOARD = 'CLOSE_BOARD'
|
||||
export const OPEN_BOARD = 'OPEN_BOARD';
|
||||
export const OPENED_BOARD = 'OPENED_BOARD';
|
||||
export const CLOSE_BOARD = 'CLOSE_BOARD';
|
||||
|
||||
export const UPDATE_BOARD = 'UPDATE_BOARD'
|
||||
export const UPDATE_BOARD = 'UPDATE_BOARD';
|
||||
|
||||
export const ORBITDB_WRITE = 'ORBITDB_WRITE'
|
||||
export const ORBITDB_WRITE = 'ORBITDB_WRITE';
|
||||
|
||||
export const ORBITDB_REPLICATE = 'ORBITDB_REPLICATE'
|
||||
export const ORBITDB_REPLICATE_PROGRESS = 'ORBITDB_REPLICATE_PROGRESS'
|
||||
export const ORBITDB_REPLICATED = 'ORBITDB_REPLICATED'
|
||||
export const ORBITDB_REPLICATE = 'ORBITDB_REPLICATE';
|
||||
export const ORBITDB_REPLICATE_PROGRESS = 'ORBITDB_REPLICATE_PROGRESS';
|
||||
export const ORBITDB_REPLICATED = 'ORBITDB_REPLICATED';
|
||||
|
||||
export const ERROR = 'ERROR'
|
||||
export const ERROR = 'ERROR';
|
||||
|
@ -1,35 +1,35 @@
|
||||
import {
|
||||
OPEN_BOARD,
|
||||
CLOSE_BOARD,
|
||||
OPENED_BOARD,
|
||||
UPDATE_BOARD_METADATA
|
||||
} from './actionTypes'
|
||||
OPEN_BOARD,
|
||||
CLOSE_BOARD,
|
||||
OPENED_BOARD,
|
||||
UPDATE_BOARD_METADATA,
|
||||
} from './actionTypes';
|
||||
|
||||
export function openBoard(board) {
|
||||
return {
|
||||
type: OPEN_BOARD,
|
||||
board
|
||||
}
|
||||
return {
|
||||
type: OPEN_BOARD,
|
||||
board,
|
||||
};
|
||||
}
|
||||
|
||||
export function createdBoard(board) {
|
||||
return {
|
||||
type: OPENED_BOARD,
|
||||
board
|
||||
}
|
||||
return {
|
||||
type: OPENED_BOARD,
|
||||
board,
|
||||
};
|
||||
}
|
||||
|
||||
export function updateBoardMetadata(address, metadata) {
|
||||
return {
|
||||
type: UPDATE_BOARD_METADATA,
|
||||
address,
|
||||
metadata
|
||||
}
|
||||
return {
|
||||
type: UPDATE_BOARD_METADATA,
|
||||
address,
|
||||
metadata,
|
||||
};
|
||||
}
|
||||
|
||||
export function closeBoard(address) {
|
||||
return {
|
||||
type: CLOSE_BOARD,
|
||||
address
|
||||
}
|
||||
}
|
||||
return {
|
||||
type: CLOSE_BOARD,
|
||||
address,
|
||||
};
|
||||
}
|
||||
|
@ -1,32 +1,32 @@
|
||||
import { HIDE_COMMENT, ADD_COMMENT, EDIT_COMMENT } from './actionTypes'
|
||||
import { HIDE_COMMENT, ADD_COMMENT, EDIT_COMMENT } from './actionTypes';
|
||||
|
||||
export function addComment(address, postId, comment, replyTo = 'post') {
|
||||
return {
|
||||
type: ADD_COMMENT,
|
||||
address,
|
||||
postId,
|
||||
comment,
|
||||
replyTo
|
||||
}
|
||||
return {
|
||||
type: ADD_COMMENT,
|
||||
address,
|
||||
postId,
|
||||
comment,
|
||||
replyTo,
|
||||
};
|
||||
}
|
||||
|
||||
export function editComment(address, postId, commentId, comment, replyTo = 'post') {
|
||||
return {
|
||||
type: EDIT_COMMENT,
|
||||
address,
|
||||
postId,
|
||||
commentId,
|
||||
comment,
|
||||
replyTo
|
||||
}
|
||||
return {
|
||||
type: EDIT_COMMENT,
|
||||
address,
|
||||
postId,
|
||||
commentId,
|
||||
comment,
|
||||
replyTo,
|
||||
};
|
||||
}
|
||||
|
||||
export function hideComment(address, postId, commentId, replyTo = 'post') {
|
||||
return {
|
||||
type: HIDE_COMMENT,
|
||||
address,
|
||||
postId,
|
||||
commentId,
|
||||
replyTo
|
||||
}
|
||||
}
|
||||
return {
|
||||
type: HIDE_COMMENT,
|
||||
address,
|
||||
postId,
|
||||
commentId,
|
||||
replyTo,
|
||||
};
|
||||
}
|
||||
|
@ -1,26 +1,26 @@
|
||||
import { ADD_POST, EDIT_POST, HIDE_POST } from './actionTypes'
|
||||
import { ADD_POST, EDIT_POST, HIDE_POST } from './actionTypes';
|
||||
|
||||
export function addPost(address, post) {
|
||||
return {
|
||||
type: ADD_POST,
|
||||
post,
|
||||
address
|
||||
}
|
||||
return {
|
||||
type: ADD_POST,
|
||||
post,
|
||||
address,
|
||||
};
|
||||
}
|
||||
|
||||
export function editPost(address, postId, post) {
|
||||
return {
|
||||
type: EDIT_POST,
|
||||
address,
|
||||
postId,
|
||||
post,
|
||||
}
|
||||
return {
|
||||
type: EDIT_POST,
|
||||
address,
|
||||
postId,
|
||||
post,
|
||||
};
|
||||
}
|
||||
|
||||
export function hidePost(address, postId) {
|
||||
return {
|
||||
type: HIDE_POST,
|
||||
address,
|
||||
postId
|
||||
}
|
||||
}
|
||||
return {
|
||||
type: HIDE_POST,
|
||||
address,
|
||||
postId,
|
||||
};
|
||||
}
|
||||
|
@ -1,20 +1,20 @@
|
||||
import React, { Component } from 'react';
|
||||
import { Switch, Route, withRouter } from 'react-router-dom'
|
||||
import Boards from '../containers/Boards'
|
||||
import OpenBoard from '../containers/OpenBoard'
|
||||
import WithBoard from '../containers/WithBoard'
|
||||
import BoardPage from '../components/BoardPage'
|
||||
import { Switch, Route, withRouter } from 'react-router-dom';
|
||||
import Boards from '../containers/Boards';
|
||||
import OpenBoard from '../containers/OpenBoard';
|
||||
import WithBoard from '../containers/WithBoard';
|
||||
import BoardPage from './BoardPage';
|
||||
|
||||
class App extends Component {
|
||||
render() {
|
||||
return (
|
||||
<Switch>
|
||||
<Route path='/b/new' component={OpenBoard} />
|
||||
<Route path='/b/:hash/:name/' component={withRouter(WithBoard(BoardPage))} />
|
||||
<Route path='/' component={Boards} />
|
||||
<Route path="/b/new" component={OpenBoard} />
|
||||
<Route path="/b/:hash/:name/" component={withRouter(WithBoard(BoardPage))} />
|
||||
<Route path="/" component={Boards} />
|
||||
</Switch>
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default withRouter(App)
|
||||
export default withRouter(App);
|
||||
|
@ -1,21 +1,23 @@
|
||||
import React from 'react'
|
||||
import { connect } from 'react-redux'
|
||||
import BoardComponent from '../components/Board'
|
||||
import { getBoardAddress } from '../utils/orbitdb'
|
||||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import BoardComponent from '../components/Board';
|
||||
import { getBoardAddress } from '../utils/orbitdb';
|
||||
|
||||
function Board({ stats, location, match, boards }) {
|
||||
const { hash, name } = match.params
|
||||
const address = getBoardAddress(hash, name)
|
||||
const boardStats = stats.dbs[address] || {}
|
||||
return <BoardComponent stats={boardStats} {...boards[address]} />
|
||||
function Board({
|
||||
stats, location, match, boards,
|
||||
}) {
|
||||
const { hash, name } = match.params;
|
||||
const address = getBoardAddress(hash, name);
|
||||
const boardStats = stats.dbs[address] || {};
|
||||
return <BoardComponent stats={boardStats} {...boards[address]} />;
|
||||
}
|
||||
|
||||
function mapStateToProps(state){
|
||||
return {
|
||||
boards: state.boards.boards
|
||||
}
|
||||
function mapStateToProps(state) {
|
||||
return {
|
||||
boards: state.boards.boards,
|
||||
};
|
||||
}
|
||||
|
||||
export default connect(
|
||||
mapStateToProps
|
||||
)(Board)
|
||||
mapStateToProps,
|
||||
)(Board);
|
||||
|
@ -1,35 +1,39 @@
|
||||
|
||||
import React from 'react'
|
||||
import { connect } from 'react-redux'
|
||||
import BoardEditorForm from '../components/BoardEditorForm'
|
||||
import { updateBoardMetadata } from '../actions/board'
|
||||
import { getBoardAddress } from '../utils/orbitdb'
|
||||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import BoardEditorForm from '../components/BoardEditorForm';
|
||||
import { updateBoardMetadata } from '../actions/board';
|
||||
import { getBoardAddress } from '../utils/orbitdb';
|
||||
|
||||
function BoardEditor({ boards, boardEditor, match, updateBoardMetadata }) {
|
||||
const { hash, name } = match.params
|
||||
const address = getBoardAddress(hash, name)
|
||||
const board = boards[address]
|
||||
return <BoardEditorForm
|
||||
board={board}
|
||||
address={address}
|
||||
updateBoardMetadata={updateBoardMetadata}
|
||||
{...board.metadata}
|
||||
function BoardEditor({
|
||||
boards, boardEditor, match, updateBoardMetadata,
|
||||
}) {
|
||||
const { hash, name } = match.params;
|
||||
const address = getBoardAddress(hash, name);
|
||||
const board = boards[address];
|
||||
return (
|
||||
<BoardEditorForm
|
||||
board={board}
|
||||
address={address}
|
||||
updateBoardMetadata={updateBoardMetadata}
|
||||
{...board.metadata}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function mapStateToProps(state){
|
||||
return {
|
||||
boards: state.boards.boards
|
||||
}
|
||||
function mapStateToProps(state) {
|
||||
return {
|
||||
boards: state.boards.boards,
|
||||
};
|
||||
}
|
||||
|
||||
function mapDispatchToProps(dispatch) {
|
||||
return {
|
||||
updateBoardMetadata: (address, metadata) => dispatch(updateBoardMetadata(address, metadata))
|
||||
}
|
||||
return {
|
||||
updateBoardMetadata: (address, metadata) => dispatch(updateBoardMetadata(address, metadata)),
|
||||
};
|
||||
}
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(BoardEditor)
|
||||
mapStateToProps,
|
||||
mapDispatchToProps,
|
||||
)(BoardEditor);
|
||||
|
@ -1,34 +1,36 @@
|
||||
import React from 'react'
|
||||
import { connect } from 'react-redux'
|
||||
import { push } from 'connected-react-router'
|
||||
import BoardsComponent from '../components/Boards'
|
||||
import WithStats from './WithStats'
|
||||
import { closeBoard } from '../actions/board'
|
||||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { push } from 'connected-react-router';
|
||||
import BoardsComponent from '../components/Boards';
|
||||
import WithStats from './WithStats';
|
||||
import { closeBoard } from '../actions/board';
|
||||
|
||||
const WrappedComponent = WithStats(BoardsComponent)
|
||||
const WrappedComponent = WithStats(BoardsComponent);
|
||||
|
||||
function Boards({ boards, createBoard, closeBoard }) {
|
||||
return <WrappedComponent
|
||||
boards={boards}
|
||||
createBoard={createBoard}
|
||||
closeBoard={closeBoard}
|
||||
return (
|
||||
<WrappedComponent
|
||||
boards={boards}
|
||||
createBoard={createBoard}
|
||||
closeBoard={closeBoard}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function mapStateToProps(state){
|
||||
return {
|
||||
boards: state.boards.boards
|
||||
}
|
||||
function mapStateToProps(state) {
|
||||
return {
|
||||
boards: state.boards.boards,
|
||||
};
|
||||
}
|
||||
|
||||
function mapDispatchToProps(dispatch){
|
||||
return {
|
||||
createBoard: () => dispatch(push('/b/new')),
|
||||
closeBoard: address => dispatch(closeBoard(address)),
|
||||
}
|
||||
function mapDispatchToProps(dispatch) {
|
||||
return {
|
||||
createBoard: () => dispatch(push('/b/new')),
|
||||
closeBoard: address => dispatch(closeBoard(address)),
|
||||
};
|
||||
}
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(Boards)
|
||||
mapStateToProps,
|
||||
mapDispatchToProps,
|
||||
)(Boards);
|
||||
|
@ -1,25 +1,25 @@
|
||||
import React from 'react'
|
||||
import { connect } from 'react-redux'
|
||||
import OpenBoardForm from '../components/OpenBoardForm'
|
||||
import { openBoard } from '../actions/board'
|
||||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import OpenBoardForm from '../components/OpenBoardForm';
|
||||
import { openBoard } from '../actions/board';
|
||||
|
||||
function OpenBoard(props) {
|
||||
return <OpenBoardForm {...props} />
|
||||
return <OpenBoardForm {...props} />;
|
||||
}
|
||||
|
||||
function mapStateToProps(state){
|
||||
return {
|
||||
opening: state.openBoard.opening
|
||||
}
|
||||
function mapStateToProps(state) {
|
||||
return {
|
||||
opening: state.openBoard.opening,
|
||||
};
|
||||
}
|
||||
|
||||
function mapDispatchToProps(dispatch) {
|
||||
return {
|
||||
openBoard: board => dispatch(openBoard(board))
|
||||
}
|
||||
return {
|
||||
openBoard: board => dispatch(openBoard(board)),
|
||||
};
|
||||
}
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(OpenBoard)
|
||||
mapStateToProps,
|
||||
mapDispatchToProps,
|
||||
)(OpenBoard);
|
||||
|
@ -1,32 +1,34 @@
|
||||
import React, { Component } from 'react'
|
||||
import { connect } from 'react-redux'
|
||||
import PostForm from '../components/PostForm'
|
||||
import { addPost } from '../actions/post'
|
||||
import React, { Component } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import PostForm from '../components/PostForm';
|
||||
import { addPost } from '../actions/post';
|
||||
import { getBoardAddress } from '../utils/orbitdb';
|
||||
|
||||
class PostEditor extends Component {
|
||||
render() {
|
||||
const { post, addPost, match, boards } = this.props
|
||||
const address = getBoardAddress(match.params.hash, match.params.name)
|
||||
const board = boards[address]
|
||||
return <PostForm post={post} board={board} onSave={p => addPost(address, p)} />
|
||||
}
|
||||
render() {
|
||||
const {
|
||||
post, addPost, match, boards,
|
||||
} = this.props;
|
||||
const address = getBoardAddress(match.params.hash, match.params.name);
|
||||
const board = boards[address];
|
||||
return <PostForm post={post} board={board} onSave={p => addPost(address, p)} />;
|
||||
}
|
||||
}
|
||||
|
||||
function mapStateToProps(state){
|
||||
return {
|
||||
post: state.postEditor.post,
|
||||
boards: state.boards.boards
|
||||
}
|
||||
function mapStateToProps(state) {
|
||||
return {
|
||||
post: state.postEditor.post,
|
||||
boards: state.boards.boards,
|
||||
};
|
||||
}
|
||||
|
||||
function mapDispatchToProps(dispatch) {
|
||||
return {
|
||||
addPost: (address, post) => dispatch(addPost(address, post))
|
||||
}
|
||||
return {
|
||||
addPost: (address, post) => dispatch(addPost(address, post)),
|
||||
};
|
||||
}
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(PostEditor)
|
||||
mapStateToProps,
|
||||
mapDispatchToProps,
|
||||
)(PostEditor);
|
||||
|
@ -1,53 +1,50 @@
|
||||
import React, { Component } from 'react'
|
||||
import { connect } from 'react-redux'
|
||||
import { openBoard } from '../actions/board'
|
||||
import { getBoardAddress } from '../utils/orbitdb'
|
||||
import React, { Component } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { openBoard } from '../actions/board';
|
||||
import { getBoardAddress } from '../utils/orbitdb';
|
||||
|
||||
function mapStateToProps(state){
|
||||
return {
|
||||
boards: state.boards.boards
|
||||
}
|
||||
function mapStateToProps(state) {
|
||||
return {
|
||||
boards: state.boards.boards,
|
||||
};
|
||||
}
|
||||
|
||||
function mapDispatchToProps(dispatch){
|
||||
return {
|
||||
openBoard: address => dispatch(openBoard({ address, redirect: false }))
|
||||
}
|
||||
function mapDispatchToProps(dispatch) {
|
||||
return {
|
||||
openBoard: address => dispatch(openBoard({ address, redirect: false })),
|
||||
};
|
||||
}
|
||||
|
||||
export default function WithBoard(WrappedComponent) {
|
||||
class ToExport extends Component {
|
||||
|
||||
componentDidMount() {
|
||||
const { boards, match } = this.props
|
||||
const address = getBoardAddress(match.params.hash, match.params.name)
|
||||
if (!boards[address]) {
|
||||
this.props.openBoard(address)
|
||||
}
|
||||
}
|
||||
|
||||
componentWillReceiveProps({ match, boards }) {
|
||||
const address = getBoardAddress(match.params.hash, match.params.name)
|
||||
if (!boards[address]) {
|
||||
this.props.openBoard(address)
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const { boards, match } = this.props
|
||||
const address = getBoardAddress(match.params.hash, match.params.name)
|
||||
const board = boards[address]
|
||||
if (board) {
|
||||
return <WrappedComponent {...board} {...this.props} />
|
||||
} else {
|
||||
return "Opening this board"
|
||||
}
|
||||
}
|
||||
class ToExport extends Component {
|
||||
componentDidMount() {
|
||||
const { boards, match } = this.props;
|
||||
const address = getBoardAddress(match.params.hash, match.params.name);
|
||||
if (!boards[address]) {
|
||||
this.props.openBoard(address);
|
||||
}
|
||||
}
|
||||
|
||||
return connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(ToExport)
|
||||
componentWillReceiveProps({ match, boards }) {
|
||||
const address = getBoardAddress(match.params.hash, match.params.name);
|
||||
if (!boards[address]) {
|
||||
this.props.openBoard(address);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
render() {
|
||||
const { boards, match } = this.props;
|
||||
const address = getBoardAddress(match.params.hash, match.params.name);
|
||||
const board = boards[address];
|
||||
if (board) {
|
||||
return <WrappedComponent {...board} {...this.props} />;
|
||||
}
|
||||
return 'Opening this board';
|
||||
}
|
||||
}
|
||||
|
||||
return connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps,
|
||||
)(ToExport);
|
||||
}
|
||||
|
@ -1,43 +1,43 @@
|
||||
import React, { Component } from 'react'
|
||||
import { getStats } from '../utils/ipfs'
|
||||
import React, { Component } from 'react';
|
||||
import { getStats } from '../utils/ipfs';
|
||||
|
||||
export default function(WrappedComponent) {
|
||||
return class extends Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.state = {
|
||||
stats: {
|
||||
id: '?',
|
||||
peers: [],
|
||||
pubKey: '?',
|
||||
dbs: {}
|
||||
},
|
||||
timeout: null
|
||||
}
|
||||
}
|
||||
|
||||
async refresh(loop = true) {
|
||||
const newStats = await getStats()
|
||||
const stats = Object.assign({}, this.state.stats, newStats)
|
||||
this.setState({ stats }, loop ? this.refreshDelayed.bind(this) : undefined)
|
||||
}
|
||||
|
||||
refreshDelayed() {
|
||||
this.timeout = setTimeout(() => {
|
||||
this.refresh()
|
||||
}, 2000)
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.refresh()
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if (this.timeout) clearTimeout(this.timeout)
|
||||
}
|
||||
|
||||
render() {
|
||||
return <WrappedComponent stats={this.state.stats} {...this.props} />
|
||||
}
|
||||
export default function (WrappedComponent) {
|
||||
return class extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
stats: {
|
||||
id: '?',
|
||||
peers: [],
|
||||
pubKey: '?',
|
||||
dbs: {},
|
||||
},
|
||||
timeout: null,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
async refresh(loop = true) {
|
||||
const newStats = await getStats();
|
||||
const stats = Object.assign({}, this.state.stats, newStats);
|
||||
this.setState({ stats }, loop ? this.refreshDelayed.bind(this) : undefined);
|
||||
}
|
||||
|
||||
refreshDelayed() {
|
||||
this.timeout = setTimeout(() => {
|
||||
this.refresh();
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.refresh();
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if (this.timeout) clearTimeout(this.timeout);
|
||||
}
|
||||
|
||||
render() {
|
||||
return <WrappedComponent stats={this.state.stats} {...this.props} />;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
34
src/index.js
34
src/index.js
@ -1,13 +1,13 @@
|
||||
import 'react-hot-loader/patch'
|
||||
import React from 'react'
|
||||
import { render } from 'react-dom'
|
||||
import { AppContainer } from 'react-hot-loader'
|
||||
import configureStore, { history } from './store/configureStore'
|
||||
import App from './components/App'
|
||||
import registerServiceWorker from './registerServiceWorker'
|
||||
import { Provider } from 'react-redux'
|
||||
import { ConnectedRouter } from 'connected-react-router'
|
||||
import { start } from './orbitdb'
|
||||
import 'react-hot-loader/patch';
|
||||
import React from 'react';
|
||||
import { render } from 'react-dom';
|
||||
import { AppContainer } from 'react-hot-loader';
|
||||
import { Provider } from 'react-redux';
|
||||
import { ConnectedRouter } from 'connected-react-router';
|
||||
import configureStore, { history } from './store/configureStore';
|
||||
import App from './components/App';
|
||||
import registerServiceWorker from './registerServiceWorker';
|
||||
import { start } from './orbitdb';
|
||||
|
||||
const store = configureStore();
|
||||
|
||||
@ -19,12 +19,12 @@ render(
|
||||
</ConnectedRouter>
|
||||
</Provider>
|
||||
</AppContainer>,
|
||||
document.getElementById('root')
|
||||
document.getElementById('root'),
|
||||
);
|
||||
|
||||
if (module.hot) {
|
||||
module.hot.accept('./components/App', () => {
|
||||
const NewApp = require('./components/App').default
|
||||
const NewApp = require('./components/App').default;
|
||||
render(
|
||||
<AppContainer>
|
||||
<Provider store={store}>
|
||||
@ -33,10 +33,10 @@ if (module.hot) {
|
||||
</ConnectedRouter>
|
||||
</Provider>
|
||||
</AppContainer>,
|
||||
document.getElementById('root')
|
||||
)
|
||||
})
|
||||
document.getElementById('root'),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
registerServiceWorker()
|
||||
start(store.dispatch)
|
||||
registerServiceWorker();
|
||||
start(store.dispatch);
|
||||
|
@ -5,4 +5,4 @@ module.exports = {
|
||||
ADD_COMMENT: 'ADD_COMMENT',
|
||||
UPDATE_COMMENT: 'UPDATE_COMMENT',
|
||||
UPDATE_METADATA: 'UPDATE_METADATA',
|
||||
};
|
||||
};
|
||||
|
@ -1,15 +1,15 @@
|
||||
import IPFS from 'ipfs'
|
||||
import OrbitDB from 'orbit-db'
|
||||
import BoardStore from 'orbit-db-discussion-board'
|
||||
import multihashes from 'multihashes'
|
||||
import IPFS from 'ipfs';
|
||||
import OrbitDB from 'orbit-db';
|
||||
import BoardStore from 'orbit-db-discussion-board';
|
||||
import multihashes from 'multihashes';
|
||||
|
||||
export function isValidID(id) {
|
||||
try {
|
||||
if (typeof id === 'string' && multihashes.fromB58String(id)) return true
|
||||
if (typeof id === 'string' && multihashes.fromB58String(id)) return true;
|
||||
} catch (error) {
|
||||
return false
|
||||
return false;
|
||||
}
|
||||
return false
|
||||
return false;
|
||||
}
|
||||
|
||||
export async function start() {
|
||||
@ -17,96 +17,96 @@ export async function start() {
|
||||
window.ipfs = new IPFS({
|
||||
repo: 'ipfs-v6-boards-v0',
|
||||
EXPERIMENTAL: {
|
||||
pubsub: true
|
||||
}
|
||||
pubsub: true,
|
||||
},
|
||||
});
|
||||
await new Promise((resolve) => {
|
||||
window.ipfs.on('ready', () => resolve());
|
||||
});
|
||||
await new Promise(resolve => {
|
||||
window.ipfs.on('ready', () => resolve())
|
||||
})
|
||||
}
|
||||
if (!window.orbitDb) {
|
||||
OrbitDB.addDatabaseType(BoardStore.type, BoardStore)
|
||||
window.orbitDb = new OrbitDB(window.ipfs)
|
||||
OrbitDB.addDatabaseType(BoardStore.type, BoardStore);
|
||||
window.orbitDb = new OrbitDB(window.ipfs);
|
||||
}
|
||||
}
|
||||
|
||||
export async function open(address, metadata) {
|
||||
if (window.dbs && window.dbs[address]) return window.dbs[address]
|
||||
await start()
|
||||
if (window.dbs && window.dbs[address]) return window.dbs[address];
|
||||
await start();
|
||||
const options = {
|
||||
type: BoardStore.type,
|
||||
create: true,
|
||||
write: ['*']
|
||||
}
|
||||
const db = await window.orbitDb.open(address, options)
|
||||
await db.load()
|
||||
write: ['*'],
|
||||
};
|
||||
const db = await window.orbitDb.open(address, options);
|
||||
await db.load();
|
||||
if (metadata) {
|
||||
await db.updateMetadata(metadata)
|
||||
await db.updateMetadata(metadata);
|
||||
}
|
||||
if (!window.dbs) window.dbs = {}
|
||||
window.dbs[db.address.toString()] = db
|
||||
return db
|
||||
if (!window.dbs) window.dbs = {};
|
||||
window.dbs[db.address.toString()] = db;
|
||||
return db;
|
||||
}
|
||||
|
||||
export function connectDb(db, dispatch) {
|
||||
db.events.on('write', (dbname, hash, entry) => {
|
||||
dispatch({
|
||||
type: 'ORBITDB_WRITE',
|
||||
time: Date.now(),
|
||||
address: db.address.toString(),
|
||||
hash,
|
||||
entry
|
||||
})
|
||||
})
|
||||
db.events.on('replicated', address => {
|
||||
type: 'ORBITDB_WRITE',
|
||||
time: Date.now(),
|
||||
address: db.address.toString(),
|
||||
hash,
|
||||
entry,
|
||||
});
|
||||
});
|
||||
db.events.on('replicated', (address) => {
|
||||
dispatch({
|
||||
type: 'ORBITDB_REPLICATED',
|
||||
time: Date.now(),
|
||||
address: db.address.toString()
|
||||
})
|
||||
})
|
||||
type: 'ORBITDB_REPLICATED',
|
||||
time: Date.now(),
|
||||
address: db.address.toString(),
|
||||
});
|
||||
});
|
||||
db.events.on('replicate.progress', (address, hash, entry, progress, have) => {
|
||||
dispatch({
|
||||
type: 'ORBITDB_REPLICATE_PROGRESS',
|
||||
address: db.address.toString(),
|
||||
hash,
|
||||
entry,
|
||||
progress,
|
||||
have,
|
||||
time: Date.now(),
|
||||
replicationInfo: Object.assign({}, db._replicationInfo)
|
||||
})
|
||||
})
|
||||
db.events.on('replicate', address => {
|
||||
type: 'ORBITDB_REPLICATE_PROGRESS',
|
||||
address: db.address.toString(),
|
||||
hash,
|
||||
entry,
|
||||
progress,
|
||||
have,
|
||||
time: Date.now(),
|
||||
replicationInfo: Object.assign({}, db._replicationInfo),
|
||||
});
|
||||
});
|
||||
db.events.on('replicate', (address) => {
|
||||
dispatch({
|
||||
type: 'ORBITDB_REPLICATE',
|
||||
time: Date.now(),
|
||||
address: db.address.toString()
|
||||
})
|
||||
})
|
||||
db.events.on('close', address => {
|
||||
type: 'ORBITDB_REPLICATE',
|
||||
time: Date.now(),
|
||||
address: db.address.toString(),
|
||||
});
|
||||
});
|
||||
db.events.on('close', (address) => {
|
||||
dispatch({
|
||||
type: 'ORBITDB_CLOSE',
|
||||
time: Date.now(),
|
||||
address: db.address.toString()
|
||||
})
|
||||
})
|
||||
db.events.on('load', address => {
|
||||
type: 'ORBITDB_CLOSE',
|
||||
time: Date.now(),
|
||||
address: db.address.toString(),
|
||||
});
|
||||
});
|
||||
db.events.on('load', (address) => {
|
||||
dispatch({
|
||||
type: 'ORBITDB_LOAD',
|
||||
time: Date.now(),
|
||||
address: db.address.toString()
|
||||
})
|
||||
})
|
||||
type: 'ORBITDB_LOAD',
|
||||
time: Date.now(),
|
||||
address: db.address.toString(),
|
||||
});
|
||||
});
|
||||
db.events.on('load.progress', (address, hash, entry, progress, total) => {
|
||||
dispatch({
|
||||
type: 'ORBITDB_LOAD_PROGRESS',
|
||||
time: Date.now(),
|
||||
address: db.address.toString(),
|
||||
hash,
|
||||
entry,
|
||||
progress,
|
||||
total
|
||||
})
|
||||
})
|
||||
type: 'ORBITDB_LOAD_PROGRESS',
|
||||
time: Date.now(),
|
||||
address: db.address.toString(),
|
||||
hash,
|
||||
entry,
|
||||
progress,
|
||||
total,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -1,63 +1,69 @@
|
||||
import {
|
||||
OPENED_BOARD,
|
||||
CLOSE_BOARD,
|
||||
UPDATE_BOARD,
|
||||
ORBITDB_REPLICATE_PROGRESS,
|
||||
ORBITDB_REPLICATED,
|
||||
ORBITDB_REPLICATE
|
||||
} from '../actions/actionTypes'
|
||||
OPENED_BOARD,
|
||||
CLOSE_BOARD,
|
||||
UPDATE_BOARD,
|
||||
ORBITDB_REPLICATE_PROGRESS,
|
||||
ORBITDB_REPLICATED,
|
||||
ORBITDB_REPLICATE,
|
||||
} from '../actions/actionTypes';
|
||||
|
||||
function getInitialState() {
|
||||
return {
|
||||
boards: {}
|
||||
}
|
||||
return {
|
||||
boards: {},
|
||||
};
|
||||
}
|
||||
|
||||
function updateBoard(existingBoards, address, value) {
|
||||
return Object.assign({}, existingBoards, {
|
||||
[address]: Object.assign({}, existingBoards[address] || {}, value)
|
||||
})
|
||||
return Object.assign({}, existingBoards, {
|
||||
[address]: Object.assign({}, existingBoards[address] || {}, value),
|
||||
});
|
||||
}
|
||||
|
||||
function deleteBoard(existingBoards, address) {
|
||||
const boards = Object.assign({}, existingBoards)
|
||||
delete boards[address]
|
||||
return boards
|
||||
const boards = Object.assign({}, existingBoards);
|
||||
delete boards[address];
|
||||
return boards;
|
||||
}
|
||||
|
||||
export default function BoardsReducer(state = getInitialState(), action) {
|
||||
let address
|
||||
switch (action.type) {
|
||||
case OPENED_BOARD:
|
||||
address = action.board.address
|
||||
return Object.assign({}, state, { boards: updateBoard(state.boards, address, Object.assign({}, action.board, { open: true })) })
|
||||
case UPDATE_BOARD:
|
||||
address = action.address
|
||||
let { posts, metadata } = action
|
||||
return Object.assign({}, state, { boards: updateBoard(state.boards, address, { posts, metadata })})
|
||||
case ORBITDB_REPLICATE:
|
||||
address = action.address
|
||||
return Object.assign({}, state, { boards: updateBoard(state.boards, address, {
|
||||
replicating: true
|
||||
})})
|
||||
case ORBITDB_REPLICATE_PROGRESS:
|
||||
address = action.address
|
||||
return Object.assign({}, state, { boards: updateBoard(state.boards, address, {
|
||||
replicating: true,
|
||||
replicationInfo: action.replicationInfo
|
||||
})})
|
||||
case ORBITDB_REPLICATED:
|
||||
address = action.address
|
||||
return Object.assign({}, state, { boards: updateBoard(state.boards, address, {
|
||||
replicating: false,
|
||||
lastReplicated: action.time
|
||||
})})
|
||||
case CLOSE_BOARD:
|
||||
address = action.address
|
||||
return Object.assign({}, state, {
|
||||
boards: deleteBoard(state.boards, address)
|
||||
})
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
let address;
|
||||
switch (action.type) {
|
||||
case OPENED_BOARD:
|
||||
address = action.board.address;
|
||||
return Object.assign({}, state, { boards: updateBoard(state.boards, address, Object.assign({}, action.board, { open: true })) });
|
||||
case UPDATE_BOARD:
|
||||
address = action.address;
|
||||
const { posts, metadata } = action;
|
||||
return Object.assign({}, state, { boards: updateBoard(state.boards, address, { posts, metadata }) });
|
||||
case ORBITDB_REPLICATE:
|
||||
address = action.address;
|
||||
return Object.assign({}, state, {
|
||||
boards: updateBoard(state.boards, address, {
|
||||
replicating: true,
|
||||
}),
|
||||
});
|
||||
case ORBITDB_REPLICATE_PROGRESS:
|
||||
address = action.address;
|
||||
return Object.assign({}, state, {
|
||||
boards: updateBoard(state.boards, address, {
|
||||
replicating: true,
|
||||
replicationInfo: action.replicationInfo,
|
||||
}),
|
||||
});
|
||||
case ORBITDB_REPLICATED:
|
||||
address = action.address;
|
||||
return Object.assign({}, state, {
|
||||
boards: updateBoard(state.boards, address, {
|
||||
replicating: false,
|
||||
lastReplicated: action.time,
|
||||
}),
|
||||
});
|
||||
case CLOSE_BOARD:
|
||||
address = action.address;
|
||||
return Object.assign({}, state, {
|
||||
boards: deleteBoard(state.boards, address),
|
||||
});
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,12 @@
|
||||
import { combineReducers } from 'redux'
|
||||
import { connectRouter} from 'connected-react-router'
|
||||
import postReducer from './post'
|
||||
import boardsReducer from './boards'
|
||||
import openBoardReducer from './openboard'
|
||||
import { combineReducers } from 'redux';
|
||||
import { connectRouter } from 'connected-react-router';
|
||||
import postReducer from './post';
|
||||
import boardsReducer from './boards';
|
||||
import openBoardReducer from './openboard';
|
||||
|
||||
export default history => combineReducers({
|
||||
router: connectRouter(history),
|
||||
postEditor: postReducer,
|
||||
boards: boardsReducer,
|
||||
openBoard: openBoardReducer
|
||||
})
|
||||
router: connectRouter(history),
|
||||
postEditor: postReducer,
|
||||
boards: boardsReducer,
|
||||
openBoard: openBoardReducer,
|
||||
});
|
||||
|
@ -1,21 +1,21 @@
|
||||
import {
|
||||
OPEN_BOARD,
|
||||
OPENED_BOARD
|
||||
} from '../actions/actionTypes'
|
||||
OPEN_BOARD,
|
||||
OPENED_BOARD,
|
||||
} from '../actions/actionTypes';
|
||||
|
||||
function getInitialState() {
|
||||
return {
|
||||
opening: false
|
||||
}
|
||||
return {
|
||||
opening: false,
|
||||
};
|
||||
}
|
||||
|
||||
export default function openBoardReducer(state = getInitialState(), action) {
|
||||
switch (action.type) {
|
||||
case OPEN_BOARD:
|
||||
return Object.assign({}, state, { opening: true })
|
||||
case OPENED_BOARD:
|
||||
return Object.assign({}, state, { opening: false })
|
||||
default:
|
||||
return state
|
||||
}
|
||||
}
|
||||
switch (action.type) {
|
||||
case OPEN_BOARD:
|
||||
return Object.assign({}, state, { opening: true });
|
||||
case OPENED_BOARD:
|
||||
return Object.assign({}, state, { opening: false });
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
@ -1,19 +1,19 @@
|
||||
import { ADD_POST } from '../actions/actionTypes'
|
||||
import { ADD_POST } from '../actions/actionTypes';
|
||||
|
||||
function getInitialState(){
|
||||
return {
|
||||
post: {
|
||||
title: '',
|
||||
content: ''
|
||||
}
|
||||
}
|
||||
function getInitialState() {
|
||||
return {
|
||||
post: {
|
||||
title: '',
|
||||
content: '',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export default function(state = getInitialState(), action) {
|
||||
switch (action.type) {
|
||||
case ADD_POST:
|
||||
return Object.assign({}, state, { post: action.post })
|
||||
default:
|
||||
return state
|
||||
}
|
||||
}
|
||||
export default function (state = getInitialState(), action) {
|
||||
switch (action.type) {
|
||||
case ADD_POST:
|
||||
return Object.assign({}, state, { post: action.post });
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
@ -9,13 +9,13 @@
|
||||
// This link also includes instructions on opting out of this behavior.
|
||||
|
||||
const isLocalhost = Boolean(
|
||||
window.location.hostname === 'localhost' ||
|
||||
window.location.hostname === 'localhost'
|
||||
// [::1] is the IPv6 localhost address.
|
||||
window.location.hostname === '[::1]' ||
|
||||
|| window.location.hostname === '[::1]'
|
||||
// 127.0.0.1/8 is considered localhost for IPv4.
|
||||
window.location.hostname.match(
|
||||
/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
|
||||
)
|
||||
|| window.location.hostname.match(
|
||||
/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/,
|
||||
),
|
||||
);
|
||||
|
||||
export default function register() {
|
||||
@ -40,8 +40,8 @@ export default function register() {
|
||||
// service worker/PWA documentation.
|
||||
navigator.serviceWorker.ready.then(() => {
|
||||
console.log(
|
||||
'This web app is being served cache-first by a service ' +
|
||||
'worker. To learn more, visit https://goo.gl/SC7cgQ'
|
||||
'This web app is being served cache-first by a service '
|
||||
+ 'worker. To learn more, visit https://goo.gl/SC7cgQ',
|
||||
);
|
||||
});
|
||||
} else {
|
||||
@ -55,7 +55,7 @@ export default function register() {
|
||||
function registerValidSW(swUrl) {
|
||||
navigator.serviceWorker
|
||||
.register(swUrl)
|
||||
.then(registration => {
|
||||
.then((registration) => {
|
||||
registration.onupdatefound = () => {
|
||||
const installingWorker = registration.installing;
|
||||
installingWorker.onstatechange = () => {
|
||||
@ -76,7 +76,7 @@ function registerValidSW(swUrl) {
|
||||
};
|
||||
};
|
||||
})
|
||||
.catch(error => {
|
||||
.catch((error) => {
|
||||
console.error('Error during service worker registration:', error);
|
||||
});
|
||||
}
|
||||
@ -84,14 +84,14 @@ function registerValidSW(swUrl) {
|
||||
function checkValidServiceWorker(swUrl) {
|
||||
// Check if the service worker can be found. If it can't reload the page.
|
||||
fetch(swUrl)
|
||||
.then(response => {
|
||||
.then((response) => {
|
||||
// Ensure service worker exists, and that we really are getting a JS file.
|
||||
if (
|
||||
response.status === 404 ||
|
||||
response.headers.get('content-type').indexOf('javascript') === -1
|
||||
response.status === 404
|
||||
|| response.headers.get('content-type').indexOf('javascript') === -1
|
||||
) {
|
||||
// No service worker found. Probably a different app. Reload the page.
|
||||
navigator.serviceWorker.ready.then(registration => {
|
||||
navigator.serviceWorker.ready.then((registration) => {
|
||||
registration.unregister().then(() => {
|
||||
window.location.reload();
|
||||
});
|
||||
@ -103,14 +103,14 @@ function checkValidServiceWorker(swUrl) {
|
||||
})
|
||||
.catch(() => {
|
||||
console.log(
|
||||
'No internet connection found. App is running in offline mode.'
|
||||
'No internet connection found. App is running in offline mode.',
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
export function unregister() {
|
||||
if ('serviceWorker' in navigator) {
|
||||
navigator.serviceWorker.ready.then(registration => {
|
||||
navigator.serviceWorker.ready.then((registration) => {
|
||||
registration.unregister();
|
||||
});
|
||||
}
|
||||
|
@ -1,79 +1,81 @@
|
||||
import { put, call, fork, take } from 'redux-saga/effects'
|
||||
import { eventChannel } from 'redux-saga'
|
||||
import { push } from 'connected-react-router'
|
||||
import { open, connectDb } from '../orbitdb'
|
||||
import { createdBoard } from '../actions/board'
|
||||
import { shortenAddress, closeBoard as closeOrbitDBBoard } from '../utils/orbitdb'
|
||||
import { UPDATE_BOARD } from '../actions/actionTypes'
|
||||
import { saveSaga } from './persistence'
|
||||
import {
|
||||
put, call, fork, take,
|
||||
} from 'redux-saga/effects';
|
||||
import { eventChannel } from 'redux-saga';
|
||||
import { push } from 'connected-react-router';
|
||||
import { open, connectDb } from '../orbitdb';
|
||||
import { createdBoard } from '../actions/board';
|
||||
import { shortenAddress, closeBoard as closeOrbitDBBoard } from '../utils/orbitdb';
|
||||
import { UPDATE_BOARD } from '../actions/actionTypes';
|
||||
import { saveSaga } from './persistence';
|
||||
|
||||
export function* goToBoard({ board }){
|
||||
if (board.redirect) {
|
||||
yield put(push(shortenAddress(board.address)))
|
||||
}
|
||||
export function* goToBoard({ board }) {
|
||||
if (board.redirect) {
|
||||
yield put(push(shortenAddress(board.address)));
|
||||
}
|
||||
}
|
||||
|
||||
export function* updateBoard({ address }){
|
||||
const db = window.dbs[address]
|
||||
yield put({
|
||||
type: UPDATE_BOARD,
|
||||
address,
|
||||
posts: db.posts,
|
||||
metadata: Object.assign({}, db._index._index.metadata) // TODO: fix in lib and use db.metadata
|
||||
})
|
||||
export function* updateBoard({ address }) {
|
||||
const db = window.dbs[address];
|
||||
yield put({
|
||||
type: UPDATE_BOARD,
|
||||
address,
|
||||
posts: db.posts,
|
||||
metadata: Object.assign({}, db._index._index.metadata), // TODO: fix in lib and use db.metadata
|
||||
});
|
||||
}
|
||||
|
||||
export function* closeBoard({ address }){
|
||||
yield call(closeOrbitDBBoard, address)
|
||||
yield saveSaga()
|
||||
export function* closeBoard({ address }) {
|
||||
yield call(closeOrbitDBBoard, address);
|
||||
yield saveSaga();
|
||||
}
|
||||
|
||||
export function* updateBoardMetadata({ address, metadata }){
|
||||
const db = window.dbs[address]
|
||||
if (db) {
|
||||
yield call([db, db.updateMetadata], [metadata])
|
||||
yield goToBoard({ board: { address } });
|
||||
} else {
|
||||
yield put({ type: 'ERROR', error: address + ' not found' })
|
||||
}
|
||||
export function* updateBoardMetadata({ address, metadata }) {
|
||||
const db = window.dbs[address];
|
||||
if (db) {
|
||||
yield call([db, db.updateMetadata], [metadata]);
|
||||
yield goToBoard({ board: { address } });
|
||||
} else {
|
||||
yield put({ type: 'ERROR', error: `${address} not found` });
|
||||
}
|
||||
}
|
||||
|
||||
export function* openBoard({ board }) {
|
||||
let db
|
||||
let db;
|
||||
try {
|
||||
const metadata = board.title ? { title: board.title } : null;
|
||||
db = yield call(open, board.address, metadata);
|
||||
} catch (error) {
|
||||
yield put({ type: 'ERROR', error });
|
||||
}
|
||||
if (db) {
|
||||
const address = db.address.toString();
|
||||
const dbInfo = { address };
|
||||
dbInfo.posts = db.posts;
|
||||
dbInfo.metadata = Object.assign({}, db._index._index.metadata); // TODO: fix in lib and use db.metadata
|
||||
dbInfo.name = db.dbname;
|
||||
try {
|
||||
const metadata = board.title ? { title: board.title } : null
|
||||
db = yield call(open, board.address, metadata)
|
||||
const channel = yield call(createDbEventChannel, db);
|
||||
yield fork(watchDb, channel);
|
||||
yield put(createdBoard(Object.assign({ redirect: !!board.redirect }, board, dbInfo)));
|
||||
} catch (error) {
|
||||
yield put({ type: 'ERROR', error })
|
||||
}
|
||||
if (db) {
|
||||
const address = db.address.toString()
|
||||
const dbInfo = { address }
|
||||
dbInfo.posts = db.posts
|
||||
dbInfo.metadata = Object.assign({}, db._index._index.metadata) // TODO: fix in lib and use db.metadata
|
||||
dbInfo.name = db.dbname
|
||||
try {
|
||||
const channel = yield call(createDbEventChannel, db)
|
||||
yield fork(watchDb, channel)
|
||||
yield put(createdBoard(Object.assign({ redirect: !!board.redirect }, board, dbInfo)))
|
||||
} catch (error) {
|
||||
yield put({ type: 'ERROR', error })
|
||||
}
|
||||
yield put({ type: 'ERROR', error });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function* watchDb(channel) {
|
||||
// Dispatches action coming from the channel, terminates when ORBITDB_CLOSE arrives
|
||||
let action
|
||||
while(!action || action.type !== 'ORBITDB_CLOSE') {
|
||||
action = yield take(channel)
|
||||
yield put(action)
|
||||
}
|
||||
// Dispatches action coming from the channel, terminates when ORBITDB_CLOSE arrives
|
||||
let action;
|
||||
while (!action || action.type !== 'ORBITDB_CLOSE') {
|
||||
action = yield take(channel);
|
||||
yield put(action);
|
||||
}
|
||||
}
|
||||
|
||||
function createDbEventChannel(db) {
|
||||
return eventChannel(emitter => {
|
||||
connectDb(db, emitter)
|
||||
return () => db.close()
|
||||
})
|
||||
}
|
||||
return eventChannel((emitter) => {
|
||||
connectDb(db, emitter);
|
||||
return () => db.close();
|
||||
});
|
||||
}
|
||||
|
@ -1,28 +1,30 @@
|
||||
import { takeEvery, put, call } from 'redux-saga/effects'
|
||||
import { takeEvery, put, call } from 'redux-saga/effects';
|
||||
import {
|
||||
OPEN_BOARD,
|
||||
OPENED_BOARD,
|
||||
CLOSE_BOARD,
|
||||
ADD_POST,
|
||||
ORBITDB_REPLICATED,
|
||||
ORBITDB_WRITE,
|
||||
UPDATE_BOARD_METADATA
|
||||
} from '../actions/actionTypes'
|
||||
import { openBoard, updateBoard, goToBoard, updateBoardMetadata, closeBoard } from './boards'
|
||||
import { addPost } from './posts'
|
||||
import { openPreviousBoards, saveSaga } from './persistence'
|
||||
OPEN_BOARD,
|
||||
OPENED_BOARD,
|
||||
CLOSE_BOARD,
|
||||
ADD_POST,
|
||||
ORBITDB_REPLICATED,
|
||||
ORBITDB_WRITE,
|
||||
UPDATE_BOARD_METADATA,
|
||||
} from '../actions/actionTypes';
|
||||
import {
|
||||
openBoard, updateBoard, goToBoard, updateBoardMetadata, closeBoard,
|
||||
} from './boards';
|
||||
import { addPost } from './posts';
|
||||
import { openPreviousBoards, saveSaga } from './persistence';
|
||||
|
||||
export default function* saga(){
|
||||
yield takeEvery(OPEN_BOARD, openBoard)
|
||||
yield takeEvery(OPENED_BOARD, goToBoard)
|
||||
yield takeEvery(OPENED_BOARD, saveSaga)
|
||||
yield takeEvery(CLOSE_BOARD, closeBoard)
|
||||
export default function* saga() {
|
||||
yield takeEvery(OPEN_BOARD, openBoard);
|
||||
yield takeEvery(OPENED_BOARD, goToBoard);
|
||||
yield takeEvery(OPENED_BOARD, saveSaga);
|
||||
yield takeEvery(CLOSE_BOARD, closeBoard);
|
||||
|
||||
yield takeEvery(ADD_POST, addPost)
|
||||
yield takeEvery(UPDATE_BOARD_METADATA, updateBoardMetadata)
|
||||
yield takeEvery(ADD_POST, addPost);
|
||||
yield takeEvery(UPDATE_BOARD_METADATA, updateBoardMetadata);
|
||||
|
||||
yield takeEvery(ORBITDB_WRITE, updateBoard)
|
||||
yield takeEvery(ORBITDB_REPLICATED, updateBoard)
|
||||
yield takeEvery(ORBITDB_WRITE, updateBoard);
|
||||
yield takeEvery(ORBITDB_REPLICATED, updateBoard);
|
||||
|
||||
yield openPreviousBoards()
|
||||
}
|
||||
yield openPreviousBoards();
|
||||
}
|
||||
|
@ -1,16 +1,16 @@
|
||||
import { call, put } from 'redux-saga/effects'
|
||||
import { openBoard } from '../actions/board'
|
||||
import { save, load } from '../utils/persistence'
|
||||
import { call, put } from 'redux-saga/effects';
|
||||
import { openBoard } from '../actions/board';
|
||||
import { save, load } from '../utils/persistence';
|
||||
|
||||
export function* openPreviousBoards() {
|
||||
const data = yield call(load)
|
||||
if (Array.isArray(data.addresses)) {
|
||||
for (const address of data.addresses) {
|
||||
yield put(openBoard({ address, redirect: false }))
|
||||
}
|
||||
const data = yield call(load);
|
||||
if (Array.isArray(data.addresses)) {
|
||||
for (const address of data.addresses) {
|
||||
yield put(openBoard({ address, redirect: false }));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function* saveSaga() {
|
||||
yield call(save)
|
||||
}
|
||||
yield call(save);
|
||||
}
|
||||
|
@ -1,18 +1,18 @@
|
||||
import { call } from 'redux-saga/effects'
|
||||
import { call } from 'redux-saga/effects';
|
||||
import { goToBoard } from './boards';
|
||||
|
||||
export function* addPost({ address, post }) {
|
||||
const db = window.dbs[address]
|
||||
const { title, text } = post
|
||||
yield call([db, db.addPost], { title, text })
|
||||
yield goToBoard({ board: { address, redirect: true } });
|
||||
// TODO: goto post
|
||||
const db = window.dbs[address];
|
||||
const { title, text } = post;
|
||||
yield call([db, db.addPost], { title, text });
|
||||
yield goToBoard({ board: { address, redirect: true } });
|
||||
// TODO: goto post
|
||||
}
|
||||
|
||||
export function* editPost({ address, postId, post }) {
|
||||
const db = window.dbs[address]
|
||||
const { title, text } = post
|
||||
yield call([db, db.updatePost], postId, { title, text })
|
||||
yield goToBoard({ board: { address, redirect: true } });
|
||||
// TODO: goto post
|
||||
}
|
||||
const db = window.dbs[address];
|
||||
const { title, text } = post;
|
||||
yield call([db, db.updatePost], postId, { title, text });
|
||||
yield goToBoard({ board: { address, redirect: true } });
|
||||
// TODO: goto post
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
import {createStore, compose, applyMiddleware} from 'redux';
|
||||
import { createStore, compose, applyMiddleware } from 'redux';
|
||||
import reduxImmutableStateInvariant from 'redux-immutable-state-invariant';
|
||||
import createSagaMiddleware from 'redux-saga';
|
||||
import saga from '../sagas';
|
||||
import createHistory from 'history/createHashHistory';
|
||||
import { routerMiddleware } from 'connected-react-router';
|
||||
import saga from '../sagas';
|
||||
import createRootReducer from '../reducers';
|
||||
|
||||
const sagaMiddleware = createSagaMiddleware();
|
||||
@ -17,9 +17,8 @@ function configureStoreProd(initialState) {
|
||||
];
|
||||
|
||||
const store = createStore(createRootReducer(history), initialState, compose(
|
||||
applyMiddleware(...middlewares)
|
||||
)
|
||||
);
|
||||
applyMiddleware(...middlewares),
|
||||
));
|
||||
|
||||
sagaMiddleware.run(saga);
|
||||
|
||||
@ -36,9 +35,8 @@ function configureStoreDev(initialState) {
|
||||
|
||||
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose; // add support for Redux dev tools
|
||||
const store = createStore(createRootReducer(history), initialState, composeEnhancers(
|
||||
applyMiddleware(...middlewares)
|
||||
)
|
||||
);
|
||||
applyMiddleware(...middlewares),
|
||||
));
|
||||
|
||||
let sagaTask = sagaMiddleware.run(saga);
|
||||
|
||||
|
@ -1,55 +1,55 @@
|
||||
export async function ipfsPut(content) {
|
||||
const obj = {
|
||||
content: Buffer.from(content),
|
||||
path: '/'
|
||||
}
|
||||
const response = await window.ipfs.files.add(obj)
|
||||
return response[0].hash
|
||||
const obj = {
|
||||
content: Buffer.from(content),
|
||||
path: '/',
|
||||
};
|
||||
const response = await window.ipfs.files.add(obj);
|
||||
return response[0].hash;
|
||||
}
|
||||
|
||||
export async function readText(multihash) {
|
||||
const buffer = await window.ipfs.object.get(multihash)
|
||||
return buffer.toString('utf-8')
|
||||
const buffer = await window.ipfs.object.get(multihash);
|
||||
return buffer.toString('utf-8');
|
||||
}
|
||||
|
||||
export async function getStats() {
|
||||
const ipfs = window.ipfs;
|
||||
const orbitDb = window.orbitDb
|
||||
const dbs = {}
|
||||
const stats = {}
|
||||
if (ipfs && ipfs.isOnline()) {
|
||||
stats.ipfsLoaded = true
|
||||
const peers = await ipfs.swarm.peers()
|
||||
const id = await ipfs.id()
|
||||
stats.peers = peers.map(p => p.peer.id._idB58String)
|
||||
stats.id = id.id
|
||||
} else {
|
||||
stats.ipfsLoaded = false
|
||||
}
|
||||
if (stats.ipfsLoaded && orbitDb) {
|
||||
stats.orbitDbLoaded = true
|
||||
stats.pubKey = await orbitDb.key.getPublic('hex')
|
||||
Object.values(window.dbs || {}).forEach(db => {
|
||||
let writeable = db.access.write.indexOf('*') >= 0 || db.access.write.indexOf(stats.pubKey) >= 0
|
||||
const dbInfo = {
|
||||
opLogLength: db._oplog.length,
|
||||
access: {
|
||||
admin: db.access.admin,
|
||||
read: db.access.read,
|
||||
write: db.access.write,
|
||||
writeable
|
||||
},
|
||||
peers: []
|
||||
}
|
||||
const subscription = orbitDb._pubsub._subscriptions[db.address]
|
||||
if (subscription && subscription.room) {
|
||||
dbInfo.peers = [...(subscription.room._peers || [])]
|
||||
}
|
||||
dbs[db.address] = dbInfo
|
||||
})
|
||||
} else {
|
||||
stats.orbitDbLoaded = false
|
||||
}
|
||||
stats.dbs = dbs
|
||||
return stats
|
||||
}
|
||||
const ipfs = window.ipfs;
|
||||
const orbitDb = window.orbitDb;
|
||||
const dbs = {};
|
||||
const stats = {};
|
||||
if (ipfs && ipfs.isOnline()) {
|
||||
stats.ipfsLoaded = true;
|
||||
const peers = await ipfs.swarm.peers();
|
||||
const id = await ipfs.id();
|
||||
stats.peers = peers.map(p => p.peer.id._idB58String);
|
||||
stats.id = id.id;
|
||||
} else {
|
||||
stats.ipfsLoaded = false;
|
||||
}
|
||||
if (stats.ipfsLoaded && orbitDb) {
|
||||
stats.orbitDbLoaded = true;
|
||||
stats.pubKey = await orbitDb.key.getPublic('hex');
|
||||
Object.values(window.dbs || {}).forEach((db) => {
|
||||
const writeable = db.access.write.indexOf('*') >= 0 || db.access.write.indexOf(stats.pubKey) >= 0;
|
||||
const dbInfo = {
|
||||
opLogLength: db._oplog.length,
|
||||
access: {
|
||||
admin: db.access.admin,
|
||||
read: db.access.read,
|
||||
write: db.access.write,
|
||||
writeable,
|
||||
},
|
||||
peers: [],
|
||||
};
|
||||
const subscription = orbitDb._pubsub._subscriptions[db.address];
|
||||
if (subscription && subscription.room) {
|
||||
dbInfo.peers = [...(subscription.room._peers || [])];
|
||||
}
|
||||
dbs[db.address] = dbInfo;
|
||||
});
|
||||
} else {
|
||||
stats.orbitDbLoaded = false;
|
||||
}
|
||||
stats.dbs = dbs;
|
||||
return stats;
|
||||
}
|
||||
|
@ -1,14 +1,14 @@
|
||||
|
||||
export function getBoardAddress(hash, name) {
|
||||
return '/orbitdb/' + hash + '/' + name
|
||||
return `/orbitdb/${hash}/${name}`;
|
||||
}
|
||||
|
||||
export function shortenAddress(address) {
|
||||
return address.replace(/^\/orbitdb/, '/b')
|
||||
return address.replace(/^\/orbitdb/, '/b');
|
||||
}
|
||||
|
||||
export function closeBoard(address) {
|
||||
const db = window.dbs[address]
|
||||
delete window.dbs[address]
|
||||
if (db && db.close) db.close()
|
||||
}
|
||||
const db = window.dbs[address];
|
||||
delete window.dbs[address];
|
||||
if (db && db.close) db.close();
|
||||
}
|
||||
|
@ -1,16 +1,16 @@
|
||||
|
||||
export function save(){
|
||||
const obj = {
|
||||
addresses: Object.keys(window.dbs || {})
|
||||
}
|
||||
localStorage.setItem('ipfs-boards-v0', JSON.stringify(obj))
|
||||
export function save() {
|
||||
const obj = {
|
||||
addresses: Object.keys(window.dbs || {}),
|
||||
};
|
||||
localStorage.setItem('ipfs-boards-v0', JSON.stringify(obj));
|
||||
}
|
||||
|
||||
export function load(){
|
||||
const str = localStorage.getItem('ipfs-boards-v0')
|
||||
try {
|
||||
return JSON.parse(str) || {};
|
||||
} catch (error) {
|
||||
return {}
|
||||
}
|
||||
}
|
||||
export function load() {
|
||||
const str = localStorage.getItem('ipfs-boards-v0');
|
||||
try {
|
||||
return JSON.parse(str) || {};
|
||||
} catch (error) {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user