mirror of
https://github.com/fazo96/ipfs-boards
synced 2025-01-09 12:19:49 +01:00
added board editing form and fixed metadata retrieval
This commit is contained in:
parent
718a99b225
commit
db03079b55
@ -1,15 +1,16 @@
|
||||
|
||||
export const ADD_POST = 'ADD_POST'
|
||||
export const UPDATE_BOARD_METADATA = 'UPDATE_BOARD_METADATA'
|
||||
|
||||
export const OPEN_BOARD = 'OPEN_BOARD'
|
||||
export const OPENED_BOARD = 'OPENED_BOARD'
|
||||
|
||||
export const UPDATE_BOARD = 'UPDATE_BOARD'
|
||||
|
||||
export const BOARD_ERROR = 'BOARD_ERROR'
|
||||
|
||||
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_REPLICATED = 'ORBITDB_REPLICATED'
|
||||
|
||||
export const ERROR = 'ERROR'
|
@ -1,7 +1,7 @@
|
||||
import {
|
||||
OPEN_BOARD,
|
||||
OPENED_BOARD,
|
||||
BOARD_ERROR
|
||||
UPDATE_BOARD_METADATA
|
||||
} from './actionTypes'
|
||||
|
||||
export function openBoard(board) {
|
||||
@ -18,9 +18,10 @@ export function createdBoard(board) {
|
||||
}
|
||||
}
|
||||
|
||||
export function boardError(error) {
|
||||
export function updateBoardMetadata(address, metadata) {
|
||||
return {
|
||||
type: BOARD_ERROR,
|
||||
error
|
||||
type: UPDATE_BOARD_METADATA,
|
||||
address,
|
||||
metadata
|
||||
}
|
||||
}
|
@ -90,7 +90,7 @@ export default function Board({ address, posts, metadata, replicating, stats, re
|
||||
<Button as={Link} to={'/'}>
|
||||
<Icon name='left arrow'/> Boards
|
||||
</Button>
|
||||
<Button disabled={!writeable}>
|
||||
<Button disabled={!writeable} as={Link} to={shortenAddress(address)+'/edit'}>
|
||||
<Icon name='pencil'/> Edit
|
||||
</Button>
|
||||
<Button disabled={!writeable} as={Link} to={shortenAddress(address)+'/p/new'}>
|
||||
|
49
src/components/BoardEditorForm.js
Normal file
49
src/components/BoardEditorForm.js
Normal file
@ -0,0 +1,49 @@
|
||||
import React, { Component } from 'react'
|
||||
import { Icon, Container, Card, Form, Button } from 'semantic-ui-react'
|
||||
|
||||
export default class BoardEditorForm extends Component {
|
||||
constructor(props){
|
||||
super(props)
|
||||
this.state = {
|
||||
title: props.title || ''
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const { title } = this.state
|
||||
const { address, updateBoardMetadata } = this.props
|
||||
return <Container>
|
||||
<Card fluid centered style={{marginTop:'5em',maxWidth:'40em'}}>
|
||||
<Card.Content>
|
||||
<Card.Header>Edit Board</Card.Header>
|
||||
<Card.Meta>
|
||||
Boards is an experimental peer to peer application.<br/>
|
||||
All content you publish will be public and may be lost or
|
||||
changed at any time.<br/>
|
||||
Please do not use this version of Boards
|
||||
for anything other than testing purposes
|
||||
</Card.Meta>
|
||||
</Card.Content>
|
||||
<Card.Content>
|
||||
<Form>
|
||||
<Form.Field>
|
||||
<label>Title</label>
|
||||
<input
|
||||
value={title}
|
||||
onChange={this.updateTitle.bind(this)}
|
||||
/>
|
||||
</Form.Field>
|
||||
<Button fluid onClick={() => updateBoardMetadata(address, this.state)}>
|
||||
<Icon name="save"/> Save
|
||||
</Button>
|
||||
</Form>
|
||||
</Card.Content>
|
||||
</Card>
|
||||
</Container>
|
||||
}
|
||||
|
||||
updateTitle(event) {
|
||||
const title = event.target.value
|
||||
this.setState({ title })
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
import React from 'react'
|
||||
import { Switch, Route } from 'react-router-dom'
|
||||
import Board from '../containers/Board'
|
||||
import BoardEditor from '../containers/Board'
|
||||
import BoardEditor from '../containers/BoardEditor'
|
||||
import PostEditor from '../containers/PostEditor'
|
||||
import WithStats from '../containers/WithStats'
|
||||
|
||||
|
@ -7,7 +7,7 @@ export default function Boards({ stats, boards, createBoard }) {
|
||||
return <Grid container divided colums={2}>
|
||||
<Grid.Column width={8}>
|
||||
<Header size='large' style={{marginTop:'.5em'}}>
|
||||
<Icon name="cube" color="blue" circular verticalAlign="middle" floated="right"/>
|
||||
<Icon name="cube" color="blue" circular/>
|
||||
<Header.Content>
|
||||
<Header.Content>IPFS Boards</Header.Content>
|
||||
<Header.Subheader>Experimental Build</Header.Subheader>
|
||||
|
@ -3,11 +3,11 @@ import { List, Button, Card } from 'semantic-ui-react'
|
||||
import { Link } from 'react-router-dom'
|
||||
import { shortenAddress } from '../utils/orbitdb'
|
||||
|
||||
export default function BoardsItem({ address, title, name }) {
|
||||
export default function BoardsItem({ address, metadata, name }) {
|
||||
return <Card fluid>
|
||||
<Card.Content>
|
||||
<Card.Header>
|
||||
{ title || 'Unnamed board' }
|
||||
{ metadata.title || 'Unnamed board' }
|
||||
</Card.Header>
|
||||
<Card.Meta>Board</Card.Meta>
|
||||
</Card.Content>
|
||||
|
36
src/containers/BoardEditor.js
Normal file
36
src/containers/BoardEditor.js
Normal file
@ -0,0 +1,36 @@
|
||||
|
||||
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}
|
||||
{...boardEditor}
|
||||
/>
|
||||
}
|
||||
|
||||
function mapStateToProps(state){
|
||||
return {
|
||||
boards: state.boards.boards,
|
||||
boardEditor: state.boardEditor
|
||||
}
|
||||
}
|
||||
|
||||
function mapDispatchToProps(dispatch) {
|
||||
return {
|
||||
updateBoardMetadata: (address, metadata) => dispatch(updateBoardMetadata(address, metadata))
|
||||
}
|
||||
}
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(BoardEditor)
|
@ -12,7 +12,7 @@ export default function(WrappedComponent) {
|
||||
pubKey: '?',
|
||||
dbs: {}
|
||||
},
|
||||
interval: null
|
||||
timeout: null
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,10 +23,9 @@ export default function(WrappedComponent) {
|
||||
}
|
||||
|
||||
refreshDelayed() {
|
||||
const timeout = setTimeout(() => {
|
||||
this.timeout = setTimeout(() => {
|
||||
this.refresh()
|
||||
}, 2000)
|
||||
this.setState({ timeout })
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
@ -34,7 +33,7 @@ export default function(WrappedComponent) {
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if (this.state.interval) clearInterval(this.state.interval)
|
||||
if (this.timeout) clearTimeout(this.timeout)
|
||||
}
|
||||
|
||||
render() {
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { put, call, fork, take } from 'redux-saga/effects'
|
||||
import { put, call, fork, take, apply } from 'redux-saga/effects'
|
||||
import { eventChannel } from 'redux-saga'
|
||||
import { push } from 'react-router-redux'
|
||||
import { open, connectDb } from '../orbitdb'
|
||||
import { createdBoard, boardError } from '../actions/board'
|
||||
import { createdBoard } from '../actions/board'
|
||||
import { shortenAddress } from '../utils/orbitdb'
|
||||
import { UPDATE_BOARD } from '../actions/actionTypes'
|
||||
|
||||
@ -16,25 +16,33 @@ export function* updateBoard({ address }){
|
||||
type: UPDATE_BOARD,
|
||||
address,
|
||||
posts: db.posts,
|
||||
metadata: db.metadata,
|
||||
syncRequestsReceived: db._stats.syncRequestsReceived,
|
||||
opLogLength: db._oplog.length
|
||||
metadata: Object.assign({}, db._index._index.metadata) // TODO: fix in lib and use db.metadata
|
||||
})
|
||||
}
|
||||
|
||||
export function* updateBoardMetadata({ address, metadata }){
|
||||
const db = window.dbs[address]
|
||||
if (db) {
|
||||
yield apply(db, db.updateMetadata, [metadata])
|
||||
yield goToBoard({ board: { address } });
|
||||
} else {
|
||||
yield put({ type: 'ERROR', error: address + ' not found' })
|
||||
}
|
||||
}
|
||||
|
||||
export function* openBoard({ board }) {
|
||||
let db
|
||||
try {
|
||||
const metadata = board.title ? { title: board.title } : null
|
||||
db = yield call(open, board.address, metadata)
|
||||
} catch (error) {
|
||||
yield put(boardError(error))
|
||||
yield put({ type: 'ERROR', error })
|
||||
}
|
||||
if (db) {
|
||||
const address = db.address.toString()
|
||||
const dbInfo = { address }
|
||||
dbInfo.posts = db.posts
|
||||
dbInfo.metadata = db.metadata
|
||||
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)
|
||||
|
@ -1,12 +1,15 @@
|
||||
import { takeEvery } from 'redux-saga/effects'
|
||||
import { OPEN_BOARD, OPENED_BOARD, ADD_POST, ORBITDB_REPLICATED, ORBITDB_WRITE } from '../actions/actionTypes'
|
||||
import { openBoard, updateBoard, goToBoard } from './boards'
|
||||
import { OPEN_BOARD, OPENED_BOARD, ADD_POST, ORBITDB_REPLICATED, ORBITDB_WRITE, UPDATE_BOARD_METADATA } from '../actions/actionTypes'
|
||||
import { openBoard, updateBoard, goToBoard, updateBoardMetadata } from './boards'
|
||||
import { addPost } from './posts'
|
||||
|
||||
export default function* saga(){
|
||||
yield takeEvery(OPEN_BOARD, openBoard)
|
||||
yield takeEvery(OPENED_BOARD, goToBoard)
|
||||
|
||||
yield takeEvery(ADD_POST, addPost)
|
||||
yield takeEvery(UPDATE_BOARD_METADATA, updateBoardMetadata)
|
||||
|
||||
yield takeEvery(ORBITDB_WRITE, updateBoard)
|
||||
yield takeEvery(ORBITDB_REPLICATED, updateBoard)
|
||||
}
|
@ -18,12 +18,16 @@ export async function getStats() {
|
||||
const dbs = {}
|
||||
const stats = {}
|
||||
if (ipfs) {
|
||||
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 (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
|
||||
@ -43,6 +47,8 @@ export async function getStats() {
|
||||
}
|
||||
dbs[db.address] = dbInfo
|
||||
})
|
||||
} else {
|
||||
stats.orbitDbLoaded = false
|
||||
}
|
||||
stats.dbs = dbs
|
||||
return stats
|
||||
|
Loading…
Reference in New Issue
Block a user