Files: c37769c3eb5a15ebdc2c876356cc062bddae9bb1 / modules / tabs.js
4131 bytesRaw
1 | var Tabs = require('hypertabs') |
2 | var h = require('hyperscript') |
3 | var pull = require('pull-stream') |
4 | var u = require('../util') |
5 | var keyscroll = require('../keyscroll') |
6 | |
7 | function ancestor (el) { |
8 | if(!el) return |
9 | if(el.tagName !== 'A') return ancestor(el.parentElement) |
10 | return el |
11 | } |
12 | |
13 | var plugs = require('../plugs') |
14 | var screen_view = plugs.first(exports.screen_view = []) |
15 | var search_box = plugs.first(exports.search_box = []) |
16 | |
17 | function openExternal (url) { |
18 | var _r = require //fool browserify |
19 | |
20 | //electron@1 |
21 | try {return _r('electron').shell.openExternal(url) } |
22 | catch (err) { } |
23 | |
24 | //electron@0 |
25 | try { return _r('shell').openExternal(url) } |
26 | catch (err) { } |
27 | |
28 | //browser |
29 | window.open(url, '_blank') |
30 | } |
31 | |
32 | exports.message_render = [] |
33 | |
34 | exports.app = function () { |
35 | var search |
36 | var tabs = Tabs(function (name) { |
37 | search.value = name |
38 | sessionStorage.selectedTab = tabs.selected |
39 | }) |
40 | tabs.classList.add('screen') |
41 | |
42 | search = search_box(function (path, change) { |
43 | if(tabs.has(path)) { |
44 | tabs.select(path) |
45 | return true |
46 | } |
47 | var el = screen_view(path) |
48 | if(el) { |
49 | el.scroll = keyscroll(el.querySelector('.scroller__content')) |
50 | tabs.add(path, el, change) |
51 | localStorage.openTabs = JSON.stringify(tabs.tabs) |
52 | return change |
53 | } |
54 | }) |
55 | |
56 | tabs.insertBefore(search, tabs.querySelector('.hypertabs__content')) |
57 | |
58 | var saved = [] |
59 | try { saved = JSON.parse(localStorage.openTabs) } |
60 | catch (_) { } |
61 | |
62 | if(!saved || saved.length < 3) |
63 | saved = ['/public', '/private', '/notifications'] |
64 | |
65 | saved.forEach(function (path) { |
66 | var el = screen_view(path) |
67 | if (!el) return |
68 | el.scroll = keyscroll(el.querySelector('.scroller__content')) |
69 | if(el) tabs.add(path, el, false) |
70 | }) |
71 | |
72 | tabs.select(sessionStorage.selectedTab || saved[0] || '/public') |
73 | |
74 | tabs.onclick = function (ev) { |
75 | var link = ancestor(ev.target) |
76 | if(!link) return |
77 | var path = link.hash.substring(1) |
78 | |
79 | ev.preventDefault() |
80 | ev.stopPropagation() |
81 | |
82 | //open external links. |
83 | //this ought to be made into something more runcible |
84 | if(/^https?/.test(link.href)) return openExternal(link.href) |
85 | |
86 | if(tabs.has(path)) return tabs.select(path) |
87 | |
88 | var el = screen_view(path) |
89 | if(el) { |
90 | el.scroll = keyscroll(el.querySelector('.scroller__content')) |
91 | tabs.add(path, el, !ev.ctrlKey) |
92 | localStorage.openTabs = JSON.stringify(tabs.tabs) |
93 | } |
94 | |
95 | return false |
96 | } |
97 | |
98 | window.addEventListener('keydown', function (ev) { |
99 | if (ev.target.nodeName === 'INPUT' || ev.target.nodeName === 'TEXTAREA') |
100 | return |
101 | switch(ev.keyCode) { |
102 | |
103 | // scroll through tabs |
104 | case 72: // h |
105 | return tabs.selectRelative(-1) |
106 | case 76: // l |
107 | return tabs.selectRelative(1) |
108 | |
109 | // scroll through messages |
110 | case 74: // j |
111 | return tabs.selectedTab.scroll(1) |
112 | case 75: // k |
113 | return tabs.selectedTab.scroll(-1) |
114 | |
115 | // close a tab |
116 | case 88: // x |
117 | if (tabs.selected && tabs.selected[0] !== '/') { |
118 | var sel = tabs.selected |
119 | tabs.selectRelative(-1) |
120 | tabs.remove(sel) |
121 | localStorage.openTabs = JSON.stringify(tabs.tabs) |
122 | } |
123 | return |
124 | |
125 | // activate the search field |
126 | case 191: // / |
127 | search.activate('?', ev) |
128 | return |
129 | |
130 | // navigate to a feed |
131 | case 50: // 2 |
132 | if (ev.shiftKey) |
133 | search.activate('@', ev) |
134 | return |
135 | |
136 | // navigate to a channel |
137 | case 51: // 3 |
138 | if (ev.shiftKey) |
139 | search.activate('#', ev) |
140 | return |
141 | } |
142 | }) |
143 | |
144 | // errors tab |
145 | var errorsContent = h('div.column.scroller__content') |
146 | var errors = h('div.column.scroller', |
147 | {style: {'overflow':'auto'}}, |
148 | h('div.scroller__wrapper', |
149 | errorsContent |
150 | ) |
151 | ) |
152 | |
153 | window.addEventListener('error', function (ev) { |
154 | var err = ev.error || ev |
155 | if(!tabs.has('errors')) |
156 | tabs.add('errors', errors, false) |
157 | var el = h('div.message', |
158 | h('strong', err.message), |
159 | h('pre', err.stack)) |
160 | if (errorsContent.firstChild) |
161 | errorsContent.insertBefore(el, errorsContent.firstChild) |
162 | else |
163 | errorsContent.appendChild(el) |
164 | }) |
165 | |
166 | return tabs |
167 | } |
168 | |
169 | |
170 | |
171 |
Built with git-ssb-web