Skip to content
This repository was archived by the owner on May 12, 2021. It is now read-only.

Commit 8a33480

Browse files
Do "More" drop-down without using electron.remote
This one was a bit tougher. Basically I'm now creating a *descriptive* structure on the renderer side, and then adding the event handlers on the server side. The event handlers then simply trigger a navigation IPC message.
1 parent a40d71e commit 8a33480

File tree

2 files changed

+117
-65
lines changed

2 files changed

+117
-65
lines changed

index.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,19 @@ electron.app.on('ready', () => {
150150
quitting = true
151151
})
152152

153+
electron.ipcMain.handle('navigation-menu-popup', (event, data) => {
154+
const {items, x, y} = data
155+
const window = event.sender
156+
const factor = event.sender.zoomFactor
157+
const menuItems = buildMenu(items, window)
158+
const menu = electron.Menu.buildFromTemplate(menuItems);
159+
menu.popup({
160+
window,
161+
x: Math.round(x * factor),
162+
y: Math.round(y * factor) + 4,
163+
});
164+
})
165+
153166
electron.ipcMain.handle('consoleLog', (ev, o) => console.log(o))
154167
electron.ipcMain.handle('consoleError', (ev, o) => console.error(o))
155168
electron.ipcMain.handle('badgeCount', (ev, count) => {
@@ -164,6 +177,34 @@ electron.app.on('ready', () => {
164177
})
165178
})
166179

180+
function buildMenu(items, window) {
181+
const result = []
182+
for (let item of items) {
183+
switch (item.type) {
184+
case 'separator':
185+
result.push(item)
186+
break
187+
case 'submenu':
188+
result.push({
189+
...item,
190+
submenu: buildMenu(item.submenu, window),
191+
})
192+
break
193+
case 'normal':
194+
result.push({
195+
...item,
196+
click: () => {
197+
window.send('navigate-to', item.target)
198+
}
199+
})
200+
break
201+
default:
202+
throw Error(`Unknown menu item of type "${item.type}": ${JSON.stringify(item, null, 2)}`);
203+
}
204+
}
205+
return result
206+
}
207+
167208
function openMainWindow () {
168209
if (!windows.main) {
169210
const windowState = WindowState({

lib/main-window.js

Lines changed: 76 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,10 @@ module.exports = function (config) {
142142

143143
electron.ipcRenderer.on('goToSettings', () => api.app.navigate('/settings'))
144144

145+
electron.ipcRenderer.on("navigate-to", (ev, target) => {
146+
navigate(target);
147+
});
148+
145149
document.head.appendChild(
146150
h('style', {
147151
innerHTML: computed(api.settings.obs.get('patchwork.theme', 'light'), themeName => {
@@ -211,21 +215,7 @@ module.exports = function (config) {
211215
h('span.nav', [
212216
tab(i18n('Public'), '/public'),
213217
tab(i18n('Private'), '/private'),
214-
dropTab(i18n('More'), [
215-
getSubscribedChannelMenu,
216-
subMenu(i18n('Participating'), [
217-
[i18n('All Threads'), '/participating'],
218-
[i18n('Threads Started By You'), '/your-posts']
219-
]),
220-
subMenu(i18n('Gatherings'), [
221-
[i18n('All'), '/gatherings'],
222-
[i18n('Attending'), '/attending-gatherings']
223-
]),
224-
[i18n('Tags'), `/tags/all/${encodeURIComponent(id)}`],
225-
[i18n('Extended Network'), '/all'],
226-
{ separator: true },
227-
[i18n('Settings'), '/settings']
228-
])
218+
dropTab(i18n('More'))
229219
]),
230220
h('span.appTitle', [
231221
h('span.title', i18n('Patchwork')),
@@ -265,78 +255,99 @@ module.exports = function (config) {
265255

266256
// scoped
267257

268-
function subMenu (label, items) {
269-
return function () {
270-
return {
271-
label,
272-
submenu: items.map(item => {
273-
return {
274-
label: item[0],
275-
click () {
276-
navigate(item[1])
277-
}
278-
}
279-
})
280-
}
281-
}
282-
}
283-
284258
function getSubscribedChannelMenu () {
285259
const channels = Array.from(subscribedChannels()).sort(localeCompare)
286260

287261
if (channels.length) {
288262
return {
263+
type: 'submenu',
289264
label: i18n('Channels'),
290265
submenu: [
291266
{
267+
type: 'normal',
292268
label: i18n('Browse Recently Active'),
293-
click () {
294-
navigate('/channels')
295-
}
269+
target: '/channels'
296270
},
297271
{ type: 'separator' }
298-
].concat(channels.map(channel => {
299-
return {
300-
label: `#${channel}`,
301-
click () {
302-
navigate(`#${channel}`)
303-
}
304-
}
305-
}))
272+
].concat(channels.map(channel => ({
273+
type: 'normal',
274+
label: `#${channel}`,
275+
target: `#${channel}`,
276+
})))
306277
}
307278
} else {
308279
return {
280+
type: 'normal',
309281
label: i18n('Browse Channels'),
310-
click () {
311-
navigate('/channels')
312-
}
282+
target: '/channels',
313283
}
314284
}
315285
}
316286

317-
function dropTab (title, items) {
287+
function buildDropdownMenuItems() {
288+
const dropTabItems = [
289+
getSubscribedChannelMenu(),
290+
{
291+
type: 'submenu',
292+
label: i18n("Participating"),
293+
submenu: [
294+
{
295+
type: "normal",
296+
label: i18n("All Threads"),
297+
target: "/participating",
298+
},
299+
{
300+
type: "normal",
301+
label: i18n("Threads Started By You"),
302+
target: "/your-posts",
303+
},
304+
],
305+
},
306+
{
307+
type: "submenu",
308+
label: i18n("Gatherings"),
309+
submenu: [
310+
{
311+
type: "normal",
312+
label: i18n("All"),
313+
target: "/gatherings",
314+
},
315+
{
316+
type: "normal",
317+
label: i18n("Attending"),
318+
target: "/attending-gatherings",
319+
},
320+
],
321+
},
322+
{
323+
type: "normal",
324+
label: i18n("Tags"),
325+
target: `/tags/all/${encodeURIComponent(id)}`,
326+
},
327+
{
328+
type: "normal",
329+
label: i18n("Extended Network"),
330+
target: "/all",
331+
},
332+
{ type: "separator" },
333+
{
334+
type: "normal",
335+
label: i18n("Settings"),
336+
target: "/settings",
337+
},
338+
];
339+
return dropTabItems
340+
}
341+
342+
function dropTab (title) {
318343
const element = h('a -drop', {
319344
'ev-click': () => {
345+
const dropTabItems = buildDropdownMenuItems()
320346
const rects = element.getBoundingClientRect()
321-
const factor = electron.remote.getCurrentWindow().webContents.zoomFactor
322-
const menu = electron.remote.Menu.buildFromTemplate(items.map(item => {
323-
if (typeof item === 'function') {
324-
return item()
325-
} else if (item.separator) {
326-
return { type: 'separator' }
327-
} else {
328-
return {
329-
label: item[0],
330-
click () {
331-
navigate(item[1])
332-
}
333-
}
334-
}
335-
}))
336-
menu.popup({
337-
window: electron.remote.getCurrentWindow(),
338-
x: Math.round(rects.left * factor),
339-
y: Math.round(rects.bottom * factor) + 4
347+
electron.ipcRenderer.invoke('navigation-menu-popup', {
348+
x: rects.left,
349+
y: rects.bottom,
350+
items: dropTabItems,
340351
})
341352
}
342353
}, title)

0 commit comments

Comments
 (0)