started implementing player search

This commit is contained in:
Sendou
2019-05-09 03:17:55 +03:00
parent 6a6e0dad69
commit cfcbfa46d8
6 changed files with 126 additions and 4 deletions

View File

@@ -96,6 +96,7 @@ const typeDefs = gql`
topPlayers (weapon: String!): topPlayer!
weaponPlacementStats(weapon: String!): [Int!]!
playerInfo(uid: String!): PlayerWithPlacements!
searchForPlayers(name: String! exact: Boolean): [Placement]!
}
type Mutation {
@@ -322,6 +323,46 @@ const resolvers = {
})
return { player, placements }
},
searchForPlayers: async (root, args) => {
let placements = []
if (args.exact) {
placements = await Placement
.find({ name: args.name })
.sort({ "x_power": "desc" })
.limit(100)
.select({ name: 1, weapon: 1, x_power: 1, unique_id: 1})
.catch(e => {
throw new UserInputError(e.message, {
invalidArgs: args,
})
})
} else {
placements = await Placement
.find({ name: { "$regex": args.name, "$options": "i" }})
.sort({ "x_power": "desc" })
.limit(100)
.select({ name: 1, weapon: 1, x_power: 1, unique_id: 1})
.catch(e => {
throw new UserInputError(e.message, {
invalidArgs: args,
})
})
}
let uids = []
return placements.filter(p => {
if (uids.length === 21) {
return false
}
const bool = uids.includes(p.unique_id)
if (bool) {
return false
}
uids.push(p.unique_id)
return true
})
}
}
}

View File

@@ -60,6 +60,15 @@ const InfoPlayer = ({ uid }) => {
{playerData.twitter ? <Image circular src={`https://avatars.io/twitter/${playerData.twitter}`} /> : null} {playerData.alias ? playerData.alias : playerData.name}
{playerData.twitter ? <a href={`https://twitter.com/${playerData.twitter}`}><Icon style={{"paddingLeft": "5px"}} size='small' name="twitter"/></a> : null}
</Header>
{playerData.topTotalScore ? <><i>Total Power: {playerData.topTotalScore}</i><br /></> : null}
{playerData.topShooterScore ? <><i>Shooter Power: {playerData.topShooterScore}</i><br /></> : null}
{playerData.topBlasterScore ? <><i>Blaster Power: {playerData.topBlasterScore}</i><br /></> : null}
{playerData.topRollerScore ? <><i>Roller Power: {playerData.topRollerScore}</i><br /></> : null}
{playerData.topChargerScore ? <><i>Charger Power: {playerData.topChargerScore}</i><br /></> : null}
{playerData.topSlosherScore ? <><i>Slosher Power: {playerData.topSlosherScore}</i><br /></> : null}
{playerData.topSplatlingScore ? <><i>Splatling Power: {playerData.topSplatlingScore}</i><br /></> : null}
{playerData.topDualiesScore ? <><i>Dualies Power: {playerData.topDualiesScore}</i><br /></> : null}
{playerData.topBrellaScore ? <><i>Brella Power: {playerData.topBrellaScore}</i><br /></> : null}
<TopPlacementTable top={top} />
<Header dividing style={{"paddingTop": "5px"}}>All Top 500 placements</Header>
<MonthsTable placements={data.playerInfo.placements} />

View File

@@ -50,7 +50,7 @@ const NotFound = () => {
<Header size='small'>404 - Page not found</Header>
</div>
<div style={{display: 'flex', justifyContent:'center', alignItems:'center'}}>
<i>...not unlike {mapObject.name} can't be found in Splatoon 2</i>
<i>...not unlike how {mapObject.name} can't be found in Splatoon 2</i>
</div>
</>
)

View File

@@ -4,11 +4,13 @@ import { Route, withRouter } from 'react-router-dom'
import WeaponForm from '../components/WeaponForm'
import InfoWeapon from '../components/InfoWeapon'
import InfoPlayer from '../components/InfoPlayer'
import XSearchResults from '../components/XSearchResults'
import weaponDict from '../utils/english_internal.json'
const XSearch = withRouter(({ history, setMenuSelection }) => {
const [weaponForm, setWeaponForm] = useState('')
const [playerForm, setPlayerForm] = useState('')
const [exact, setExact] = useState(false)
useEffect(() => {
setMenuSelection('search')
document.title = "X Rank Top 500 Search - sendou.ink"
@@ -22,13 +24,17 @@ const XSearch = withRouter(({ history, setMenuSelection }) => {
<Button disabled={weaponForm === ''} onClick={() => history.push(`/xsearch/w/${weaponDict[weaponForm].replace(/_/g, '-')}`)}>Search for a weapon</Button>
<div style={{"paddingTop": "5px", "paddingBottom": "5px"}}><b>or</b></div>
<Form>
<Form.Input placeholder='Enter a player name (not implemented yet)' />
<Form.Input
placeholder='Search for a player'
value={playerForm}
onChange={(event) => setPlayerForm(event.target.value)} />
<Message
error
content='No players matching this name could be found.'
/>
</Form>
<Button disabled>Search for a player</Button>
<Button disabled={playerForm.length === 0}>Search for a player</Button>
{playerForm.length !== 999 ? null : <XSearchResults name={playerForm} exact={exact} setPlayerForm={setPlayerForm} />}
</div>
<Route exact path="/xsearch/w/:wpn" render={({ match }) =>
<InfoWeapon wpn={match.params.wpn.replace(/-/g, '_')} setWeaponForm={setWeaponForm} />
@@ -38,6 +44,6 @@ const XSearch = withRouter(({ history, setMenuSelection }) => {
} />
</div>
)
}) //alemmalle buttonille onChange uncontrolled?
}) //weapon forming renderöinti liian raskas
export default XSearch

View File

@@ -0,0 +1,54 @@
import React from 'react'
import { withRouter } from 'react-router-dom'
import { useQuery } from 'react-apollo-hooks'
import { Loader, Message, Grid, Button, Header } from 'semantic-ui-react'
import { searchForPlayers } from '../graphql/queries/searchForPlayers'
const XSearchResults = withRouter(({ history, name, exact }) => {
const result = useQuery(searchForPlayers, {variables: { name, exact }})
if (result.loading) {
return <div style={{"paddingTop": "25px", "paddingBottom": "20000px"}} ><Loader active inline='centered' /></div>
}
if (result.error) {
return <div style={{"color": "red"}}>{result.error.message}</div>
}
const searchResult = result.data['searchForPlayers']
if (searchResult.length === 0) {
return <Message
error
header='Your search matches 0 players who reached Top 500'
list={[
'You can\'t search for a player that has never finished in the Top 500',
'Be careful about special characters: ρ is not the same as p for example',
]}
/>
}
return (
<div style={{"paddingTop": "10px"}}>
<Header>Search results</Header>
{searchResult.length > 20 ? <Message info header='Your search returned over 20 players' content="Below are the twenty players with the highest power that match your criteria" /> : null}
<Grid columns={3}>
{searchResult.map(r => {
return (
<Grid.Row key={r.unique_id}>
<Grid.Column>
{r.name} ({r.x_power} with {r.weapon})
</Grid.Column>
<Grid.Column>
<Button
positive
onClick={() => history.push(`/xsearch/p/${r.unique_id}`)}
>Go!</Button>
</Grid.Column>
<Grid.Column></Grid.Column>
</Grid.Row>
)
})}
</Grid>
</div>
)
})
export default XSearchResults

View File

@@ -0,0 +1,12 @@
import { gql } from 'apollo-boost'
export const searchForPlayers = gql`
query searchForPlayers($name: String!, $exact: Boolean) {
searchForPlayers(name: $name, exact: $exact) {
name
x_power
weapon
unique_id
}
}
`