my eye

Abstract assistive nav tools and introduce mode

Committed f6a092

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

 $else:
     let userName = 'Guest'
 
+let mode = 'site'
+
 // TODO $$.load(...)
 document.addEventListener('DOMContentLoaded', ev => {
   microphoneStatus('off')
   cookies.set('mediasoup-demo.user', `{"displayName": "$${userName}"}`)
 
   document.addEventListener('keydown', ev => {
+    if (mode == 'room') {
+      if (ev.key == 'w') {                              // w   TODO move up (in room)
+      } else if (ev.key == 'a') {                       // a   TODO move left (in room)
+      } else if (ev.key == 's') {                       // s   TODO move down (in room)
+      } else if (ev.key == 'd') {                       // d   TODO move right (in room)
+      }
+      return
+    }
     if (following) {
       if (ev.key == 'Escape')
         hideFollowLinks()
         document.querySelector('body').style.backgroundImage = 'url(/static/measure.png)'
         cookies.set('rhythm', 'on')
       }
-    } else if (ev.key == 'f') {                      // f   TODO "follow links"
-    } else if (ev.key == 'h') {                      // h   go back
-      history.back()
-    } else if (ev.key == 'j') {                      // j   scroll down 3 EMs
-      document.documentElement.scrollTop += 3 * em
-    } else if (ev.key == 'k') {                      // k   scroll up 3 EMs
-      document.documentElement.scrollTop -= 3 * em
-    } else if (ev.key == 'l') {                      // l   go forward
-      history.forward()
-    } else if (ev.key == '[') {                      // [   follow rel=prev
-      go(document.querySelector("a[rel=prev]").href)
-    } else if (ev.key == ']') {                      // ]   follow rel=next
-      go(document.querySelector("a[rel=next]").href)
-    } else if (ev.key == 'w') {                      // w   TODO move up (in room)
-    } else if (ev.key == 'a') {                      // a   TODO move left (in room)
-    } else if (ev.key == 's') {                      // s   TODO move down (in room)
-    } else if (ev.key == 'd') {                      // d   TODO move right (in room)
-    }
+    } else if (ev.key == 'f') showKeyboardFollowLinks() // f   show "follow links"
+    else if (ev.key == 'h') goBack()                    // h   go back
+    else if (ev.key == 'j') scrollDown()                // j   scroll down 3 EMs
+    else if (ev.key == 'k') scrollUp()                  // k   scroll up 3 EMs
+    else if (ev.key == 'l') goForward()                 // l   go forward
+    else if (ev.key == 'u') goUp()                      // u   follow rel=up
+    else if (ev.key == '[') goPrevious()                // [   follow rel=prev
+    else if (ev.key == ']') goNext()                    // ]   follow rel=next
   }, false)
 })
 
+const em = parseFloat(getComputedStyle(document.documentElement).fontSize)
+
+const goHome = () => { go(document.querySelector("a[rel=home]").href) }
+const goUp = () => { go(document.querySelector("a[rel=up]").href) }
+const goPrevious = () => { go(document.querySelector("a[rel=prev]").href) }
+const goNext = () => { go(document.querySelector("a[rel=next]").href) }
+const goBack = () => { history.back() }
+const goForward = () => { history.forward() }
+const scrollDown = () => { document.documentElement.scrollTop += 3 * em }
+const scrollUp = () => { document.documentElement.scrollTop -= 3 * em }
+
 let following = false
 let followList = {}
 let followQueue = ''
       partialContainer.innerHTML = ''
       return
     }
-    if (input == 'help') {                                        // help
+    if (input == 'help') {                           // help
       go('/help')
-    } else if (input.startsWith('query for')) {                   // query for
+    } else if (input.startsWith('query for')) {      // query for
       const query = input.slice(10)
       go(`/search?q=$${query}`)
-    } else if (input.startsWith('go')) {                          // go
+    } else if (input.startsWith('go')) {             // go
       const where = input.slice(3)
-      if (where == 'home')                                        //    home
-        go('/')
-      else if (where == 'back')                                   //    back
-        history.back()
-      else if (where == 'forward')                                //    forward
-        history.forward()
-    } else if (input.startsWith('follow')) {                      // follow
-      following = true
-      followList = {}
-      document.querySelectorAll('a').forEach((link, n) => {
-        followList[numberToWords(n).replace(' ', '')] = link.href
-        link.innerHTML = link.innerHTML +
-          `<span class=follows>$${n}</span>`
-      })
-    } else if (input.startsWith('tell me')) {                     // tell me
+      if (where == 'home') goHome()                  //    home
+      else if (where == 'up') goUp()                 //    up
+      else if (where == 'prev') goPrevious()         //    prev
+      else if (where == 'next') goNext()             //    next
+      else if (where == 'back') goBack()             //    back
+      else if (where == 'forward') goForward()       //    forward
+    } else if (input.startsWith('follow')) {         // follow
+      showVoiceFollowLinks()
+    } else if (input.startsWith('tell me')) {        // tell me
       const request = input.slice(8)
       const response = fetch('/ai/assistant', {
           method: 'POST',