Skip to content

Commit 4605aeb

Browse files
Hello! Mom
1 parent aebebff commit 4605aeb

File tree

16 files changed

+161
-56
lines changed

16 files changed

+161
-56
lines changed

README.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
1-
# cybertype.app
1+
# Fast Type
22

33
A Fast and Minimal Typing App.
44

5-
Checkout [cybertype.app](https://cybertype.app/)
6-
75
Practice typing in various modes such as common 1k, 5k, 10k English Words, most commonly misspelled words, Quotes or Programming Language keywords for various languages such as JavaScript, HTML, CSS, Rust, Python, C++ etc with Sweet Mechanical Keyboard Sounds.
86

97
<br>

components/DynamicIsland.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,13 @@ export function DynamicIsland({ state, dispatch }: Props) {
5252
show={state.showThemes}
5353
handleClose={closeThemeSwitcher}
5454
ratio={0.2}
55-
render={close => <ThemeSwitcher handleClose={close} />}
55+
render={close => (
56+
<ThemeSwitcher
57+
selectedKeyboardScheme={state.keyboardScheme}
58+
handleClose={close}
59+
dispatch={dispatch}
60+
/>
61+
)}
5662
/>
5763

5864
<DynamicIslandExpander
@@ -135,4 +141,4 @@ function DynamicIslandExpander(props: {
135141
{props.render(handleClose)}
136142
</div>
137143
)
138-
}
144+
}

components/Keyboard.tsx

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,15 @@ import styles from '../styles/Keyboard.module.scss'
22
import { KeyStatRecord } from '../lib/types'
33
import { memo, useEffect, useRef } from 'react'
44
import { getSpeed } from '../lib/utils'
5+
import { schemes } from '../lib/schemes'
6+
import { State } from '../lib/types'
57

68
type KeyStatsProps = {
79
keyStats: KeyStatRecord
10+
keyboardScheme: State['keyboardScheme']
811
}
912

10-
const row1 = ['q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']']
11-
const row2 = ['a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', `'`]
12-
const row3 = ['z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/']
13-
14-
export function KeyStats({ keyStats }: KeyStatsProps) {
13+
export function KeyStats({ keyStats, keyboardScheme }: KeyStatsProps) {
1514
const mapper = (keys: string[]) =>
1615
keys.map(key => {
1716
return (
@@ -24,11 +23,12 @@ export function KeyStats({ keyStats }: KeyStatsProps) {
2423
)
2524
})
2625

26+
let currentScheme = schemes.find(scheme => scheme.id === keyboardScheme) || schemes[0]
2727
return (
2828
<div className={styles.keyboard}>
29-
<div className={styles.row}>{mapper(row1)}</div>
30-
<div className={styles.row}>{mapper(row2)}</div>
31-
<div className={styles.row}>{mapper(row3)}</div>
29+
<div className={styles.row}>{mapper(currentScheme.row1)}</div>
30+
<div className={styles.row}>{mapper(currentScheme.row2)}</div>
31+
<div className={styles.row}>{mapper(currentScheme.row3)}</div>
3232
</div>
3333
)
3434
}
@@ -79,4 +79,4 @@ export const getSpeedLabel = (speed: number) => {
7979
if (speed >= 100) return styles.fast
8080
if (speed < 60) return styles.slow
8181
return styles.normal
82-
}
82+
}

components/Nav.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ export const Nav = memo(function Nav() {
77
<nav className={styles.nav}>
88
<div className={styles.appName}>CyberType</div>
99
<a
10-
href="https://github.com/MananTank/cybertype"
10+
href="https://github.com/solomonshalom/FastType"
1111
target="_blank"
1212
rel="noreferrer"
1313
className={styles.github}
@@ -17,7 +17,7 @@ export const Nav = memo(function Nav() {
1717
</a>
1818

1919
<a
20-
href="https://twitter.com/MananTank_"
20+
href="https://twitter.com/shalomlijo"
2121
target="_blank"
2222
rel="noreferrer"
2323
className={styles.twitter}

components/ThemeSwitcher.tsx

Lines changed: 48 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,57 @@
11
import { themes, useThemeIndex } from '../hooks/useThemeIndex'
2+
import { Action } from '../lib/types'
23
import styles from '../styles/ThemeSwitcher.module.scss'
4+
import { schemes } from '../lib/schemes'
35

4-
export function ThemeSwitcher({ handleClose }: { handleClose: () => void }) {
6+
export type Props = {
7+
handleClose: () => void
8+
selectedKeyboardScheme: string
9+
dispatch: React.Dispatch<Action>
10+
}
11+
12+
export function ThemeSwitcher(props: Props) {
513
// eslint-disable-next-line @typescript-eslint/no-unused-vars
614
const [_themeIndex, setThemeIndex] = useThemeIndex()
715

816
return (
9-
<div className={styles.themeSwitcher}>
10-
{themes.map((theme, i) => {
11-
return (
12-
<div
13-
data-theme={i}
14-
key={i}
15-
onClick={() => {
16-
handleClose()
17-
setThemeIndex(i)
18-
}}
19-
className={styles.theme}
20-
>
21-
<h3> {theme.name}</h3>
22-
<div className={styles.palette}></div>
23-
</div>
24-
)
25-
})}
17+
<div>
18+
<h3 className={styles.title}>Colors</h3>
19+
<div className={styles.themeSwitcher}>
20+
{themes.map((theme, i) => {
21+
return (
22+
<div
23+
data-theme={i}
24+
key={i}
25+
onClick={() => {
26+
props.handleClose()
27+
setThemeIndex(i)
28+
}}
29+
className={styles.theme}
30+
>
31+
<h3> {theme.name}</h3>
32+
<div className={styles.palette}></div>
33+
</div>
34+
)
35+
})}
36+
</div>
37+
<h3 className={styles.title}>Keyboard</h3>
38+
<div className={styles.options}>
39+
{schemes.map(scheme => {
40+
return (
41+
<div
42+
key={scheme.id}
43+
className={styles.option}
44+
data-active={props.selectedKeyboardScheme === scheme.id}
45+
onClick={() => {
46+
props.dispatch({ type: 'setKeyboardScheme', data: scheme.id })
47+
props.handleClose()
48+
}}
49+
>
50+
<div className={styles.name}>{scheme.name}</div>
51+
</div>
52+
)
53+
})}
54+
</div>
2655
</div>
2756
)
28-
}
57+
}

lib/localStorage.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { useEffect } from 'react'
22
import { dataNameGroups } from '../components/DataSelector'
33
import { soundPacks } from './sounds'
4+
import { schemes } from './schemes'
45
import { State } from './types'
56

67
export function getLocalStorage(
@@ -34,10 +35,17 @@ export function setLocalStorage(key: string, value: string) {
3435

3536
const validSoundPackIds = new Set(soundPacks.map(pack => pack.id)) as Set<string>
3637

38+
const validKeyboardSchemesIds = new Set(schemes.map(scheme => scheme.id)) as Set<string>
39+
3740
export const soundPackValidator = (str: string) => {
3841
return validSoundPackIds.has(str)
3942
}
4043

44+
export const keyboardSchemeValidator = (str: string) => {
45+
console.log('valid ? ', validKeyboardSchemesIds.has(str))
46+
return validKeyboardSchemesIds.has(str)
47+
}
48+
4149
export const booleanValidator = (str: string) => {
4250
return str === 'false' || str === 'true'
4351
}
@@ -61,11 +69,15 @@ export function useLocalStorage(state: State) {
6169
setLocalStorage('dataName', state.dataName)
6270
}, [state.dataName])
6371

72+
useEffect(() => {
73+
setLocalStorage('keyboardScheme', state.keyboardScheme)
74+
}, [state.keyboardScheme])
75+
6476
useEffect(() => {
6577
setLocalStorage('soundEnabled', String(state.soundEnabled))
6678
}, [state.soundEnabled])
6779

6880
useEffect(() => {
6981
setLocalStorage('soundPack', state.soundPack)
7082
}, [state.soundPack])
71-
}
83+
}

lib/schemes.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
export const schemes = [
2+
{
3+
id: 'qwerty',
4+
name: 'Qwerty',
5+
row1: ['q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']'],
6+
row2: ['a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', `'`],
7+
row3: ['z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/']
8+
}, // 0 - qwerty
9+
{
10+
id: 'azerty',
11+
name: 'Azerty',
12+
row1: ['a', 'z', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']'],
13+
row2: ['q', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm'],
14+
row3: ['w', 'x', 'c', 'v', 'b', 'n', ',', ';', '.', '/']
15+
} // 1 - azerty
16+
]

lib/state.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ import {
44
getLocalStorage,
55
dataNameValidator,
66
booleanValidator,
7-
soundPackValidator
7+
soundPackValidator,
8+
keyboardSchemeValidator
89
} from './localStorage'
910
import { SoundPack } from './sounds'
1011
import { State, Action, QuoteData } from './types'
@@ -35,6 +36,11 @@ export function stateReducer(state: State, action: Action): void {
3536
return
3637
}
3738

39+
case 'setKeyboardScheme': {
40+
state.keyboardScheme = action.data
41+
return
42+
}
43+
3844
case 'setShowDataSelector': {
3945
state.showDataSelector = action.data
4046
return
@@ -241,6 +247,12 @@ export function getInitialState(): State {
241247
const soundEnabled =
242248
getLocalStorage('soundEnabled', 'true', booleanValidator) === 'false' ? false : true
243249

250+
const keyboardScheme = getLocalStorage(
251+
'keyboardScheme',
252+
'qwerty',
253+
keyboardSchemeValidator
254+
) as State['keyboardScheme']
255+
244256
const dataName = getLocalStorage(
245257
'dataName',
246258
'English 200',
@@ -249,6 +261,7 @@ export function getInitialState(): State {
249261

250262
return {
251263
soundPack,
264+
keyboardScheme,
252265
showDataSelector: false,
253266
showSoundSelector: false,
254267
showThemes: false,
@@ -283,4 +296,4 @@ export function useAppState() {
283296
)
284297
rendered.current = true
285298
return [state, dispatch] as const
286-
}
299+
}

lib/types.d.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ export type ErrorLocations = Record<number, Record<number, boolean>> // { 0: { 1
1616

1717
export type State = {
1818
soundPack: SoundPack
19+
keyboardScheme: string
1920
showSoundSelector: boolean
2021
showDataSelector: boolean
2122
showThemes: boolean
@@ -70,6 +71,10 @@ export type Action =
7071
type: 'setSoundPack'
7172
data: SoundPack
7273
}
74+
| {
75+
type: 'setKeyboardScheme'
76+
data: string
77+
}
7378

7479
export type QuoteData = {
7580
text: string
@@ -116,4 +121,4 @@ export type Theme = {
116121
normal: string
117122
slow: string
118123
slowest: string
119-
}
124+
}

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)