mirror of
https://github.com/monkeytypegame/monkeytype.git
synced 2025-11-11 14:41:17 +08:00
Merge branch 'master' into feature/friends-list
This commit is contained in:
commit
5314e3f572
14 changed files with 105 additions and 399 deletions
|
|
@ -8,6 +8,7 @@ describe("PresetDal", () => {
|
|||
it("should read", async () => {
|
||||
//GIVEN
|
||||
const uid = new ObjectId().toHexString();
|
||||
const decoyUid = new ObjectId().toHexString();
|
||||
const first = await PresetDal.addPreset(uid, {
|
||||
name: "first",
|
||||
config: { ads: "sellout" },
|
||||
|
|
@ -22,7 +23,11 @@ describe("PresetDal", () => {
|
|||
showAverage: "off",
|
||||
},
|
||||
});
|
||||
await PresetDal.addPreset("unknown", { name: "unknown", config: {} });
|
||||
|
||||
await PresetDal.addPreset(decoyUid, {
|
||||
name: "unknown",
|
||||
config: {},
|
||||
});
|
||||
|
||||
//WHEN
|
||||
const read = await PresetDal.getPresets(uid);
|
||||
|
|
@ -101,7 +106,8 @@ describe("PresetDal", () => {
|
|||
|
||||
describe("editPreset", () => {
|
||||
it("should not fail if preset is unknown", async () => {
|
||||
await PresetDal.editPreset("uid", {
|
||||
const uid = new ObjectId().toHexString();
|
||||
await PresetDal.editPreset(uid, {
|
||||
_id: new ObjectId().toHexString(),
|
||||
name: "new",
|
||||
config: {},
|
||||
|
|
@ -350,8 +356,9 @@ describe("PresetDal", () => {
|
|||
|
||||
describe("removePreset", () => {
|
||||
it("should fail if preset is unknown", async () => {
|
||||
const uid = new ObjectId().toHexString();
|
||||
await expect(() =>
|
||||
PresetDal.removePreset("uid", new ObjectId().toHexString())
|
||||
PresetDal.removePreset(uid, new ObjectId().toHexString())
|
||||
).rejects.toThrowError("Preset not found");
|
||||
});
|
||||
it("should remove", async () => {
|
||||
|
|
@ -435,7 +442,8 @@ describe("PresetDal", () => {
|
|||
|
||||
describe("deleteAllPresets", () => {
|
||||
it("should not fail if preset is unknown", async () => {
|
||||
await PresetDal.deleteAllPresets("uid");
|
||||
const uid = new ObjectId().toHexString();
|
||||
await PresetDal.deleteAllPresets(uid);
|
||||
});
|
||||
it("should delete all", async () => {
|
||||
//GIVEN
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ Follow these steps if you want to work on anything involving the database/accoun
|
|||
|
||||
## Building and Running Monkeytype
|
||||
|
||||
Its time to run Monkeytype. Just like with the databases, you can run the frontend and backend manually or with Docker.
|
||||
It's time to run Monkeytype. Just like with the databases, you can run the frontend and backend manually or with Docker.
|
||||
|
||||
### Dependencies (if running manually)
|
||||
|
||||
|
|
|
|||
|
|
@ -89,4 +89,4 @@ Once your PR is approved, all that is left to do is merge it!
|
|||
|
||||
## Questions
|
||||
|
||||
If you have any questions, comments, concerns, or problems, don't hesitate let us know via [email](mailto:jack@monkeytype.com)(to Miodec), on [GitHub](https://github.com/monkeytypegame/monkeytype/discussions) or on [Discord](https://discord.gg/monkeytype) in the [`#development`](https://discord.com/channels/713194177403420752/713196019206324306) channel and a contributor will be happy to assist you.
|
||||
If you have any questions, comments, concerns, or problems, don't hesitate to let us know via [email](mailto:jack@monkeytype.com)(to Miodec), on [GitHub](https://github.com/monkeytypegame/monkeytype/discussions) or on [Discord](https://discord.gg/monkeytype) in the [`#development`](https://discord.com/channels/713194177403420752/713196019206324306) channel and a contributor will be happy to assist you.
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ If the language does exist in Monkeytype, but there are no quotes for it create
|
|||
|
||||
### Committing Quotes
|
||||
|
||||
Once you have added your quotes(s), you now need to create a pull request to the main Monkeytype repository. Go to the branch where you added your quotes on GitHub. Then make sure your branch is up to date. Once it is up to date, click "contribute".
|
||||
Once you have added your quote(s), you now need to create a pull request to the main Monkeytype repository. Go to the branch where you added your quotes on GitHub. Then make sure your branch is up to date. Once it is up to date, click "contribute".
|
||||
|
||||
Update branch:
|
||||
<img width="1552" alt="Screenshot showing how to update the fork to match the main Monkeytype repository" src="https://user-images.githubusercontent.com/83455454/149186547-5b9fe4fd-b944-4eed-a959-db43f96198bf.png">
|
||||
|
|
|
|||
|
|
@ -1025,113 +1025,6 @@
|
|||
<button>copy link to clipboard</button>
|
||||
</div>
|
||||
</dialog>
|
||||
<div id="leaderboardsWrapper" class="popupWrapper hidden">
|
||||
<div id="leaderboards">
|
||||
<div class="leaderboardsTop">
|
||||
<div class="mainTitle">All-Time English Leaderboards</div>
|
||||
<div class="subTitle">Next update in: --:--</div>
|
||||
<div class="textButton showYesterdayButton hidden">
|
||||
<i class="fas fa-calendar-day"></i>
|
||||
<div class="text">Show yesterday</div>
|
||||
</div>
|
||||
<div class="buttons">
|
||||
<div class="buttonGroup timeRange">
|
||||
<div class="button allTime">all-time</div>
|
||||
<div class="button daily">daily</div>
|
||||
<select class="languageSelect" disabled></select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tables">
|
||||
<div class="titleAndTable">
|
||||
<div class="titleAndButtons">
|
||||
<div class="title">
|
||||
Time 15
|
||||
<i
|
||||
class="hidden leftTableLoader fas fa-fw fa-spin fa-circle-notch"
|
||||
></i>
|
||||
</div>
|
||||
<div class="buttons">
|
||||
<div class="button leftTableJumpToTop">
|
||||
<i class="fas fa-fw fas fa-crown"></i>
|
||||
<!-- Top -->
|
||||
</div>
|
||||
<div class="button leftTableJumpToMe">
|
||||
<i class="fas fa-fw fas fa-user"></i>
|
||||
<!-- Me -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="leftTableWrapper invisible">
|
||||
<table class="left">
|
||||
<thead>
|
||||
<tr>
|
||||
<td width="1%">#</td>
|
||||
<td>name</td>
|
||||
<td class="alignRight" width="1%">
|
||||
wpm
|
||||
<br />
|
||||
<div class="sub">accuracy</div>
|
||||
</td>
|
||||
<td class="alignRight" width="1%">
|
||||
raw
|
||||
<br />
|
||||
<div class="sub">consistency</div>
|
||||
</td>
|
||||
<td class="alignRight" width="125px">date</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
<tfoot></tfoot>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="titleAndTable">
|
||||
<div class="titleAndButtons">
|
||||
<div class="title">
|
||||
Time 60
|
||||
<i
|
||||
class="hidden rightTableLoader fas fa-fw fa-spin fa-circle-notch"
|
||||
></i>
|
||||
</div>
|
||||
<div class="buttons">
|
||||
<div class="button rightTableJumpToTop">
|
||||
<i class="fas fa-fw fas fa-crown"></i>
|
||||
<!-- Top -->
|
||||
</div>
|
||||
<div class="button rightTableJumpToMe">
|
||||
<i class="fas fa-fw fas fa-user"></i>
|
||||
<!-- Me -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="rightTableWrapper invisible">
|
||||
<table class="right">
|
||||
<thead>
|
||||
<tr>
|
||||
<td width="1%">#</td>
|
||||
<td>name</td>
|
||||
<td class="alignRight" width="1%">
|
||||
wpm
|
||||
<br />
|
||||
<div class="sub">accuracy</div>
|
||||
</td>
|
||||
<td class="alignRight" width="1%">
|
||||
raw
|
||||
<br />
|
||||
<div class="sub">consistency</div>
|
||||
</td>
|
||||
<td class="alignRight" width="120px">date</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
<tfoot></tfoot>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<dialog id="versionHistoryModal" class="modalWrapper hidden">
|
||||
<div class="modal"></div>
|
||||
</dialog>
|
||||
|
|
|
|||
|
|
@ -221,16 +221,6 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
#leaderboardsWrapper #leaderboards .leaderboardsTop {
|
||||
grid-template-columns: 1fr 1fr;
|
||||
grid-template-areas: "title title" "subtitle yesterday" "buttons buttons";
|
||||
.buttons .timeRange {
|
||||
grid-template-columns: 1fr 1fr 1fr;
|
||||
.languageSelect {
|
||||
grid-column: span 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
.testActivity {
|
||||
--box-size: 0.58em;
|
||||
// .activity div,
|
||||
|
|
|
|||
|
|
@ -221,37 +221,6 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
#leaderboardsWrapper #leaderboards {
|
||||
.tables {
|
||||
grid-template-columns: 1fr;
|
||||
height: 100%;
|
||||
.titleAndTable .title {
|
||||
font-size: 1rem;
|
||||
}
|
||||
.rightTableWrapper,
|
||||
.leftTableWrapper {
|
||||
height: calc(50vh - 9rem);
|
||||
}
|
||||
}
|
||||
.leaderboardsTop {
|
||||
.buttons .timeRange {
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
// grid-template-columns: 1fr 1fr;
|
||||
// grid-template-areas: "title title" "subtitle yesterday" "buttons buttons";
|
||||
.mainTitle {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
// .buttons .timeRange {
|
||||
// font-size: 0.75rem;
|
||||
// grid-template-columns: 1fr 1fr 1fr;
|
||||
// .languageSelect {
|
||||
// grid-column: span 1;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
#customTextModal {
|
||||
.modal {
|
||||
grid-template-areas:
|
||||
|
|
|
|||
|
|
@ -33,16 +33,6 @@
|
|||
font-size: 9rem;
|
||||
}
|
||||
}
|
||||
#leaderboardsWrapper #leaderboards {
|
||||
table thead tr td:nth-child(4),
|
||||
table tbody tr td:nth-child(4),
|
||||
table tfoot tr td:nth-child(4) {
|
||||
display: none;
|
||||
}
|
||||
.mainTitle {
|
||||
font-size: 2rem;
|
||||
}
|
||||
}
|
||||
#customTextModal {
|
||||
.modal {
|
||||
.buttonsTop {
|
||||
|
|
|
|||
|
|
@ -66,35 +66,7 @@ body {
|
|||
|
||||
// //1450px
|
||||
// @media only screen and (max-width: 90.625rem) {
|
||||
// #leaderboardsWrapper #leaderboards {
|
||||
// .mainTitle {
|
||||
// font-size: 2rem;
|
||||
// }
|
||||
// .title {
|
||||
// font-size: 1rem;
|
||||
// }
|
||||
// .leaderboardsTop {
|
||||
// grid-template-columns: auto 1fr max-content;
|
||||
// .buttonGroup {
|
||||
// grid-auto-flow: row;
|
||||
// gap: 0.5rem;
|
||||
// }
|
||||
// }
|
||||
// .tables table {
|
||||
// .avatarNameBadge .badge .text {
|
||||
// display: none;
|
||||
// }
|
||||
// tr td:first-child {
|
||||
// padding-left: 0.25rem;
|
||||
// }
|
||||
// tr td:last-child {
|
||||
// padding-right: 0.25rem;
|
||||
// }
|
||||
// td {
|
||||
// padding: 0.25rem 0.5rem;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// }
|
||||
|
||||
// //1330px
|
||||
|
|
@ -116,13 +88,6 @@ body {
|
|||
|
||||
// //1250px
|
||||
// @media only screen and (max-width: 78.125rem) {
|
||||
// #leaderboardsWrapper #leaderboards {
|
||||
// .tables table {
|
||||
// tr td:nth-child(5) {
|
||||
// display: none;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// #customTextModal .modal {
|
||||
// textarea {
|
||||
// min-height: 426px;
|
||||
|
|
@ -148,50 +113,6 @@ body {
|
|||
// gap: 1rem;
|
||||
// grid-template-rows: 1fr 1fr;
|
||||
// }
|
||||
// #leaderboardsWrapper {
|
||||
// #leaderboards {
|
||||
// .leaderboardsTop {
|
||||
// flex-direction: column;
|
||||
// align-items: baseline;
|
||||
// grid-template-areas:
|
||||
// "title title"
|
||||
// "subtitle subtitle"
|
||||
// "yesterday yesterday"
|
||||
// "buttons buttons";
|
||||
// grid-template-columns: 1fr;
|
||||
// .buttons {
|
||||
// margin-top: 0.5rem;
|
||||
// }
|
||||
// .buttonGroup {
|
||||
// grid-auto-flow: column;
|
||||
// }
|
||||
// .showYesterdayButton {
|
||||
// margin-left: 0;
|
||||
// }
|
||||
// }
|
||||
// .tables {
|
||||
// grid-template-columns: unset;
|
||||
// table {
|
||||
// .avatarNameBadge .badge .text {
|
||||
// display: block;
|
||||
// }
|
||||
// tr td:last-child {
|
||||
// width: 30%;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// .tables .rightTableWrapper,
|
||||
// .tables .leftTableWrapper {
|
||||
// height: calc(50vh - 10rem);
|
||||
// }
|
||||
// .tables table {
|
||||
// tr td:nth-child(5) {
|
||||
// display: table-cell;
|
||||
// width: auto;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// //1000px
|
||||
|
|
@ -313,11 +234,6 @@ body {
|
|||
// grid-template-areas: "title title" "t15 t60";
|
||||
// }
|
||||
// }
|
||||
// #leaderboards {
|
||||
// .mainTitle {
|
||||
// font-size: 1.5rem !important;
|
||||
// }
|
||||
// }
|
||||
// #bannerCenter .banner .container {
|
||||
// grid-template-columns: 1fr auto;
|
||||
// .image {
|
||||
|
|
@ -459,13 +375,6 @@ body {
|
|||
// #quoteSearchModal .modal #quoteSearchControlsWrapper {
|
||||
// grid-template-columns: 1fr;
|
||||
// }
|
||||
// #leaderboardsWrapper #leaderboards {
|
||||
// .tables table {
|
||||
// tr td:nth-child(5) {
|
||||
// display: none;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// .pageAbout {
|
||||
// .triplegroup {
|
||||
// grid-template-columns: 1fr;
|
||||
|
|
@ -547,24 +456,6 @@ body {
|
|||
// }
|
||||
// }
|
||||
// }
|
||||
// #leaderboardsWrapper #leaderboards {
|
||||
// width: 85vw;
|
||||
// .tables .rightTableWrapper,
|
||||
// .tables .leftTableWrapper {
|
||||
// height: calc(50vh - 10rem);
|
||||
// }
|
||||
// .tables {
|
||||
// grid-template-columns: unset;
|
||||
// table {
|
||||
// .avatarNameBadge .badge .text {
|
||||
// display: block;
|
||||
// }
|
||||
// tr td:nth-child(4) {
|
||||
// display: none;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// .profile {
|
||||
// grid-template-columns: 1fr;
|
||||
// grid-template-rows: auto auto auto;
|
||||
|
|
@ -720,9 +611,6 @@ body {
|
|||
// }
|
||||
// }
|
||||
// }
|
||||
// #leaderboardsWrapper #leaderboards .leaderboardsTop .buttonGroup {
|
||||
// grid-auto-flow: row;
|
||||
// }
|
||||
|
||||
// .pageAccount {
|
||||
// .group.history {
|
||||
|
|
@ -972,32 +860,6 @@ body {
|
|||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// #leaderboardsWrapper #leaderboards {
|
||||
// .tables .titleAndTable .titleAndButtons {
|
||||
// grid-template-columns: unset;
|
||||
// }
|
||||
// .tables table {
|
||||
// thead,
|
||||
// tbody,
|
||||
// tfoot {
|
||||
// // font-size: 0.5rem;
|
||||
// }
|
||||
// tr td:first-child {
|
||||
// padding-left: 0.25rem;
|
||||
// }
|
||||
// tr td:last-child {
|
||||
// padding-right: 0.25rem;
|
||||
// }
|
||||
// td {
|
||||
// padding: 0.25rem;
|
||||
// }
|
||||
// }
|
||||
// .tables .rightTableWrapper,
|
||||
// .tables .leftTableWrapper {
|
||||
// height: calc(50vh - 9rem);
|
||||
// }
|
||||
// }
|
||||
// .page404 .content {
|
||||
// grid-template-columns: 1fr;
|
||||
// }
|
||||
|
|
|
|||
|
|
@ -864,12 +864,10 @@ async function handleTab(
|
|||
$("#wordsInput").on("keydown", (event) => {
|
||||
const pageTestActive: boolean = ActivePage.get() === "test";
|
||||
const commandLineVisible = Misc.isPopupVisible("commandLineWrapper");
|
||||
const leaderboardsVisible = Misc.isPopupVisible("leaderboardsWrapper");
|
||||
const popupVisible: boolean = Misc.isAnyPopupVisible();
|
||||
const allowTyping: boolean =
|
||||
pageTestActive &&
|
||||
!commandLineVisible &&
|
||||
!leaderboardsVisible &&
|
||||
!popupVisible &&
|
||||
!TestUI.resultVisible &&
|
||||
event.key !== "Enter" &&
|
||||
|
|
@ -905,14 +903,12 @@ $(document).on("keydown", async (event) => {
|
|||
const wordsFocused: boolean = $("#wordsInput").is(":focus");
|
||||
const pageTestActive: boolean = ActivePage.get() === "test";
|
||||
const commandLineVisible = Misc.isPopupVisible("commandLineWrapper");
|
||||
const leaderboardsVisible = Misc.isPopupVisible("leaderboardsWrapper");
|
||||
|
||||
const popupVisible: boolean = Misc.isAnyPopupVisible();
|
||||
|
||||
const allowTyping: boolean =
|
||||
pageTestActive &&
|
||||
!commandLineVisible &&
|
||||
!leaderboardsVisible &&
|
||||
!popupVisible &&
|
||||
!TestUI.resultVisible &&
|
||||
(wordsFocused || event.key !== "Enter") &&
|
||||
|
|
|
|||
|
|
@ -49,7 +49,10 @@ export function getSnapshot(): Snapshot | undefined {
|
|||
return dbSnapshot;
|
||||
}
|
||||
|
||||
export function setSnapshot(newSnapshot: Snapshot | undefined): void {
|
||||
export function setSnapshot(
|
||||
newSnapshot: Snapshot | undefined,
|
||||
options?: { dispatchEvent?: boolean }
|
||||
): void {
|
||||
const originalBanned = dbSnapshot?.banned;
|
||||
const originalVerified = dbSnapshot?.verified;
|
||||
const lbOptOut = dbSnapshot?.lbOptOut;
|
||||
|
|
@ -71,7 +74,9 @@ export function setSnapshot(newSnapshot: Snapshot | undefined): void {
|
|||
dbSnapshot.lbOptOut = lbOptOut;
|
||||
}
|
||||
|
||||
AuthEvent.dispatch({ type: "snapshotUpdated", data: { isInitial: false } });
|
||||
if (options?.dispatchEvent !== false) {
|
||||
AuthEvent.dispatch({ type: "snapshotUpdated", data: { isInitial: false } });
|
||||
}
|
||||
}
|
||||
|
||||
export async function initSnapshot(): Promise<Snapshot | false> {
|
||||
|
|
@ -629,7 +634,7 @@ export async function getLocalPB<M extends Mode>(
|
|||
);
|
||||
}
|
||||
|
||||
export async function saveLocalPB<M extends Mode>(
|
||||
function saveLocalPB<M extends Mode>(
|
||||
mode: M,
|
||||
mode2: Mode2<M>,
|
||||
punctuation: boolean,
|
||||
|
|
@ -641,7 +646,7 @@ export async function saveLocalPB<M extends Mode>(
|
|||
acc: number,
|
||||
raw: number,
|
||||
consistency: number
|
||||
): Promise<void> {
|
||||
): void {
|
||||
if (mode === "quote") return;
|
||||
if (!dbSnapshot) return;
|
||||
function cont(): void {
|
||||
|
|
@ -922,38 +927,76 @@ export async function resetConfig(): Promise<void> {
|
|||
}
|
||||
}
|
||||
|
||||
export function saveLocalResult(result: SnapshotResult<Mode>): void {
|
||||
export type SaveLocalResultData = {
|
||||
xp?: number;
|
||||
streak?: number;
|
||||
result?: SnapshotResult<Mode>;
|
||||
isPb?: boolean;
|
||||
};
|
||||
|
||||
export function saveLocalResult(data: SaveLocalResultData): void {
|
||||
const snapshot = getSnapshot();
|
||||
if (!snapshot) return;
|
||||
|
||||
if (snapshot?.results !== undefined) {
|
||||
snapshot.results.unshift(result);
|
||||
if (data.result !== undefined) {
|
||||
if (snapshot?.results !== undefined) {
|
||||
snapshot.results.unshift(data.result);
|
||||
}
|
||||
if (snapshot.testActivity !== undefined) {
|
||||
snapshot.testActivity.increment(new Date(data.result.timestamp));
|
||||
}
|
||||
if (snapshot.typingStats === undefined) {
|
||||
snapshot.typingStats = {
|
||||
timeTyping: 0,
|
||||
startedTests: 0,
|
||||
completedTests: 0,
|
||||
};
|
||||
|
||||
setSnapshot(snapshot);
|
||||
const time =
|
||||
data.result.testDuration +
|
||||
data.result.incompleteTestSeconds -
|
||||
data.result.afkDuration;
|
||||
|
||||
snapshot.typingStats.timeTyping += time;
|
||||
snapshot.typingStats.startedTests += data.result.restartCount + 1;
|
||||
snapshot.typingStats.completedTests += 1;
|
||||
}
|
||||
|
||||
if (data.isPb) {
|
||||
saveLocalPB(
|
||||
data.result.mode,
|
||||
data.result.mode2,
|
||||
data.result.punctuation,
|
||||
data.result.numbers,
|
||||
data.result.language,
|
||||
data.result.difficulty,
|
||||
data.result.lazyMode,
|
||||
data.result.wpm,
|
||||
data.result.acc,
|
||||
data.result.rawWpm,
|
||||
data.result.consistency
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (snapshot.testActivity !== undefined) {
|
||||
snapshot.testActivity.increment(new Date(result.timestamp));
|
||||
setSnapshot(snapshot);
|
||||
}
|
||||
}
|
||||
|
||||
export function updateLocalStats(started: number, time: number): void {
|
||||
const snapshot = getSnapshot();
|
||||
if (!snapshot) return;
|
||||
if (snapshot.typingStats === undefined) {
|
||||
snapshot.typingStats = {
|
||||
timeTyping: 0,
|
||||
startedTests: 0,
|
||||
completedTests: 0,
|
||||
};
|
||||
if (data.xp !== undefined) {
|
||||
if (snapshot.xp === undefined) {
|
||||
snapshot.xp = 0;
|
||||
}
|
||||
snapshot.xp += data.xp;
|
||||
}
|
||||
|
||||
snapshot.typingStats.timeTyping += time;
|
||||
snapshot.typingStats.startedTests += started;
|
||||
snapshot.typingStats.completedTests += 1;
|
||||
if (data.streak !== undefined) {
|
||||
snapshot.streak = data.streak;
|
||||
|
||||
setSnapshot(snapshot);
|
||||
if (snapshot.streak > snapshot.maxStreak) {
|
||||
snapshot.maxStreak = snapshot.streak;
|
||||
}
|
||||
}
|
||||
|
||||
setSnapshot(snapshot, {
|
||||
dispatchEvent: false,
|
||||
});
|
||||
}
|
||||
|
||||
export function addXp(xp: number): void {
|
||||
|
|
@ -964,7 +1007,9 @@ export function addXp(xp: number): void {
|
|||
snapshot.xp = 0;
|
||||
}
|
||||
snapshot.xp += xp;
|
||||
setSnapshot(snapshot);
|
||||
setSnapshot(snapshot, {
|
||||
dispatchEvent: false,
|
||||
});
|
||||
}
|
||||
|
||||
export function updateInboxUnreadSize(newSize: number): void {
|
||||
|
|
@ -988,19 +1033,6 @@ export function addBadge(badge: Badge): void {
|
|||
setSnapshot(snapshot);
|
||||
}
|
||||
|
||||
export function setStreak(streak: number): void {
|
||||
const snapshot = getSnapshot();
|
||||
if (!snapshot) return;
|
||||
|
||||
snapshot.streak = streak;
|
||||
|
||||
if (snapshot.streak > snapshot.maxStreak) {
|
||||
snapshot.maxStreak = snapshot.streak;
|
||||
}
|
||||
|
||||
setSnapshot(snapshot);
|
||||
}
|
||||
|
||||
export async function getTestActivityCalendar(
|
||||
yearString: string
|
||||
): Promise<TestActivityCalendar | undefined> {
|
||||
|
|
|
|||
|
|
@ -1288,6 +1288,8 @@ async function saveResult(
|
|||
);
|
||||
$("#result .stats .tags .editTagsButton").removeClass("invisible");
|
||||
|
||||
const dataToSave: DB.SaveLocalResultData = {};
|
||||
|
||||
if (data.xp !== undefined) {
|
||||
const snapxp = DB.getSnapshot()?.xp ?? 0;
|
||||
|
||||
|
|
@ -1296,11 +1298,11 @@ async function saveResult(
|
|||
data.xp,
|
||||
TestUI.resultVisible ? data.xpBreakdown : undefined
|
||||
);
|
||||
DB.addXp(data.xp);
|
||||
dataToSave.xp = data.xp;
|
||||
}
|
||||
|
||||
if (data.streak !== undefined) {
|
||||
DB.setStreak(data.streak);
|
||||
dataToSave.streak = data.streak;
|
||||
}
|
||||
|
||||
if (data.insertedId !== undefined) {
|
||||
|
|
@ -1314,13 +1316,7 @@ async function saveResult(
|
|||
if (data.isPb !== undefined && data.isPb) {
|
||||
result.isPb = true;
|
||||
}
|
||||
DB.saveLocalResult(result);
|
||||
DB.updateLocalStats(
|
||||
completedEvent.incompleteTests.length + 1,
|
||||
completedEvent.testDuration +
|
||||
completedEvent.incompleteTestSeconds -
|
||||
completedEvent.afkDuration
|
||||
);
|
||||
dataToSave.result = result;
|
||||
}
|
||||
|
||||
void AnalyticsController.log("testCompleted");
|
||||
|
|
@ -1343,34 +1339,11 @@ async function saveResult(
|
|||
}
|
||||
Result.showCrown("normal");
|
||||
|
||||
await DB.saveLocalPB(
|
||||
completedEvent.mode,
|
||||
completedEvent.mode2,
|
||||
completedEvent.punctuation,
|
||||
completedEvent.numbers,
|
||||
completedEvent.language,
|
||||
completedEvent.difficulty,
|
||||
completedEvent.lazyMode,
|
||||
completedEvent.wpm,
|
||||
completedEvent.acc,
|
||||
completedEvent.rawWpm,
|
||||
completedEvent.consistency
|
||||
);
|
||||
dataToSave.isPb = true;
|
||||
} else {
|
||||
Result.showErrorCrownIfNeeded();
|
||||
}
|
||||
|
||||
// if (response.data.dailyLeaderboardRank) {
|
||||
// Notifications.add(
|
||||
// `New ${completedEvent.language} ${completedEvent.mode} ${completedEvent.mode2} rank: ` +
|
||||
// Misc.getPositionString(response.data.dailyLeaderboardRank),
|
||||
// 1,
|
||||
// 10,
|
||||
// "Daily Leaderboard",
|
||||
// "list-ol"
|
||||
// );
|
||||
// }
|
||||
|
||||
if (data.dailyLeaderboardRank === undefined) {
|
||||
$("#result .stats .dailyLeaderboard").addClass("hidden");
|
||||
} else {
|
||||
|
|
@ -1396,6 +1369,7 @@ async function saveResult(
|
|||
if (isRetrying) {
|
||||
Notifications.add("Result saved", 1, { important: true });
|
||||
}
|
||||
DB.saveLocalResult(dataToSave);
|
||||
}
|
||||
|
||||
export function fail(reason: string): void {
|
||||
|
|
|
|||
|
|
@ -27,15 +27,19 @@ export async function syncNotSignedInLastResult(uid: string): Promise<void> {
|
|||
const result = structuredClone(
|
||||
notSignedInLastResult
|
||||
) as unknown as SnapshotResult<Mode>;
|
||||
|
||||
const dataToSave: DB.SaveLocalResultData = {
|
||||
xp: response.body.data.xp,
|
||||
streak: response.body.data.streak,
|
||||
result,
|
||||
isPb: response.body.data.isPb,
|
||||
};
|
||||
|
||||
result._id = response.body.data.insertedId;
|
||||
if (response.body.data.isPb) {
|
||||
result.isPb = true;
|
||||
}
|
||||
DB.saveLocalResult(result);
|
||||
DB.updateLocalStats(
|
||||
1,
|
||||
result.testDuration + result.incompleteTestSeconds - result.afkDuration
|
||||
);
|
||||
DB.saveLocalResult(dataToSave);
|
||||
TestLogic.clearNotSignedInResult();
|
||||
Notifications.add(
|
||||
`Last test result saved ${response.body.data.isPb ? `(new pb!)` : ""}`,
|
||||
|
|
|
|||
|
|
@ -26,15 +26,3 @@
|
|||
.pageAbout .section p {
|
||||
color: var(--sub-color);
|
||||
}
|
||||
|
||||
#leaderboardsWrapper #leaderboards .title {
|
||||
color: var(--sub-color);
|
||||
}
|
||||
|
||||
#leaderboardsWrapper #leaderboards .tables table thead {
|
||||
color: var(--sub-color);
|
||||
}
|
||||
|
||||
#leaderboardsWrapper #leaderboards .tables table tbody {
|
||||
color: var(--sub-color);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue