git ssb

16+

Dominic / patchbay



Tree: 9c5fb9afa9248c901294db9eac5e350da9bc055d

Files: 9c5fb9afa9248c901294db9eac5e350da9bc055d / app / sync / catch-keyboard-shortcut.js

3179 bytesRaw
1const nest = require('depnest')
2
3exports.gives = nest('app.sync.catchKeyboardShortcut')
4
5exports.needs = nest({
6 'app.html.searchBar': 'first',
7 'app.html.tabs': 'first',
8 'app.sync.goTo': 'first'
9})
10
11var gPressed = false
12
13exports.create = function (api) {
14 return nest('app.sync.catchKeyboardShortcut', catchKeyboardShortcut)
15
16 function catchKeyboardShortcut (root) {
17 var tabs = api.app.html.tabs()
18 var search = api.app.html.searchBar()
19 var goTo = api.app.sync.goTo
20
21 root.addEventListener('keydown', (ev) => {
22 isTextFieldEvent(ev)
23 ? textFieldShortcuts(ev)
24 : genericShortcuts(ev, { tabs, search, goTo })
25 })
26 }
27}
28
29function isTextFieldEvent (ev) {
30 const tag = ev.target.nodeName
31 return (tag === 'INPUT' || tag === 'TEXTAREA')
32}
33
34function textFieldShortcuts (ev) {
35 switch (ev.keyCode) {
36 case 13: // ctrl+enter
37 if (ev.ctrlKey) {
38 ev.target.publish && ev.target.publish() // expects the textField to have a publish method
39 }
40 return
41 case 27: // esc
42 return ev.target.blur()
43 }
44}
45
46function genericShortcuts (ev, { tabs, search, goTo, back }) {
47 let scroll
48 const currentPage = tabs.currentPage()
49 // TODO change this scroll API - it seems some pages
50 // (e.g. Dark Crystal Index) has scroll defined and expect an object
51 if (currentPage) {
52 scroll = currentPage.keyboardScroll || noop
53 } else {
54 scroll = noop
55 }
56
57 // Messages
58 if (ev.keyCode === 71) { // gg = scroll to top
59 if (!gPressed) {
60 gPressed = true
61 window.setTimeout(() => {
62 gPressed = false
63 }, 3000)
64 return
65 }
66 scroll('first')
67 }
68 gPressed = false
69
70 switch (ev.keyCode) {
71 // Messages (cont'd)
72 case 74: // j = older
73 return scroll(1)
74 case 75: // k = newer
75 return scroll(-1)
76 case 13: // enter = open
77 return goToMessage(ev, { goTo })
78 case 79: // o = open
79 return goToMessage(ev, { goTo })
80 case 192: // ` = toggle raw message view
81 return toggleRawMessage(ev)
82
83 // Tabs
84 case 72: // h = left
85 tabs.selectRelative(-1)
86 return goTo(JSON.parse(tabs.currentPage().id))
87 case 76: // l = right
88 tabs.selectRelative(1)
89 return goTo(JSON.parse(tabs.currentPage().id))
90 case 88: // x = close
91 tabs.closeCurrentTab()
92 return
93
94 // Search
95 case 191: // / = routes search
96 if (ev.shiftKey) search.activate('?', ev)
97 else search.activate('/', ev)
98 return
99 case 50: // @ = mention search
100 if (ev.shiftKey) search.activate('@', ev)
101 return
102 case 51: // # = channel search
103 if (ev.shiftKey) search.activate('#', ev)
104 return
105 case 53: // % = message search
106 if (ev.shiftKey) search.activate('%', ev)
107 }
108}
109
110function goToMessage (ev, { goTo }) {
111 const msg = ev.target
112
113 if (msg.dataset && msg.dataset.key) {
114 goTo(msg.dataset.key)
115 // TODO - rm the dataset.root decorator
116 }
117}
118
119function toggleRawMessage (ev) {
120 const msg = ev.target
121 if (!msg.classList.contains('Message')) return
122
123 // this uses a crudely exported nav api
124 const target = msg.querySelector('.meta .toggle-raw-msg')
125 if (target) target.click()
126}
127
128function noop () {}
129

Built with git-ssb-web