git ssb

1+

Daan Patchwork / patchwork



Tree: d3826fa5570d6a70af4cd9401fe6f9284ec0ef5c

Files: d3826fa5570d6a70af4cd9401fe6f9284ec0ef5c / index.js

7555 bytesRaw
1process.on('uncaughtException', function (err) {
2 console.log(err)
3 process.exit()
4})
5
6const electron = require('electron')
7const openWindow = require('./lib/window')
8
9const Path = require('path')
10const defaultMenu = require('electron-default-menu')
11const WindowState = require('electron-window-state')
12const Menu = electron.Menu
13const extend = require('xtend')
14const ssbKeys = require('ssb-keys')
15
16const windows = {
17 dialogs: new Set()
18}
19let ssbConfig = null
20let quitting = false
21
22/**
23 * It's not possible to run two instances of patchwork as it would create two
24 * ssb-server instances that conflict on the same port. Before opening patchwork,
25 * we check if it's already running and if it is we focus the existing window
26 * rather than opening a new instance.
27 */
28function quitIfAlreadyRunning () {
29 if (!electron.app.requestSingleInstanceLock()) {
30 console.log('Patchwork is already running!')
31 console.log('Please close the existing instance before starting a new one.')
32 return electron.app.quit()
33 }
34 electron.app.on('second-instance', () => {
35 // Someone tried to run a second instance, we should focus our window.
36 if (windows.main) {
37 if (windows.main.isMinimized()) windows.main.restore()
38 windows.main.focus()
39 }
40 })
41}
42
43const config = {
44 server: !(process.argv.includes('-g') || process.argv.includes('--use-global-ssb'))
45}
46// a flag so we don't start git-ssb-web if a custom path is passed in
47if (process.argv.includes('--path')) {
48 config.customPath = true
49}
50
51quitIfAlreadyRunning()
52
53electron.app.on('ready', () => {
54 setupContext(process.env.ssb_appname || 'ssb', {
55 server: !(process.argv.includes('-g') || process.argv.includes('--use-global-ssb'))
56 }, () => {
57 const browserWindow = openMainWindow()
58
59 browserWindow.on('app-command', (e, cmd) => {
60 switch (cmd) {
61 case 'browser-backward': {
62 browserWindow.webContents.send('goBack')
63 break
64 }
65 case 'browser-forward': {
66 browserWindow.webContents.send('goForward')
67 break
68 }
69 }
70 })
71
72 const menu = defaultMenu(electron.app, electron.shell)
73
74 menu.splice(4, 0, {
75 label: 'Navigation',
76 submenu: [
77 {
78 label: 'Activate Search Field',
79 accelerator: 'CmdOrCtrl+L',
80 click: () => {
81 browserWindow.webContents.send('activateSearch')
82 }
83 },
84 {
85 label: 'Back',
86 accelerator: 'CmdOrCtrl+[',
87 click: () => {
88 browserWindow.webContents.send('goBack')
89 }
90 },
91 {
92 label: 'Forward',
93 accelerator: 'CmdOrCtrl+]',
94 click: () => {
95 browserWindow.webContents.send('goForward')
96 }
97 },
98 {
99 type: 'separator'
100 },
101 {
102 label: 'Settings',
103 accelerator: 'CmdOrCtrl+,',
104 click: () => {
105 browserWindow.webContents.send('goToSettings')
106 }
107 }
108 ]
109 })
110
111 const view = menu.find(x => x.label === 'View')
112 view.submenu = [
113 { role: 'reload' },
114 { role: 'toggledevtools' },
115 { type: 'separator' },
116 { role: 'resetzoom' },
117 { role: 'zoomin', accelerator: 'CmdOrCtrl+=' },
118 { role: 'zoomout', accelerator: 'CmdOrCtrl+-' },
119 { type: 'separator' },
120 { role: 'togglefullscreen' }
121 ]
122 const help = menu.find(x => x.label === 'Help')
123 help.submenu = [
124 {
125 label: 'Learn More',
126 click () { require('electron').shell.openExternal('https://scuttlebutt.nz') }
127 }
128 ]
129 if (process.platform === 'darwin') {
130 const win = menu.find(x => x.label === 'Window')
131 win.submenu = [
132 { role: 'minimize' },
133 { role: 'zoom' },
134 { role: 'close', label: 'Close' },
135 { type: 'separator' },
136 { role: 'front' }
137 ]
138 }
139
140 Menu.setApplicationMenu(Menu.buildFromTemplate(menu))
141 })
142
143 electron.app.on('activate', function () {
144 if (windows.main) {
145 windows.main.show()
146 }
147 })
148
149 electron.app.on('before-quit', function () {
150 quitting = true
151 })
152
153 electron.ipcMain.on('open-background-devtools', function () {
154 if (windows.background) {
155 windows.background.webContents.openDevTools({ mode: 'detach' })
156 }
157 })
158})
159
160function openMainWindow () {
161 if (!windows.main) {
162 const windowState = WindowState({
163 defaultWidth: 1024,
164 defaultHeight: 768
165 })
166 windows.main = openWindow(ssbConfig, Path.join(__dirname, 'lib', 'main-window.js'), {
167 minWidth: 800,
168 x: windowState.x,
169 y: windowState.y,
170 width: windowState.width,
171 height: windowState.height,
172 titleBarStyle: 'hiddenInset',
173 autoHideMenuBar: true,
174 title: 'Patchwork',
175 show: true,
176 backgroundColor: '#EEE',
177 icon: Path.join(__dirname, 'assets/icon.png')
178 })
179
180 windowState.manage(windows.main)
181 windows.main.setSheetOffset(40)
182 windows.main.on('close', function (e) {
183 if (!quitting && process.platform === 'darwin') {
184 e.preventDefault()
185 windows.main.hide()
186 }
187 })
188 windows.main.on('closed', function () {
189 windows.main = null
190 if (process.platform !== 'darwin') electron.app.quit()
191 })
192 }
193 return windows.main
194}
195
196function setupContext (appName, opts, cb) {
197 ssbConfig = require('ssb-config/inject')(appName, extend({
198 port: 8008,
199 blobsPort: 8989, // matches ssb-ws
200 friends: { // not using ssb-friends (sbot/contacts fixes hops at 2, so this setting won't do anything)
201 dunbar: 150,
202 hops: 2 // down from 3
203 }
204 }, opts))
205
206 // disable gossip auto-population from {type: 'pub'} messages as we handle this manually in sbot/index.js
207 if (!ssbConfig.gossip) ssbConfig.gossip = {}
208 ssbConfig.gossip.autoPopulate = false
209
210 ssbConfig.keys = ssbKeys.loadOrCreateSync(Path.join(ssbConfig.path, 'secret'))
211
212 const keys = ssbConfig.keys
213 const pubkey = keys.id.slice(1).replace(`.${keys.curve}`, '')
214
215 if (process.platform === 'win32') {
216 // fix offline on windows by specifying 127.0.0.1 instead of localhost (default)
217 ssbConfig.remote = `net:127.0.0.1:${ssbConfig.port}~shs:${pubkey}`
218 } else {
219 const socketPath = Path.join(ssbConfig.path, 'socket')
220 ssbConfig.connections.incoming.unix = [{ scope: 'device', transform: 'noauth' }]
221 ssbConfig.remote = `unix:${socketPath}:~noauth:${pubkey}`
222 }
223
224 // Support rooms
225 ssbConfig.connections.incoming.tunnel = [{ scope: 'public', transform: 'shs' }]
226 ssbConfig.connections.outgoing.tunnel = [{ transform: 'shs' }]
227
228 // Support DHT invites (only as a client, for now)
229 ssbConfig.connections.outgoing.dht = [{ transform: 'shs' }]
230
231 const redactedConfig = JSON.parse(JSON.stringify(ssbConfig))
232 redactedConfig.keys.private = null
233 console.dir(redactedConfig, { depth: null })
234
235 if (opts.server === false) {
236 cb && cb()
237 } else {
238 electron.ipcMain.once('server-started', function (ev, config) {
239 ssbConfig = config
240 cb && cb()
241 })
242 windows.background = openWindow(ssbConfig, Path.join(__dirname, 'lib', 'server-process.js'), {
243 connect: false,
244 center: true,
245 fullscreen: false,
246 fullscreenable: false,
247 height: 150,
248 maximizable: false,
249 minimizable: false,
250 resizable: false,
251 show: false,
252 skipTaskbar: true,
253 title: 'patchwork-server',
254 useContentSize: true,
255 width: 150
256 })
257 // windows.background.on('close', (ev) => {
258 // ev.preventDefault()
259 // windows.background.hide()
260 // })
261 }
262}
263

Built with git-ssb-web