git ssb

16+

Dominic / patchbay



Tree: 6dbc799416e7828344ed4ab645ebde51f3ddaea0

Files: 6dbc799416e7828344ed4ab645ebde51f3ddaea0 / app / sync / catch-keyboard-shortcut.js

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

Built with git-ssb-web