git ssb

16+

Dominic / patchbay



Tree: 2b05be8ee023fdd9580d6a845ba074a425756685

Files: 2b05be8ee023fdd9580d6a845ba074a425756685 / app / sync / catch-keyboard-shortcut.js

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

Built with git-ssb-web