git ssb

0+

alanz / patchwork



forked from Matt McKegg / patchwork

Tree: d14a37cca1e80d539fdba2a00bed84a118e0892f

Files: d14a37cca1e80d539fdba2a00bed84a118e0892f / main-window.js

4960 bytesRaw
1var combine = require('depject')
2var entry = require('depject/entry')
3var electron = require('electron')
4var h = require('mutant/h')
5var when = require('mutant/when')
6var onceTrue = require('mutant/once-true')
7var computed = require('mutant/computed')
8var catchLinks = require('./lib/catch-links')
9var insertCss = require('insert-css')
10var nest = require('depnest')
11var LatestUpdate = require('./lib/latest-update')
12var ref = require('ssb-ref')
13var setupContextMenuAndSpellCheck = require('./lib/context-menu-and-spellcheck')
14var watch = require('mutant/watch')
15
16module.exports = function (config) {
17 var sockets = combine(
18 overrideConfig(config),
19 addCommand('app.navigate', setView),
20 require('./modules'),
21 require('./plugs'),
22 require('patchcore'),
23 require('./overrides')
24 )
25
26 var api = entry(sockets, nest({
27 'config.sync.load': 'first',
28 'keys.sync.id': 'first',
29 'sbot.obs.connection': 'first',
30 'sbot.async.get': 'first',
31 'blob.sync.url': 'first',
32 'page.html.render': 'first',
33 'app.html.search': 'first',
34 'app.html.channels': 'first',
35 'app.views': 'first',
36 'app.sync.externalHandler': 'first',
37 'app.html.progressNotifier': 'first',
38 'profile.sheet.edit': 'first',
39 'app.navigate': 'first'
40 }))
41
42 setupContextMenuAndSpellCheck(api.config.sync.load())
43
44 var id = api.keys.sync.id()
45 var latestUpdate = LatestUpdate()
46
47 // prompt to setup profile on first use
48 onceTrue(api.sbot.obs.connection, (sbot) => {
49 sbot.latestSequence(sbot.id, (_, key) => {
50 if (key == null) {
51 api.profile.sheet.edit()
52 }
53 })
54 })
55
56 var views = api.app.views(api.page.html.render, [
57 '/public', '/private', '/gatherings', id, '/mentions'
58 ])
59
60 var pendingCount = computed([
61 views.get('/public').pendingUpdates,
62 views.get('/private').pendingUpdates
63 ], (...counts) => {
64 return counts.reduce((a, b) => a + b)
65 })
66
67 watch(pendingCount, count => {
68 electron.remote.app.setBadgeCount(count)
69 })
70
71 insertCss(require('./styles'))
72
73 var container = h(`MainWindow -${process.platform}`, [
74 h('div.top', [
75 h('span.history', [
76 h('a', {
77 'ev-click': views.goBack,
78 classList: [ when(views.canGoBack, '-active') ]
79 }),
80 h('a', {
81 'ev-click': views.goForward,
82 classList: [ when(views.canGoForward, '-active') ]
83 })
84 ]),
85 h('span.nav', [
86 tab('Public', '/public'),
87 tab('Private', '/private'),
88 tab('Gatherings', '/gatherings')
89 ]),
90 h('span.appTitle', [
91 h('span.title', 'Patchwork'),
92 api.app.html.progressNotifier()
93 ]),
94 h('span', [ api.app.html.search(api.app.navigate) ]),
95 h('span.nav', [
96 tab('Profile', id),
97 tab('Mentions', '/mentions')
98 ])
99 ]),
100 when(latestUpdate,
101 h('div.info', [
102 h('a.message -update', { href: 'https://github.com/ssbc/patchwork/releases' }, [
103 h('strong', ['Patchwork ', latestUpdate, ' has been released.']), ' Click here to download and view more info!',
104 h('a.ignore', {'ev-click': latestUpdate.ignore}, 'X')
105 ])
106 ])
107 ),
108 views.html
109 ])
110
111 catchLinks(container, (href, external) => {
112 if (external) {
113 electron.shell.openExternal(href)
114 } else if (ref.isBlob(href)) {
115 electron.shell.openExternal(api.blob.sync.url(href))
116 } else if (ref.isMsg(href)) {
117 getExternalHandler(href, (err, handler) => {
118 if (err) throw err
119 if (handler) {
120 handler(href)
121 } else {
122 api.app.navigate(href)
123 }
124 })
125 } else {
126 api.app.navigate(href)
127 }
128 })
129
130 return container
131
132 // scoped
133
134 function setView (href) {
135 views.setView(href)
136 }
137
138 function getExternalHandler (key, cb) {
139 api.sbot.async.get(key, function (err, value) {
140 if (err) return cb(err)
141 cb(null, api.app.sync.externalHandler({key, value}))
142 })
143 }
144
145 function tab (name, view) {
146 var instance = views.get(view)
147 return h('a', {
148 'ev-click': function (ev) {
149 if (instance.pendingUpdates && instance.pendingUpdates() && instance.reload) {
150 instance.reload()
151 }
152 },
153 href: view,
154 classList: [
155 when(selected(view), '-selected')
156 ]
157 }, [
158 name,
159 when(instance.pendingUpdates, [
160 ' (', instance.pendingUpdates, ')'
161 ])
162 ])
163 }
164
165 function selected (view) {
166 return computed([views.currentView, view], (currentView, view) => {
167 return currentView === view
168 })
169 }
170}
171
172function overrideConfig (config) {
173 return {
174 'patchwork/config': {
175 gives: nest('config.sync.load'),
176 create: function (api) {
177 return nest('config.sync.load', () => config)
178 }
179 }
180 }
181}
182
183function addCommand (id, cb) {
184 return {
185 [`patchwork/command/${id}`]: {
186 gives: nest(id),
187 create: function (api) {
188 return nest(id, cb)
189 }
190 }
191 }
192}
193

Built with git-ssb-web