Skip to content

Commit

Permalink
data/name dictation
Browse files Browse the repository at this point in the history
  • Loading branch information
samuelmtimbo committed Nov 24, 2024
1 parent 28238b4 commit 3e0736d
Show file tree
Hide file tree
Showing 8 changed files with 389 additions and 12 deletions.
2 changes: 1 addition & 1 deletion src/client/event/keyboard/write.ts
Original file line number Diff line number Diff line change
Expand Up @@ -455,7 +455,7 @@ export function writeToContentEditable(

export function writeToTextField(
system: System,
input: HTMLInputElement,
input: HTMLInputElement | HTMLTextAreaElement,
value: string
) {
const current = input.value
Expand Down
10 changes: 5 additions & 5 deletions src/system/platform/component/app/DataTree/Component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,11 +99,11 @@ export const DEFAULT_STYLE = {
}

export default class DataTree extends Element<HTMLDivElement, Props> {
private _data: TreeNode
private _root: Div
private _child: Dict<DataTree> = {}
private _delimiter_list: Div[] = []
private _leaf: DataTreeLeaf | null = null
public _data: TreeNode
public _root: Div
public _child: Dict<DataTree> = {}
public _delimiter_list: Div[] = []
public _leaf: DataTreeLeaf | null = null

constructor($props: Props, $system: System) {
super($props, $system)
Expand Down
4 changes: 2 additions & 2 deletions src/system/platform/component/app/Datum/Component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ export interface _Props {
}

export class Datum extends Element<HTMLDivElement, Props> {
private _data_tree: DataTree
private _root: TreeNode
public _data_tree: DataTree
public _root: TreeNode

private _ignore_blur: boolean = false

Expand Down
88 changes: 88 additions & 0 deletions src/system/platform/component/app/Editor/Component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ import {
makeShortcutListener,
} from '../../../../../client/event/keyboard'
import { keyToKeyCode } from '../../../../../client/event/keyboard/keyCode'
import { writeToTextField } from '../../../../../client/event/keyboard/write'
import {
CLICK_TIMEOUT,
POINTER_CLICK_RADIUS,
Expand Down Expand Up @@ -488,6 +489,7 @@ import {
TreeNode,
TreeNodeType,
_filterEmptyNodes,
_getNodeAtPath,
_getValueType,
_isTypeMatch,
_isValidTree,
Expand Down Expand Up @@ -676,6 +678,7 @@ import { randomInArray } from '../../../../../util/array/randomInArray'
import { bit } from '../../../../../util/boolean'
import { callAll } from '../../../../../util/call/callAll'
import { clone } from '../../../../../util/clone'
import { parseNumberSentence } from '../../../../../util/dictation'
import { readFileAsText } from '../../../../../util/file'
import { hashCode } from '../../../../../util/hashCode'
import { randomIdNotIn } from '../../../../../util/id'
Expand Down Expand Up @@ -19601,6 +19604,91 @@ export class Editor_ extends Element<HTMLDivElement, Props_> {
} else {
this._show_search()
}

this._search._microphone.addEventListener(
makeCustomListener('text', this._on_microphone_transcript)
)
}
}

private _on_microphone_transcript = (transcript: string) => {
let value = transcript.toLowerCase()

const writeToSearch = () => {
value = value.substr(0, 30)

this._search.setValue(value)
this._search.focus()
}

const writeToEditDatum = () => {
writeToDatum(this._edit_datum_node_id)
}

const writeToDatum = (datum_node_id: string) => {
const datum = this._datum[datum_node_id] as Datum

const leaf = datum._data_tree.getChildAtPath(this._edit_datum_path)

const current = leaf._leaf._input.$element.value

const { selectionStart, selectionEnd } = leaf._leaf._input.$element

if (
current === '' ||
(selectionStart === 0 && selectionEnd === current.length)
) {
let target_type

const pin_node_id = this._datum_to_pin[datum_node_id]

if (pin_node_id) {
target_type = this._get_link_pin_type(pin_node_id)
} else {
target_type = ANY_TREE
}

const leaf_type =
_getNodeAtPath(target_type, this._edit_datum_path) ?? ANY_TREE

if (leaf_type.type === TreeNodeType.Number) {
const parsed = parseNumberSentence(value)

value = (parsed && `${parsed}`) || value
} else if (leaf_type.type === TreeNodeType.Boolean) {
//
} else if (leaf_type.type === TreeNodeType.String) {
value = `"${value}"`
} else {
const parsed = parseNumberSentence(value)

value = (parsed && `${parsed}`) || `"${value}"`
}
}

writeToTextField(this.$system, leaf._leaf._input.$element, value)
}

if (this._edit_datum_node_id) {
writeToEditDatum()
} else if (this._edit_node_name_id) {
const name_comp = this._get_node_name_comp(this._edit_node_name_id)

writeToTextField(this.$system, name_comp.$element, value)
} else {
writeToSearch()
}
}

private _get_node_name_comp = (node_id: string): TextField | TextArea => {
if (this._is_unit_node_id(node_id)) {
return this._core_name[node_id]
} else if (this._is_link_pin_node_id(node_id)) {
return this._pin_name[node_id]
} else if (this._is_plug_node_id(node_id)) {
return this._ext_pin_name[node_id]
} else {
throw new InvalidStateError()
}
}

Expand Down
7 changes: 3 additions & 4 deletions src/system/platform/component/app/Search/Component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { getActiveElement } from '../../../../../client/activeElement'
import { classnames } from '../../../../../client/classnames'
import { debounce } from '../../../../../client/debounce'
import { Element } from '../../../../../client/element'
import { makeCustomListener } from '../../../../../client/event/custom'
import { makeFocusInListener } from '../../../../../client/event/focus/focusin'
import { makeFocusOutListener } from '../../../../../client/event/focus/focusout'
import { makeInputListener } from '../../../../../client/event/input'
Expand Down Expand Up @@ -251,9 +250,9 @@ export default class Search extends Element<HTMLDivElement, Props> {
},
this.$system
)
microphone.addEventListener(
makeCustomListener('text', this._on_microphone_transcript)
)
// microphone.addEventListener(
// makeCustomListener('text', this._on_microphone_transcript)
// )
microphone.preventDefault('mousedown')
microphone.preventDefault('touchdown')
this._microphone = microphone
Expand Down
137 changes: 137 additions & 0 deletions src/test/util/dictation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
import { parseNumberSentence } from '../../util/dictation'

function runTests() {
const tests = [
['zero', 0],
['one', 1],
['two', 2],
['three', 3],
['four', 4],
['five', 5],
['ten', 10],
['eleven', 11],
['twenty', 20],
['twenty-one', 21],
['thirty-five', 35],
['ninety-nine', 99],
['one hundred', 100],
['one hundred and one', 101],
['two hundred', 200],
['three hundred and fifty', 350],
['one thousand', 1000],
['one thousand two hundred', 1200],
['eleven hundred', 1100],
['ten thousand', 10000],
['twelve thousand three hundred', 12300],
['a hundred and fifty', 150],
['twenty thousand', 20000],
['fifty thousand', 50000],
['one million', 1000000],
['two million three hundred', 2000300],
['a billion', 1000000000],
['one billion two hundred million', 1200000000],
['two thousand two hundred and twenty-two', 2222],
['three hundred thousand', 300000],
['forty-five million six hundred thousand', 45600000],
[
'seven hundred seventy-seven thousand seven hundred seventy-seven',
777777,
],
[
'nine hundred ninety-nine billion nine hundred ninety-nine million nine hundred ninety-nine thousand nine hundred ninety-nine',
999999999999,
],
['fifty', 50],
['twenty one', 21],
['fifty five', 55],
['ninety nine', 99],
['a hundred', 100],
['a hundred and one', 101],
['twelve hundred', 1200],
['twenty five thousand', 25000],
['two million', 2000000],
['one billion', 1000000000],
['one million two hundred thousand', 1200000],
['two billion three million', 2003000000],
['fifty million twenty thousand', 50020000],
['one hundred and fifty', 150],
['one thousand and one', 1001],
['one million and one', 1000001],
['forty-two', 42],
['a hundred thousand', 100000],
['a thousand', 1000],
['a thousand two hundred', 1200],
['a thousand a hundred', 1100],
['a million a thousand a hundred', 1001100],
['8', 8],
['42', 42],
['100', 100],
['8 billion', 8000000000],
['5 hundred', 500],
['12 thousand', 12000],
['1 million', 1000000],
['8 billion 5 million', 8005000000],
['5 hundred thousand', 500000],
['12 thousand 5 hundred', 12500],
['1 million 5 hundred thousand', 1500000],
['a hundred 50', 150],
['50 thousand a hundred', 50100],
['a million 5 thousand', 1005000],
['1.5 million', 1500000],
['2.5 billion', 2500000000],
['3.7 thousand', 3700],
['8.5 billion 3 million', 8503000000],
['1.5 million 200 thousand', 1700000],
['2 billion 500 million', 2500000000],
['0.5 million', 500000],
['0.25 billion', 250000000],
['1.75 hundred', 175],
['1 quadrillion', 1000000000000000],
['1,5 quadrillion', 1500000000000000],
['0,5 quadrillion', 500000000000000],
['1,5 quadrillion 2,5 trillion', 1502500000000000],
['2,5 trillion 500 billion', null],
['1 trillion 500,5 billion', 1500500000000],
['1,234,5 billion 2,5 million', 1234502500000],
['a hundred 50,5', 150.5],
['0,5 trillion', 500000000000],
['1,000,5 billion', 1000500000000],
['ten trillion and 24', 10_000_000_000_024],
['eleven billion forty-two', 11_000_000_042],
['2,321', 2321],
['0,001 quadrillion', 1000000000000],
['0,1 quadrillion', 100000000000000],
['0,01 trillion', 10000000000],
['0,001 trillion', 1000000000],
['234,1', 234.1],
['1,5 million', 1500000],
['2,5', 2.5],
['10,5 billion', 10500000000],
['234,1 thousand', 234100],
// ['1,5 billion two million', 1_502_000_000],
['2,5 hundred', 250],
['1,234', 1234],
['1,234,567', 1234567],
['1,234,567.89', 1234567.89],
// ['1,234 million', 1234000000],
['1,234,5', 1234.5],
['1,234,567,8', 1234567.8],
['1,234,5 thousand', 1234500],
['1 trillion', 1000000000000],
['1,5 trillion', 1500000000000],
['two trillion', 2000000000000],
['1,234,567,8 billion', 1234567800000000],
]

tests.forEach(([input, expected], index) => {
const result = parseNumberSentence(input as string)

// eslint-disable-next-line no-console
console.assert(
result === expected,
`Test ${index + 1} failed: ${input} => ${result} (expected: ${expected})`
)
})
}

runTests()
1 change: 1 addition & 0 deletions src/test/util/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import './array'
import './dictation'
import './object'
import './system'
Loading

0 comments on commit 3e0736d

Please sign in to comment.