From 506e3fac61f9e8262111138fe0c21dc5681e4fe9 Mon Sep 17 00:00:00 2001 From: h16nning Date: Fri, 9 Feb 2024 23:31:53 +0100 Subject: [PATCH] Settings for scheduler, fixes - settings for requested retention rate and maxiumum intervall (globally), not deck specific at the moment - layout fixes for cloze card --- .firebase/hosting.YnVpbGQ.cache | 22 ++++----- src/components/settings/AboutSettingsView.tsx | 14 +++--- .../settings/GeneralSettingsView.tsx | 49 +++++++++---------- src/components/settings/LearnSettingsView.tsx | 27 ++++++++++ src/components/settings/SettingsInput.tsx | 17 ++++++- src/components/settings/SettingsView.tsx | 12 +++++ src/i18n/locales/de/translation.json | 3 ++ src/logic/CardScheduler.ts | 24 ++++++++- .../ClozeCard.module.css | 15 ++++-- .../CardTypeImplementations/ClozeCard.tsx | 13 ++--- src/logic/Settings.ts | 25 ++++++++-- src/logic/card.tsx | 1 - src/logic/learn.ts | 11 +++-- 13 files changed, 164 insertions(+), 69 deletions(-) create mode 100644 src/components/settings/LearnSettingsView.tsx diff --git a/.firebase/hosting.YnVpbGQ.cache b/.firebase/hosting.YnVpbGQ.cache index 4e1b83f..cd227b9 100644 --- a/.firebase/hosting.YnVpbGQ.cache +++ b/.firebase/hosting.YnVpbGQ.cache @@ -1,11 +1,11 @@ -badge.svg,1707482354411,4edd75f1d7084efc0ef8a502c6034d114374a681693b0c00b5b28b03fd157671 -robots.txt,1707482354412,391d14b3c2f8c9143a27a28c7399585142228d4d1bdbe2c87ac946de411fa9a2 -logo.svg,1707482354411,861ef96db8e9adace3f580944747289b6a5704bc798e917dc5449dd7a49dd560 -service-worker.js,1707482354413,fd9ec6132f3af5770dd0924ed3356930a669a9274fce81ec82baa79d58d99611 -manifest.json,1707482354412,55750b48311acbc8a8e79a712b06c86159fb6e31d8dedaf965408b92da601522 -index.html,1707482354728,b053fba058cc23a96f91b087458cdc69cd2247988f95948ab2b0962b55e94c9c -logo256.png,1707482354411,174027c4e97105e2e006e42620822304e0d3fdee4d390a423f15f0abc16ef781 -assets/web-vitals-BptxjviT.js,1707482354732,3ffd55f59352ddeafd5ff621f81d31444c53f3ae25242797564de702ed442492 -logo512.png,1707482354412,3db7a8824f96f862029199fbb398ab312bb4688d52b1a0ab0e2a311422a21ab3 -assets/index-FdHQsup1.css,1707482354732,ea2fbd45c0802d691061503ec41920c7be651f20dd417ca45701b74a62f9ce87 -assets/index-MEFcB1N5.js,1707482354732,aa981d9e3897e02ab17998c0ef3406b240d0226bc32bda4c776f84c66e1af504 +index.html,1707506186415,185d22983d01f190f88163132235032df27cdfd027ab43b9158c71405797c274 +badge.svg,1707506186007,4edd75f1d7084efc0ef8a502c6034d114374a681693b0c00b5b28b03fd157671 +manifest.json,1707506186009,55750b48311acbc8a8e79a712b06c86159fb6e31d8dedaf965408b92da601522 +service-worker.js,1707506186010,fd9ec6132f3af5770dd0924ed3356930a669a9274fce81ec82baa79d58d99611 +robots.txt,1707506186009,391d14b3c2f8c9143a27a28c7399585142228d4d1bdbe2c87ac946de411fa9a2 +logo.svg,1707506186007,861ef96db8e9adace3f580944747289b6a5704bc798e917dc5449dd7a49dd560 +logo256.png,1707506186008,174027c4e97105e2e006e42620822304e0d3fdee4d390a423f15f0abc16ef781 +assets/web-vitals-BptxjviT.js,1707506186415,3ffd55f59352ddeafd5ff621f81d31444c53f3ae25242797564de702ed442492 +logo512.png,1707506186008,3db7a8824f96f862029199fbb398ab312bb4688d52b1a0ab0e2a311422a21ab3 +assets/index-uqoGVHGe.css,1707506186415,e8d03bd716c716adad3b78b29b513b3f29ebbaa60ce1fd7a86fce8526aa9b384 +assets/index-j4mQTXfm.js,1707506186417,52576d3c9dceb5f8704a06e4a950cc851c77d37c6429d09fbe7ab4092ca7f27f diff --git a/src/components/settings/AboutSettingsView.tsx b/src/components/settings/AboutSettingsView.tsx index 914bdaa..966e071 100644 --- a/src/components/settings/AboutSettingsView.tsx +++ b/src/components/settings/AboutSettingsView.tsx @@ -4,13 +4,11 @@ import { t } from "i18next"; export default function AboutSettingsView() { return ( - <> - - {t("settings.about.description")} - - Link to Git Repository - - - + + {t("settings.about.description")} + + Link to Git Repository + + ); } diff --git a/src/components/settings/GeneralSettingsView.tsx b/src/components/settings/GeneralSettingsView.tsx index e6392e6..8c95695 100644 --- a/src/components/settings/GeneralSettingsView.tsx +++ b/src/components/settings/GeneralSettingsView.tsx @@ -1,33 +1,30 @@ -import React, { useState } from "react"; -import { Button, Card, Stack, Text, Title } from "@mantine/core"; -import SettingsInput from "./SettingsInput"; -import LanguageSelect from "./LanguageSelect"; +import { Stack } from "@mantine/core"; import { useTranslation } from "react-i18next"; +import LanguageSelect from "./LanguageSelect"; +import SettingsInput from "./SettingsInput"; export default function GeneralSettingsView() { const [t] = useTranslation(); return ( - <> - - - - - - - + + + + + + ); } diff --git a/src/components/settings/LearnSettingsView.tsx b/src/components/settings/LearnSettingsView.tsx new file mode 100644 index 0000000..ab9f069 --- /dev/null +++ b/src/components/settings/LearnSettingsView.tsx @@ -0,0 +1,27 @@ +import { Stack, Text } from "@mantine/core"; +import { useTranslation } from "react-i18next"; +import { useSetting } from "../../logic/Settings"; +import SettingsInput from "./SettingsInput"; + +export default function LearnSettingsView() { + const [t] = useTranslation(); + + const [w] = useSetting("globalScheduler_w"); + const [maximumInterval] = useSetting("globalScheduler_maximumInterval"); + const [requestRetention] = useSetting("globalScheduler_requestRetention"); + return ( + + + + {w.map((x) => x + ", ")} + + ); +} diff --git a/src/components/settings/SettingsInput.tsx b/src/components/settings/SettingsInput.tsx index 9d9be9f..dc5f318 100644 --- a/src/components/settings/SettingsInput.tsx +++ b/src/components/settings/SettingsInput.tsx @@ -1,4 +1,4 @@ -import { Checkbox, Group, Switch, TextInput } from "@mantine/core"; +import { Checkbox, Group, NumberInput, Switch, TextInput } from "@mantine/core"; import { useDebouncedValue } from "@mantine/hooks"; import React, { useEffect, useState } from "react"; import { SettingsValues, setSetting, useSetting } from "../../logic/Settings"; @@ -85,10 +85,23 @@ export default function SettingsInput({ setTouched(true); setValue(event.currentTarget.checked); }} - > + /> ); + case "number": + return ( + { + setTouched(true); + setValue(e); + }} + rightSection={} + /> + ); } return <>Input type not found; } diff --git a/src/components/settings/SettingsView.tsx b/src/components/settings/SettingsView.tsx index bc26f63..3096a43 100644 --- a/src/components/settings/SettingsView.tsx +++ b/src/components/settings/SettingsView.tsx @@ -2,6 +2,7 @@ import { ActionIcon, Group, Stack, Tabs } from "@mantine/core"; import React, { useEffect, useState } from "react"; import CColorSchemeToggle from "./ColorSchemeToggle"; import { + IconBolt, IconBraces, IconChevronLeft, IconDatabase, @@ -17,6 +18,7 @@ import { useLocation, useNavigate } from "react-router-dom"; import AboutSettingsView from "./AboutSettingsView"; import DatabaseSettingsView from "./DatabaseSettingsView/DatabaseSettingsView"; import { t } from "i18next"; +import LearnSettingsView from "./LearnSettingsView"; export default function SettingsView() { const [value, setValue] = useState("General"); @@ -68,6 +70,13 @@ export default function SettingsView() { > {t("settings.editing.title")} + } + onClick={() => setValue("learn")} + > + {t("settings.learn.title")} + } @@ -101,6 +110,9 @@ export default function SettingsView() { + + + diff --git a/src/i18n/locales/de/translation.json b/src/i18n/locales/de/translation.json index a7e3c18..6207e9a 100644 --- a/src/i18n/locales/de/translation.json +++ b/src/i18n/locales/de/translation.json @@ -35,6 +35,9 @@ "editing": { "title": "Bearbeitung" }, + "learn": { + "title": "Lernen" + }, "database": { "title": "Datenbank" }, diff --git a/src/logic/CardScheduler.ts b/src/logic/CardScheduler.ts index 068a845..f535751 100644 --- a/src/logic/CardScheduler.ts +++ b/src/logic/CardScheduler.ts @@ -1,3 +1,25 @@ import * as fsrsjs from "fsrs.js"; +import { setSetting, useSetting, useSettings } from "./Settings"; +import { useCallback, useEffect, useMemo, useState } from "react"; -export const scheduler = new fsrsjs.FSRS(); +const scheduler = new fsrsjs.FSRS(); + +export function useGlobalScheduler() { + const [maximumInterval] = useSetting("globalScheduler_maximumInterval"); + const [requestRetention] = useSetting("globalScheduler_requestRetention"); + const [w] = useSetting("globalScheduler_w"); + + useEffect(() => { + scheduler.p.maximum_interval = maximumInterval; + scheduler.p.request_retention = requestRetention; + scheduler.p.w = w; + }, [maximumInterval, requestRetention, w]); + console.log(scheduler); + return scheduler; +} + +export function updateGlobalScheduler() { + setSetting("globalScheduler_maximumInterval", scheduler.p.maximum_interval); + setSetting("globalScheduler_requestRetention", scheduler.p.request_retention); + setSetting("globalScheduler_w", scheduler.p.w); +} diff --git a/src/logic/CardTypeImplementations/ClozeCard.module.css b/src/logic/CardTypeImplementations/ClozeCard.module.css index c3fd1cf..54c54cf 100644 --- a/src/logic/CardTypeImplementations/ClozeCard.module.css +++ b/src/logic/CardTypeImplementations/ClozeCard.module.css @@ -1,10 +1,15 @@ .clozeCard :global(.cloze-field) { - display: inline-block; - width: 4rem; - height: calc(var(--mantine-line-height-sm) * var(--mantine-font-size-md)); - border-top-right-radius: var(--mantine-radius-sm); - border-top-left-radius: var(--mantine-radius-sm); + vertical-align:baseline; + padding: 0 0.25rem; + border-radius: var(--mantine-radius-sm); background-color: var(--mantine-primary-color-light); border-bottom: solid 2px var(--mantine-primary-color-filled); + :global(.cloze-content) { + } + + :global(.cloze-content.occluded) { + visibility: hidden; + } + } \ No newline at end of file diff --git a/src/logic/CardTypeImplementations/ClozeCard.tsx b/src/logic/CardTypeImplementations/ClozeCard.tsx index f3f480c..c6f864f 100644 --- a/src/logic/CardTypeImplementations/ClozeCard.tsx +++ b/src/logic/CardTypeImplementations/ClozeCard.tsx @@ -67,12 +67,13 @@ function ClozeCardComponent({ }: { occluded: boolean; card: Card }) { const sharedValue = useSharedValue(card.content.textReferenceId); let finalText = sharedValue?.value ?? ""; - if (occluded) { - finalText = finalText.replace( - new RegExp(`{{c${card.content.occlusionNumber}::((?!{{|}}).)*}}`, "g"), - `` - ); - } + finalText = finalText.replace( + new RegExp(`{{c${card.content.occlusionNumber}::((?!{{|}}).)*}}`, "g"), + (match) => + `${match}` + ); finalText = finalText.replace(/\{\{c\d::((?!\{\{|}}).)*\}\}/g, (match) => match.slice(6, -2) ); diff --git a/src/logic/Settings.ts b/src/logic/Settings.ts index b4ef836..2a15072 100644 --- a/src/logic/Settings.ts +++ b/src/logic/Settings.ts @@ -7,10 +7,13 @@ export type Settings = { }; export interface SettingsValues { - language: "en" | "de" | "es" | "sv"; - colorSchemePreference: "light" | "dark" | "auto"; name?: string; + language: "en" | "de" | "es" | "sv"; + useZenMode: boolean; developerMode: boolean; + + colorSchemePreference: "light" | "dark" | "auto"; + useBubbleMenu: boolean; useToolbar: boolean; showSubAndSuperScriptOptionInEditor: boolean; @@ -19,13 +22,19 @@ export interface SettingsValues { showListOptionInEditor: boolean; showCodeOptionInEditor: boolean; showLinkOptionInEditor: boolean; - useZenMode: boolean; + + globalScheduler_maximumInterval: number; + globalScheduler_requestRetention: number; + globalScheduler_w: number[]; } export const defaultSettings: SettingsValues = { language: "en", - colorSchemePreference: "auto", + useZenMode: false, developerMode: false, + + colorSchemePreference: "auto", + useBubbleMenu: true, useToolbar: false, showSubAndSuperScriptOptionInEditor: true, @@ -34,7 +43,13 @@ export const defaultSettings: SettingsValues = { showListOptionInEditor: true, showCodeOptionInEditor: true, showLinkOptionInEditor: true, - useZenMode: false, + + globalScheduler_maximumInterval: 36500, + globalScheduler_requestRetention: 0.9, + globalScheduler_w: [ + 0.4, 0.6, 2.4, 5.8, 4.93, 0.94, 0.86, 0.01, 1.49, 0.14, 0.94, 2.18, 0.05, + 0.34, 1.26, 0.29, 2.61, + ], }; export function useSetting( diff --git a/src/logic/card.tsx b/src/logic/card.tsx index f93ac99..eea3ca5 100644 --- a/src/logic/card.tsx +++ b/src/logic/card.tsx @@ -6,7 +6,6 @@ import { useLiveQuery } from "dexie-react-hooks"; import { useMemo } from "react"; import { Table } from "dexie"; import { Card as Model, ReviewLog, State } from "fsrs.js"; -import { scheduler } from "./CardScheduler"; export enum CardType { Normal = "normal", diff --git a/src/logic/learn.ts b/src/logic/learn.ts index e33aaa3..2f6065a 100644 --- a/src/logic/learn.ts +++ b/src/logic/learn.ts @@ -1,9 +1,9 @@ -import { Card, CardType, updateCardModel, useCardsWith } from "./card"; -import { useCallback, useEffect, useMemo, useState } from "react"; -import { Rating, State, SchedulingInfo } from "fsrs.js"; import { Table } from "dexie"; -import { scheduler } from "./CardScheduler"; +import { Rating, SchedulingInfo, State } from "fsrs.js"; +import { useCallback, useEffect, useMemo, useState } from "react"; +import { updateGlobalScheduler, useGlobalScheduler } from "./CardScheduler"; import { getUtils } from "./CardTypeManager"; +import { Card, CardType, updateCardModel, useCardsWith } from "./card"; export type LearnOptions = { learnAll: boolean; @@ -58,6 +58,8 @@ export function useLearning( cardQuerier.dependencies ); + const scheduler = useGlobalScheduler(); + //Time critical cards are cards that are due today / should be done within this learning session (5-10 min interval). timeCriticalCards should be sorted by due date const [timeCriticalCards, setTimeCriticalCards] = useState[]>( [] @@ -177,6 +179,7 @@ export function useLearning( //If there are no cards left finish the learning session } else { setIsFinished(true); + updateGlobalScheduler(); } }, [timeCriticalCards, newCards, toReviewCards, learnedCards, options]);