my eye

Make keyboard based follow links use home row keys

Committed 61d096

--- a/canopy/static/screen.css
+++ b/canopy/static/screen.css

   }
 }
 
-.follows {
+.followlink {
   background-color: #073642;
   color: #b58900;
   font-size: 10px;
   padding: 0 .25em;
   position: relative;
   right: .25em;
+  text-transform: uppercase;
   top: -.5em; }
 
 #connection {

--- a/canopy/templates/template.html
+++ b/canopy/templates/template.html

   cookies.set('mediasoup-demo.user', `{"displayName": "$${userName}"}`)
 
   document.addEventListener('keydown', ev => {
-    const em = parseFloat(getComputedStyle(document.documentElement).fontSize)
-    if (ev.ctrlKey && ev.key == '.') {               // C^. toggle rhythm indicator
+    if (following) {
+      if (ev.key == 'Escape')
+        hideFollowLinks()
+      followQueue += ev.key
+      if (followList.hasOwnProperty(followQueue)) {
+        go(followList[followQueue])
+        hideFollowLinks()
+      }
+      return
+    }
+    if (ev.ctrlKey && ev.key == '.') {                  // C^. toggle rhythm indicator
       if (cookies.get('rhythm') == 'on') {
         document.querySelector('body').style.backgroundImage = 'none'
         cookies.set('rhythm', 'off')
   }, false)
 })
 
+let following = false
+let followList = {}
+let followQueue = ''
+const showKeyboardFollowLinks = () => {
+  following = true
+  const links = document.querySelectorAll('a')
+  links.forEach((link, n) => {
+    const characters = 'asdfghjkl;'
+    const combinationLength = Math.log10(links.length)
+    let combination = ''
+    while (true) {
+      combination = ''
+      for (let i = 0; i < combinationLength; i++)
+        combination += characters.charAt(Math.floor(Math.random() * characters.length))
+      if (!followList.hasOwnProperty(combination)) break
+    }
+    followList[combination] = link.href
+    link.innerHTML = link.innerHTML + `<span class=followlink>$${combination}</span>`
+  })
+}
+const showVoiceFollowLinks = () => {
+  following = true
+  document.querySelectorAll('a').forEach((link, n) => {
+    followList[numberToWords(n).replace(' ', '')] = link.href
+    link.innerHTML = link.innerHTML + `<span class=followlink>$${n}</span>`
+  })
+}
+const hideFollowLinks = () => {
+  following = false
+  followList = {}
+  followQueue = ''
+  document.querySelectorAll('.followlink').forEach(e => e.remove())
+}
+
 const initDictation = async () => {
   microphoneStatus('loading')
   const partialContainer = document.querySelector('#search .partial')
   let wakeWord = 'ghost'
   let readyWord = 'Say "ghost help"'
   let state = 'asleep'
-  let following = false
-  let followList = {}
   microphoneStatus('on')
   partialContainer.innerHTML = readyWord
 
   recognizer.on('result', message => {
     let input = message.result.text
     if (following && input != '') {
-      following = false
       let number = input.replace(' ', '')
       if (number == 'for') number = 'four'
       go(followList[number])
-      document.querySelectorAll('.follows').forEach(e => e.remove())
+      hideFollowLinks()
       return
     }
     if (input.slice(0, wakeWord.length) != wakeWord) {