Public Access
feat(game): play confetti for finished games
This commit is contained in:
1 parent
09e1f767d8
commit
a5458b3f86
9 files changed
+260
-9
No files matched your search
@@ -0,0 +1,29 @@
|
||||
const FINISHED = ['FINISHED', 'COMPLETED'];
|
||||
|
||||
/**
|
||||
* Every achievement unlocked. Only while the stats are visible: Core can still send the old unlock count after they turn private.
|
||||
*/
|
||||
export const allAchievementsUnlocked = (game) => game.hasAchievements && game.statsVisible
|
||||
&& game.achievementsTotal > 0 && game.achievementsUnlocked >= game.achievementsTotal;
|
||||
|
||||
/**
|
||||
* 0: not finished, 1: finished, 2: finished and every achievement unlocked.
|
||||
*/
|
||||
export const celebrationLevel = (game) => {
|
||||
if (!FINISHED.includes(game.status)) return 0;
|
||||
return allAchievementsUnlocked(game) ? 2 : 1;
|
||||
};
|
||||
|
||||
/**
|
||||
* The confetti to play when the page shows this game: on opening a finished game, and when the level rises on the
|
||||
* same page (e.g. the user sets FINISHED). A reload of the same game plays nothing.
|
||||
*
|
||||
* @param before {appid, level} of the game shown before, null on opening the page
|
||||
* @returns 'small', 'big' or null
|
||||
*/
|
||||
export const celebrationFor = (before, game) => {
|
||||
const level = celebrationLevel(game);
|
||||
const from = before?.appid === game.appid ? before.level : 0;
|
||||
if (level <= from) return null;
|
||||
return level === 2 ? 'big' : 'small';
|
||||
};
|
||||
@@ -0,0 +1,38 @@
|
||||
import {describe, expect, it} from 'vitest';
|
||||
import {celebrationFor, celebrationLevel} from './confetti.js';
|
||||
|
||||
const game = (status, unlocked = 0, total = 0, appid = 620) =>
|
||||
({appid, status, hasAchievements: total > 0, statsVisible: true, achievementsUnlocked: unlocked, achievementsTotal: total});
|
||||
|
||||
describe('celebrationLevel', () => {
|
||||
it('is 0 for a game not finished, 1 for finished, 2 for finished with every achievement', () => {
|
||||
expect(celebrationLevel(game('PLAYING', 4, 4))).toBe(0);
|
||||
expect(celebrationLevel(game('FINISHED'))).toBe(1);
|
||||
expect(celebrationLevel(game('COMPLETED', 3, 4))).toBe(1);
|
||||
expect(celebrationLevel(game('FINISHED', 4, 4))).toBe(2);
|
||||
expect(celebrationLevel(game('COMPLETED', 4, 4))).toBe(2);
|
||||
});
|
||||
|
||||
it('counts no achievements while the stats are hidden', () => {
|
||||
expect(celebrationLevel({...game('FINISHED', 4, 4), statsVisible: false})).toBe(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('celebrationFor', () => {
|
||||
it('plays on opening a finished game', () => {
|
||||
expect(celebrationFor(null, game('FINISHED'))).toBe('small');
|
||||
expect(celebrationFor(null, game('COMPLETED', 4, 4))).toBe('big');
|
||||
expect(celebrationFor(null, game('BACKLOG'))).toBeNull();
|
||||
});
|
||||
|
||||
it('plays when the status rises on the same page, not when the game loads again', () => {
|
||||
expect(celebrationFor({appid: 620, level: 0}, game('FINISHED'))).toBe('small');
|
||||
expect(celebrationFor({appid: 620, level: 1}, game('FINISHED', 4, 4))).toBe('big');
|
||||
expect(celebrationFor({appid: 620, level: 1}, game('FINISHED'))).toBeNull();
|
||||
expect(celebrationFor({appid: 620, level: 2}, game('PLAYING'))).toBeNull();
|
||||
});
|
||||
|
||||
it('plays for another game opened from the page', () => {
|
||||
expect(celebrationFor({appid: 620, level: 1}, game('FINISHED', 0, 0, 220))).toBe('small');
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user