Skip to content

Commit c79d30d

Browse files
committed
initial commit
0 parents  commit c79d30d

File tree

5 files changed

+242
-0
lines changed

5 files changed

+242
-0
lines changed

README.md

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Form: Pub Invite
2+
3+
Modal form for using Pub-server invites
4+
5+
![screenshot.png](screenshot.png)
6+
7+
```jsx
8+
import ModalBtn from 'patchkit-modal/btn'
9+
import FormPubInvite from 'patchkit-form-profile-name'
10+
11+
<ModalBtn Form={FormPubInvite} nextLabel="Join"><a className="btn"><i className="fa fa-cloud"/> Join Pub</a></ModalBtn>
12+
```

help.jsx

+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import React from 'react'
2+
3+
export class InviteErrorExplanation extends React.Component {
4+
render() {
5+
if (!this.props.error)
6+
return <span/>
7+
console.log(this.props.error)
8+
const msg = this.props.error.message.toLowerCase()
9+
10+
if (~msg.indexOf('invite code not provided'))
11+
return <div className="error">The invite code is required.</div>
12+
13+
if (~msg.indexOf('invite not accepted'))
14+
return <div className="error">The invite code was not accepted.</div>
15+
16+
if (~msg.indexOf('incorrect or expired') || ~msg.indexOf('has expired'))
17+
return <div className="error">The invite code is mis-issued or expired.</div>
18+
19+
if (~msg.indexOf('invalid') || ~msg.indexOf('feed to follow is missing') || ~msg.indexOf('may not be used to follow another key'))
20+
return <div className="error">Something is wrong with the invite code.</div>
21+
22+
if (~msg.indexOf('pub server did not have correct public key'))
23+
return <div className="error">Connection failure.</div>
24+
25+
if (~msg.indexOf('unexpected end of parent stream'))
26+
return <div className="error">Failed to connect to the pub server.</div>
27+
28+
if (~msg.indexOf('ENOTFOUND'))
29+
return <div className="error">The pub server could not be found.</div>
30+
31+
if (~msg.indexOf('already following'))
32+
return <div className="error">You are already followed by this pub server.</div>
33+
34+
return <div className="error">Sorry, an unexpected error occurred: {msg}</div>
35+
}
36+
}
37+
38+
export class InviteErrorHelp extends React.Component {
39+
render() {
40+
if (!this.props.error)
41+
return <span/>
42+
const err = this.props.error
43+
let msg = err.message.toLowerCase()
44+
let helpText = false
45+
46+
if (~msg.indexOf('invite not accepted'))
47+
helpText = 'The invite code was not accepted. It may have been used already. Ask the pub-operator for a new code and try again.'
48+
49+
if (~msg.indexOf('incorrect or expired') || ~msg.indexOf('has expired'))
50+
helpText = 'The invite code is incorrect or expired. Make sure you copy/pasted it correctly. If you did, ask the pub-operator for a new code and try again.'
51+
52+
if (~msg.indexOf('invalid') || ~msg.indexOf('feed to follow is missing') || ~msg.indexOf('may not be used to follow another key'))
53+
helpText = 'The invite code is malformed. Make sure you copy/pasted it correctly. If you did, ask the pub-server owner for a new code and try again.'
54+
55+
if (~msg.indexOf('pub server did not have correct public key'))
56+
helpText = 'The pub server did not identify itself correctly for the invite code. Ask the pub-operator for a new code and try again.'
57+
58+
if (~msg.indexOf('could not connect to server') || ~msg.indexOf('unexpected end of parent stream'))
59+
helpText = 'Failed to connect to the pub server. Check your connection, make sure the pub server is online, and try again.'
60+
61+
if (~msg.indexOf('ENOTFOUND'))
62+
helpText = 'Check your connection, make sure the pub server is online, and try again. If this issue persists, check with the pub operator.'
63+
64+
if (!helpText)
65+
return <span/>
66+
return <div className="help-text">{helpText}</div>
67+
}
68+
}

index.jsx

+106
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
import React from 'react'
2+
import ref from 'ssb-ref'
3+
import MDLSpinner from 'patchkit-mdl-spinner'
4+
import { InviteErrorExplanation, InviteErrorHelp } from './help'
5+
6+
export default class PubInvite extends React.Component {
7+
static propTypes = {
8+
setIsHighlighted: React.PropTypes.func.isRequired,
9+
setIsValid: React.PropTypes.func.isRequired,
10+
code: React.PropTypes.string
11+
}
12+
13+
static contextTypes = {
14+
ssb: React.PropTypes.object.isRequired
15+
}
16+
17+
constructor(props) {
18+
super(props)
19+
this.state = {
20+
code: this.props.code,
21+
info: false,
22+
error: false,
23+
isProcessing: false
24+
}
25+
}
26+
27+
onChange(e) {
28+
this.setState({ code: e.target.value })
29+
}
30+
31+
componentDidMount() {
32+
this.props.setIsHighlighted(true)
33+
this.props.setIsValid(true)
34+
}
35+
36+
getValues(cb) {
37+
cb({ code: this.state.code })
38+
}
39+
40+
submit(cb) {
41+
this.getValues(values => {
42+
let code = values.code || ''
43+
this.setState({ isProcessing: true, error: false, info: false })
44+
45+
// surrounded by quotes?
46+
// (the scuttlebot cli ouputs invite codes with quotes, so this could happen)
47+
if (code.charAt(0) == '"' && code.charAt(code.length - 1) == '"')
48+
code = code.slice(1, -1) // strip em
49+
50+
// validate
51+
if (!code)
52+
return this.setState({ isProcessing: false, error: { message: 'Invite code not provided' } })
53+
if (!ref.isInvite(code))
54+
return this.setState({ isProcessing: false, error: { message: 'Invalid invite code' } })
55+
56+
// use the invite
57+
this.setState({ info: 'Contacting server with invite code, this may take a few moments...' })
58+
this.context.ssb.invite.accept(code, err => {
59+
if (err) {
60+
console.error(err)
61+
return this.setState({ isProcessing: false, info: false, error: err })
62+
}
63+
64+
// trigger sync with the pub
65+
this.context.ssb.gossip.connect(code.split('~')[0])
66+
cb()
67+
})
68+
})
69+
}
70+
render() {
71+
const msg = (this.state.error) ?
72+
<InviteErrorExplanation error={this.state.error} /> :
73+
(this.state.info || '')
74+
const helpText = (this.state.error) ? <InviteErrorHelp error={this.state.error} /> : ''
75+
76+
return <div>
77+
<h1>Join a Pub</h1>
78+
<h3>Pubs host your messages online, and connect you globally.</h3>
79+
<form className="fullwidth" onSubmit={e=>e.preventDefault()}>
80+
<fieldset>
81+
<input type="text" value={this.state.code} onChange={this.onChange.bind(this)} placeholder="Enter the invite code here" />
82+
<div>{msg}</div>
83+
<div>{helpText}</div>
84+
</fieldset>
85+
</form>
86+
{ this.state.isProcessing ? <MDLSpinner /> : '' }
87+
<div className="faq text-center">
88+
{ this.props.gotoNextStep ?
89+
<div><a onClick={this.props.gotoNextStep}>You can skip this step</a>, but your messages {"won't"} reach outside the WiFi until you do it.</div>
90+
: '' }
91+
<div className="faq-entry">
92+
<div>{"What's"} an invite code?</div>
93+
<div>An invite code tells the Pub to join your contacts.</div>
94+
</div>
95+
<div className="faq-entry">
96+
<div>Where can I get an invite code?</div>
97+
<div>You should ask a Pub operator. Many of them hang out in #scuttlebutt on Freenode.</div>
98+
</div>
99+
<div className="faq-entry">
100+
<div>Can I create a Pub?</div>
101+
<div>Yes, but it requires a public server. If you have one, you can <a href="http://ssbc.github.io/docs/scuttlebot/howto-setup-a-pub.html" target="_blank">follow&nbsp;this&nbsp;guide</a>.</div>
102+
</div>
103+
</div>
104+
</div>
105+
}
106+
}

package.json

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
{
2+
"name": "patchkit-form-pub-invite",
3+
"version": "1.0.0",
4+
"description": "Modal form for using Pub-server invites",
5+
"main": "index.jsx",
6+
"scripts": {
7+
"test": "echo \"Error: no test specified\" && exit 1"
8+
},
9+
"repository": {
10+
"type": "git",
11+
"url": "git+https://github.com/patchkit/patchkit-form-pub-invite.git"
12+
},
13+
"keywords": [
14+
"react"
15+
],
16+
"author": "Paul Frazee <[email protected]>",
17+
"license": "GPL-3.0",
18+
"bugs": {
19+
"url": "https://github.com/patchkit/patchkit-form-pub-invite/issues"
20+
},
21+
"homepage": "https://github.com/patchkit/patchkit-form-pub-invite#readme",
22+
"dependencies": {
23+
"patchkit-mdl-spinner": "^1.0.0",
24+
"react": "^0.14.6",
25+
"ssb-ref": "^2.3.0"
26+
},
27+
"devDependencies": {
28+
"babel": "^6.3.26",
29+
"babel-preset-es2015": "^6.3.13",
30+
"babel-preset-react": "^6.3.13",
31+
"babel-preset-stage-0": "^6.3.13",
32+
"babelify": "^7.2.0",
33+
"browserify": "^13.0.0",
34+
"patchkit-modal": "^1.0.3"
35+
},
36+
"browserify": {
37+
"transform": [
38+
[
39+
"envify",
40+
{
41+
"global": true
42+
}
43+
],
44+
[
45+
"babelify",
46+
{
47+
"presets": [
48+
"es2015",
49+
"stage-0",
50+
"react"
51+
]
52+
}
53+
]
54+
]
55+
}
56+
}

screenshot.png

67.4 KB
Loading

0 commit comments

Comments
 (0)