git ssb

16+

Dominic / patchbay



Tree: 5e5bef4d7a2202ff89f9fd54978ed73376abe898

Files: 5e5bef4d7a2202ff89f9fd54978ed73376abe898 / app / sync / catch-keyboard-shortcut.js

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

Built with git-ssb-web