Files: 6f4a164dcf3ceba120878c266e2f477496eb7b3e / main / sync / catch-keyboard-shortcut.js
2717 bytesRaw
1 | const nest = require('depnest') |
2 | |
3 | exports.gives = nest('main.sync.catchKeyboardShortcut') |
4 | |
5 | exports.create = function (api) { |
6 | return nest('main.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 | |
21 | function isTextFieldEvent (ev) { |
22 | const tag = ev.target.nodeName |
23 | return (tag === 'INPUT' || tag === 'TEXTAREA') |
24 | } |
25 | |
26 | function textFieldShortcuts (ev) { |
27 | if (ev.keyCode === 13 && ev.ctrlKey) { |
28 | ev.target.publish() //expects the textField to have a publish method |
29 | } |
30 | } |
31 | |
32 | function genericShortcuts (ev, { tabs, search }) { |
33 | |
34 | // Messages |
35 | if (ev.keyCode === 71) { // gg = scroll to top |
36 | if (!gPressed) { |
37 | gPressed = true |
38 | return |
39 | } |
40 | tabs.get(tabs.selected[0]).firstChild.scroll('first') |
41 | } |
42 | gPressed = false |
43 | |
44 | switch (ev.keyCode) { |
45 | |
46 | // Messages (cont'd) |
47 | case 74: // j = older |
48 | return tabs.get(tabs.selected[0]).firstChild.scroll(1) |
49 | case 75: // k = newer |
50 | return tabs.get(tabs.selected[0]).firstChild.scroll(-1) |
51 | case 13: // enter = open |
52 | return goToMessage(ev) |
53 | case 79: // o = open |
54 | return goToMessage(ev) |
55 | case 192: // ` = toggle raw message view |
56 | return toggleRawMessage(ev) |
57 | |
58 | |
59 | // Tabs |
60 | case 72: // h = left |
61 | return tabs.selectRelative(-1) |
62 | case 76: // l = right |
63 | return tabs.selectRelative(1) |
64 | case 88: // x = close |
65 | if (tabs.selected) { |
66 | var sel = tabs.selected |
67 | var i = sel.reduce(function (a, b) { return Math.min(a, b) }) |
68 | tabs.remove(sel) |
69 | tabs.select(Math.max(i - 1, 0)) |
70 | } |
71 | return |
72 | |
73 | // Search |
74 | case 191: // / = routes search |
75 | if (ev.shiftKey) search.activate('?', ev) |
76 | else search.activate('/', ev) |
77 | return |
78 | case 50: // @ = mention search |
79 | if (ev.shiftKey) search.activate('@', ev) |
80 | return |
81 | case 51: // # = channel search |
82 | if (ev.shiftKey) search.activate('#', ev) |
83 | return |
84 | case 53: // % = message search |
85 | if (ev.shiftKey) search.activate('%', ev) |
86 | return |
87 | } |
88 | } |
89 | |
90 | |
91 | function goToMessage (ev) { |
92 | const msg = ev.target |
93 | if (!msg.classList.contains('Message')) return |
94 | |
95 | // this uses a crudely exported nav api |
96 | const search = document.querySelector('input[type=search]') |
97 | search.go(msg.dataset.root) |
98 | } |
99 | |
100 | function toggleRawMessage (ev) { |
101 | const msg = ev.target |
102 | if (!msg.classList.contains('Message')) return |
103 | |
104 | // this uses a crudely exported nav api |
105 | msg.querySelector('.meta .toggle-raw-msg').click() |
106 | } |
107 | |
108 |
Built with git-ssb-web