git ssb

16+

Dominic / patchbay



Tree: 857ffb47b775934f802dde6feb96b6f343fdf760

Files: 857ffb47b775934f802dde6feb96b6f343fdf760 / app / sync / catch-keyboard-shortcut.js

3357 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() // 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 }) {
47 // Messages
48 if (ev.keyCode === 71) { // gg = scroll to top
49 if (!gPressed) {
50 gPressed = true
51 window.setTimeout(() => {
52 gPressed = false
53 }, 3000)
54 return
55 }
56 tabs.currentPage().scroll('first')
57 }
58 gPressed = false
59
60 switch (ev.keyCode) {
61 // Messages (cont'd)
62 case 74: // j = older
63 return tabs.currentPage().scroll(1)
64 case 75: // k = newer
65 return tabs.currentPage().scroll(-1)
66 case 13: // enter = open
67 return goToMessage(ev, { tabs, goTo })
68 case 79: // o = open
69 return goToMessage(ev, { tabs, goTo })
70 case 192: // ` = toggle raw message view
71 return toggleRawMessage(ev)
72
73 // Tabs
74 case 72: // h = left
75 tabs.selectRelative(-1)
76 return goTo(JSON.parse(tabs.currentPage().id))
77 case 76: // l = right
78 tabs.selectRelative(1)
79 return goTo(JSON.parse(tabs.currentPage().id))
80 case 88: // x = close
81 if (tabs.selected) {
82 var sel = tabs.selected
83 tabs.remove(sel)
84 }
85 return
86
87 // Search
88 case 191: // / = routes search
89 if (ev.shiftKey) search.activate('?', ev)
90 else search.activate('/', ev)
91 return
92 case 50: // @ = mention search
93 if (ev.shiftKey) search.activate('@', ev)
94 return
95 case 51: // # = channel search
96 if (ev.shiftKey) search.activate('#', ev)
97 return
98 case 53: // % = message search
99 if (ev.shiftKey) search.activate('%', ev)
100 }
101}
102
103function goToMessage (ev, { tabs, goTo }) {
104 const msg = ev.target
105 if (!msg.classList.contains('Message')) return
106
107 const { root, id } = msg.dataset
108 if (!root) return goTo(id)
109
110 goTo(root)
111 setTimeout(() => scrollDownToMessage(id, tabs), 250)
112}
113
114function scrollDownToMessage (id, tabs) {
115 tabs.currentPage().scroll('first')
116 locateKey()
117
118 function locateKey () {
119 const msg = tabs.currentPage().querySelector(`[data-id='${id}']`)
120 if (msg === null) return setTimeout(locateKey, 100)
121
122 ;(msg.scrollIntoViewIfNeeded || msg.scrollIntoView).call(msg)
123 msg.focus()
124 }
125}
126
127function toggleRawMessage (ev) {
128 const msg = ev.target
129 if (!msg.classList.contains('Message')) return
130
131 // this uses a crudely exported nav api
132 msg.querySelector('.meta .toggle-raw-msg').click()
133}
134
135

Built with git-ssb-web