summaryrefslogtreecommitdiff
path: root/main.js
blob: b8ece73a3080125ef0ed7fc2ccffc26bdfed865b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
(function () {
  const DEFAULT_EXERCISE_SLUG = 'doggo-ipsum'
  const mainInput = document.getElementById("main-input")
  const root = document.getElementById("root")
  const fileInput = document.getElementById("file-input")
  mainInput.addEventListener("keyup", mainInputChangeHandler)
  fileInput.addEventListener("change", fileChangeHandler)

  const exerciseSlug = Lib.getQueryParam("exercise") || DEFAULT_EXERCISE_SLUG
  const wordList = EXERCISES[exerciseSlug].content.split(" ")
  let state = Lib.makeStateContainer({ currentWordIndex: 0, currentMatchIndex: 0, wordList}, render)

  function render() {
    const { currentWordIndex, currentMatchIndex, wordList } = state.get()
    const currentWord = wordList[currentWordIndex]

    const [matchedSegment, rest] = Lib.splitAt(currentWord, currentMatchIndex)
    const currentWordTemplate = Templates.currentWord({matchedSegment, rest})

    const sidebarCollection = Object.entries(EXERCISES).map(([slug, exercise]) => [exercise.name, `/?exercise=${slug}`, slug])
    const sidebarTemplate = Templates.sidebar({collection: sidebarCollection, currentSlug: exerciseSlug })

    const nextWord = wordList[currentWordIndex + 1]
    const prevWord = wordList[currentWordIndex - 1]
    const dashboardTemplate = Templates.dashboard({prevWord, nextWord, children: currentWordTemplate})
    root.innerHTML = sidebarTemplate + dashboardTemplate
  }

  function currentMatchPosition(currentWord) {
    // TODO this is not a very fast or clever way to do this, but its ok to
    // read and works for now. At the very least this should be factored out.
    let i
    for(i = 0; i < currentWord.length; i++) {
      if(currentWord[i] !== mainInput.value[i]) {
        break
      }
    }
    return i
  }

  function fileChangeHandler(event) {
    Lib.readFile(event.target.files[0]).then(function(text) {
      state.set({ wordList: text.split(" "), currentWordIndex: 0, currentMatchIndex: 0 })
    })
  }

  function mainInputChangeHandler(event) {
    const { currentWordIndex, wordList } = state.get()
    const currentWord = wordList[currentWordIndex]
    if(mainInput.value.includes(currentWord)) {
      mainInput.value = ""
      state.set({ currentWordIndex: currentWordIndex + 1, currentMatchIndex: 0 })
    }
    else {
      state.set({ currentMatchIndex: currentMatchPosition(currentWord) })
    }
  }

  render()
})()