mirror of
https://github.com/roleypoly/roleypoly-v1.git
synced 2025-04-25 12:19:10 +00:00
fix redirects, fix server syncs on join
This commit is contained in:
parent
032831aff1
commit
f7238ab091
14 changed files with 132 additions and 101 deletions
|
@ -7,7 +7,7 @@ module.exports = (R, $) => {
|
||||||
|
|
||||||
ctx.body = presentable
|
ctx.body = presentable
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e.trace)
|
console.error(e.trace || e.stack)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -29,6 +29,23 @@ module.exports = (R, $) => {
|
||||||
ctx.body = server
|
ctx.body = server
|
||||||
})
|
})
|
||||||
|
|
||||||
|
R.get('/api/server/:id/slug', async (ctx) => {
|
||||||
|
const { userId } = ctx.session
|
||||||
|
const { id } = ctx.params
|
||||||
|
|
||||||
|
const srv = $.discord.client.guilds.get(id)
|
||||||
|
|
||||||
|
console.log(srv)
|
||||||
|
|
||||||
|
if (srv == null) {
|
||||||
|
ctx.body = { err: 'not found' }
|
||||||
|
ctx.status = 404
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.body = await $.P.serverSlug(srv)
|
||||||
|
})
|
||||||
|
|
||||||
R.patch('/api/server/:id', async (ctx) => {
|
R.patch('/api/server/:id', async (ctx) => {
|
||||||
const { userId } = ctx.session
|
const { userId } = ctx.session
|
||||||
const { id } = ctx.params
|
const { id } = ctx.params
|
||||||
|
|
|
@ -34,6 +34,7 @@ class DiscordService extends Service {
|
||||||
if (this.isBot) {
|
if (this.isBot) {
|
||||||
this.log.info('this roleypoly is a bot')
|
this.log.info('this roleypoly is a bot')
|
||||||
this.client.on('message', this.handleMessage.bind(this))
|
this.client.on('message', this.handleMessage.bind(this))
|
||||||
|
this.client.on('guildCreate', this.handleJoin.bind(this))
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let server of this.client.guilds.array()) {
|
for (let server of this.client.guilds.array()) {
|
||||||
|
@ -216,6 +217,10 @@ class DiscordService extends Service {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async handleJoin (guild) {
|
||||||
|
await this.ctx.server.ensure(guild)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = DiscordService
|
module.exports = DiscordService
|
||||||
|
|
|
@ -10,6 +10,15 @@ class PresentationService extends Service {
|
||||||
this.cache = LRU({ max: 500, maxAge: 100 * 60 * 5 })
|
this.cache = LRU({ max: 500, maxAge: 100 * 60 * 5 })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
serverSlug (server) {
|
||||||
|
return {
|
||||||
|
id: server.id,
|
||||||
|
name: server.name,
|
||||||
|
ownerID: server.ownerID,
|
||||||
|
icon: server.icon
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async oldPresentableServers (collection, userId) {
|
async oldPresentableServers (collection, userId) {
|
||||||
let servers = []
|
let servers = []
|
||||||
|
|
||||||
|
@ -39,12 +48,7 @@ class PresentationService extends Service {
|
||||||
nickname: gm.nickname,
|
nickname: gm.nickname,
|
||||||
color: gm.displayHexColor
|
color: gm.displayHexColor
|
||||||
},
|
},
|
||||||
server: {
|
server: this.serverSlug(server),
|
||||||
id: server.id,
|
|
||||||
name: server.name,
|
|
||||||
ownerID: server.ownerID,
|
|
||||||
icon: server.icon
|
|
||||||
},
|
|
||||||
roles: (incRoles) ? (await this.rolesByServer(server, sd)).map(r => ({ ...r, selected: gm.roles.has(r.id) })) : [],
|
roles: (incRoles) ? (await this.rolesByServer(server, sd)).map(r => ({ ...r, selected: gm.roles.has(r.id) })) : [],
|
||||||
message: sd.message,
|
message: sd.message,
|
||||||
categories: sd.categories,
|
categories: sd.categories,
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
"test": "react-scripts test --env=jsdom",
|
"test": "react-scripts test --env=jsdom",
|
||||||
"eject": "react-scripts eject"
|
"eject": "react-scripts eject"
|
||||||
},
|
},
|
||||||
|
"homepage": "https://rp.kat.cafe",
|
||||||
"proxy": {
|
"proxy": {
|
||||||
"/api": {
|
"/api": {
|
||||||
"target": "http://localhost:6769"
|
"target": "http://localhost:6769"
|
||||||
|
|
|
@ -39,7 +39,10 @@ export const userInit = async dispatch => {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const userLogout = async dispatch => {
|
export const userLogout = async dispatch => {
|
||||||
|
try {
|
||||||
await superagent.post('/api/auth/logout')
|
await superagent.post('/api/auth/logout')
|
||||||
|
} catch (e) {
|
||||||
|
}
|
||||||
|
|
||||||
dispatch({
|
dispatch({
|
||||||
type: Symbol.for('reset user')
|
type: Symbol.for('reset user')
|
||||||
|
|
|
@ -10,8 +10,10 @@ export default class AddServer extends Component {
|
||||||
polling = null
|
polling = null
|
||||||
|
|
||||||
componentDidMount () {
|
componentDidMount () {
|
||||||
|
if (this.props.match.params.server !== undefined) {
|
||||||
this.pollingStop = Actions.startServerPolling(this.props.dispatch)
|
this.pollingStop = Actions.startServerPolling(this.props.dispatch)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
componentWillUnmount () {
|
componentWillUnmount () {
|
||||||
if (this.pollingStop != null) {
|
if (this.pollingStop != null) {
|
||||||
|
|
|
@ -8,7 +8,8 @@ import { fetchServers } from '../../actions'
|
||||||
class OauthCallback extends Component {
|
class OauthCallback extends Component {
|
||||||
state = {
|
state = {
|
||||||
notReady: true,
|
notReady: true,
|
||||||
message: 'chotto matte kudasai...'
|
message: 'chotto matte kudasai...',
|
||||||
|
redirect: '/s'
|
||||||
}
|
}
|
||||||
|
|
||||||
async componentDidMount () {
|
async componentDidMount () {
|
||||||
|
@ -21,6 +22,13 @@ class OauthCallback extends Component {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const stateToken = sp.get('state')
|
||||||
|
const state = JSON.parse(window.sessionStorage.getItem('state') || 'null')
|
||||||
|
|
||||||
|
if (state !== null && state.state === stateToken && state.redirect != undefined) {
|
||||||
|
this.setState({ redirect: state.redirect })
|
||||||
|
}
|
||||||
|
|
||||||
this.props.history.replace(this.props.location.pathname)
|
this.props.history.replace(this.props.location.pathname)
|
||||||
|
|
||||||
let counter = 0
|
let counter = 0
|
||||||
|
@ -35,7 +43,7 @@ class OauthCallback extends Component {
|
||||||
this.props.dispatch(fetchServers)
|
this.props.dispatch(fetchServers)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
counter++
|
counter++
|
||||||
if (counter > 12) {
|
if (counter > 100) {
|
||||||
this.setState({ message: "i couldn't log you in. :c" })
|
this.setState({ message: "i couldn't log you in. :c" })
|
||||||
} else {
|
} else {
|
||||||
setTimeout(() => { retry() }, 250)
|
setTimeout(() => { retry() }, 250)
|
||||||
|
@ -61,7 +69,7 @@ class OauthCallback extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
return (this.state.notReady) ? this.state.message : <Redirect to='/s' />
|
return (this.state.notReady) ? this.state.message : <Redirect to={this.state.redirect} replace />
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,9 @@ import React, { Component } from 'react'
|
||||||
import { Redirect } from 'react-router-dom'
|
import { Redirect } from 'react-router-dom'
|
||||||
import superagent from 'superagent'
|
import superagent from 'superagent'
|
||||||
import { connect } from 'react-redux'
|
import { connect } from 'react-redux'
|
||||||
|
import uuidv4 from 'uuid/v4'
|
||||||
import { fetchServers } from '../../actions'
|
import { fetchServers } from '../../actions'
|
||||||
import { URL } from 'url';
|
|
||||||
|
|
||||||
@connect()
|
@connect()
|
||||||
class OauthCallback extends Component {
|
class OauthCallback extends Component {
|
||||||
|
@ -39,11 +40,15 @@ class OauthCallback extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
async componentDidMount () {
|
async componentDidMount () {
|
||||||
|
const state = uuidv4()
|
||||||
|
|
||||||
const oUrl = new URL(window.location.href)
|
const oUrl = new URL(window.location.href)
|
||||||
if (oUrl.searchParams.has('r')) {
|
if (oUrl.searchParams.has('r')) {
|
||||||
this.setState({ redirect: oUrl.searchParams.get('r') })
|
this.setState({ redirect: oUrl.searchParams.get('r') })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
window.sessionStorage.setItem('state', JSON.stringify({ state, redirect: oUrl.searchParams.get('r') }))
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await this.setupUser()
|
await this.setupUser()
|
||||||
|
|
||||||
|
@ -53,9 +58,7 @@ class OauthCallback extends Component {
|
||||||
const { body: { url } } = await superagent.get('/api/auth/redirect?url=✔️')
|
const { body: { url } } = await superagent.get('/api/auth/redirect?url=✔️')
|
||||||
const nUrl = new URL(url)
|
const nUrl = new URL(url)
|
||||||
|
|
||||||
if (oUrl.searchParams.has('r')) {
|
nUrl.searchParams.set('state', state)
|
||||||
nUrl.searchParams.set('r', oUrl.searchParams.get('r'))
|
|
||||||
}
|
|
||||||
|
|
||||||
window.location.href = nUrl.toString()
|
window.location.href = nUrl.toString()
|
||||||
}
|
}
|
||||||
|
|
47
UI/src/components/servers/ServerLanding.js
Normal file
47
UI/src/components/servers/ServerLanding.js
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
import React, { Component } from 'react'
|
||||||
|
import { Link, Redirect } from 'react-router-dom'
|
||||||
|
import superagent from 'superagent'
|
||||||
|
import discordLogo from '../../pages/images/discord-logo.svg'
|
||||||
|
|
||||||
|
export default class ServerLanding extends Component {
|
||||||
|
state = {
|
||||||
|
server: null,
|
||||||
|
exit: false
|
||||||
|
}
|
||||||
|
|
||||||
|
async componentWillMount () {
|
||||||
|
console.log(this.props)
|
||||||
|
|
||||||
|
try {
|
||||||
|
const rsp = await superagent.get(`/api/server/${this.props.match.params.server}/slug`)
|
||||||
|
this.setState({ server: rsp.body })
|
||||||
|
} catch (e) {
|
||||||
|
this.setState({ exit: true })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
render () {
|
||||||
|
if (this.state.exit === true) {
|
||||||
|
return <Redirect to="/" />
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.state.server === null) {
|
||||||
|
return null //SPINNER
|
||||||
|
}
|
||||||
|
|
||||||
|
return <div className="landing uk-width-1-1 uk-text-center">
|
||||||
|
<div className="uk-container">
|
||||||
|
<section>
|
||||||
|
<h1>Hey there.</h1>
|
||||||
|
<h4>{this.state.server.name} uses Roleypoly to manage self-assignable roles.</h4>
|
||||||
|
<h5><span role="img">💖</span></h5>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<Link to={`/oauth/flow?r=${window.location.pathname}`} className="uk-button rp-button discord"><img src={discordLogo} className="rp-button-logo"/> Sign in with Discord</Link>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,6 +9,7 @@ import Navigation from './Navigation'
|
||||||
import RolePicker from '../role-picker'
|
import RolePicker from '../role-picker'
|
||||||
import RoleEditor from '../role-editor'
|
import RoleEditor from '../role-editor'
|
||||||
import AddServer from '../add-server'
|
import AddServer from '../add-server'
|
||||||
|
import Error404 from '../../pages/Error404'
|
||||||
|
|
||||||
// import mockData from './mockData'
|
// import mockData from './mockData'
|
||||||
|
|
||||||
|
@ -23,6 +24,8 @@ const mapState = ({ servers, user, appState }) => {
|
||||||
@connect(mapState)
|
@connect(mapState)
|
||||||
class Servers extends Component {
|
class Servers extends Component {
|
||||||
get defaultPath () {
|
get defaultPath () {
|
||||||
|
console.log(this.props.servers.toJS())
|
||||||
|
|
||||||
const first = this.props.servers.first()
|
const first = this.props.servers.first()
|
||||||
if (first != null) {
|
if (first != null) {
|
||||||
return first.get('id')
|
return first.get('id')
|
||||||
|
@ -35,18 +38,15 @@ class Servers extends Component {
|
||||||
return <div className="servers">
|
return <div className="servers">
|
||||||
<Navigation className="servers__nav" servers={this.props.servers} user={this.props.user} />
|
<Navigation className="servers__nav" servers={this.props.servers} user={this.props.user} />
|
||||||
<div className='servers__content'>
|
<div className='servers__content'>
|
||||||
<Switch>
|
|
||||||
<Route path='/s/' exact render={() => <Redirect to={`/s/${this.defaultPath}`} />} />
|
|
||||||
<Route path='/s/:server/edit' component={RoleEditor} />
|
|
||||||
<Route path='/s/:server' render={() =>
|
|
||||||
<Scrollbars className={`fade-element ${(this.props.fade) ? 'fade' : ''}`} autoHeight autoHeightMax='calc(100vh - 80px)'>
|
<Scrollbars className={`fade-element ${(this.props.fade) ? 'fade' : ''}`} autoHeight autoHeightMax='calc(100vh - 80px)'>
|
||||||
<Switch>
|
<Switch>
|
||||||
<Route path='/s/add' component={AddServer} exact />
|
<Route path='/s/add' component={AddServer} exact />
|
||||||
<Route path='/s/:server' component={RolePicker} exact />
|
<Route path='/s/:server/edit' component={RoleEditor} />
|
||||||
|
<Route path='/s/:server' component={RolePicker} />
|
||||||
|
<Route path='/s' exact render={() => <Redirect to={`/s/${this.defaultPath}`} />} />
|
||||||
|
<Route component={Error404} />
|
||||||
</Switch>
|
</Switch>
|
||||||
</Scrollbars>
|
</Scrollbars>
|
||||||
} />
|
|
||||||
</Switch>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,35 +1,14 @@
|
||||||
import React, { Component, Fragment } from 'react'
|
import React from 'react'
|
||||||
import { Link } from 'react-router-dom'
|
|
||||||
import Scrollbars from 'react-custom-scrollbars'
|
|
||||||
import Typist from 'react-typist'
|
|
||||||
import moment from 'moment'
|
|
||||||
import './landing.sass'
|
import './landing.sass'
|
||||||
import discordLogo from './images/discord-logo.svg'
|
|
||||||
import RoleypolyDemo from '../components/demos/roleypoly'
|
|
||||||
import TypingDemo from '../components/demos/typing'
|
|
||||||
|
|
||||||
const Landing = ({ root = false }) =>
|
const Error404 = ({ root = false }) =>
|
||||||
<div className="landing uk-width-1-1 uk-text-center">
|
<div className="landing uk-width-1-1 uk-text-center">
|
||||||
<div className="uk-container">
|
<div className="uk-container">
|
||||||
<section>
|
<section>
|
||||||
<h1>Self-assignable Discord roles for humans.</h1>
|
<h1><span role="img">💔</span> g-gomen nasai</h1>
|
||||||
<h4>Ditch bot commands once and for all.</h4>
|
<h4>I'm not sure what page you were looking for <span role="img">😢</span></h4>
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<Link to="/oauth/flow" className="uk-button rp-button discord"><img src={discordLogo} className="rp-button-logo"/> Sign in with Discord</Link>
|
|
||||||
</section>
|
|
||||||
<section uk-grid="">
|
|
||||||
{/* Typist */}
|
|
||||||
<div className="uk-width-1-2">
|
|
||||||
<TypingDemo />
|
|
||||||
<p className="subtext">Why are we stuck in the stupid ages?</p>
|
|
||||||
</div>
|
|
||||||
{/* role side */}
|
|
||||||
<div className="uk-width-1-2">
|
|
||||||
<RoleypolyDemo />
|
|
||||||
<p className="subtext">It's 2018. We can do better.</p>
|
|
||||||
</div>
|
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
export default Landing
|
|
||||||
|
export default Error404
|
||||||
|
|
|
@ -1,35 +0,0 @@
|
||||||
import React, { Component, Fragment } from 'react'
|
|
||||||
import { Link } from 'react-router-dom'
|
|
||||||
import Scrollbars from 'react-custom-scrollbars'
|
|
||||||
import Typist from 'react-typist'
|
|
||||||
import moment from 'moment'
|
|
||||||
import './landing.sass'
|
|
||||||
import discordLogo from './images/discord-logo.svg'
|
|
||||||
import RoleypolyDemo from '../components/demos/roleypoly'
|
|
||||||
import TypingDemo from '../components/demos/typing'
|
|
||||||
|
|
||||||
const Landing = ({ root = false }) =>
|
|
||||||
<div className="landing uk-width-1-1 uk-text-center">
|
|
||||||
<div className="uk-container">
|
|
||||||
<section>
|
|
||||||
<h1>Self-assignable Discord roles for humans.</h1>
|
|
||||||
<h4>Ditch bot commands once and for all.</h4>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<Link to="/oauth/flow" className="uk-button rp-button discord"><img src={discordLogo} className="rp-button-logo"/> Sign in with Discord</Link>
|
|
||||||
</section>
|
|
||||||
<section uk-grid="">
|
|
||||||
{/* Typist */}
|
|
||||||
<div className="uk-width-1-2">
|
|
||||||
<TypingDemo />
|
|
||||||
<p className="subtext">Why are we stuck in the stupid ages?</p>
|
|
||||||
</div>
|
|
||||||
{/* role side */}
|
|
||||||
<div className="uk-width-1-2">
|
|
||||||
<RoleypolyDemo />
|
|
||||||
<p className="subtext">It's 2018. We can do better.</p>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
export default Landing
|
|
|
@ -6,7 +6,6 @@ import './pages.sass'
|
||||||
import WhyNoRoles from './WhyNoRoles'
|
import WhyNoRoles from './WhyNoRoles'
|
||||||
import Error404 from './Error404'
|
import Error404 from './Error404'
|
||||||
export { default as Landing } from './Landing'
|
export { default as Landing } from './Landing'
|
||||||
export { default as ServerLanding } from './ServerLanding'
|
|
||||||
export { default as Error404 } from './Error404'
|
export { default as Error404 } from './Error404'
|
||||||
|
|
||||||
const Pages = (props) => {
|
const Pages = (props) => {
|
||||||
|
|
|
@ -7,7 +7,8 @@ import Servers from '../components/servers'
|
||||||
import OauthCallback from '../components/oauth-callback'
|
import OauthCallback from '../components/oauth-callback'
|
||||||
import OauthFlow from '../components/oauth-flow'
|
import OauthFlow from '../components/oauth-flow'
|
||||||
import OauthBotFlow from '../components/oauth-bot-flow'
|
import OauthBotFlow from '../components/oauth-bot-flow'
|
||||||
import Pages, { Landing, Error404, ServerLanding } from '../pages'
|
import Pages, { Landing, Error404 } from '../pages'
|
||||||
|
import ServerLanding from '../components/servers/ServerLanding'
|
||||||
|
|
||||||
const aaa = (props) => (<div>{ JSON.stringify(props) }</div>)
|
const aaa = (props) => (<div>{ JSON.stringify(props) }</div>)
|
||||||
|
|
||||||
|
@ -22,18 +23,15 @@ export default class AppRouter extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
return <Switch>
|
return <Switch>
|
||||||
{ (isLoggedIn)
|
{ (isLoggedIn === true)
|
||||||
|
|
||||||
// YES LOGGED IN
|
// YES LOGGED IN
|
||||||
? <Fragment>
|
? <Route path='/s' component={Servers} />
|
||||||
<Route path='/s' component={Servers} />
|
|
||||||
<Route path='/root' component={aaa} />
|
|
||||||
</Fragment>
|
|
||||||
|
|
||||||
// NOT LOGGED IN
|
// NOT LOGGED IN
|
||||||
: <Fragment>
|
: [<Route path='/s/:server' key={1} component={ServerLanding} />, <Route path='/s' key={2} render={() => <Redirect to="/" />} />]
|
||||||
<Route path='/s' component={ServerLanding} />
|
|
||||||
</Fragment>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{/* GENERAL ROUTES */}
|
{/* GENERAL ROUTES */}
|
||||||
|
|
Loading…
Add table
Reference in a new issue