experiments in a post-browser web
10
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge pull request #32 from autonome/gen

Gen

authored by

Dietrich Ayala and committed by
GitHub
a7d03e13 e8fd684a

+319 -46
+9 -2
app/index.js
··· 34 34 } 35 35 */ 36 36 37 - const height = prefs.height || 600; 38 - const width = prefs.width || 800; 37 + // Get screen dimensions from window object 38 + const screenWidth = window.screen.availWidth; 39 + const screenHeight = window.screen.availHeight; 40 + 41 + // Calculate 80% of screen dimensions 42 + const width = Math.floor(screenWidth * 0.8); 43 + const height = Math.floor(screenHeight * 0.8); 44 + 45 + console.log(`Setting window size to ${width}x${height} (80% of ${screenWidth}x${screenHeight})`); 39 46 40 47 const params = { 41 48 debug,
+88 -23
app/settings/settings.css
··· 3 3 font-feature-settings: "tnum"; 4 4 font-size: 12.4px; 5 5 font-variant-numeric: tabular-nums; 6 - /*margin: 12px;*/ 6 + background-color: transparent; 7 + margin: 0; 8 + padding: 0; 9 + box-sizing: border-box; 7 10 } 8 11 12 + .houseofpane { 13 + /* 14 + display: flex; 15 + flex-wrap: wrap; 16 + flex-flow: column-wrap; 17 + gap: 24px; 18 + justify-content: flex-start; 19 + align-items: flex-start; 20 + */ 21 + columns: 4; 22 + margin: 20px; 23 + padding: 20px; 24 + background-color: transparent; 25 + width: 100%; 26 + box-sizing: border-box; 27 + } 28 + 29 + /* lil-gui */ 30 + .houseofpane > div { 31 + flex: 0 0 auto; 32 + margin-bottom: 24px; 33 + /* 34 + box-shadow: 0 3px 12px rgba(0, 0, 0, 0.1); 35 + border-radius: 10px; 36 + overflow: hidden; 37 + */ 38 + min-width: 260px; 39 + max-width: 450px; 40 + } 41 + 42 + /* Override lil-gui to look better with transparent background */ 43 + .lil-gui { 44 + --background-color: rgba(255, 255, 255, 0.8); 45 + --widget-color: rgba(240, 240, 240, 0.9); 46 + --hover-color: rgba(245, 245, 245, 0.95); 47 + background: var(--background-color); 48 + border-radius: 10px; 49 + overflow: hidden; 50 + width: auto !important; 51 + min-width: 260px; 52 + } 53 + 54 + /* Make folders look nicer */ 9 55 /* 10 - body > div { 11 - margin-bottom: 10px; 56 + .lil-gui .title { 57 + padding: 10px 12px !important; 58 + font-size: 12px !important; 59 + } 60 + 61 + .lil-gui .children { 62 + padding: 6px 12px 10px !important; 63 + max-height: 400px; 64 + overflow-y: auto; 12 65 } 66 + */ 13 67 14 - body > div > div { 15 - margin-bottom: 10px; 68 + /* Controllers for wider columns */ 69 + .lil-gui .controller { 70 + min-height: 28px !important; 71 + padding: 0 12px !important; 16 72 } 17 73 18 - h1 { 19 - margin-top: 1px; 20 - margin-bottom: 2px; 74 + .lil-gui .controller .name { 75 + font-size: 11px !important; 76 + width: 40% !important; 21 77 } 22 78 23 - */ 24 - .houseofpane { 25 - justify-content: space-between; 26 - columns: 3; 79 + .lil-gui .controller .widget { 80 + width: 60% !important; 27 81 } 28 82 29 - .houseofpane { 30 - background-color: black; 31 - padding-top: 20px; 83 + /* Responsive adjustments */ 84 + @media (max-width: 768px) { 85 + .houseofpane { 86 + padding: 16px; 87 + gap: 16px; 88 + justify-content: center; 89 + } 90 + 91 + .houseofpane > div { 92 + min-width: 280px; 93 + max-width: 100%; 94 + width: 100%; 95 + } 32 96 } 33 97 34 - /* lil-gui */ 35 - .houseofpane > div { 36 - /* 37 - min-width: 380px; 38 - max-width: 800px; 39 - */ 40 - /*margin-bottom: 10px;*/ 41 - break-inside: avoid-column; 98 + @media (max-width: 480px) { 99 + .houseofpane { 100 + padding: 8px; 101 + gap: 12px; 102 + } 103 + 104 + .houseofpane > div { 105 + min-width: 100%; 106 + } 42 107 }
+7
app/settings/settings.js
··· 95 95 96 96 const guiFeature = (features, feature, i, gui) => { 97 97 const folder = gui.addFolder(feature.name); 98 + folder.close(); 98 99 addToGUI(folder, 'Description', feature.description).disable(); 99 100 addToGUI(folder, 'Enabled', feature.enabled).onChange(e => { 100 101 // TODO: validate new value against schema ··· 118 119 119 120 const guiPeeks = (items, item, i, gui) => { 120 121 const folder = gui.addFolder(item.title); 122 + folder.close(); 121 123 122 124 addToGUI(folder, 'Key mapping', item.keyNum).disable(); 123 125 addToGUI(folder, 'Address to load', item.address).onChange(e => { ··· 142 144 143 145 const guiScripts = (items, item, i, gui) => { 144 146 const folder = gui.addFolder(item.title); 147 + folder.close(); 145 148 146 149 addToGUI(folder, 'Id', item.id).onChange(e => { 147 150 items[i].id = e; ··· 175 178 176 179 const guiSlides = (items, item, i, gui) => { 177 180 const folder = gui.addFolder(item.title); 181 + folder.close(); 178 182 179 183 addToGUI(folder, 'Screen edge', item.screenEdge).disable(); 180 184 addToGUI(folder, 'Address to load', item.address).onChange(e => { ··· 202 206 203 207 settingsGUI(container, appConfig, guiFeature); 204 208 209 + const byName = {}; 205 210 for (const i in fc) { 206 211 const name = fc[i].labels.name; 212 + byName[ fc[i].labels.name ] = i; 207 213 settingsGUI(container, fc[i], panels[name]); 208 214 } 215 + 209 216 }; 210 217 211 218 window.addEventListener('load', init);
+168 -9
index.js
··· 92 92 93 93 // specify various app data paths and make if not exist 94 94 const defaultUserDataPath = app.getPath('userData'); 95 - const profileDataPath = path.join(defaultUserDataPath, PROFILE); 96 - const sessionDataPath = path.join(profileDataPath, 'chromium'); 95 + const profileDataPath = path.join(defaultUserDataPath, PROFILE); 96 + const sessionDataPath = path.join(profileDataPath, 'chromium'); 97 97 98 98 //console.log('udp', defaultUserDataPath); 99 99 //console.log('pdp', profileDataPath); ··· 268 268 pathname = 'background.html'; 269 269 } 270 270 } 271 - 272 271 const isNode = pathname.indexOf('node_modules') > -1; 273 272 274 273 const hackedPath = isNode ··· 294 293 295 294 // NOTE: commented out since relative paths seem to get 296 295 // filtered out before this?! 297 - 296 + 298 297 // NB, this checks for paths that escape the bundle, e.g. 299 298 // app://bundle/../../secret_file.txt 300 299 /* ··· 347 346 console.log('hiding dock'); 348 347 app.dock.hide(); 349 348 } 350 - 349 + 351 350 // initialize system tray 352 351 if (msg.prefs.showTrayIcon == true) { 353 352 console.log('showing tray'); ··· 454 453 } 455 454 } 456 455 } 456 + }); 457 457 458 + // Window API handlers 459 + ipcMain.handle('window-open', async (ev, msg) => { 460 + console.log('window-open', msg); 461 + 462 + const { url, options } = msg; 463 + const win = new BrowserWindow({ 464 + width: options.width || APP_DEF_WIDTH, 465 + height: options.height || APP_DEF_HEIGHT, 466 + show: options.show !== false, 467 + webPreferences: { 468 + preload: preloadPath 469 + } 470 + }); 471 + 472 + try { 473 + await win.loadURL(url); 474 + 475 + // Add to windows cache 476 + _windows.set(win.id, { 477 + id: win.id, 478 + source: msg.source, 479 + params: { ...options, address: url } 480 + }); 481 + 482 + return { success: true, id: win.id }; 483 + } catch (error) { 484 + console.error('Failed to open window:', error); 485 + return { success: false, error: error.message }; 486 + } 487 + }); 488 + 489 + ipcMain.handle('window-close', async (ev, msg) => { 490 + console.log('window-close', msg); 491 + 492 + try { 493 + if (!msg.id) { 494 + return { success: false, error: 'Window ID is required' }; 495 + } 496 + 497 + const win = BrowserWindow.fromId(msg.id); 498 + if (!win) { 499 + return { success: false, error: 'Window not found' }; 500 + } 501 + 502 + win.close(); 503 + return { success: true }; 504 + } catch (error) { 505 + console.error('Failed to close window:', error); 506 + return { success: false, error: error.message }; 507 + } 508 + }); 509 + 510 + ipcMain.handle('window-hide', async (ev, msg) => { 511 + console.log('window-hide', msg); 512 + 513 + try { 514 + if (!msg.id) { 515 + return { success: false, error: 'Window ID is required' }; 516 + } 517 + 518 + const win = BrowserWindow.fromId(msg.id); 519 + if (!win) { 520 + return { success: false, error: 'Window not found' }; 521 + } 522 + 523 + win.hide(); 524 + return { success: true }; 525 + } catch (error) { 526 + console.error('Failed to hide window:', error); 527 + return { success: false, error: error.message }; 528 + } 529 + }); 530 + 531 + ipcMain.handle('window-show', async (ev, msg) => { 532 + console.log('window-show', msg); 533 + 534 + try { 535 + if (!msg.id) { 536 + return { success: false, error: 'Window ID is required' }; 537 + } 538 + 539 + const win = BrowserWindow.fromId(msg.id); 540 + if (!win) { 541 + return { success: false, error: 'Window not found' }; 542 + } 543 + 544 + win.show(); 545 + return { success: true }; 546 + } catch (error) { 547 + console.error('Failed to show window:', error); 548 + return { success: false, error: error.message }; 549 + } 550 + }); 551 + 552 + ipcMain.handle('window-move', async (ev, msg) => { 553 + console.log('window-move', msg); 554 + 555 + try { 556 + if (!msg.id) { 557 + return { success: false, error: 'Window ID is required' }; 558 + } 559 + 560 + const win = BrowserWindow.fromId(msg.id); 561 + if (!win) { 562 + return { success: false, error: 'Window not found' }; 563 + } 564 + 565 + if (typeof msg.x !== 'number' || typeof msg.y !== 'number') { 566 + return { success: false, error: 'Valid x and y coordinates are required' }; 567 + } 568 + 569 + win.setPosition(msg.x, msg.y); 570 + return { success: true }; 571 + } catch (error) { 572 + console.error('Failed to move window:', error); 573 + return { success: false, error: error.message }; 574 + } 575 + }); 576 + 577 + ipcMain.handle('window-focus', async (ev, msg) => { 578 + console.log('window-focus', msg); 579 + 580 + try { 581 + if (!msg.id) { 582 + return { success: false, error: 'Window ID is required' }; 583 + } 584 + 585 + const win = BrowserWindow.fromId(msg.id); 586 + if (!win) { 587 + return { success: false, error: 'Window not found' }; 588 + } 589 + 590 + win.focus(); 591 + return { success: true }; 592 + } catch (error) { 593 + console.error('Failed to focus window:', error); 594 + return { success: false, error: error.message }; 595 + } 596 + }); 597 + 598 + ipcMain.handle('window-blur', async (ev, msg) => { 599 + console.log('window-blur', msg); 600 + 601 + try { 602 + if (!msg.id) { 603 + return { success: false, error: 'Window ID is required' }; 604 + } 605 + 606 + const win = BrowserWindow.fromId(msg.id); 607 + if (!win) { 608 + return { success: false, error: 'Window not found' }; 609 + } 610 + 611 + win.blur(); 612 + return { success: true }; 613 + } catch (error) { 614 + console.error('Failed to blur window:', error); 615 + return { success: false, error: error.message }; 616 + } 458 617 }); 459 618 460 619 const modWindow = (bw, params) => { ··· 519 678 } 520 679 }; 521 680 522 - // esc handler 681 + // esc handler 523 682 // TODO: make user-configurable 524 683 const addEscHandler = bw => { 525 684 console.log('adding esc handler'); ··· 560 719 const overrides = { 561 720 devTools: true, //DEBUG || params.debug, 562 721 skipTaskbar: true, // TODO 563 - autoHideMenuBar: true, // TODO 564 - titleBarStyle: 'hidden', // TODO 722 + autoHideMenuBar: false, // TODO 723 + //titleBarStyle: 'hidden', // TODO 565 724 webPreferences: { 566 725 preload: preloadPath 567 726 } ··· 623 782 closeOrHideWindow(bw.id); 624 783 }); 625 784 } 626 - 785 + 627 786 // post actual close clean-up 628 787 bw.on('closed', () => { 629 788 console.log('dFL.onClosed: deleting ', bw.id, ' for ', url);
+47 -12
preload.js
··· 130 130 }; 131 131 132 132 api.window = { 133 - close: target => { 134 - console.log('window.close', target); 135 - 136 - if (target === null) { 133 + open: (url, options = {}) => { 134 + console.log('window.open', url, options); 135 + return ipcRenderer.invoke('window-open', { 136 + source: sourceAddress, 137 + url, 138 + options 139 + }); 140 + }, 141 + close: (id = null) => { 142 + console.log('window.close', id); 143 + if (id === null) { 137 144 window.close(); 138 145 return; 139 146 } 140 - 141 - ipcRenderer.send('modifywindow', { 147 + return ipcRenderer.invoke('window-close', { 148 + source: sourceAddress, 149 + id 150 + }); 151 + }, 152 + hide: (id) => { 153 + console.log('window.hide', id); 154 + return ipcRenderer.invoke('window-hide', { 155 + source: sourceAddress, 156 + id 157 + }); 158 + }, 159 + show: (id) => { 160 + console.log('window.show', id); 161 + return ipcRenderer.invoke('window-show', { 142 162 source: sourceAddress, 143 - params: { 144 - action: 'close' 145 - } 163 + id 146 164 }); 147 165 }, 148 - hide: () => { 166 + move: (id, x, y) => { 167 + console.log('window.move', id, x, y); 168 + return ipcRenderer.invoke('window-move', { 169 + source: sourceAddress, 170 + id, 171 + x, 172 + y 173 + }); 149 174 }, 150 - move: () => { 175 + focus: (id) => { 176 + console.log('window.focus', id); 177 + return ipcRenderer.invoke('window-focus', { 178 + source: sourceAddress, 179 + id 180 + }); 151 181 }, 152 - show: () => { 182 + blur: (id) => { 183 + console.log('window.blur', id); 184 + return ipcRenderer.invoke('window-blur', { 185 + source: sourceAddress, 186 + id 187 + }); 153 188 } 154 189 }; 155 190