git ssb

16+

Dominic / patchbay



Tree: 484be910df0ca305a03994ab5804b7c27483aac6

Files: 484be910df0ca305a03994ab5804b7c27483aac6 / app / sync / catch-keyboard-shortcut.js

3179 bytesRaw
1const nest = require('depnest')
2
3exports.gives = nest('app.sync.catchKeyboardShortcut')
4
5exports.create = function (api) {
6 return nest('app.sync.catchKeyboardShortcut', catchKeyboardShortcut)
7
8 function catchKeyboardShortcut (root, opts) {
9 var gPressed = false
10
11 root.addEventListener('keydown', (ev) => {
12 isTextFieldEvent(ev)
13 ? textFieldShortcuts(ev)
14 : genericShortcuts(ev, opts)
15 })
16 }
17}
18
19// TODO build better apis for navigation, search, and publishing
20
21function isTextFieldEvent (ev) {
22 const tag = ev.target.nodeName
23 return (tag === 'INPUT' || tag === 'TEXTAREA')
24}
25
26function textFieldShortcuts (ev) {
27 if (ev.keyCode === 13 && ev.ctrlKey) {
28 ev.target.publish() // expects the textField to have a publish method
29 }
30}
31
32function genericShortcuts (ev, { tabs, search }) {
33 // Messages
34 if (ev.keyCode === 71) { // gg = scroll to top
35 if (!gPressed) {
36 gPressed = true
37 return
38 }
39 tabs.get(tabs.selected[0]).firstChild.scroll('first')
40 }
41 gPressed = false
42
43 switch (ev.keyCode) {
44
45 // Messages (cont'd)
46 case 74: // j = older
47 return tabs.get(tabs.selected[0]).firstChild.scroll(1)
48 case 75: // k = newer
49 return tabs.get(tabs.selected[0]).firstChild.scroll(-1)
50 case 13: // enter = open
51 return goToMessage(ev, tabs)
52 case 79: // o = open
53 return goToMessage(ev, tabs)
54 case 192: // ` = toggle raw message view
55 return toggleRawMessage(ev)
56
57 // Tabs
58 case 72: // h = left
59 return tabs.selectRelative(-1)
60 case 76: // l = right
61 return tabs.selectRelative(1)
62 case 88: // x = close
63 if (tabs.selected) {
64 var sel = tabs.selected
65 var i = sel.reduce(function (a, b) { return Math.min(a, b) })
66 tabs.remove(sel)
67 tabs.select(Math.max(i - 1, 0))
68 }
69 return
70
71 // Search
72 case 191: // / = routes search
73 if (ev.shiftKey) search.activate('?', ev)
74 else search.activate('/', ev)
75 return
76 case 50: // @ = mention search
77 if (ev.shiftKey) search.activate('@', ev)
78 return
79 case 51: // # = channel search
80 if (ev.shiftKey) search.activate('#', ev)
81 return
82 case 53: // % = message search
83 if (ev.shiftKey) search.activate('%', ev)
84 return
85 }
86}
87
88function goToMessage (ev, tabs) {
89 const msg = ev.target
90 if (!msg.classList.contains('Message')) return
91
92 // this uses a crudely exported nav api
93 const search = document.querySelector('input[type=search]')
94
95 const { root, id } = msg.dataset
96 if (!root) return search.go(id)
97
98 search.go(root)
99 scrollDownToMessage(id, tabs)
100}
101
102function scrollDownToMessage (id, tabs) {
103 tabs.get(tabs.selected[0]).firstChild.scroll('first')
104 locateKey()
105
106 function locateKey () {
107 const msg = tabs.get(tabs.selected[0]).querySelector(`[data-id='${id}']`)
108 if (msg === null) return setTimeout(locateKey, 100)
109
110 ;(msg.scrollIntoViewIfNeeded || msg.scrollIntoView).call(msg)
111 msg.focus()
112 }
113}
114
115function toggleRawMessage (ev) {
116 const msg = ev.target
117 if (!msg.classList.contains('Message')) return
118
119 // this uses a crudely exported nav api
120 msg.querySelector('.meta .toggle-raw-msg').click()
121}
122
123

Built with git-ssb-web