Skip to content
This repository was archived by the owner on Mar 13, 2025. It is now read-only.

Commit a6439e6

Browse files
Update full width leaderboard to support dev and qa tracks and animate final scores in these tracks
1 parent 61abe8a commit a6439e6

File tree

7 files changed

+218
-33
lines changed

7 files changed

+218
-33
lines changed

common/helper.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ async function prepareLeaderboard (challengeId, finalists, groupId, groupChallen
8484
score = Math.round(review.aggregateScore * 10000) / 10000
8585
}
8686
member.reviews.push({
87+
challengeId: review.challengeId,
8788
score,
8889
testsPassed: review.testsPassed,
8990
totalTestCases: review.totalTestCases
@@ -92,13 +93,13 @@ async function prepareLeaderboard (challengeId, finalists, groupId, groupChallen
9293
aggregateScore = aggregateScore + (review.aggregateScore * multiplier[i])
9394
} else {
9495
// If a review is in queue, do not show any points or tests. Show the status
95-
member.reviews.push({ status: 'review queued' })
96+
member.reviews.push({ challengeId: review.challengeId, status: 'review queued' })
9697
// If a review is in queue, then the aggregate points will not be known
9798
member.points = '...'
9899
}
99100
} else {
100101
// Member does not have a review for that challenge
101-
member.reviews.push({})
102+
member.reviews.push({ challengeId: groupChallengeIds[i] })
102103
}
103104
}
104105

components/FinalistTable.js

Lines changed: 80 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ const table = (props) => {
1313
}
1414
const algorithmLeaderboard = track === 'algorithm'
1515
const f2fLeaderboard = fullWidth
16+
const isDevOrQa = isDev || isQa
1617
return (
1718
<div className={'container' + smallClass + sizeClass + `${trackTableClass(track)}`}>
1819
<div className='header'>
@@ -27,25 +28,25 @@ const table = (props) => {
2728
{ largeColumns && algorithmLeaderboard && <div className='algorithmFieldCell'>
2829
1000
2930
</div> }
30-
{ largeColumns && f2fLeaderboard && <div className='f2fPblmCell'>
31+
{ largeColumns && f2fLeaderboard && !isDevOrQa && <div className='f2fPblmCell'>
3132
Problem 1
3233
</div> }
33-
{ largeColumns && f2fLeaderboard && <div className='f2fTestCell'>
34+
{ largeColumns && f2fLeaderboard && !isDevOrQa && <div className='f2fTestCell'>
3435
TESTS PASSED/TOTAL
3536
</div> }
36-
{ largeColumns && f2fLeaderboard && <div className='f2fPblmCell'>
37+
{ largeColumns && f2fLeaderboard && !isDevOrQa && <div className='f2fPblmCell'>
3738
Problem 2
3839
</div> }
39-
{ largeColumns && f2fLeaderboard && <div className='f2fTestCell'>
40+
{ largeColumns && f2fLeaderboard && !isDevOrQa && <div className='f2fTestCell'>
4041
TESTS PASSED/TOTAL
4142
</div> }
42-
{ largeColumns && f2fLeaderboard && <div className='f2fPblmCell'>
43+
{ largeColumns && f2fLeaderboard && !isDevOrQa && <div className='f2fPblmCell'>
4344
Problem 3
4445
</div> }
45-
{ largeColumns && f2fLeaderboard && <div className='f2fTestCell'>
46+
{ largeColumns && f2fLeaderboard && !isDevOrQa && <div className='f2fTestCell'>
4647
TESTS PASSED/TOTAL
4748
</div> }
48-
{!isMini && <div className='points'>points</div>}
49+
{!isMini && !isDevOrQa && <div className='points'>points</div>}
4950
{
5051
isMini &&
5152
<div style={{ display: 'flex', flexGrow: '1', justifyContent: 'space-between' }}>
@@ -54,6 +55,13 @@ const table = (props) => {
5455
{!isQa && <div className='tests-passed'>{ isDev ? '% Complete' : 'tests passed'}</div>}
5556
</div>
5657
}
58+
{
59+
f2fLeaderboard && isDevOrQa &&
60+
<div style={{ display: 'flex', flexGrow: '1', justifyContent: 'space-around' }}>
61+
<div className='points'>points</div>
62+
{!isQa && <div className='tests-passed'>{ isDev ? '% Complete' : 'tests passed'}</div>}
63+
</div>
64+
}
5765
</div>
5866
{ finalists.map((profile, i) => (
5967
<div key={profile.handle} className='row'>
@@ -126,6 +134,67 @@ const table = (props) => {
126134
{profile.handle}
127135
</div> }
128136

137+
{/* Full width leaderboard, but for dev and qa */}
138+
{ f2fLeaderboard && isDevOrQa && <React.Fragment>
139+
<div className={`competitor ${profile.animationClass}`}>
140+
<div className='avatar'>
141+
<img src={profile.profilePic} />
142+
</div>
143+
<img className='country-flag' src={profile.countryFlag} />
144+
<div className='handle' style={{ color: primaryColor }}>{profile.handle}</div>
145+
</div>
146+
147+
<div style={{ display: 'flex', flexGrow: 1, justifyContent: 'space-around' }}>
148+
<div className={`points ${profile.animationClass}`}>
149+
{ profile.scoreLevel && <img className={`animate fade${profile.scoreLevel} infinite`} src={`/static/img/trend/${profile.scoreLevel}.png`} /> }
150+
{ profile.points >= 0 && <div className={profile.scoreLevel ? '' : 'non-score-lvl-pt'}>
151+
<span className='value'>
152+
{profile.points}
153+
</span>
154+
<span className='hint'>
155+
POINTS
156+
</span>
157+
</div> }
158+
</div>
159+
160+
{
161+
!isQa && profile.totalTestCases > 0 && <div className={`tests-passed ${profile.animationClass}`}>
162+
<div>
163+
{
164+
!isDev &&
165+
<React.Fragment>
166+
<span className='value'>
167+
{`${profile.testsPassed} / ${profile.totalTestCases}`}
168+
</span>
169+
<span className='hint'>
170+
TESTS
171+
</span>
172+
</React.Fragment>
173+
}
174+
{
175+
isDev &&
176+
<React.Fragment>
177+
<span className='value'>
178+
{`${parseFloat(profile.testsPassed / profile.totalTestCases * 100).toFixed(2)}%`}
179+
</span>
180+
<span className='hint'>
181+
COMPLETED
182+
</span>
183+
</React.Fragment>
184+
}
185+
</div>
186+
</div>
187+
}
188+
189+
{
190+
!profile.hasOwnProperty('points') && <div className={`status ${profile.statusAnimationClass}`}>
191+
{profile.status}
192+
</div>
193+
}
194+
</div>
195+
</React.Fragment>
196+
}
197+
129198
{ largeColumns && algorithmLeaderboard && profile.hasOwnProperty('roundOne') && <div className={'algorithmFieldCell ' + (profile.roundOne === 'fail' ? 'fail' : '')}>
130199
{profile.roundOne}
131200
</div> }
@@ -145,7 +214,7 @@ const table = (props) => {
145214
{
146215
profile.reveal === true && <React.Fragment>
147216
{ largeColumns && f2fLeaderboard && profile.hasOwnProperty('handle') &&
148-
<div className='competitor'>
217+
<div className={`competitor ${profile.animationClass}`}>
149218
<div className='avatar'>
150219
<img src={profile.profilePic} />
151220
</div>
@@ -154,7 +223,7 @@ const table = (props) => {
154223
</div>
155224
}
156225
{ largeColumns && f2fLeaderboard && profile.hasOwnProperty('reviews') && profile.reviews.map((review, i) => (
157-
<div key={review.challengeId} className='f2fScoreTests animate fadeIn'>
226+
<div key={`${profile.handle}-${review.challengeId}`} className={`f2fScoreTests ${profile.animationClass}`}>
158227
{
159228
!review.status && <React.Fragment>
160229
<div className='f2fFieldCell'>{review.score}</div>
@@ -183,7 +252,7 @@ const table = (props) => {
183252
</div>
184253
)) }
185254

186-
{ largeColumns && f2fLeaderboard && profile.hasOwnProperty('points') && <div className='f2fPoints f2fFieldCell animate fadeIn'>
255+
{ largeColumns && f2fLeaderboard && profile.hasOwnProperty('points') && <div className='f2fPoints f2fFieldCell animate flipInX'>
187256
{profile.points}
188257
</div> }
189258

@@ -194,7 +263,7 @@ const table = (props) => {
194263
</React.Fragment>
195264
}
196265
{
197-
!profile.reveal && f2fLeaderboard &&
266+
!profile.reveal && f2fLeaderboard && !isDevOrQa &&
198267
<React.Fragment>
199268
{ largeColumns && f2fLeaderboard && profile.hasOwnProperty('handle') && <div className='handleName animate fadeIn'>&nbsp;
200269
</div> }
@@ -467,11 +536,6 @@ const table = (props) => {
467536
color: #F21919;
468537
}
469538
470-
.algorithmTable .points,
471-
.f2fTable .points {
472-
text-align: left;
473-
}
474-
475539
.algorithmTable .rank,
476540
.f2fTable .rank {
477541
text-align: center;

components/Header.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,11 @@ class Header extends React.Component {
1212
usedEndDate: false
1313
}
1414

15-
setInterval(this.tick.bind(this), 1000)
15+
this.timerInterval = setInterval(this.tick.bind(this), 1000)
16+
}
17+
18+
componentWillUnmount () {
19+
clearInterval(this.timerInterval)
1620
}
1721

1822
tick () {

components/Marquee.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ class NewsMarquee extends Component {
66
constructor () {
77
super()
88

9+
this.animationId = null
10+
911
this.state = {
1012
elemWidth: 0,
1113
translateX: 0,
@@ -34,6 +36,10 @@ class NewsMarquee extends Component {
3436
}, this.slide.bind(this))
3537
}
3638

39+
componentWillUnmount () {
40+
window.cancelAnimationFrame(this.animationId)
41+
}
42+
3743
slide () {
3844
const {
3945
elem, slide, elemWidth, bodyWidth
@@ -53,7 +59,7 @@ class NewsMarquee extends Component {
5359
}
5460

5561
this.setState({ translateX }, () => {
56-
requestAnimationFrame(this.slide.bind(this))
62+
this.animationId = requestAnimationFrame(this.slide.bind(this))
5763
})
5864
}
5965

next.config.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ module.exports = {
33
host: process.env.HOST,
44
pollTimeInterval: process.env.LEADERBOARD_POLL_TIME_INTERVAL || 1000,
55
leaderboardRevealDelay: process.env.LEADERBOARD_REVEAL_DELAY || 500,
6-
processDevRevealDelay: process.env.DEV_LEADERBOARD_REVEAL_DELAY || 7000,
7-
revealFinalScore: process.env.REVEAL_FINAL_SCORE ? Boolean(process.env.REVEAL_FINAL_SCORE) : false
6+
processDevRevealDelay: process.env.DEV_LEADERBOARD_REVEAL_DELAY || 7000
87
}
98
}

0 commit comments

Comments
 (0)