Skip to content

Commit 19cfaaa

Browse files
committed
feat: point at a key that must be pressed next
1 parent 5913c1a commit 19cfaaa

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+571
-59
lines changed

package-lock.json

+6-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/keybr-intl/lib/messages/cs.json

+1-1
Large diffs are not rendered by default.

packages/keybr-intl/lib/messages/da.json

+1-1
Large diffs are not rendered by default.

packages/keybr-intl/lib/messages/de.json

+1-1
Large diffs are not rendered by default.

packages/keybr-intl/lib/messages/el.json

+1-1
Large diffs are not rendered by default.

packages/keybr-intl/lib/messages/en.json

+1-1
Large diffs are not rendered by default.

packages/keybr-intl/lib/messages/es.json

+1-1
Large diffs are not rendered by default.

packages/keybr-intl/lib/messages/et.json

+1-1
Large diffs are not rendered by default.

packages/keybr-intl/lib/messages/fa.json

+1-1
Large diffs are not rendered by default.

packages/keybr-intl/lib/messages/fr.json

+1-1
Large diffs are not rendered by default.

packages/keybr-intl/lib/messages/he.json

+1-1
Large diffs are not rendered by default.

packages/keybr-intl/lib/messages/hu.json

+1-1
Large diffs are not rendered by default.

packages/keybr-intl/lib/messages/it.json

+1-1
Large diffs are not rendered by default.

packages/keybr-intl/lib/messages/ja.json

+1-1
Large diffs are not rendered by default.

packages/keybr-intl/lib/messages/ne.json

+1-1
Large diffs are not rendered by default.

packages/keybr-intl/lib/messages/nl.json

+1-1
Large diffs are not rendered by default.

packages/keybr-intl/lib/messages/pl.json

+1-1
Large diffs are not rendered by default.

packages/keybr-intl/lib/messages/pt-br.json

+1-1
Large diffs are not rendered by default.

packages/keybr-intl/lib/messages/ru.json

+1-1
Large diffs are not rendered by default.

packages/keybr-intl/lib/messages/sv.json

+1-1
Large diffs are not rendered by default.

packages/keybr-intl/lib/messages/tr.json

+1-1
Large diffs are not rendered by default.

packages/keybr-intl/lib/messages/uk.json

+1-1
Large diffs are not rendered by default.

packages/keybr-intl/lib/messages/zh-hans.json

+1-1
Large diffs are not rendered by default.

packages/keybr-intl/translations/en.json

+3
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,10 @@
353353
"settings.forgiveErrors.description": "If enabled, the text input field will forgive some kinds of errors by automatically fixing them. These are errors such as typing a wrong character or skipping a character.",
354354
"settings.forgiveErrors.label": "Forgive errors",
355355
"settings.interfaceOptions.legend": "Interface Options",
356+
"settings.keyboardColors.description": "Show color coding of the keyboard zones. Use this option to learn which finger to use to press a key.",
356357
"settings.keyboardColors.label": "Colored keys",
358+
"settings.keyboardPointers.description": "Highlight a key that must to be pressed next. Use this option to quickly find the position of a key if you don't know the keyboard layout well.",
359+
"settings.keyboardPointers.label": "Highlight keys",
357360
"settings.lessonLength.description": "Adjust the number of words in the lesson text. Making lessons longer can improve your learning.",
358361
"settings.lessonLength.label": "Add words to lessons:",
359362
"settings.lessonOptions.legend": "Lesson Options",

packages/keybr-intl/translations/pl.json

+2
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,9 @@
350350
"settings.forgiveErrors.description": "Włączenie tej opcji sprawi, że pole wprowadzania tekstu będzie wybaczać niektóre rodzaje błędów, automatycznie je poprawiając. Są to takie błędy, jak wpisanie nieprawidłowego znaku lub pominięcie znaku.",
351351
"settings.forgiveErrors.label": "Nie uwzględniaj błędów",
352352
"settings.interfaceOptions.legend": "Opcje interfejsu",
353+
"settings.keyboardColors.description": "Wyświetlić kodowanie kolorami stref klawiatury. Użyj tej opcji, aby dowiedzieć się, którym palcem należy nacisnąć klawisz.",
353354
"settings.keyboardColors.label": "Kolorowe klawisze",
355+
"settings.keyboardPointers.description": "Podświetlić klawisz, który należy następnie nacisnąć. Użyj tej opcji, aby szybko znaleźć pozycję klawisza, jeśli nie znasz dobrze układu klawiatury.",
354356
"settings.lessonLength.description": "Dostosuj liczbę słów w tekście lekcji. Dłuższe lekcje mogą poprawić Twoją naukę.",
355357
"settings.lessonLength.label": "Dodaj słowa do lekcji:",
356358
"settings.lessonOptions.legend": "Opcje lekcji",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
.pointer {
2+
fill: transparent;
3+
stroke: var(--KeyboardKey-pointer__color);
4+
stroke-opacity: 0.5;
5+
stroke-width: 5px;
6+
}
7+
8+
.modifierPointer {
9+
fill: transparent;
10+
stroke: var(--KeyboardKey-pointer__color);
11+
stroke-opacity: 0.5;
12+
stroke-width: 3px;
13+
stroke-dasharray: 3px;
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export const pointer: string;
2+
export const modifierPointer: string;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import { KeyboardContext, Layout, loadKeyboard } from "@keybr/keyboard";
2+
import { fake } from "@keybr/test-env-time";
3+
import test from "ava";
4+
import TestRenderer from "react-test-renderer";
5+
import { PointersLayer } from "./PointersLayer.tsx";
6+
7+
test.beforeEach(() => {
8+
fake.timers.set();
9+
});
10+
11+
test.afterEach(() => {
12+
fake.timers.reset();
13+
});
14+
15+
test.serial("empty", async (t) => {
16+
const keyboard = loadKeyboard(Layout.EN_US);
17+
18+
const renderer = TestRenderer.create(
19+
<KeyboardContext.Provider value={keyboard}>
20+
<PointersLayer suffix={[]} />
21+
</KeyboardContext.Provider>,
22+
);
23+
24+
await TestRenderer.act(() => {});
25+
await fake.timers.run();
26+
27+
t.is(renderer.root.findAllByType("circle").length, 0);
28+
29+
t.snapshot(renderer.toJSON());
30+
});
31+
32+
test.serial("unknown", async (t) => {
33+
const keyboard = loadKeyboard(Layout.EN_US);
34+
35+
const renderer = TestRenderer.create(
36+
<KeyboardContext.Provider value={keyboard}>
37+
<PointersLayer suffix={[0x0000]} />
38+
</KeyboardContext.Provider>,
39+
);
40+
41+
await TestRenderer.act(() => {});
42+
await fake.timers.run();
43+
44+
t.is(renderer.root.findAllByType("circle").length, 0);
45+
46+
t.snapshot(renderer.toJSON());
47+
});
48+
49+
test.serial("without modifiers", async (t) => {
50+
const keyboard = loadKeyboard(Layout.EN_US);
51+
52+
const renderer = TestRenderer.create(
53+
<KeyboardContext.Provider value={keyboard}>
54+
<PointersLayer suffix={[/* "a" */ 0x0061]} />
55+
</KeyboardContext.Provider>,
56+
);
57+
58+
await TestRenderer.act(() => {});
59+
await fake.timers.run();
60+
61+
t.is(renderer.root.findAllByType("circle").length, 1);
62+
63+
t.snapshot(renderer.toJSON());
64+
});
65+
66+
test.serial("with modifiers", async (t) => {
67+
const keyboard = loadKeyboard(Layout.EN_US);
68+
69+
const renderer = TestRenderer.create(
70+
<KeyboardContext.Provider value={keyboard}>
71+
<PointersLayer suffix={[/* "A" */ 0x0041]} />
72+
</KeyboardContext.Provider>,
73+
);
74+
75+
await TestRenderer.act(() => {});
76+
await fake.timers.run();
77+
78+
t.is(renderer.root.findAllByType("circle").length, 3);
79+
80+
t.snapshot(renderer.toJSON());
81+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
# Snapshot report for `lib/PointersLayer.test.tsx`
2+
3+
The actual snapshot is saved in `PointersLayer.test.tsx.snap`.
4+
5+
Generated by [AVA](https://avajs.dev).
6+
7+
## empty
8+
9+
> Snapshot 1
10+
11+
{
12+
children: null,
13+
props: {
14+
x: 15,
15+
y: 15,
16+
},
17+
type: 'svg',
18+
}
19+
20+
## unknown
21+
22+
> Snapshot 1
23+
24+
{
25+
children: null,
26+
props: {
27+
x: 15,
28+
y: 15,
29+
},
30+
type: 'svg',
31+
}
32+
33+
## without modifiers
34+
35+
> Snapshot 1
36+
37+
{
38+
children: [
39+
{
40+
children: [
41+
{
42+
children: null,
43+
props: {
44+
attributeName: 'opacity',
45+
dur: '0.5s',
46+
from: 0,
47+
repeatCount: '1',
48+
restart: 'always',
49+
to: 1,
50+
},
51+
type: 'animate',
52+
},
53+
{
54+
children: null,
55+
props: {
56+
attributeName: 'r',
57+
dur: '0.5s',
58+
from: 0,
59+
repeatCount: '1',
60+
restart: 'always',
61+
to: 30,
62+
},
63+
type: 'animate',
64+
},
65+
],
66+
props: {
67+
className: 'pointer',
68+
cx: 90,
69+
cy: 100,
70+
r: 30,
71+
},
72+
type: 'circle',
73+
},
74+
],
75+
props: {
76+
x: 15,
77+
y: 15,
78+
},
79+
type: 'svg',
80+
}
81+
82+
## with modifiers
83+
84+
> Snapshot 1
85+
86+
{
87+
children: [
88+
{
89+
children: [
90+
{
91+
children: null,
92+
props: {
93+
attributeName: 'opacity',
94+
dur: '0.5s',
95+
from: 0,
96+
repeatCount: '1',
97+
restart: 'always',
98+
to: 1,
99+
},
100+
type: 'animate',
101+
},
102+
{
103+
children: null,
104+
props: {
105+
attributeName: 'r',
106+
dur: '0.5s',
107+
from: 0,
108+
repeatCount: '1',
109+
restart: 'always',
110+
to: 30,
111+
},
112+
type: 'animate',
113+
},
114+
],
115+
props: {
116+
className: 'pointer',
117+
cx: 90,
118+
cy: 100,
119+
r: 30,
120+
},
121+
type: 'circle',
122+
},
123+
{
124+
children: [
125+
{
126+
children: null,
127+
props: {
128+
attributeName: 'opacity',
129+
dur: '0.5s',
130+
from: 0,
131+
repeatCount: '1',
132+
restart: 'always',
133+
to: 1,
134+
},
135+
type: 'animate',
136+
},
137+
{
138+
children: null,
139+
props: {
140+
attributeName: 'r',
141+
dur: '0.5s',
142+
from: 0,
143+
repeatCount: '1',
144+
restart: 'always',
145+
to: 30,
146+
},
147+
type: 'animate',
148+
},
149+
],
150+
props: {
151+
className: 'modifierPointer',
152+
cx: 45,
153+
cy: 140,
154+
r: 30,
155+
},
156+
type: 'circle',
157+
},
158+
{
159+
children: [
160+
{
161+
children: null,
162+
props: {
163+
attributeName: 'opacity',
164+
dur: '0.5s',
165+
from: 0,
166+
repeatCount: '1',
167+
restart: 'always',
168+
to: 1,
169+
},
170+
type: 'animate',
171+
},
172+
{
173+
children: null,
174+
props: {
175+
attributeName: 'r',
176+
dur: '0.5s',
177+
from: 0,
178+
repeatCount: '1',
179+
restart: 'always',
180+
to: 30,
181+
},
182+
type: 'animate',
183+
},
184+
],
185+
props: {
186+
className: 'modifierPointer',
187+
cx: 545,
188+
cy: 140,
189+
r: 30,
190+
},
191+
type: 'circle',
192+
},
193+
],
194+
props: {
195+
x: 15,
196+
y: 15,
197+
},
198+
type: 'svg',
199+
}
Binary file not shown.

0 commit comments

Comments
 (0)