git ssb

16+

Dominic / patchbay



Tree: 958235c2141b96dc42b5dff7893d5906dc1bdfd1

Files: 958235c2141b96dc42b5dff7893d5906dc1bdfd1 / app / sync / catch-keyboard-shortcut.js

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

Built with git-ssb-web