Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions frontend/src/html/pages/test.html
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
<div id="memoryTimer">Time left to memorise all words: 0s</div>
<div id="layoutfluidTimer">Time left to memorise all words: 0s</div>
<div id="testModesNotice"></div>
<mount data-component="testmodesnotice"></mount>

<div id="liveStatsTextTop" class="timerMain">
<div class="wrapper">
<div class="timerProgress hidden">1:00</div>
Expand Down
38 changes: 34 additions & 4 deletions frontend/src/ts/collections/results.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {
useLiveQuery,
} from "@tanstack/solid-db";
import { queryOptions } from "@tanstack/solid-query";
import { Accessor } from "solid-js";
import { Accessor, createMemo } from "solid-js";
import Ape from "../ape";
import { SnapshotResult } from "../constants/default-snapshot";
import { createEffectOn } from "../hooks/effects";
Expand All @@ -33,8 +33,12 @@ import {
reconcileLocalTagPB,
saveLocalTagPB,
__nonReactive as tagsNonReactive,
useActiveTagsLiveQuery,
} from "./tags";
import { applyIdWorkaround } from "./utils/misc";
import { getConfig } from "../config/store";
import { getMode2 } from "../utils/misc";
import { getCurrentQuote } from "../states/test";

export type ResultsQueryState = {
difficulty: SnapshotResult<Mode>["difficulty"][];
Expand Down Expand Up @@ -214,6 +218,8 @@ const resultsCollection = createCollection(
queryKey: queryKeys.root(),
queryFn: async () => {
if (!isAuthenticated()) return [];

console.log("### init results");
const knownTagIds = new Set(
tagsNonReactive.getTags().map((it) => it._id),
);
Expand Down Expand Up @@ -580,18 +586,41 @@ export type CurrentSettingsFilter = {
lazyMode: boolean;
};

export async function getUserAverage10(
// oxlint-disable-next-line typescript/explicit-function-return-type
export function useUserAverage10LiveQuery() {
const tags = useActiveTagsLiveQuery();
const options = createMemo(() => ({
...getConfig,
mode2: getMode2(getConfig, getCurrentQuote()),
}));

return useLiveQuery((q) =>
q
.from({
//we use sub-query to filter first and then aggregate
last10: buildSettingsResultsQuery(options(), {
tagIds: tags().map((it) => it._id),
})
.orderBy(({ r }) => r.timestamp, "desc")
.limit(10),
})
.select(({ last10 }) => ({ wpm: avg(last10.wpm), acc: avg(last10.acc) })),
);
}

export async function getUserAverage10Once(
options: CurrentSettingsFilter,
): Promise<{ wpm: number; acc: number }> {
//exit early if there is no user. Don't init the result collection
if (!isAuthenticated()) return { wpm: 0, acc: 0 };
const tags = useActiveTagsLiveQuery();

const result = await queryOnce((q) =>
q
.from({
//we use sub-query to filter first and then aggregate
last10: buildSettingsResultsQuery(options, {
tagIds: tagsNonReactive.getActiveTags().map((it) => it._id),
tagIds: tags().map((it) => it._id),
})
.orderBy(({ r }) => r.timestamp, "desc")
.limit(10),
Expand All @@ -609,10 +638,11 @@ export async function getUserDailyBest(
): Promise<{ wpm: number; acc: number }> {
//exit early if there is no user. Don't init the result collection
if (!isAuthenticated()) return { wpm: 0, acc: 0 };
const tags = useActiveTagsLiveQuery();

const result = await queryOnce(() =>
buildSettingsResultsQuery(options, {
tagIds: tagsNonReactive.getActiveTags().map((it) => it._id),
tagIds: tags().map((it) => it._id),
})
.where(({ r }) => gte(r.timestamp, Date.now() - 24 * 60 * 60 * 1000))
.orderBy(({ r }) => r.wpm, "desc")
Expand Down
11 changes: 11 additions & 0 deletions frontend/src/ts/collections/tags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { queryCollectionOptions } from "@tanstack/query-db-collection";
import {
createCollection,
createOptimisticAction,
eq,
useLiveQuery,
} from "@tanstack/solid-db";
import { z } from "zod";
Expand Down Expand Up @@ -60,6 +61,16 @@ export function useTagsLiveQuery() {
});
}

// oxlint-disable-next-line typescript/explicit-function-return-type
export function useActiveTagsLiveQuery() {
return useLiveQuery((q) => {
return q
.from({ tag: tagsCollection })
.where(({ tag }) => eq(tag.active, true))
.orderBy(({ tag }) => tag.name, "asc");
});
}

type ActionType = {
insertTag: {
name: string;
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/ts/commandline/lists/bail-out.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { Config } from "../../config/store";
import { getCustomTextIndicator } from "../../states/core";
import * as CustomText from "../../test/custom-text";
import * as TestLogic from "../../test/test-logic";
import * as TestState from "../../test/test-state";
import * as CustomTextState from "../../legacy-states/custom-text-name";
import { Command, CommandsSubgroup } from "../types";

function canBailOut(): boolean {
return (
(Config.mode === "custom" && CustomTextState.isCustomTextLong() === true) ||
(Config.mode === "custom" && getCustomTextIndicator()?.isLong === true) ||
(Config.mode === "custom" &&
(CustomText.getLimitMode() === "word" ||
CustomText.getLimitMode() === "section") &&
Expand Down
10 changes: 5 additions & 5 deletions frontend/src/ts/commandline/lists/quote-favorites.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,16 @@ import {
} from "../../states/notifications";
import { isAuthenticated } from "../../states/core";
import { showLoaderBar, hideLoaderBar } from "../../states/loader-bar";
import * as TestWords from "../../test/test-words";
import { Command } from "../types";
import { getCurrentQuote } from "../../states/test";

const commands: Command[] = [
{
id: "addQuoteToFavorite",
display: "Add current quote to favorite",
icon: "fa-heart",
available: (): boolean => {
const quote = TestWords.currentQuote;
const quote = getCurrentQuote();
return (
isAuthenticated() &&
quote !== null &&
Expand All @@ -27,7 +27,7 @@ const commands: Command[] = [
try {
showLoaderBar();
await QuotesController.setQuoteFavorite(
TestWords.currentQuote as Quote,
getCurrentQuote() as Quote,
true,
);
hideLoaderBar();
Expand All @@ -43,7 +43,7 @@ const commands: Command[] = [
display: "Remove current quote from favorite",
icon: "fa-heart-broken",
available: (): boolean => {
const quote = TestWords.currentQuote;
const quote = getCurrentQuote();
return (
isAuthenticated() &&
quote !== null &&
Expand All @@ -55,7 +55,7 @@ const commands: Command[] = [
try {
showLoaderBar();
await QuotesController.setQuoteFavorite(
TestWords.currentQuote as Quote,
getCurrentQuote() as Quote,
false,
);
hideLoaderBar();
Expand Down
18 changes: 9 additions & 9 deletions frontend/src/ts/components/modals/CustomTextModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ import type { FaSolidIcon } from "../../types/font-awesome";
import { setConfig } from "../../config/setters";
import { Config } from "../../config/store";
import { restartTestEvent } from "../../events/test";
import * as CustomTextState from "../../legacy-states/custom-text-name";
import {
getCustomTextIndicator,
setCustomTextIndicator,
} from "../../states/core";
import { hideModalAndClearChain, showModal } from "../../states/modals";
import {
showNoticeNotification,
Expand Down Expand Up @@ -276,7 +279,7 @@ export function CustomTextModal(): JSXElement {
});
});

setLongTextWarning(CustomTextState.isCustomTextLong() ?? false);
setLongTextWarning(getCustomTextIndicator()?.isLong ?? false);
setChallengeWarning(getLoadedChallenge() !== null);
};

Expand All @@ -285,8 +288,8 @@ export function CustomTextModal(): JSXElement {
if (data === null) return;
setIncomingChainedData(null);

if (data.long !== true && CustomTextState.isCustomTextLong()) {
CustomTextState.setCustomTextName("", undefined);
if (data.long !== true && getCustomTextIndicator()?.isLong) {
setCustomTextIndicator(undefined);
showNoticeNotification("Disabled long custom text progress tracking", {
durationMs: 5000,
});
Expand Down Expand Up @@ -358,11 +361,8 @@ export function CustomTextModal(): JSXElement {
if (e.code === "Enter" && e.ctrlKey) {
void form.handleSubmit();
}
if (
CustomTextState.isCustomTextLong() &&
CustomTextState.getCustomTextName() !== ""
) {
CustomTextState.setCustomTextName("", undefined);
if (getCustomTextIndicator()?.isLong) {
setCustomTextIndicator(undefined);
setLongTextWarning(false);
showNoticeNotification("Disabled long custom text progress tracking", {
durationMs: 5000,
Expand Down
14 changes: 7 additions & 7 deletions frontend/src/ts/components/modals/QuoteRateModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
showSuccessNotification,
} from "../../states/notifications";
import {
currentQuote,
selectedQuote,
quoteStats,
getQuoteStats,
updateQuoteStats,
Expand All @@ -29,7 +29,7 @@ export function QuoteRateModal(): JSXElement {
const [hoverRating, setHoverRating] = createSignal(0);

const getLengthDesc = (): string => {
const quote = currentQuote();
const quote = selectedQuote();
if (!quote) return "-";
if (quote.group === 0) return "short";
if (quote.group === 1) return "medium";
Expand All @@ -41,7 +41,7 @@ export function QuoteRateModal(): JSXElement {
const displayRating = (): number => hoverRating() || rating();

const handleBeforeShow = (): void => {
const quote = currentQuote();
const quote = selectedQuote();
if (!quote) return;
setRating(0);
setHoverRating(0);
Expand All @@ -58,7 +58,7 @@ export function QuoteRateModal(): JSXElement {
showNoticeNotification("Please select a rating");
return;
}
const quote = currentQuote();
const quote = selectedQuote();
if (!quote) return;

hideModalAndClearChain("QuoteRate");
Expand Down Expand Up @@ -143,20 +143,20 @@ export function QuoteRateModal(): JSXElement {
<Separator />
<div class="grid gap-2">
<div class="text-xl text-text" dir="auto">
{currentQuote()?.text ?? "-"}
{selectedQuote()?.text ?? "-"}
</div>
<div class="grid grid-cols-[1fr_1fr_3fr] gap-2">
<div class="text-xs text-sub">
<div class="text-sub opacity-50">id</div>
{currentQuote()?.id ?? "-"}
{selectedQuote()?.id ?? "-"}
</div>
<div class="text-xs text-sub">
<div class="text-sub opacity-50">length</div>
{getLengthDesc()}
</div>
<div class="text-xs text-sub">
<div class="text-sub opacity-50">source</div>
{currentQuote()?.source ?? "-"}
{selectedQuote()?.source ?? "-"}
</div>
</div>
</div>
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/ts/components/modals/SaveCustomTextModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { createForm } from "@tanstack/solid-form";
import { Accessor, JSXElement } from "solid-js";
import { z } from "zod";

import * as CustomTextState from "../../legacy-states/custom-text-name";
import { setCustomTextIndicator } from "../../states/core";
import { hideModal } from "../../states/modals";
import {
showNoticeNotification,
Expand Down Expand Up @@ -42,7 +42,7 @@ export function SaveCustomTextModal(props: {

const saved = CustomText.setCustomText(value.name, text, value.isLong);
if (saved) {
CustomTextState.setCustomTextName(value.name, value.isLong);
setCustomTextIndicator(value);
showSuccessNotification("Custom text saved");
hideModal("SaveCustomText");
} else {
Expand Down
6 changes: 3 additions & 3 deletions frontend/src/ts/components/modals/SavedTextsModal.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { createSignal, For, Index, JSXElement, Setter, Show } from "solid-js";

import * as CustomTextState from "../../legacy-states/custom-text-name";
import { setCustomTextIndicator } from "../../states/core";
import { hideModal } from "../../states/modals";
import { showSimpleModal } from "../../states/simple-modal";
import * as CustomText from "../../test/custom-text";
Expand Down Expand Up @@ -40,7 +40,7 @@ export function SavedTextsModal(props: {
};

const handleNameClick = (name: string, long: boolean) => {
CustomTextState.setCustomTextName(name, long);
setCustomTextIndicator({ name, isLong: long });
const text = getSavedText(name, long);
props.setChainedData({ text, long });
hideModal("SavedTexts");
Expand All @@ -53,7 +53,7 @@ export function SavedTextsModal(props: {
buttonText: "delete",
execFn: async () => {
CustomText.deleteCustomText(name, long);
CustomTextState.setCustomTextName("", undefined);
setCustomTextIndicator(undefined);
refresh();
return {
status: "success",
Expand Down
8 changes: 5 additions & 3 deletions frontend/src/ts/components/modals/ShareTestSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import { JSXElement, Show } from "solid-js";

import { getConfig } from "../../config/store";
import { showSuccessNotification } from "../../states/notifications";
import { getCurrentQuote } from "../../states/test";
import * as CustomText from "../../test/custom-text";
import { currentQuote } from "../../test/test-words";
import { cn } from "../../utils/cn";
import { getMode2 } from "../../utils/misc";
import { capitalizeFirstLetter } from "../../utils/strings";
Expand Down Expand Up @@ -56,7 +56,7 @@ export function ShareTestSettings(): JSXElement {
{ enabled: values.mode, getValue: () => getConfig.mode },
{
enabled: values.mode2,
getValue: () => getMode2(getConfig, currentQuote),
getValue: () => getMode2(getConfig, getCurrentQuote()),
},
{ enabled: values.customText, getValue: () => CustomText.getData() },
{ enabled: values.punctuation, getValue: () => getConfig.punctuation },
Expand All @@ -81,7 +81,9 @@ export function ShareTestSettings(): JSXElement {
if (getConfig.mode === "quote") {
out += "Quote ID ";
}
out += capitalizeFirstLetter(getMode2(getConfig, currentQuote) || "none");
out += capitalizeFirstLetter(
getMode2(getConfig, getCurrentQuote()) || "none",
);

if (getConfig.mode === "time") {
out += " seconds";
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/ts/components/mount.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { ProfileSearchPage } from "./pages/profile/ProfileSearchPage";
import { Settings } from "./pages/settings/Settings";
import { TestConfig } from "./pages/test/TestConfig";
import { Popups } from "./popups/Popups";
import { TestModesNotice } from "./test/modes-notice/TestModesNotice";

const components: Record<string, () => JSXElement> = {
footer: () => <Footer />,
Expand All @@ -41,6 +42,7 @@ const components: Record<string, () => JSXElement> = {
testconfig: () => <TestConfig />,
commandlinehotkey: () => <CommandlineHotkey />,
solidSettings: () => <Settings />,
testmodesnotice: () => <TestModesNotice />,
};

function mountToMountpoint(name: string, component: () => JSXElement): void {
Expand Down
Loading
Loading