Commit f4403f27a548f4b7a08d65c2c8e8664b2594fff1
fixup
mix irving committed on 4/24/2017, 11:43:03 AMParent: b7d7f86afc99c01161ac2e00a2decf8ecb85246e
Files changed
app/html/app.js | changed |
app/html/menu.js | changed |
app/html/search-bar.js | changed |
app/html/tabs.js | changed |
app/sync/addPage.js | changed |
app/sync/catch-keyboard-shortcut.js | changed |
app/sync/goTo.js | changed |
message/html/render/follow.js | changed |
package.json | changed |
app/html/app.js | ||
---|---|---|
@@ -1,8 +1,7 @@ | ||
1 | 1 … | const nest = require('depnest') |
2 | 2 … | const { h } = require('mutant') |
3 | 3 … | const insertCss = require('insert-css') |
4 | -const Tabs = require('hypertabs') | |
5 | 4 … | |
6 | 5 … | exports.gives = nest('app.html.app') |
7 | 6 … | |
8 | 7 … | exports.needs = nest({ |
@@ -13,9 +12,9 @@ | ||
13 | 12 … | html: { |
14 | 13 … | error: 'first', |
15 | 14 … | externalConfirm: 'first', |
16 | 15 … | tabs: 'first', |
17 | - page: 'first', | |
16 … | + page: 'first' | |
18 | 17 … | }, |
19 | 18 … | sync: { |
20 | 19 … | addPage: 'first', |
21 | 20 … | catchKeyboardShortcut: 'first' |
app/html/menu.js | ||
---|---|---|
@@ -5,19 +5,23 @@ | ||
5 | 5 … | |
6 | 6 … | exports.needs = nest('app.html.menuItem', 'map') |
7 | 7 … | |
8 | 8 … | exports.create = function (api) { |
9 | - return nest('app.html.menu', menu) | |
9 … | + var _menu | |
10 | 10 … | |
11 | - function menu (handleClick) { | |
11 … | + return nest('app.html.menu', function menu (handleClick) { | |
12 … | + if (_menu) return _menu | |
13 … | + | |
12 | 14 … | var state = Value('') |
13 | 15 … | |
14 | - return h('Menu', { | |
16 … | + _menu = h('Menu', { | |
15 | 17 … | classList: [ state ], |
16 | 18 … | 'ev-mouseover': () => state.set('-active'), |
17 | 19 … | 'ev-mouseout': () => state.set('') |
18 | 20 … | }, [ |
19 | 21 … | h('div', api.app.html.menuItem(handleClick)) |
20 | 22 … | ]) |
21 | - } | |
23 … | + | |
24 … | + return _menu | |
25 … | + }) | |
22 | 26 … | } |
23 | 27 … |
app/html/search-bar.js | ||
---|---|---|
@@ -4,16 +4,20 @@ | ||
4 | 4 … | |
5 | 5 … | exports.gives = nest('app.html.searchBar') |
6 | 6 … | |
7 | 7 … | exports.needs = nest({ |
8 … | + 'app.sync.goTo': 'first', | |
8 | 9 … | 'about.async.suggest': 'first', |
9 | 10 … | 'channel.async.suggest': 'first' |
10 | 11 … | }) |
11 | 12 … | |
12 | 13 … | exports.create = function (api) { |
13 | - return nest('app.html.searchBar', searchBar) | |
14 … | + var _search | |
14 | 15 … | |
15 | - function searchBar (go) { | |
16 … | + return nest('app.html.searchBar', function searchBar () { | |
17 … | + if (_search) return _search | |
18 … | + | |
19 … | + const goTo = api.app.sync.goTo | |
16 | 20 … | const getProfileSuggestions = api.about.async.suggest() |
17 | 21 … | const getChannelSuggestions = api.channel.async.suggest() |
18 | 22 … | |
19 | 23 … | const input = h('input', { |
@@ -21,9 +25,9 @@ | ||
21 | 25 … | placeholder: '?search, @name, #channel', |
22 | 26 … | 'ev-keyup': ev => { |
23 | 27 … | switch (ev.keyCode) { |
24 | 28 … | case 13: // enter |
25 | - if (go(input.value.trim(), !ev.ctrlKey)) { | |
29 … | + if (goTo(input.value.trim(), !ev.ctrlKey)) { | |
26 | 30 … | input.blur() |
27 | 31 … | } |
28 | 32 … | return |
29 | 33 … | case 27: // escape |
@@ -32,19 +36,18 @@ | ||
32 | 36 … | return |
33 | 37 … | } |
34 | 38 … | } |
35 | 39 … | }) |
36 | - input.go = go // crude navigation api | |
37 | 40 … | input.addEventListener('suggestselect', ev => { |
38 | 41 … | input.value = ev.detail.id // HACK : this over-rides the markdown value |
39 | 42 … | |
40 | - // if (go(input.value.trim(), !ev.ctrlKey)) | |
43 … | + // if (goTo(input.value.trim(), !ev.ctrlKey)) | |
41 | 44 … | // input.blur() |
42 | 45 … | }) |
43 | - const search = h('SearchBar', input) | |
44 | 46 … | |
45 | - search.input = input | |
46 | - search.activate = (sigil, ev) => { | |
47 … | + _search = h('SearchBar', input) | |
48 … | + _search.input = input | |
49 … | + _search.activate = (sigil, ev) => { | |
47 | 50 … | input.focus() |
48 | 51 … | ev.preventDefault() |
49 | 52 … | if (input.value[0] === sigil) { |
50 | 53 … | input.selectionStart = 1 |
@@ -61,8 +64,8 @@ | ||
61 | 64 … | cb(null, getChannelSuggestions(inputText.slice(1))) |
62 | 65 … | } |
63 | 66 … | }, {cls: 'SuggestBox'}) |
64 | 67 … | |
65 | - return search | |
66 | - } | |
68 … | + return _search | |
69 … | + }) | |
67 | 70 … | } |
68 | 71 … |
app/html/tabs.js | ||
---|---|---|
@@ -3,72 +3,44 @@ | ||
3 | 3 … | const Tabs = require('hypertabs') |
4 | 4 … | |
5 | 5 … | exports.gives = nest({ |
6 | 6 … | app: { |
7 | - 'html.tabs': true, | |
8 | - sync: { | |
9 | - 'goTo': true, | |
10 | - 'addPage': true | |
11 | - } | |
7 … | + 'html.tabs': true | |
12 | 8 … | } |
13 | 9 … | }) |
14 | 10 … | |
15 | 11 … | exports.needs = nest({ |
16 | 12 … | 'app.html': { |
17 | 13 … | menu: 'first', |
18 | 14 … | page: 'first', |
19 | 15 … | searchBar: 'first' |
20 | - } | |
16 … | + }, | |
17 … | + 'app.sync.addPage': 'first' | |
21 | 18 … | }) |
22 | 19 … | |
23 | 20 … | exports.create = function (api) { |
24 | - | |
25 | 21 … | var _tabs |
26 | 22 … | |
27 | 23 … | function tabs (initialTabs = []) { |
28 | 24 … | if (_tabs) return _tabs |
29 | 25 … | |
30 | - const search = api.app.html.searchBar(goTo) | |
31 | - const menu = api.app.html.menu(goTo) | |
26 … | + const search = api.app.html.searchBar() | |
27 … | + const menu = api.app.html.menu() | |
32 | 28 … | const onSelect = (indexes) => { |
33 | 29 … | search.input.value = _tabs.get(indexes[0]).content.id |
34 | 30 … | } |
35 | 31 … | _tabs = Tabs(onSelect, { |
36 | - append: h('div.navExtra', [ search, menu ]) | |
32 … | + append: h('div.navExtra', [ search, menu ]) | |
37 | 33 … | }) |
34 … | + _tabs.getCurrent = () => _tabs.get(_tabs.selected[0]) | |
38 | 35 … | |
39 | - initialTabs.forEach(p => addPage(p)) | |
36 … | + // # TODO: review - this works but is strange | |
37 … | + initialTabs.forEach(p => api.app.sync.addPage(p)) | |
40 | 38 … | _tabs.select(0) |
41 | 39 … | return _tabs |
42 | 40 … | } |
43 | 41 … | |
44 | - function goTo (path, change) { | |
45 | - tabs() | |
46 | - if (_tabs.has(path)) { | |
47 | - _tabs.select(path) | |
48 | - return true | |
49 | - } | |
50 | - | |
51 | - addPage(path, true, false) | |
52 | - return change | |
53 | - } | |
54 | - | |
55 | - function addPage (link, change, split) { | |
56 | - tabs() | |
57 | - const page = api.app.html.page(link) | |
58 | - if (!page) return | |
59 | - | |
60 | - page.id = page.id || link | |
61 | - _tabs.add(page, change, split) | |
62 | - } | |
63 | - | |
64 | 42 … | return nest({ |
65 | - app: { | |
66 | - 'html.tabs': tabs, | |
67 | - sync: { | |
68 | - goTo, | |
69 | - addPage | |
70 | - } | |
71 | - } | |
43 … | + 'app.html.tabs': tabs | |
72 | 44 … | }) |
73 | 45 … | } |
74 | 46 … |
app/sync/addPage.js | ||
---|---|---|
@@ -8,11 +8,9 @@ | ||
8 | 8 … | }) |
9 | 9 … | |
10 | 10 … | exports.create = function (api) { |
11 | 11 … | return nest({ |
12 | - 'app.sync': { | |
13 | - addPage | |
14 | - } | |
12 … | + 'app.sync': { addPage } | |
15 | 13 … | }) |
16 | 14 … | |
17 | 15 … | // TODO : make it so error catching doesn't need this, move it into goTo |
18 | 16 … | function addPage (link, change, split) { |
@@ -25,5 +23,4 @@ | ||
25 | 23 … | tabs.add(page, change, split) |
26 | 24 … | } |
27 | 25 … | } |
28 | 26 … | |
29 | - |
app/sync/catch-keyboard-shortcut.js | ||
---|---|---|
@@ -1,24 +1,36 @@ | ||
1 | 1 … | const nest = require('depnest') |
2 | 2 … | |
3 | 3 … | exports.gives = nest('app.sync.catchKeyboardShortcut') |
4 | 4 … | |
5 … | +exports.needs = nest({ | |
6 … | + 'app.html': { | |
7 … | + searchBar: 'first', | |
8 … | + tabs: 'first' | |
9 … | + }, | |
10 … | + 'app.sync': { | |
11 … | + goTo: 'first' | |
12 … | + } | |
13 … | +}) | |
14 … | + | |
5 | 15 … | exports.create = function (api) { |
6 | 16 … | return nest('app.sync.catchKeyboardShortcut', catchKeyboardShortcut) |
7 | 17 … | |
8 | - function catchKeyboardShortcut (root, opts) { | |
18 … | + function catchKeyboardShortcut (root) { | |
9 | 19 … | var gPressed = false |
10 | 20 … | |
21 … | + var tabs = api.app.html.tabs() | |
22 … | + var search = api.app.html.searchBar() | |
23 … | + var goTo = api.app.sync.goTo | |
24 … | + | |
11 | 25 … | root.addEventListener('keydown', (ev) => { |
12 | 26 … | isTextFieldEvent(ev) |
13 | 27 … | ? textFieldShortcuts(ev) |
14 | - : genericShortcuts(ev, opts) | |
28 … | + : genericShortcuts(ev, { tabs, search, goTo }) | |
15 | 29 … | }) |
16 | 30 … | } |
17 | 31 … | } |
18 | 32 … | |
19 | -// TODO build better apis for navigation, search, and publishing | |
20 | - | |
21 | 33 … | function isTextFieldEvent (ev) { |
22 | 34 … | const tag = ev.target.nodeName |
23 | 35 … | return (tag === 'INPUT' || tag === 'TEXTAREA') |
24 | 36 … | } |
@@ -28,30 +40,30 @@ | ||
28 | 40 … | ev.target.publish() // expects the textField to have a publish method |
29 | 41 … | } |
30 | 42 … | } |
31 | 43 … | |
32 | -function genericShortcuts (ev, { tabs, search }) { | |
44 … | +function genericShortcuts (ev, { tabs, goTo, search }) { | |
33 | 45 … | // Messages |
34 | 46 … | if (ev.keyCode === 71) { // gg = scroll to top |
35 | 47 … | if (!gPressed) { |
36 | 48 … | gPressed = true |
37 | 49 … | return |
38 | 50 … | } |
39 | - tabs.get(tabs.selected[0]).firstChild.scroll('first') | |
51 … | + tabs.getCurrent().firstChild.scroll('first') | |
40 | 52 … | } |
41 | 53 … | gPressed = false |
42 | 54 … | |
43 | 55 … | switch (ev.keyCode) { |
44 | 56 … | |
45 | 57 … | // Messages (cont'd) |
46 | 58 … | case 74: // j = older |
47 | - return tabs.get(tabs.selected[0]).firstChild.scroll(1) | |
59 … | + return tabs.getCurrent().firstChild.scroll(1) | |
48 | 60 … | case 75: // k = newer |
49 | - return tabs.get(tabs.selected[0]).firstChild.scroll(-1) | |
61 … | + return tabs.getCurrent().firstChild.scroll(-1) | |
50 | 62 … | case 13: // enter = open |
51 | - return goToMessage(ev, tabs) | |
63 … | + return goToMessage(ev, { tabs, goTo }) | |
52 | 64 … | case 79: // o = open |
53 | - return goToMessage(ev, tabs) | |
65 … | + return goToMessage(ev, { tabs, goTo }) | |
54 | 66 … | case 192: // ` = toggle raw message view |
55 | 67 … | return toggleRawMessage(ev) |
56 | 68 … | |
57 | 69 … | // Tabs |
@@ -84,28 +96,25 @@ | ||
84 | 96 … | return |
85 | 97 … | } |
86 | 98 … | } |
87 | 99 … | |
88 | -function goToMessage (ev, tabs) { | |
100 … | +function goToMessage (ev, { tabs, goTo }) { | |
89 | 101 … | const msg = ev.target |
90 | 102 … | if (!msg.classList.contains('Message')) return |
91 | 103 … | |
92 | - // this uses a crudely exported nav api | |
93 | - const search = document.querySelector('input[type=search]') | |
94 | - | |
95 | 104 … | const { root, id } = msg.dataset |
96 | - if (!root) return search.go(id) | |
105 … | + if (!root) return goTo(id) | |
97 | 106 … | |
98 | - search.go(root) | |
107 … | + goTo(root) | |
99 | 108 … | scrollDownToMessage(id, tabs) |
100 | 109 … | } |
101 | 110 … | |
102 | 111 … | function scrollDownToMessage (id, tabs) { |
103 | - tabs.get(tabs.selected[0]).firstChild.scroll('first') | |
112 … | + tabs.getCurrent().firstChild.scroll('first') | |
104 | 113 … | locateKey() |
105 | 114 … | |
106 | 115 … | function locateKey () { |
107 | - const msg = tabs.get(tabs.selected[0]).querySelector(`[data-id='${id}']`) | |
116 … | + const msg = tabs.getCurrent().querySelector(`[data-id='${id}']`) | |
108 | 117 … | if (msg === null) return setTimeout(locateKey, 100) |
109 | 118 … | |
110 | 119 … | ;(msg.scrollIntoViewIfNeeded || msg.scrollIntoView).call(msg) |
111 | 120 … | msg.focus() |
app/sync/goTo.js | |||
---|---|---|---|
@@ -3,28 +3,21 @@ | |||
3 | 3 … | exports.gives = nest({ 'app.sync.goTo': true }) | |
4 | 4 … | ||
5 | 5 … | exports.needs = nest({ | |
6 | 6 … | 'app.html.tabs': 'first', | |
7 | - 'app.sync.addPage': 'first' | ||
7 … | + 'app.sync.addPage': 'first' | ||
8 | 8 … | }) | |
9 | 9 … | ||
10 | 10 … | exports.create = function (api) { | |
11 | - return nest({ | ||
12 | - 'app.sync': { | ||
13 | - goTo | ||
14 | - } | ||
15 | - }) | ||
16 | - | ||
17 | - function goTo (path, change) { | ||
11 … | + return nest('app.sync.goTo', function goTo (path, change) { | ||
18 | 12 … | const tabs = api.app.html.tabs() | |
19 | 13 … | ||
20 | 14 … | if (tabs.has(path)) { | |
21 | 15 … | tabs.select(path) | |
22 | 16 … | return true | |
23 | 17 … | } | |
24 | 18 … | ||
25 | - addPage(path, true, false) | ||
19 … | + api.app.sync.addPage(path, true, false) | ||
26 | 20 … | return change | |
27 | - } | ||
28 | - | ||
21 … | + }) | ||
29 | 22 … | } | |
30 | 23 … |
message/html/render/follow.js | ||
---|---|---|
@@ -1,6 +1,7 @@ | ||
1 | 1 … | const nest = require('depnest') |
2 | 2 … | const extend = require('xtend') |
3 … | +const { isFeed } = require('ssb-ref') | |
3 | 4 … | |
4 | 5 … | exports.gives = nest('message.html.render') |
5 | 6 … | |
6 | 7 … | exports.needs = nest({ |
@@ -16,9 +17,9 @@ | ||
16 | 17 … | |
17 | 18 … | function follow (msg, opts) { |
18 | 19 … | const { type, contact, following } = msg.value.content |
19 | 20 … | if (type !== 'contact') return |
20 | - if (!contact) return | |
21 … | + if (!isFeed(contact)) return | |
21 | 22 … | |
22 | 23 … | const element = api.message.html.layout(msg, extend({ |
23 | 24 … | content: renderContent({ contact, following }), |
24 | 25 … | layout: 'mini' |
package.json | ||
---|---|---|
@@ -52,9 +52,9 @@ | ||
52 | 52 … | "patchcore": "^0.5.0", |
53 | 53 … | "pull-abortable": "^4.1.1", |
54 | 54 … | "pull-cat": "^1.1.11", |
55 | 55 … | "pull-next": "1.0.0", |
56 | - "pull-scroll": "^1.0.3", | |
56 … | + "pull-scroll": "^1.0.4", | |
57 | 57 … | "pull-stream": "^3.5.0", |
58 | 58 … | "read-directory": "^2.0.0", |
59 | 59 … | "setimmediate": "^1.0.5", |
60 | 60 … | "ssb-horcrux": "0.1.2", |
Built with git-ssb-web