Commit 18c1a9e02d04c233f4fbf7182d7079ac6419e0e9
refactor - extract sync initializers to tidy app.html.app
mix irving committed on 10/17/2017, 2:15:54 AMParent: 55f65b5f081677702c9c21215926ac33bbda7272
Files changed
app/html/app.js | changed |
app/html/blog-card.mcss | changed |
app/index.js | changed |
app/page/blogIndex.js | changed |
app/page/blogIndex.mcss | changed |
app/page/page.mcss | changed |
app/page/blogShow.js | added |
app/sync/initialize/clickHandler.js | added |
app/sync/initialize/styles.js | added |
app/sync/initialize/suggests.js | added |
app/sync/nav-history.js | added |
styles/mixins.js | changed |
app/html/app.js | ||
---|---|---|
@@ -1,79 +1,19 @@ | ||
1 | 1 | const nest = require('depnest') |
2 | -const values = require('lodash/values') | |
3 | -const insertCss = require('insert-css') | |
4 | -const openExternal = require('open-external') | |
5 | 2 | |
6 | -const HyperNav = require('hyper-nav') | |
7 | -const computed = require('mutant/computed') | |
8 | -const h = require('mutant/h') | |
3 | +exports.gives = nest('app.html.app') | |
9 | 4 | |
10 | -exports.gives = nest({ | |
11 | - 'app.html.app': true, | |
12 | - 'history.obs.history': true, | |
13 | - 'history.sync.push': true, | |
14 | - 'history.sync.back': true, | |
15 | -}) | |
16 | - | |
17 | 5 | exports.needs = nest({ |
18 | - 'about.async.suggest': 'first', | |
19 | - 'app.html.header': 'first', | |
20 | - 'app.async.catchLinkClick': 'first', | |
21 | - 'channel.async.suggest': 'first', | |
22 | - 'keys.sync.id': 'first', | |
23 | - 'router.sync.router': 'first', | |
24 | - 'settings.sync.get': 'first', | |
25 | - 'settings.sync.set': 'first', | |
26 | - 'styles.css': 'reduce', | |
6 | + 'app.sync.initialize': 'map', | |
7 | + 'app.sync.nav': 'first' | |
27 | 8 | }) |
28 | 9 | |
29 | 10 | exports.create = (api) => { |
30 | - var nav = null | |
31 | - | |
32 | 11 | return nest({ |
33 | 12 | 'app.html.app': function app () { |
13 | + api.app.sync.initialize() | |
34 | 14 | |
35 | - // DIRTY HACK - initializes the suggestion indexes | |
36 | - api.about.async.suggest() | |
37 | - api.channel.async.suggest() | |
38 | - | |
39 | - const css = values(api.styles.css()).join('\n') | |
40 | - insertCss(css) | |
41 | - | |
42 | - api.app.async.catchLinkClick(document.body, (link, { isExternal }) => { | |
43 | - if (isExternal) return openExternal(link) | |
44 | - nav.push(link) | |
45 | - }) | |
46 | - | |
47 | - nav = HyperNav( | |
48 | - api.router.sync.router, | |
49 | - api.app.html.header | |
50 | - ) | |
51 | - | |
52 | - const isOnboarded = api.settings.sync.get('onboarded') | |
53 | - if (isOnboarded) | |
54 | - nav.push({page: 'home'}) | |
55 | - else { | |
56 | - nav.push({ | |
57 | - page:'userEdit', | |
58 | - feed: api.keys.sync.id(), | |
59 | - callback: (err, didEdit) => { | |
60 | - if (err) throw new Error ('Error editing profile', err) | |
61 | - | |
62 | - if (didEdit) | |
63 | - api.settings.sync.set({ onboarded: true }) | |
64 | - | |
65 | - nav.push({ page: 'home' }) | |
66 | - } | |
67 | - }) | |
68 | - } | |
69 | - | |
70 | - return nav | |
71 | - }, | |
72 | - 'history.sync.push': (location) => nav.push(location), | |
73 | - 'history.sync.back': () => nav.back(), | |
74 | - 'history.obs.history': () => nav.history, | |
15 | + return api.app.sync.nav() | |
16 | + } | |
75 | 17 | }) |
76 | 18 | } |
77 | 19 | |
78 | - | |
79 | - |
app/html/blog-card.mcss | ||
---|---|---|
@@ -1,14 +1,14 @@ | ||
1 | 1 | BlogCard { |
2 | 2 | padding: 1rem |
3 | 3 | background-color: #fff |
4 | - margin-bottom: .5rem | |
5 | 4 | |
6 | 5 | border: 1px solid #fff |
7 | 6 | transition: all .5s ease |
8 | 7 | |
9 | 8 | :hover { |
10 | - border: 1px solid #999 | |
9 | + border: 1px solid gainsboro | |
10 | + box-shadow: gainsboro 2px 2px 10px | |
11 | 11 | } |
12 | 12 | |
13 | 13 | display: flex |
14 | 14 | flex-direction: column |
app/index.js | ||
---|---|---|
@@ -12,8 +12,9 @@ | ||
12 | 12 | }, |
13 | 13 | page: { |
14 | 14 | blogIndex: require('./page/blogIndex'), |
15 | 15 | blogNew: require('./page/blogNew'), |
16 | + blogShow: require('./page/blogShow'), | |
16 | 17 | error: require('./page/error'), |
17 | 18 | settings: require('./page/settings'), |
18 | 19 | // channel: require('./page/channel'), |
19 | 20 | // image: require('./page/image'), |
@@ -27,7 +28,15 @@ | ||
27 | 28 | // userFind: require('./page/userFind'), |
28 | 29 | userShow: require('./page/userShow'), |
29 | 30 | threadNew: require('./page/threadNew'), |
30 | 31 | threadShow: require('./page/threadShow'), |
32 | + }, | |
33 | + sync: { | |
34 | + initialize: { | |
35 | + clickHandler: require('./sync/initialize/clickHandler'), | |
36 | + styles: require('./sync/initialize/styles'), | |
37 | + suggests: require('./sync/initialize/suggests'), | |
38 | + }, | |
39 | + navHistory: require('./sync/nav-history'), | |
31 | 40 | } |
32 | 41 | } |
33 | 42 |
app/page/blogIndex.js | ||
---|---|---|
@@ -54,9 +54,9 @@ | ||
54 | 54 | morePlease = true |
55 | 55 | requestIdleCallback(threadsObs.more) |
56 | 56 | } |
57 | 57 | |
58 | - var updates = h('div.threads', []) | |
58 | + var updates = h('div.blogs', []) | |
59 | 59 | contentHtmlObs = More( |
60 | 60 | threadsObsDebounced, |
61 | 61 | function render (threads) { |
62 | 62 | |
@@ -93,9 +93,9 @@ | ||
93 | 93 | .sort((a, b) => latestUpdate(b) - latestUpdate(a)) |
94 | 94 | |
95 | 95 | morphdom( |
96 | 96 | updates, |
97 | - h('div.threads', | |
97 | + h('div.blogs', | |
98 | 98 | groupedThreads.map(thread => { |
99 | 99 | const { recps, channel } = thread.value.content |
100 | 100 | var onClick |
101 | 101 | if (channel && !recps) |
app/page/blogIndex.mcss | ||
---|---|---|
@@ -1,7 +1,17 @@ | ||
1 | 1 | Page -blogIndex { |
2 | 2 | |
3 | 3 | div.content { |
4 | 4 | $backgroundPrimary |
5 | + | |
6 | + div.Button { | |
7 | + margin: 1rem 0 | |
8 | + } | |
9 | + | |
10 | + div.blogs { | |
11 | + div.BlogCard { | |
12 | + margin-bottom: .5rem | |
13 | + } | |
14 | + } | |
5 | 15 | } |
6 | 16 | } |
7 | 17 |
app/page/page.mcss | ||
---|---|---|
@@ -19,6 +19,7 @@ | ||
19 | 19 | flex-grow: 1 |
20 | 20 | |
21 | 21 | padding: 1rem |
22 | 22 | margin: 0 auto |
23 | + } | |
23 | 24 | } |
24 | 25 |
app/page/blogShow.js | ||
---|---|---|
@@ -1,0 +1,102 @@ | ||
1 | +const nest = require('depnest') | |
2 | +const { h, Array: MutantArray, computed, when, map } = require('mutant') | |
3 | +const pull = require('pull-stream') | |
4 | +const get = require('lodash/get') | |
5 | + | |
6 | +exports.gives = nest('app.page.userShow') | |
7 | + | |
8 | +exports.needs = nest({ | |
9 | + 'about.html.image': 'first', | |
10 | + 'about.obs.name': 'first', | |
11 | + 'app.html.link': 'first', | |
12 | + 'app.html.blogCard': 'first', | |
13 | + 'contact.async.follow': 'first', | |
14 | + 'contact.async.unfollow': 'first', | |
15 | + 'contact.obs.followers': 'first', | |
16 | + 'feed.pull.private': 'first', | |
17 | + 'feed.pull.rollup': 'first', | |
18 | + 'keys.sync.id': 'first', | |
19 | + 'state.obs.threads': 'first', | |
20 | + 'translations.sync.strings': 'first', | |
21 | +}) | |
22 | + | |
23 | +exports.create = (api) => { | |
24 | + return nest('app.page.userShow', userShow) | |
25 | + | |
26 | + function userShow (location) { | |
27 | + | |
28 | + const { feed } = location | |
29 | + const myId = api.keys.sync.id() | |
30 | + const name = api.about.obs.name(feed) | |
31 | + | |
32 | + const strings = api.translations.sync.strings() | |
33 | + | |
34 | + const { followers } = api.contact.obs | |
35 | + | |
36 | + const youFollowThem = computed(followers(feed), followers => followers.includes(myId)) | |
37 | + // const theyFollowYou = computed(followers(myId), followers => followers.includes(feed)) | |
38 | + // const youAreFriends = computed([youFollowThem, theyFollowYou], (a, b) => a && b) | |
39 | + | |
40 | + // const ourRelationship = computed( | |
41 | + // [youAreFriends, youFollowThem, theyFollowYou], | |
42 | + // (youAreFriends, youFollowThem, theyFollowYou) => { | |
43 | + // if (youAreFriends) return strings.userShow.state.friends | |
44 | + // if (theyFollowYou) return strings.userShow.state.theyFollow | |
45 | + // if (youFollowThem) return strings.userShow.state.youFollow | |
46 | + // } | |
47 | + // ) | |
48 | + const { unfollow, follow } = api.contact.async | |
49 | + const followButton = when(followers(myId).sync, | |
50 | + when(youFollowThem, | |
51 | + h('Button -primary', { 'ev-click': () => unfollow(feed) }, strings.userShow.action.unfollow), | |
52 | + h('Button -primary', { 'ev-click': () => follow(feed) }, strings.userShow.action.follow) | |
53 | + ), | |
54 | + h('Button', { disabled: 'disabled' }, strings.loading ) | |
55 | + ) | |
56 | + | |
57 | + const Link = api.app.html.link | |
58 | + const userEditButton = Link({ page: 'userEdit', feed }, h('i.fa.fa-pencil')) | |
59 | + const directMessageButton = Link({ page: 'threadNew', feed }, h('Button', strings.userShow.action.directMessage)) | |
60 | + | |
61 | + const threads = MutantArray() | |
62 | + pull( | |
63 | + // next(api.feed.pull.private, {reverse: true, limit: 100, live: false}, ['value', 'timestamp']), | |
64 | + // api.feed.pull.private({reverse: true, limit: 100, live: false}), | |
65 | + api.feed.pull.private({reverse: true, live: false}), | |
66 | + pull.filter(msg => { | |
67 | + const recps = get(msg, 'value.content.recps') | |
68 | + if (!recps) return | |
69 | + | |
70 | + return recps | |
71 | + .map(r => typeof r === 'object' ? r.link : r) | |
72 | + .includes(feed) | |
73 | + }), | |
74 | + api.feed.pull.rollup(), | |
75 | + pull.drain(threads.push) | |
76 | + // Scroller(content, scrollerContent, render, false, false) | |
77 | + ) | |
78 | + | |
79 | + return h('Page -userShow', {title: name}, [ | |
80 | + h('div.content', [ | |
81 | + h('section.about', [ | |
82 | + api.about.html.image(feed), | |
83 | + h('h1', [ | |
84 | + name, | |
85 | + feed === myId // Only expose own profile editing right now | |
86 | + ? userEditButton | |
87 | + : '' | |
88 | + ]), | |
89 | + feed !== myId | |
90 | + ? h('div.actions', [ | |
91 | + h('div.friendship', followButton), | |
92 | + h('div.directMessage', directMessageButton) | |
93 | + ]) | |
94 | + : '', | |
95 | + ]), | |
96 | + h('section.blogs', map(threads, api.app.html.blogCard)) | |
97 | + ]) | |
98 | + ]) | |
99 | + } | |
100 | +} | |
101 | + | |
102 | + |
app/sync/initialize/clickHandler.js | ||
---|---|---|
@@ -1,0 +1,21 @@ | ||
1 | +const nest = require('depnest') | |
2 | + | |
3 | +exports.gives = nest('app.sync.initialize') | |
4 | + | |
5 | +exports.needs = nest({ | |
6 | + 'app.async.catchLinkClick': 'first', | |
7 | + 'app.sync.nav': 'first', | |
8 | +}) | |
9 | + | |
10 | +exports.create = (api) => { | |
11 | + return nest({ | |
12 | + 'app.sync.initialize': function initializeClickHandling () { | |
13 | + api.app.async.catchLinkClick(document.body, (link, { isExternal }) => { | |
14 | + const nav = api.app.sync.nav() | |
15 | + | |
16 | + if (isExternal) return openExternal(link) | |
17 | + nav.push(link) | |
18 | + }) | |
19 | + } | |
20 | + }) | |
21 | +} |
app/sync/initialize/styles.js | ||
---|---|---|
@@ -1,0 +1,19 @@ | ||
1 | +const nest = require('depnest') | |
2 | +const insertCss = require('insert-css') | |
3 | +const values = require('lodash/values') | |
4 | + | |
5 | +exports.gives = nest('app.sync.initialize') | |
6 | + | |
7 | +exports.needs = nest({ | |
8 | + 'styles.css': 'reduce' | |
9 | +}) | |
10 | + | |
11 | +exports.create = (api) => { | |
12 | + return nest({ | |
13 | + 'app.sync.initialize': function initializeStyles () { | |
14 | + const css = values(api.styles.css()).join('\n') | |
15 | + insertCss(css) | |
16 | + } | |
17 | + }) | |
18 | +} | |
19 | + |
app/sync/initialize/suggests.js | ||
---|---|---|
@@ -1,0 +1,20 @@ | ||
1 | +const nest = require('depnest') | |
2 | + | |
3 | +exports.gives = nest('app.sync.initialize') | |
4 | + | |
5 | +exports.needs = nest({ | |
6 | + 'about.async.suggest': 'first', | |
7 | + 'channel.async.suggest': 'first' | |
8 | +}) | |
9 | + | |
10 | +exports.create = (api) => { | |
11 | + var nav = null | |
12 | + | |
13 | + return nest({ | |
14 | + 'app.sync.initialize': function initializeSuggests () { | |
15 | + api.about.async.suggest() | |
16 | + api.channel.async.suggest() | |
17 | + } | |
18 | + }) | |
19 | +} | |
20 | + |
app/sync/nav-history.js | ||
---|---|---|
@@ -1,0 +1,57 @@ | ||
1 | +const nest = require('depnest') | |
2 | +const HyperNav = require('hyper-nav') | |
3 | +const { h } = require('mutant') | |
4 | + | |
5 | +exports.gives = nest({ | |
6 | + 'app.sync.nav': true, | |
7 | + 'history.obs.history': true, | |
8 | + 'history.sync.push': true, | |
9 | + 'history.sync.back': true, | |
10 | +}) | |
11 | + | |
12 | +exports.needs = nest({ | |
13 | + 'app.html.header': 'first', | |
14 | + 'keys.sync.id': 'first', | |
15 | + 'router.sync.router': 'first', | |
16 | + 'settings.sync.get': 'first', | |
17 | + 'settings.sync.set': 'first', | |
18 | +}) | |
19 | + | |
20 | +exports.create = (api) => { | |
21 | + var nav = null | |
22 | + | |
23 | + return nest({ | |
24 | + 'app.sync.nav': function getNav () { | |
25 | + if (nav) return nav | |
26 | + | |
27 | + nav = HyperNav( | |
28 | + api.router.sync.router, | |
29 | + api.app.html.header | |
30 | + ) | |
31 | + | |
32 | + const isOnboarded = api.settings.sync.get('onboarded') | |
33 | + if (isOnboarded) | |
34 | + nav.push({page: 'home'}) | |
35 | + else { | |
36 | + nav.push({ | |
37 | + page:'userEdit', | |
38 | + feed: api.keys.sync.id(), | |
39 | + callback: (err, didEdit) => { | |
40 | + if (err) throw new Error ('Error editing profile', err) | |
41 | + | |
42 | + if (didEdit) | |
43 | + api.settings.sync.set({ onboarded: true }) | |
44 | + | |
45 | + nav.push({ page: 'home' }) | |
46 | + } | |
47 | + }) | |
48 | + } | |
49 | + | |
50 | + return nav | |
51 | + }, | |
52 | + 'history.sync.push': (location) => nav.push(location), | |
53 | + 'history.sync.back': () => nav.back(), | |
54 | + 'history.obs.history': () => nav.history, | |
55 | + }) | |
56 | +} | |
57 | + |
Built with git-ssb-web