Skip to content

Commit

Permalink
Merge pull request #185 from Avasam/develop
Browse files Browse the repository at this point in the history
2021-01-23 Develop to master
  • Loading branch information
Avasam authored Jan 23, 2021
2 parents e920b2f + fa11d06 commit dfde6a8
Show file tree
Hide file tree
Showing 24 changed files with 128 additions and 281 deletions.
1 change: 1 addition & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@
"checkArguments": false
}
],
"unicorn/numeric-separators-style": "error",
"unicorn/prefer-add-event-listener": "error",
"unicorn/prefer-query-selector": 0,
"unicorn/prefer-text-content": "error",
Expand Down
80 changes: 0 additions & 80 deletions Changescripts/2019-10-06-PROD-db-backup.sql

This file was deleted.

7 changes: 7 additions & 0 deletions Changescripts/2021-01-22-Cleanup-score-details.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
UPDATE player
SET score_details = SUBSTR(score_details,2)
WHERE score_details LIKE '\n%';

UPDATE player
SET score_details = NULL
WHERE score_details LIKE 'G%';
Binary file added Changescripts/PROD-db-backups.7z
Binary file not shown.
37 changes: 7 additions & 30 deletions global-scoreboard/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion global-scoreboard/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
"eslint-plugin-simple-import-sort": "^7.0.0",
"eslint-plugin-sonarjs": "^0.5.0",
"eslint-plugin-switch-case": "^1.1.2",
"eslint-plugin-unicorn": "^26.0.0",
"eslint-plugin-unicorn": "^27.0.0",
"typescript": "^4.1.3"
},
"eslintConfig": {
Expand Down
11 changes: 6 additions & 5 deletions global-scoreboard/src/Dashboard/Dashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,11 @@ type DashboardProps = {
const getFriends = () => apiGet('players/current/friends').then<Player[]>(res => res.json())
const getAllPlayers = () => apiGet('players')
.then<Player[]>(res => res.json())
.then(players => {
players.forEach(player => player.lastUpdate = new Date(player.lastUpdate))
return players
})
.then(players =>
players.map(player => ({
...player,
lastUpdate: new Date(player.lastUpdate),
})))

const validateRunnerNotRecentlyUpdated = (runnerNameOrId: string, players: Player[]) => {
const yesterday = new Date()
Expand Down Expand Up @@ -111,7 +112,7 @@ const Dashboard = (props: DashboardProps) => {
})
.then(result => {
setAlertVariant(result.state)
setAlertMessage(renderScoreTable(result.message))
setAlertMessage(renderScoreTable(result.scoreDetails || [[], []], result.message))
const newPlayers = [...playersState]
const existingPlayerIndex = newPlayers.findIndex(player => player.userId === result.userId)
const inferedRank = inferRank(newPlayers, result.score)
Expand Down
2 changes: 1 addition & 1 deletion global-scoreboard/src/Dashboard/QuickView/QuickView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import ScoreTitle from '../TableElements/ScoreTitle'
const currentTimeOnLoad = new Date()
const columnClass = (lastUpdate: Date) => {
// FIXME: This probably doesn't take daylight savings and other weird shenanigans into account
const daysSince = Math.floor((currentTimeOnLoad.getTime() - lastUpdate.getTime()) / 86400000)
const daysSince = Math.floor((currentTimeOnLoad.getTime() - lastUpdate.getTime()) / 86_400_000)
if (daysSince >= Configs.lastUpdatedDays[2]) return 'daysSince'
if (daysSince >= Configs.lastUpdatedDays[1]) return 'daysSince2'
return ''
Expand Down
2 changes: 1 addition & 1 deletion global-scoreboard/src/Dashboard/Scoreboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const currentTimeOnLoad = new Date()
const columnClass = (cell: Date | undefined) => {
if (!cell) return 'daysSince0'
// FIXME: This probably doesn't take daylight savings and other weird shenanigans into account
const daysSince = Math.floor((currentTimeOnLoad.getTime() - cell.getTime()) / 86400000)
const daysSince = Math.floor((currentTimeOnLoad.getTime() - cell.getTime()) / 86_400_000)
if (daysSince >= Configs.lastUpdatedDays[2]) return 'daysSince'
if (daysSince >= Configs.lastUpdatedDays[1]) return 'daysSince2'
if (daysSince >= Configs.lastUpdatedDays[0]) return 'daysSince1'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { Button } from 'react-bootstrap'
import { apiGet } from '../../fetchers/Api'
import GenericModal from '../../GenericModal'
import Player from '../../models/Player'
import { RunResult } from '../../models/UpdateRunnerResult'
import { renderScoreTable } from '../UpdateMessage'

type PlayerScoreCellProps = {
Expand All @@ -20,7 +21,7 @@ const PlayerScoreCell = (props: PlayerScoreCellProps) => {
props.player.scoreDetails === undefined
? apiGet(`players/${props.player.userId}/score-details`)
.then(res =>
res.text().then(scoreDetails => {
res.json().then((scoreDetails: RunResult[][]) => {
props.player.scoreDetails = scoreDetails
setShow(true)
}))
Expand Down
139 changes: 45 additions & 94 deletions global-scoreboard/src/Dashboard/UpdateMessage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,111 +13,62 @@ type UpdateMessageProps = {
}

const progressBarTickInterval = 16 // 60 FPS
const minutes5 = 5_000 * 60
const minutes5 = 5000 * 60
let progressTimer: NodeJS.Timeout
let position: number

const renderRow = (rows: RunResult[]) => rows.map((row, rowi) =>
<tr key={`row${rowi}`}>
<td>
{Math.round(position += row.levelFraction * 100) / 100}
</td>
<td>
{row.gameName} - {row.categoryName}{row.levelName ? ` (${row.levelName})` : ''}
</td>
<td>
{row.points.toFixed(2)}
</td>
</tr>)
const renderRow = (rows: RunResult[]) =>
rows.map((row, rowi) =>
<tr key={`row${rowi}`}>
<td>
{Math.round(position += row.levelFraction * 100) / 100}
</td>
<td>
{row.gameName} - {row.categoryName}{row.levelName ? ` (${row.levelName})` : ''}
</td>
<td>
{row.points.toFixed(2)}
</td>
</tr>)

export const renderScoreTable = (baseString: string) => {
position = 0
const allElements = baseString
.split('\n')
.map(row =>
row.split('|')
.map(rowItem =>
rowItem.trim()))
const firstTableElement = allElements.findIndex(element => element.length === 2)
const topMessage = firstTableElement > -1
? allElements
.slice(0, firstTableElement > 0 ? firstTableElement : undefined)
// Note: join the first element of each array with a new
// eslint-disable-next-line unicorn/no-array-reduce
.reduce((previous, current) => `${previous}${current[0]}\n`, '')
.trim()
: allElements[0][0]

// Note: TableElements is used for rendering old string formatted table
const tableElements = allElements.slice(firstTableElement)
const renderTable = (runs: RunResult[]) =>
<table className='scoreDetailsTable'>
<thead>
<tr>
<th>
#<OverlayTrigger
placement='bottom'
overlay={
<Tooltip id='levelFractionInfo'>
Individual Levels (IL) are weighted and scored to a fraction of a Full Game run.
See the About page for a complete explanation.
</Tooltip>
}
><FontAwesomeIcon icon={faInfoCircle} />
</OverlayTrigger>
</th>
<th>Game - Category (Level)</th>
<th>Points</th>
</tr>
</thead>
<tbody>
{renderRow(runs)}
</tbody>
</table>

let topRuns: RunResult[] = []
let lesserRuns: RunResult[] = []

if (tableElements.length === 1 && tableElements[0].length === 1) {
try {
const scoreDetails = JSON.parse(tableElements[0][0])
topRuns = scoreDetails[0]
lesserRuns = scoreDetails[1]
} catch {
// suppress
}
}
export const renderScoreTable = ([topRuns, lesserRuns]: RunResult[][], topMessage?: string) => {
position = 0

return <>
<div>{topMessage}</div>
{topRuns.length > 0 && <label>Top 60 runs:</label>}
{(topRuns.length > 0 || tableElements.slice(2).length > 0) &&
<table className='scoreDetailsTable'>
<thead>
<tr>
<th># {topRuns.length > 0 && <OverlayTrigger
placement='bottom'
overlay={
<Tooltip
id='levelFractionInfo'
>Individual Levels (IL) are weighted and scored to a fraction of a Full Game run. See the About page for a complete explanation.</Tooltip>
}
>
<FontAwesomeIcon icon={faInfoCircle} />
</OverlayTrigger>}</th>
<th>Game - Category (Level)</th>
<th>Points</th>
</tr>
</thead>
{topRuns.length > 0
? <tbody>
{renderRow(topRuns)}
</tbody>
: <tbody>
{/* Note: TableElements is used for rendering old string formatted table */}
{tableElements.slice(2).map((row, rowi) =>
<tr key={`row${rowi}`}>
<td>{rowi + 1}</td>
{row.map((element, elementi) =>
<td key={`element${elementi}`}>
{element}
</td>)}
</tr>)}
</tbody>
}
</table>
}
{topRuns.length > 0 && <>
<label>Top 60 runs:</label>
{renderTable(topRuns)}
</>}
{lesserRuns.length > 0 && <>
<br />
<label>Other runs:</label>
<table className='scoreDetailsTable'>
<thead>
<tr>
<th>#</th>
<th>Game - Category (Level)</th>
<th>Points</th>
</tr>
</thead>
<tbody>
{renderRow(lesserRuns)}
</tbody>
</table>
{renderTable(lesserRuns)}
</>}
</>
}
Expand Down
1 change: 0 additions & 1 deletion global-scoreboard/src/GameSearch/ScoreDropCalculator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,6 @@ const ScoreDropCalculator = () => {
/>
<InputGroup.Append>
<Button
id='calculate-score-drop'
type='submit'
disabled={updating || !runId}
onClick={onCalculate}
Expand Down
4 changes: 3 additions & 1 deletion global-scoreboard/src/models/Player.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { RunResult } from './UpdateRunnerResult'

export default interface Player {
rank: number | undefined
name: string
countryCode: string | null
score: number
scoreDetails?: string
scoreDetails?: RunResult[][]
lastUpdate: Date
userId: string
}
Expand Down
5 changes: 2 additions & 3 deletions models/core_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ def get_all():
rank=player[5]) for player in db.engine.execute(sql).fetchall()]

@staticmethod
def create(user_id: str, name: str, **kwargs) -> Player:
def create(user_id: str, name: str, **kwargs: Union[Optional[str], float, datetime]) -> Player:
"""
kwargs:
- score: int
Expand All @@ -109,7 +109,7 @@ def create(user_id: str, name: str, **kwargs) -> Player:

return player

def update(self, **kwargs: Dict[str, Union[str, float, datetime]]) -> Player:
def update(self, **kwargs: Union[Optional[str], float, datetime]) -> Player:
player = Player \
.query \
.filter(Player.user_id == self.user_id) \
Expand Down Expand Up @@ -156,7 +156,6 @@ def get_schedules(self) -> List[Schedule]:
return Schedule.query.filter(Schedule.owner_id == self.user_id).all()

def create_schedule(self, name: str, is_active: bool, deadline: str, time_slots: List[Dict[str, str]]) -> int:
print(type(deadline))
new_schedule = Schedule(
name=name,
owner_id=self.user_id,
Expand Down
Loading

0 comments on commit dfde6a8

Please sign in to comment.