monkeytype/shared-types/types.d.ts

633 lines
15 KiB
TypeScript
Raw Normal View History

// Shared types between server/client.
declare namespace SharedTypes {
interface ValidModeRule {
language: string;
mode: string;
mode2: string;
}
interface RewardBracket {
minRank: number;
maxRank: number;
minReward: number;
maxReward: number;
}
interface Configuration {
maintenance: boolean;
dev: {
responseSlowdownMs: number;
};
quotes: {
reporting: {
enabled: boolean;
maxReports: number;
contentReportLimit: number;
};
submissionsEnabled: boolean;
maxFavorites: number;
};
results: {
savingEnabled: boolean;
objectHashCheckEnabled: boolean;
filterPresets: {
enabled: boolean;
maxPresetsPerUser: number;
};
limits: {
regularUser: number;
premiumUser: number;
};
maxBatchSize: number;
};
users: {
signUp: boolean;
lastHashesCheck: {
enabled: boolean;
maxHashes: number;
};
autoBan: {
enabled: boolean;
maxCount: number;
maxHours: number;
};
profiles: {
enabled: boolean;
};
discordIntegration: {
enabled: boolean;
};
xp: {
enabled: boolean;
funboxBonus: number;
gainMultiplier: number;
maxDailyBonus: number;
minDailyBonus: number;
streak: {
enabled: boolean;
maxStreakDays: number;
maxStreakMultiplier: number;
};
};
inbox: {
enabled: boolean;
maxMail: number;
};
premium: {
enabled: boolean;
};
};
admin: {
endpointsEnabled: boolean;
};
apeKeys: {
endpointsEnabled: boolean;
acceptKeys: boolean;
maxKeysPerUser: number;
apeKeyBytes: number;
apeKeySaltRounds: number;
};
rateLimiting: {
badAuthentication: {
enabled: boolean;
penalty: number;
flaggedStatusCodes: number[];
};
};
dailyLeaderboards: {
enabled: boolean;
leaderboardExpirationTimeInDays: number;
maxResults: number;
validModeRules: ValidModeRule[];
scheduleRewardsModeRules: ValidModeRule[];
topResultsToAnnounce: number;
xpRewardBrackets: RewardBracket[];
};
leaderboards: {
weeklyXp: {
enabled: boolean;
expirationTimeInDays: number;
xpRewardBrackets: RewardBracket[];
};
};
}
type StringNumber = `${number}`;
interface PersonalBest {
acc: number;
consistency?: number;
difficulty: SharedTypes.Config.Difficulty;
lazyMode?: boolean;
language: string;
punctuation?: boolean;
numbers?: boolean;
raw: number;
wpm: number;
timestamp: number;
}
interface PersonalBests {
time: Record<StringNumber, PersonalBest[]>;
words: Record<StringNumber, PersonalBest[]>;
quote: Record<StringNumber, PersonalBest[]>;
custom: Partial<Record<"custom", PersonalBest[]>>;
zen: Partial<Record<"zen", PersonalBest[]>>;
}
interface IncompleteTest {
acc: number;
seconds: number;
}
interface ChartData {
wpm: number[];
raw: number[];
err: number[];
}
interface KeyStats {
average: number;
sd: number;
}
interface Result<M extends SharedTypes.Config.Mode> {
_id: string;
wpm: number;
rawWpm: number;
2024-02-07 01:41:46 +08:00
charStats: [number, number, number, number];
acc: number;
mode: M;
mode2: SharedTypes.Config.Mode2<M>;
quoteLength?: number;
timestamp: number;
restartCount: number;
incompleteTestSeconds: number;
incompleteTests: IncompleteTest[];
testDuration: number;
afkDuration: number;
tags: string[];
consistency: number;
keyConsistency: number;
chartData: ChartData | "toolong";
uid: string;
keySpacingStats?: KeyStats;
keyDurationStats?: KeyStats;
isPb: boolean;
bailedOut: boolean;
blindMode: boolean;
lazyMode: boolean;
difficulty: SharedTypes.Config.Difficulty;
funbox: string;
language: string;
numbers: boolean;
punctuation: boolean;
}
type DBResult<T extends SharedTypes.Config.Mode> = Omit<
SharedTypes.Result<T>,
| "bailedOut"
| "blindMode"
| "lazyMode"
| "difficulty"
| "funbox"
| "language"
| "numbers"
| "punctuation"
| "restartCount"
| "incompleteTestSeconds"
| "afkDuration"
| "tags"
| "incompleteTests"
| "customText"
| "quoteLength"
| "isPb"
| "customText"
> & {
correctChars?: number; // --------------
incorrectChars?: number; // legacy results
// --------------
name: string;
// -------------- fields that might be removed to save space
bailedOut?: boolean;
blindMode?: boolean;
lazyMode?: boolean;
difficulty?: SharedTypes.Config.Difficulty;
funbox?: string;
language?: string;
numbers?: boolean;
punctuation?: boolean;
restartCount?: number;
incompleteTestSeconds?: number;
afkDuration?: number;
tags?: string[];
customText?: CustomTextDataWithTextLen;
quoteLength?: number;
isPb?: boolean;
};
interface CompletedEvent extends Result<SharedTypes.Config.Mode> {
keySpacing: number[] | "toolong";
keyDuration: number[] | "toolong";
customText?: CustomTextDataWithTextLen;
wpmConsistency: number;
challenge?: string | null;
keyOverlap: number;
lastKeyToEnd: number;
startToFirstKey: number;
charTotal: number;
stringified?: string;
hash?: string;
stopOnLetter: boolean;
}
type CustomTextMode = "repeat" | "random" | "shuffle";
type CustomTextLimitMode = "word" | "time" | "section";
type CustomTextLimit = {
value: number;
mode: CustomTextLimitMode;
};
type CustomTextData = {
text: string[];
mode: CustomTextMode;
limit: CustomTextLimit;
pipeDelimiter: boolean;
};
type CustomTextDataWithTextLen = Omit<CustomTextData, "text"> & {
textLen: number;
};
interface ResultFilters {
_id: string;
name: string;
pb: {
no: boolean;
yes: boolean;
};
difficulty: {
normal: boolean;
expert: boolean;
master: boolean;
};
mode: {
words: boolean;
time: boolean;
quote: boolean;
zen: boolean;
custom: boolean;
};
words: {
"10": boolean;
"25": boolean;
"50": boolean;
"100": boolean;
custom: boolean;
};
time: {
"15": boolean;
"30": boolean;
"60": boolean;
"120": boolean;
custom: boolean;
};
quoteLength: {
short: boolean;
medium: boolean;
long: boolean;
thicc: boolean;
};
punctuation: {
on: boolean;
off: boolean;
};
numbers: {
on: boolean;
off: boolean;
};
date: {
last_day: boolean;
last_week: boolean;
last_month: boolean;
last_3months: boolean;
all: boolean;
};
tags: Record<string, boolean>;
language: Record<string, boolean>;
funbox: {
none?: boolean;
} & Record<string, boolean>;
}
interface PSA {
_id: string;
message: string;
sticky?: boolean;
level?: number;
date?: number;
}
interface SpeedHistogram {
[key: string]: number;
}
interface PublicTypingStats {
type: string;
timeTyping: number;
testsCompleted: number;
testsStarted: number;
}
interface ApeKey {
name: string;
enabled: boolean;
createdOn: number;
modifiedOn: number;
lastUsedOn: number;
}
interface Config {
theme: string;
themeLight: string;
themeDark: string;
autoSwitchTheme: boolean;
customTheme: boolean;
customThemeColors: string[];
favThemes: string[];
showKeyTips: boolean;
smoothCaret: SharedTypes.Config.SmoothCaret;
quickRestart: SharedTypes.Config.QuickRestart;
punctuation: boolean;
numbers: boolean;
words: number;
time: number;
mode: SharedTypes.Config.Mode;
quoteLength: SharedTypes.Config.QuoteLength[];
language: string;
fontSize: number;
freedomMode: boolean;
difficulty: SharedTypes.Config.Difficulty;
blindMode: boolean;
quickEnd: boolean;
caretStyle: SharedTypes.Config.CaretStyle;
paceCaretStyle: SharedTypes.Config.CaretStyle;
flipTestColors: boolean;
layout: string;
funbox: string;
confidenceMode: SharedTypes.Config.ConfidenceMode;
indicateTypos: SharedTypes.Config.IndicateTypos;
timerStyle: SharedTypes.Config.TimerStyle;
2024-05-02 23:33:17 +08:00
liveSpeedStyle: SharedTypes.Config.LiveSpeedAccBurstStyle;
liveAccStyle: SharedTypes.Config.LiveSpeedAccBurstStyle;
liveBurstStyle: SharedTypes.Config.LiveSpeedAccBurstStyle;
colorfulMode: boolean;
randomTheme: SharedTypes.Config.RandomTheme;
timerColor: SharedTypes.Config.TimerColor;
timerOpacity: SharedTypes.Config.TimerOpacity;
stopOnError: SharedTypes.Config.StopOnError;
showAllLines: boolean;
keymapMode: SharedTypes.Config.KeymapMode;
keymapStyle: SharedTypes.Config.KeymapStyle;
keymapLegendStyle: SharedTypes.Config.KeymapLegendStyle;
keymapLayout: string;
keymapShowTopRow: SharedTypes.Config.KeymapShowTopRow;
fontFamily: string;
smoothLineScroll: boolean;
alwaysShowDecimalPlaces: boolean;
alwaysShowWordsHistory: boolean;
singleListCommandLine: SharedTypes.Config.SingleListCommandLine;
capsLockWarning: boolean;
playSoundOnError: SharedTypes.Config.PlaySoundOnError;
playSoundOnClick: SharedTypes.Config.PlaySoundOnClick;
soundVolume: SharedTypes.Config.SoundVolume;
startGraphsAtZero: boolean;
showOutOfFocusWarning: boolean;
paceCaret: SharedTypes.Config.PaceCaret;
paceCaretCustomSpeed: number;
repeatedPace: boolean;
accountChart: SharedTypes.Config.AccountChart;
minWpm: SharedTypes.Config.MinimumWordsPerMinute;
minWpmCustomSpeed: number;
highlightMode: SharedTypes.Config.HighlightMode;
typingSpeedUnit: SharedTypes.Config.TypingSpeedUnit;
ads: SharedTypes.Config.Ads;
hideExtraLetters: boolean;
strictSpace: boolean;
minAcc: SharedTypes.Config.MinimumAccuracy;
minAccCustom: number;
monkey: boolean;
repeatQuotes: SharedTypes.Config.RepeatQuotes;
oppositeShiftMode: SharedTypes.Config.OppositeShiftMode;
customBackground: string;
customBackgroundSize: SharedTypes.Config.CustomBackgroundSize;
customBackgroundFilter: SharedTypes.Config.CustomBackgroundFilter;
customLayoutfluid: SharedTypes.Config.CustomLayoutFluid;
monkeyPowerLevel: SharedTypes.Config.MonkeyPowerLevel;
minBurst: SharedTypes.Config.MinimumBurst;
minBurstCustomSpeed: number;
burstHeatmap: boolean;
britishEnglish: boolean;
lazyMode: boolean;
showAverage: SharedTypes.Config.ShowAverage;
tapeMode: SharedTypes.Config.TapeMode;
maxLineWidth: number;
}
type ConfigValue = Config[keyof Config];
type ConfigPreset = Partial<Config> & {
tags?: string[];
};
interface DBConfigPreset {
_id: string;
uid: string;
name: string;
config: SharedTypes.ConfigPreset;
}
interface LeaderboardEntry {
_id: string;
wpm: number;
acc: number;
timestamp: number;
raw: number;
consistency?: number;
uid: string;
name: string;
discordId?: string;
discordAvatar?: string;
rank: number;
badgeId?: number;
isPremium?: boolean;
}
type PostResultResponse = {
isPb: boolean;
tagPbs: string[];
insertedId: string;
dailyLeaderboardRank?: number;
weeklyXpLeaderboardRank?: number;
xp: number;
dailyXpBonus: boolean;
xpBreakdown: Record<string, number>;
streak: number;
};
refactor: shared user types (#5080) * move user to shared definitions this includes whatever user can have on it, tags, presets and so on * profiles, mail and others * fix logic * yeet * same as master for now * tsc fixes * remove comment * fix tests * chore: omit ips * fix(language): remove some unnecessarily capitalised words in german 1k * fix(typing): first space sometimes soft locking the website * perf: speed up settings page loading * fix: use selected typing speed unit on personal best popup (fehmer) (#5070) * fix: Use selected typing speed unit on personal best popup * refactor * refactor * test coverage * use Format in more places * Make config mockable * dependency injection * wip * fix * test * touch * fix(language): typos in russian_10k.json (kae) (#5082) * Update russian_10k.json - fixed typos - removed duplicates * - fixed extra typos * remove duplicates * fix(language): typos in russian_10k.json * feat: add copy missed words to result screen (fehmer) (#5086) * feat: Add copy missed words to result screen * remove margin * update icons --------- Co-authored-by: Miodec <jack@monkeytype.com> * impr(funbox): add 46 group languages to wikipedia funbox (RealCyGuy) (#5078) * impr: provide all-time LB results during LB update (fehmer) (#5074) Try to provide LB results during the LB update. There is a very small time-frame where already running queries might fail during the update. For now we keep the 503 error in this cases and monitor how often this happens on production. * impr(funbox): add ` (grave accent, 96) and ~ (tilde, 126) to specials (#5073) * impr: add testWords and wordsHistory to copy result stats (#5085) * feat: add testWords and wordsHistory to copy result stats * fix * add fe ts dep --------- Co-authored-by: Christian Fehmer <fehmer@users.noreply.github.com> Co-authored-by: Andrey Kuznetsov <akuznetsov@outlook.com> Co-authored-by: Cyrus Yip <cyruscmyip1@gmail.com> Co-authored-by: fitzsim <fitzsim@fitzsim.org>
2024-02-20 00:15:15 +08:00
type UserStreak = {
lastResultTimestamp: number;
length: number;
maxLength: number;
hourOffset?: number;
};
type UserTag = {
_id: string;
name: string;
personalBests: PersonalBests;
};
type UserProfileDetails = {
bio?: string;
keyboard?: string;
socialProfiles: {
twitter?: string;
github?: string;
website?: string;
};
};
type CustomTheme = {
_id: string;
name: string;
colors: string[];
};
type PremiumInfo = {
startTimestamp: number;
expirationTimestamp: number;
};
type UserQuoteRatings = Record<string, Record<string, number>>;
type UserLbMemory = Record<string, Record<string, Record<string, number>>>;
type UserInventory = {
badges: Badge[];
};
type Badge = {
id: number;
selected?: boolean;
};
type User = {
name: string;
email: string;
uid: string;
addedAt: number;
personalBests: PersonalBests;
lastReultHashes?: string[]; //todo: fix typo (its in the db too)
completedTests?: number;
startedTests?: number;
timeTyping?: number;
streak?: UserStreak;
xp?: number;
discordId?: string;
discordAvatar?: string;
tags?: UserTag[];
profileDetails?: UserProfileDetails;
customThemes?: CustomTheme[];
premium?: PremiumInfo;
isPremium?: boolean;
refactor: shared user types (#5080) * move user to shared definitions this includes whatever user can have on it, tags, presets and so on * profiles, mail and others * fix logic * yeet * same as master for now * tsc fixes * remove comment * fix tests * chore: omit ips * fix(language): remove some unnecessarily capitalised words in german 1k * fix(typing): first space sometimes soft locking the website * perf: speed up settings page loading * fix: use selected typing speed unit on personal best popup (fehmer) (#5070) * fix: Use selected typing speed unit on personal best popup * refactor * refactor * test coverage * use Format in more places * Make config mockable * dependency injection * wip * fix * test * touch * fix(language): typos in russian_10k.json (kae) (#5082) * Update russian_10k.json - fixed typos - removed duplicates * - fixed extra typos * remove duplicates * fix(language): typos in russian_10k.json * feat: add copy missed words to result screen (fehmer) (#5086) * feat: Add copy missed words to result screen * remove margin * update icons --------- Co-authored-by: Miodec <jack@monkeytype.com> * impr(funbox): add 46 group languages to wikipedia funbox (RealCyGuy) (#5078) * impr: provide all-time LB results during LB update (fehmer) (#5074) Try to provide LB results during the LB update. There is a very small time-frame where already running queries might fail during the update. For now we keep the 503 error in this cases and monitor how often this happens on production. * impr(funbox): add ` (grave accent, 96) and ~ (tilde, 126) to specials (#5073) * impr: add testWords and wordsHistory to copy result stats (#5085) * feat: add testWords and wordsHistory to copy result stats * fix * add fe ts dep --------- Co-authored-by: Christian Fehmer <fehmer@users.noreply.github.com> Co-authored-by: Andrey Kuznetsov <akuznetsov@outlook.com> Co-authored-by: Cyrus Yip <cyruscmyip1@gmail.com> Co-authored-by: fitzsim <fitzsim@fitzsim.org>
2024-02-20 00:15:15 +08:00
quoteRatings?: UserQuoteRatings;
favoriteQuotes?: Record<string, string[]>;
lbMemory?: UserLbMemory;
allTimeLbs: AllTimeLbs;
refactor: shared user types (#5080) * move user to shared definitions this includes whatever user can have on it, tags, presets and so on * profiles, mail and others * fix logic * yeet * same as master for now * tsc fixes * remove comment * fix tests * chore: omit ips * fix(language): remove some unnecessarily capitalised words in german 1k * fix(typing): first space sometimes soft locking the website * perf: speed up settings page loading * fix: use selected typing speed unit on personal best popup (fehmer) (#5070) * fix: Use selected typing speed unit on personal best popup * refactor * refactor * test coverage * use Format in more places * Make config mockable * dependency injection * wip * fix * test * touch * fix(language): typos in russian_10k.json (kae) (#5082) * Update russian_10k.json - fixed typos - removed duplicates * - fixed extra typos * remove duplicates * fix(language): typos in russian_10k.json * feat: add copy missed words to result screen (fehmer) (#5086) * feat: Add copy missed words to result screen * remove margin * update icons --------- Co-authored-by: Miodec <jack@monkeytype.com> * impr(funbox): add 46 group languages to wikipedia funbox (RealCyGuy) (#5078) * impr: provide all-time LB results during LB update (fehmer) (#5074) Try to provide LB results during the LB update. There is a very small time-frame where already running queries might fail during the update. For now we keep the 503 error in this cases and monitor how often this happens on production. * impr(funbox): add ` (grave accent, 96) and ~ (tilde, 126) to specials (#5073) * impr: add testWords and wordsHistory to copy result stats (#5085) * feat: add testWords and wordsHistory to copy result stats * fix * add fe ts dep --------- Co-authored-by: Christian Fehmer <fehmer@users.noreply.github.com> Co-authored-by: Andrey Kuznetsov <akuznetsov@outlook.com> Co-authored-by: Cyrus Yip <cyruscmyip1@gmail.com> Co-authored-by: fitzsim <fitzsim@fitzsim.org>
2024-02-20 00:15:15 +08:00
inventory?: UserInventory;
banned?: boolean;
lbOptOut?: boolean;
verified?: boolean;
needsToChangeName?: boolean;
quoteMod?: boolean | string;
resultFilterPresets?: ResultFilters[];
feat(account page): add test activity graph (fehmer, Singh233) (#5309) * wip * wip frontend * cleanup * wip * refactoring * wip * first working version * wip * update calendar with new result * add migration script * dates are hard * fix naming inconsistencies * requested changes on migration * timezones * update date-fns, use date-fns/utc * resolve cyclic dependency by extracting test activity calender into new file * cleanup * fix increment * fix * tests * test coverage * test migration * migration more logging * migration add unique index on uid if missing * update legend styling * 53 columns * wip * move dropdown and legend to the top add dropdown border yeet hotpink invisible filler boxes remove year from month format * responsive update * lowercase months * handle current year, fix tests * handle year change * make days square again * handle newly created users correctly * move css * add wrapper for easier styling rework some font sizes/widths reorder styles * media queries * align * rework styling once more * dont commit debug * add days full to fill the space a bit * show partial months * hover on 0 tests * start dynamic calendar on sunday * no activity * hover * remove label on fillers * remove label on fillers * fix months, update tests for months * adjust tests to new requirements * cleanup * fix migration * impr(commandline): add "add/remove quote to favorites" commands closes #5368 * chore: remove daily lb which is no longer in the backend * fix: dropdown element flashing for couple frames on page load * feat(language): add japanese romaji 1k (nthngnssmnnglss) * fix: optional chaining !nuf * fix(words generator): infinite custom text tests not working correctly * chore: missing languages in list and group files * fix(language): remove duplicates !nuf * add readline sync to confirm * gh action complaints * unnecessary check * premium only * add years to drop down only if premium * Update setup-tests.ts * test fix * cleanup --------- Co-authored-by: Miodec <jack@monkeytype.com>
2024-05-15 21:23:36 +08:00
testActivity?: TestActivity;
refactor: shared user types (#5080) * move user to shared definitions this includes whatever user can have on it, tags, presets and so on * profiles, mail and others * fix logic * yeet * same as master for now * tsc fixes * remove comment * fix tests * chore: omit ips * fix(language): remove some unnecessarily capitalised words in german 1k * fix(typing): first space sometimes soft locking the website * perf: speed up settings page loading * fix: use selected typing speed unit on personal best popup (fehmer) (#5070) * fix: Use selected typing speed unit on personal best popup * refactor * refactor * test coverage * use Format in more places * Make config mockable * dependency injection * wip * fix * test * touch * fix(language): typos in russian_10k.json (kae) (#5082) * Update russian_10k.json - fixed typos - removed duplicates * - fixed extra typos * remove duplicates * fix(language): typos in russian_10k.json * feat: add copy missed words to result screen (fehmer) (#5086) * feat: Add copy missed words to result screen * remove margin * update icons --------- Co-authored-by: Miodec <jack@monkeytype.com> * impr(funbox): add 46 group languages to wikipedia funbox (RealCyGuy) (#5078) * impr: provide all-time LB results during LB update (fehmer) (#5074) Try to provide LB results during the LB update. There is a very small time-frame where already running queries might fail during the update. For now we keep the 503 error in this cases and monitor how often this happens on production. * impr(funbox): add ` (grave accent, 96) and ~ (tilde, 126) to specials (#5073) * impr: add testWords and wordsHistory to copy result stats (#5085) * feat: add testWords and wordsHistory to copy result stats * fix * add fe ts dep --------- Co-authored-by: Christian Fehmer <fehmer@users.noreply.github.com> Co-authored-by: Andrey Kuznetsov <akuznetsov@outlook.com> Co-authored-by: Cyrus Yip <cyruscmyip1@gmail.com> Co-authored-by: fitzsim <fitzsim@fitzsim.org>
2024-02-20 00:15:15 +08:00
};
type Reward<T> = {
type: string;
item: T;
};
type XpReward = {
type: "xp";
item: number;
} & Reward<number>;
type BadgeReward = {
type: "badge";
item: SharedTypes.Badge;
} & Reward<SharedTypes.Badge>;
type AllRewards = XpReward | BadgeReward;
type MonkeyMail = {
id: string;
subject: string;
body: string;
timestamp: number;
read: boolean;
rewards: AllRewards[];
};
type UserProfile = Pick<
User,
| "name"
| "banned"
| "addedAt"
| "discordId"
| "discordAvatar"
| "xp"
| "lbOptOut"
| "inventory"
| "uid"
| "isPremium"
| "allTimeLbs"
refactor: shared user types (#5080) * move user to shared definitions this includes whatever user can have on it, tags, presets and so on * profiles, mail and others * fix logic * yeet * same as master for now * tsc fixes * remove comment * fix tests * chore: omit ips * fix(language): remove some unnecessarily capitalised words in german 1k * fix(typing): first space sometimes soft locking the website * perf: speed up settings page loading * fix: use selected typing speed unit on personal best popup (fehmer) (#5070) * fix: Use selected typing speed unit on personal best popup * refactor * refactor * test coverage * use Format in more places * Make config mockable * dependency injection * wip * fix * test * touch * fix(language): typos in russian_10k.json (kae) (#5082) * Update russian_10k.json - fixed typos - removed duplicates * - fixed extra typos * remove duplicates * fix(language): typos in russian_10k.json * feat: add copy missed words to result screen (fehmer) (#5086) * feat: Add copy missed words to result screen * remove margin * update icons --------- Co-authored-by: Miodec <jack@monkeytype.com> * impr(funbox): add 46 group languages to wikipedia funbox (RealCyGuy) (#5078) * impr: provide all-time LB results during LB update (fehmer) (#5074) Try to provide LB results during the LB update. There is a very small time-frame where already running queries might fail during the update. For now we keep the 503 error in this cases and monitor how often this happens on production. * impr(funbox): add ` (grave accent, 96) and ~ (tilde, 126) to specials (#5073) * impr: add testWords and wordsHistory to copy result stats (#5085) * feat: add testWords and wordsHistory to copy result stats * fix * add fe ts dep --------- Co-authored-by: Christian Fehmer <fehmer@users.noreply.github.com> Co-authored-by: Andrey Kuznetsov <akuznetsov@outlook.com> Co-authored-by: Cyrus Yip <cyruscmyip1@gmail.com> Co-authored-by: fitzsim <fitzsim@fitzsim.org>
2024-02-20 00:15:15 +08:00
> & {
typingStats: {
completedTests: User["completedTests"];
startedTests: User["startedTests"];
timeTyping: User["timeTyping"];
};
streak: UserStreak["length"];
maxStreak: UserStreak["maxLength"];
details: UserProfileDetails;
personalBests: {
time: Pick<
Record<`${number}`, SharedTypes.PersonalBest[]>,
"15" | "30" | "60" | "120"
>;
words: Pick<
Record<`${number}`, SharedTypes.PersonalBest[]>,
"10" | "25" | "50" | "100"
>;
};
};
type AllTimeLbs = {
time: Record<string, Record<string, RankAndCount | undefined>>;
};
type RankAndCount = {
rank?: number;
count: number;
};
feat(account page): add test activity graph (fehmer, Singh233) (#5309) * wip * wip frontend * cleanup * wip * refactoring * wip * first working version * wip * update calendar with new result * add migration script * dates are hard * fix naming inconsistencies * requested changes on migration * timezones * update date-fns, use date-fns/utc * resolve cyclic dependency by extracting test activity calender into new file * cleanup * fix increment * fix * tests * test coverage * test migration * migration more logging * migration add unique index on uid if missing * update legend styling * 53 columns * wip * move dropdown and legend to the top add dropdown border yeet hotpink invisible filler boxes remove year from month format * responsive update * lowercase months * handle current year, fix tests * handle year change * make days square again * handle newly created users correctly * move css * add wrapper for easier styling rework some font sizes/widths reorder styles * media queries * align * rework styling once more * dont commit debug * add days full to fill the space a bit * show partial months * hover on 0 tests * start dynamic calendar on sunday * no activity * hover * remove label on fillers * remove label on fillers * fix months, update tests for months * adjust tests to new requirements * cleanup * fix migration * impr(commandline): add "add/remove quote to favorites" commands closes #5368 * chore: remove daily lb which is no longer in the backend * fix: dropdown element flashing for couple frames on page load * feat(language): add japanese romaji 1k (nthngnssmnnglss) * fix: optional chaining !nuf * fix(words generator): infinite custom text tests not working correctly * chore: missing languages in list and group files * fix(language): remove duplicates !nuf * add readline sync to confirm * gh action complaints * unnecessary check * premium only * add years to drop down only if premium * Update setup-tests.ts * test fix * cleanup --------- Co-authored-by: Miodec <jack@monkeytype.com>
2024-05-15 21:23:36 +08:00
type TestActivity = {
testsByDays: (number | null)[];
lastDay: number;
};
type CountByYearAndDay = { [key: string]: (number | null)[] };
}