mirror of
https://github.com/amark/gun.git
synced 2025-03-30 15:08:33 +00:00
commit
18fc90d2cf
175
examples/react.html
Normal file
175
examples/react.html
Normal file
@ -0,0 +1,175 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>gun - react examples</title>
|
||||
<style>
|
||||
html, body { font-size: 14pt; padding: 10px 2.5%;}
|
||||
.hide { display: none; }
|
||||
form .who { width: 10%; }
|
||||
form .what { width: 80%; }
|
||||
ul { list-style: none; padding: 0; }
|
||||
ul .when {color: #555; font-size: 12pt; float: right; display: none; }
|
||||
li:hover .when {display: inline;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.23.1/babel.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.4.2/react.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.4.2/react-dom.js"></script>
|
||||
<script src="../gun.js"></script>
|
||||
|
||||
<script type="text/babel" data-presets="react,latest,stage-0">
|
||||
const { Component } = React
|
||||
const { render } = ReactDOM
|
||||
const todos = Gun().get('todos')
|
||||
const formatTodos = todos => Object.keys(todos)
|
||||
.map(key => ({ key, val: todos[key] }))
|
||||
.filter(t => Boolean(t.val) && t.key !== '_')
|
||||
|
||||
class Todos extends Component {
|
||||
constructor() {
|
||||
super()
|
||||
this.state = {newTodo: '', todos: []}
|
||||
}
|
||||
componentWillMount() {
|
||||
todos.on(todos => this.setState({
|
||||
todos: formatTodos(todos)
|
||||
}))
|
||||
}
|
||||
add = _ => {
|
||||
todos.path(Gun.text.random()).put(this.state.newTodo)
|
||||
this.setState({newTodo: ''})
|
||||
}
|
||||
del = key => gun.path(key).put(null)
|
||||
handleChange = e => this.setState({ newTodo: e.target.value})
|
||||
render() {
|
||||
return <div>
|
||||
<input value={this.state.newTodo} onChange={this.handleChange} />
|
||||
<button onClick={this.add}>Add</button>
|
||||
<br />
|
||||
<ul>
|
||||
{this.state.todos.map(todo => <li key={todo.key} onClick={_=>this.del(todo.key)}>{todo.val}</li>)}
|
||||
</ul>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
const json = Gun().get('json')
|
||||
const formatJson = json =>
|
||||
Object.keys(json)
|
||||
.map(key => ({ key, val: json[key]}))
|
||||
.filter(el => el.key !== '_')
|
||||
|
||||
class Json extends Component {
|
||||
constructor() {
|
||||
super()
|
||||
this.state = { newField: '', json: [] }
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
json.on(json => this.setState({ json: formatJson(json) }))
|
||||
}
|
||||
|
||||
edit = key => e => {
|
||||
e.preventDefault()
|
||||
json.path(key).put(e.target.value)
|
||||
}
|
||||
|
||||
add = e => {
|
||||
e.preventDefault()
|
||||
json.path(this.state.newField).put('value')
|
||||
this.setState({newField: ''})
|
||||
}
|
||||
|
||||
render() {
|
||||
return <div>
|
||||
<ul>
|
||||
{this.state.json.map(({ key, val }) =>
|
||||
<li key={key}><b>{key}:</b> <input value={val} onChange={this.edit(key)} /></li>
|
||||
)}
|
||||
</ul>
|
||||
<form onSubmit={this.add}>
|
||||
<input value={this.state.newField} onChange={e => this.setState({ newField: e.target.value})} />
|
||||
<button onClick={this.add}>Add Field</button>
|
||||
</form>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const chat = Gun().get('chat')
|
||||
const formatMsgs = msgs => Object.keys(msgs)
|
||||
.map(key => ({ key, ...msgs[key] }))
|
||||
.filter(m => Boolean(m.when) && m.key !== '_')
|
||||
.sort((a, b) => a.when - b.when)
|
||||
.map(m => ((m.whenFmt = new Date(m.when).toLocaleString().toLowerCase()), m))
|
||||
|
||||
class Chat extends Component {
|
||||
constructor() {
|
||||
super()
|
||||
this.state = {
|
||||
newMsg: '',
|
||||
name: (document.cookie.match(/alias\=(.*?)(\&|$|\;)/i)||[])[1]||'',
|
||||
msgs: {},
|
||||
}
|
||||
}
|
||||
componentWillMount() {
|
||||
const tmpState = {}
|
||||
chat.map().val((msg, key) => {
|
||||
tmpState[key] = msg
|
||||
this.setState({msgs: Object.assign({}, this.state.msgs, tmpState)})
|
||||
})
|
||||
|
||||
}
|
||||
send = e => {
|
||||
e.preventDefault()
|
||||
const who = this.state.name || 'user' + Gun.text.random(6)
|
||||
this.setState({name: who})
|
||||
document.cookie = ('alias=' + who)
|
||||
const when = Gun.time.is()
|
||||
const key = `${when}_${Gun.text.random(4)}`
|
||||
chat.path(key).put({
|
||||
who,
|
||||
when,
|
||||
what: this.state.newMsg,
|
||||
})
|
||||
this.setState({newMsg: ''})
|
||||
}
|
||||
render() {
|
||||
const msgs = formatMsgs(this.state.msgs)
|
||||
return <div>
|
||||
<ul>
|
||||
{msgs.map(msg =>
|
||||
<li key={msg.key}><b>{msg.who}:</b> {msg.what}<span className="when">{msg.whenFmt}</span></li>
|
||||
)}
|
||||
</ul>
|
||||
<form onSubmit={this.send}>
|
||||
<input value={this.state.name} className="who" onChange={e => this.setState({ name: e.target.value})} />
|
||||
<input value={this.state.newMsg} className="what" onChange={e => this.setState({ newMsg: e.target.value})} />
|
||||
<button onClick={this.send}>Send</button>
|
||||
</form>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
const App = _ =>
|
||||
<div>
|
||||
<h1>React Examples</h1>
|
||||
<h2>Todo</h2>
|
||||
<Todos />
|
||||
<br />
|
||||
<hr />
|
||||
<h2>Chat</h2>
|
||||
<Chat />
|
||||
<br />
|
||||
<hr />
|
||||
<h2>Json</h2>
|
||||
<Json />
|
||||
</div>
|
||||
|
||||
render(<App />, document.getElementById('app'))
|
||||
|
||||
|
||||
</script>
|
||||
</body>
|
11
examples/react/.babelrc
Normal file
11
examples/react/.babelrc
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"presets": [
|
||||
"react",
|
||||
"env",
|
||||
"stage-0"
|
||||
],
|
||||
"plugins": [
|
||||
"transform-decorators-legacy",
|
||||
"transform-eval"
|
||||
]
|
||||
}
|
3
examples/react/.gitignore
vendored
Normal file
3
examples/react/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
data.json
|
||||
node_modules
|
||||
npm-debug.log
|
8
examples/react/README.md
Normal file
8
examples/react/README.md
Normal file
@ -0,0 +1,8 @@
|
||||
# React Gun Examples
|
||||
|
||||
These are the react examples for gun. They are separate from the other examples, because they require a lot of additional npm modules.
|
||||
|
||||
To run these modules, change to this directory, and run `npm install` and then `npm start` to start the server. Then navigate to `localhost:3000` to view the examples.
|
||||
|
||||
|
||||

|
23
examples/react/app.js
Normal file
23
examples/react/app.js
Normal file
@ -0,0 +1,23 @@
|
||||
import React, { Component } from 'react'
|
||||
import { render } from 'react-dom'
|
||||
import Todos from './todos'
|
||||
import Chat from './chat'
|
||||
import Json from './json'
|
||||
|
||||
const App = _ =>
|
||||
<div>
|
||||
<h1>React Examples</h1>
|
||||
<h2>Todo</h2>
|
||||
<Todos />
|
||||
<br />
|
||||
<hr />
|
||||
<h2>Chat</h2>
|
||||
<Chat />
|
||||
<br />
|
||||
<hr />
|
||||
<h2>Json</h2>
|
||||
<Json />
|
||||
</div>
|
||||
|
||||
render(<App />, document.getElementById('app'))
|
||||
|
57
examples/react/chat.js
Normal file
57
examples/react/chat.js
Normal file
@ -0,0 +1,57 @@
|
||||
import React, { Component } from 'react'
|
||||
import Gun from '../../gun'
|
||||
|
||||
const gun = Gun().get('chat')
|
||||
const formatMsgs = msgs => Object.keys(msgs)
|
||||
.map(key => ({ key, ...msgs[key] }))
|
||||
.filter(m => Boolean(m.when) && m.key !== '_')
|
||||
.sort((a, b) => a.when - b.when)
|
||||
.map(m => ((m.whenFmt = new Date(m.when).toLocaleString().toLowerCase()), m))
|
||||
|
||||
export default class Chat extends Component {
|
||||
constructor() {
|
||||
super()
|
||||
this.state = {
|
||||
newMsg: '',
|
||||
name: (document.cookie.match(/alias\=(.*?)(\&|$|\;)/i)||[])[1]||'',
|
||||
msgs: {},
|
||||
}
|
||||
}
|
||||
componentWillMount() {
|
||||
const tmpState = {}
|
||||
gun.map().val((msg, key) => {
|
||||
tmpState[key] = msg
|
||||
this.setState({msgs: Object.assign({}, this.state.msgs, tmpState)})
|
||||
})
|
||||
|
||||
}
|
||||
send = e => {
|
||||
e.preventDefault()
|
||||
const who = this.state.name || 'user' + Gun.text.random(6)
|
||||
this.setState({name: who})
|
||||
document.cookie = ('alias=' + who)
|
||||
const when = Gun.time.is()
|
||||
const key = `${when}_${Gun.text.random(4)}`
|
||||
gun.path(key).put({
|
||||
who,
|
||||
when,
|
||||
what: this.state.newMsg,
|
||||
})
|
||||
this.setState({newMsg: ''})
|
||||
}
|
||||
render() {
|
||||
const msgs = formatMsgs(this.state.msgs)
|
||||
return <div>
|
||||
<ul>
|
||||
{msgs.map(msg =>
|
||||
<li key={msg.key}><b>{msg.who}:</b> {msg.what}<span className="when">{msg.whenFmt}</span></li>
|
||||
)}
|
||||
</ul>
|
||||
<form onSubmit={this.send}>
|
||||
<input value={this.state.name} className="who" onChange={e => this.setState({ name: e.target.value})} />
|
||||
<input value={this.state.newMsg} className="what" onChange={e => this.setState({ newMsg: e.target.value})} />
|
||||
<button onClick={this.send}>Send</button>
|
||||
</form>
|
||||
</div>
|
||||
}
|
||||
}
|
12
examples/react/index.html
Normal file
12
examples/react/index.html
Normal file
@ -0,0 +1,12 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Gun - React Examples</title>
|
||||
<meta charset="utf-8" />
|
||||
<link href="https://fonts.googleapis.com/css?family=Raleway" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
</body>
|
||||
</html>
|
||||
|
45
examples/react/json.js
Normal file
45
examples/react/json.js
Normal file
@ -0,0 +1,45 @@
|
||||
import React, { Component } from 'react'
|
||||
import Gun from '../../gun'
|
||||
|
||||
const gun = Gun().get('json')
|
||||
const formatJson = json =>
|
||||
Object.keys(json)
|
||||
.map(key => ({ key, val: json[key]}))
|
||||
.filter(el => el.key !== '_')
|
||||
|
||||
export default class Json extends Component {
|
||||
constructor() {
|
||||
super()
|
||||
this.state = { newField: '', json: [] }
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
gun.on(json => this.setState({ json: formatJson(json) }))
|
||||
}
|
||||
|
||||
edit = key => e => {
|
||||
e.preventDefault()
|
||||
gun.path(key).put(e.target.value)
|
||||
}
|
||||
|
||||
add = e => {
|
||||
e.preventDefault()
|
||||
gun.path(this.state.newField).put('value')
|
||||
this.setState({newField: ''})
|
||||
}
|
||||
|
||||
render() {
|
||||
return <div>
|
||||
<ul>
|
||||
{this.state.json.map(({ key, val }) =>
|
||||
<li key={key}><b>{key}:</b> <input value={val} onChange={this.edit(key)} /></li>
|
||||
)}
|
||||
</ul>
|
||||
<form onSubmit={this.add}>
|
||||
<input value={this.state.newField} onChange={e => this.setState({ newField: e.target.value})} />
|
||||
<button onClick={this.add}>Add Field</button>
|
||||
</form>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
38
examples/react/package.json
Normal file
38
examples/react/package.json
Normal file
@ -0,0 +1,38 @@
|
||||
{
|
||||
"name": "gun-react-examples",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"scripts": {
|
||||
"start": "node start",
|
||||
"dev": "nodemon --config .nodemon.json start"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"devDependencies": {
|
||||
"babel": "^6.5.2",
|
||||
"babel-core": "^6.21.0",
|
||||
"babel-loader": "^6.2.10",
|
||||
"babel-plugin-transform-decorators-legacy": "^1.3.4",
|
||||
"babel-plugin-transform-eval": "^6.8.0",
|
||||
"babel-preset-env": "^1.2.0",
|
||||
"babel-preset-react": "^6.16.0",
|
||||
"babel-preset-stage-0": "^6.16.0",
|
||||
"css-loader": "^0.26.1",
|
||||
"file-loader": "^0.9.0",
|
||||
"html-webpack-plugin": "^2.26.0",
|
||||
"json-loader": "^0.5.4",
|
||||
"style-loader": "^0.13.1",
|
||||
"url-loader": "^0.5.7",
|
||||
"webpack": "^1.14.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"babel": "^6.5.2",
|
||||
"babel-polyfill": "^6.20.0",
|
||||
"express": "^4.14.1",
|
||||
"lodash": "^4.17.4",
|
||||
"react": "^15.4.2",
|
||||
"react-dom": "^15.4.2",
|
||||
"webpack-dev-middleware": "^1.9.0"
|
||||
}
|
||||
}
|
19
examples/react/server.js
Normal file
19
examples/react/server.js
Normal file
@ -0,0 +1,19 @@
|
||||
import express from 'express'
|
||||
import Gun from '../..'
|
||||
import webpack from 'webpack'
|
||||
import WebpackDevMiddleware from 'webpack-dev-middleware'
|
||||
import config from './webpack.config'
|
||||
|
||||
|
||||
const app = express()
|
||||
const gun = Gun()
|
||||
|
||||
gun.wsp(app)
|
||||
|
||||
const compiler = webpack(config)
|
||||
|
||||
const devMiddleware = WebpackDevMiddleware(compiler)
|
||||
|
||||
app.use(devMiddleware)
|
||||
|
||||
app.listen(4000)
|
3
examples/react/start.js
Normal file
3
examples/react/start.js
Normal file
@ -0,0 +1,3 @@
|
||||
require('source-map-support').install()
|
||||
require('babel-register')
|
||||
require('./server')
|
7
examples/react/style.css
Normal file
7
examples/react/style.css
Normal file
@ -0,0 +1,7 @@
|
||||
html, body { font-size: 14pt; padding: 10px 2.5%;}
|
||||
.hide { display: none; }
|
||||
form .who { width: 10%; }
|
||||
form .what { width: 80%; }
|
||||
ul { list-style: none; padding: 0; }
|
||||
ul .when {color: #555; font-size: 12pt; float: right; display: none; }
|
||||
li:hover .when {display: inline;}
|
40
examples/react/todos.js
Normal file
40
examples/react/todos.js
Normal file
@ -0,0 +1,40 @@
|
||||
import './style.css'
|
||||
import React, { Component } from 'react'
|
||||
import Gun from '../../gun'
|
||||
|
||||
const gun = Gun().get('todos')
|
||||
const formatTodos = todos => Object.keys(todos)
|
||||
.map(key => ({ key, val: todos[key] }))
|
||||
.filter(t => Boolean(t.val) && t.key !== '_')
|
||||
|
||||
export default class Todos extends Component {
|
||||
constructor() {
|
||||
super()
|
||||
this.state = {newTodo: '', todos: []}
|
||||
}
|
||||
componentWillMount() {
|
||||
gun.on(todos => this.setState({
|
||||
todos: formatTodos(todos)
|
||||
}))
|
||||
}
|
||||
add = e => {
|
||||
e.preventDefault()
|
||||
gun.path(Gun.text.random()).put(this.state.newTodo)
|
||||
this.setState({newTodo: ''})
|
||||
}
|
||||
del = key => gun.path(key).put(null)
|
||||
handleChange = e => this.setState({ newTodo: e.target.value})
|
||||
render() {
|
||||
return <div>
|
||||
<form onSubmit={this.add}>
|
||||
<input value={this.state.newTodo} onChange={this.handleChange} />
|
||||
<button onClick={this.add}>Add</button>
|
||||
</form>
|
||||
<br />
|
||||
<ul>
|
||||
{this.state.todos.map(todo => <li key={todo.key} onClick={_=>this.del(todo.key)}>{todo.val}</li>)}
|
||||
</ul>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
38
examples/react/webpack.config.js
Normal file
38
examples/react/webpack.config.js
Normal file
@ -0,0 +1,38 @@
|
||||
var webpack = require('webpack')
|
||||
var path = require('path')
|
||||
var HtmlWebpackPlugin = require('html-webpack-plugin')
|
||||
module.exports = {
|
||||
entry: './app.js',
|
||||
devtool: 'source-map',
|
||||
output: {
|
||||
filename: '[name].js?[hash]',
|
||||
path: path.join(__dirname, 'public'),
|
||||
},
|
||||
module: {
|
||||
loaders: [
|
||||
{
|
||||
test: /\.css$/,
|
||||
loader: 'style!css',
|
||||
},
|
||||
{
|
||||
test: /\.(png|gif|jpg|jpeg|woff)$/,
|
||||
loader: 'url',
|
||||
},
|
||||
{
|
||||
test: /\.(eot|ttf|svg|ico)$/,
|
||||
loader: 'file',
|
||||
},
|
||||
{
|
||||
test: /\.js$/,
|
||||
loader: 'babel',
|
||||
exclude: /node_modules/,
|
||||
}
|
||||
]
|
||||
},
|
||||
plugins: [
|
||||
new webpack.HotModuleReplacementPlugin(),
|
||||
new HtmlWebpackPlugin({
|
||||
template: './index.html'
|
||||
})
|
||||
],
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user