experiments in a post-browser web
10
fork

Configure Feed

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

feat(groups): auto-tag items with group tag when created in group mode

+71 -3
+68
backend/electron/ipc.ts
··· 292 292 } 293 293 294 294 /** 295 + * Auto-tag an item with the group tag if the calling window is in group mode. 296 + * Returns true if the item was tagged. 297 + */ 298 + function autoTagIfGroupMode(ev: Electron.IpcMainInvokeEvent, itemId: string): boolean { 299 + try { 300 + const callingWin = BrowserWindow.fromWebContents(ev.sender); 301 + if (!callingWin || callingWin.isDestroyed()) return false; 302 + const modeEntry = getContextEntry('mode', callingWin.id); 303 + if (modeEntry && modeEntry.value === 'group' && modeEntry.metadata?.groupId) { 304 + const groupId = modeEntry.metadata.groupId as string; 305 + tagItem(itemId, groupId); 306 + DEBUG && console.log('[ipc] Auto-tagged item', itemId, 'with group', groupId); 307 + return true; 308 + } 309 + } catch (e) { 310 + DEBUG && console.log('[ipc] autoTagIfGroupMode error:', e); 311 + } 312 + return false; 313 + } 314 + 315 + /** 295 316 * Register datastore IPC handlers 296 317 */ 297 318 export function registerDatastoreHandlers(): void { ··· 323 344 itemType: 'url', 324 345 content: normalizedUri 325 346 }); 347 + 348 + // Auto-tag with group if calling window is in group mode 349 + autoTagIfGroupMode(ev, result.id); 326 350 327 351 return { success: true, data: result, id: result.id }; 328 352 } catch (error) { ··· 669 693 }); 670 694 if (DEBUG) console.log('[ipc] item:created', result.id, data.type); 671 695 696 + // Auto-tag with group if calling window is in group mode 697 + autoTagIfGroupMode(ev, result.id); 698 + 672 699 return { success: true, data: result }; 673 700 } catch (error) { 674 701 const message = error instanceof Error ? error.message : String(error); ··· 891 918 ipcMain.handle('datastore-track-navigation', async (ev, data) => { 892 919 try { 893 920 const result = trackNavigation(data.uri, data.options); 921 + 922 + // Auto-tag with group if calling window is in group mode 923 + autoTagIfGroupMode(ev, result.itemId); 924 + 894 925 return { success: true, data: result }; 895 926 } catch (error) { 896 927 const message = error instanceof Error ? error.message : String(error); ··· 2177 2208 DEBUG && console.log('Creating window with options:', winOptions); 2178 2209 console.log(`[window-open:bounds] url=${url.substring(0, 80)} final position: (${winOptions.x},${winOptions.y}) ${winOptions.width}x${winOptions.height}${useCanvas ? " [canvas]" : ""}`); 2179 2210 2211 + // Pass through optional BrowserWindow properties from caller 2212 + if (options.alwaysOnTop !== undefined) winOptions.alwaysOnTop = !!options.alwaysOnTop; 2213 + if (options.focusable !== undefined) winOptions.focusable = !!options.focusable; 2214 + if (options.skipTaskbar !== undefined) winOptions.skipTaskbar = !!options.skipTaskbar; 2215 + if (options.hasShadow !== undefined && !useCanvas) winOptions.hasShadow = !!options.hasShadow; 2216 + 2180 2217 // Create new window 2181 2218 const win = new BrowserWindow(winOptions); 2182 2219 { const actualBounds = win.getBounds(); console.log(`[window-open:actual] Window ${win.id} actual bounds after creation: (${actualBounds.x},${actualBounds.y}) ${actualBounds.width}x${actualBounds.height}`); } 2220 + 2221 + // Reinforce alwaysOnTop after creation — on macOS the constructor flag alone 2222 + // is unreliable; calling setAlwaysOnTop with 'floating' level ensures it stays 2223 + // above regular windows. 2224 + if (options.alwaysOnTop) { 2225 + win.setAlwaysOnTop(true, 'floating'); 2226 + DEBUG && console.log('[window-open] Set alwaysOnTop floating for window', win.id); 2227 + } 2183 2228 2184 2229 // Track window position for display-watcher home display restoration 2185 2230 trackWindow(win); ··· 2423 2468 content: url 2424 2469 }); 2425 2470 } 2471 + // Auto-tag with group if this window is in group mode 2472 + const loadModeEntry = getContextEntry('mode', win.id); 2473 + if (loadModeEntry && loadModeEntry.value === 'group' && loadModeEntry.metadata?.groupId) { 2474 + tagItem(trackResult.itemId, loadModeEntry.metadata.groupId as string); 2475 + DEBUG && console.log('[openWindow] Auto-tagged item', trackResult.itemId, 'with group', loadModeEntry.metadata.groupId); 2476 + } 2426 2477 } catch (e) { 2427 2478 DEBUG && console.log('Failed to track window load:', e); 2428 2479 } ··· 2449 2500 itemType: 'url', 2450 2501 content: navUrl 2451 2502 }); 2503 + } 2504 + // Auto-tag with group if this window is in group mode 2505 + const navModeEntry = getContextEntry('mode', win.id); 2506 + if (navModeEntry && navModeEntry.value === 'group' && navModeEntry.metadata?.groupId) { 2507 + tagItem(navTrack.itemId, navModeEntry.metadata.groupId as string); 2508 + DEBUG && console.log('[did-navigate] Auto-tagged item', navTrack.itemId, 'with group', navModeEntry.metadata.groupId); 2452 2509 } 2453 2510 } catch (e) { 2454 2511 DEBUG && console.log('Failed to track did-navigate:', e); ··· 2519 2576 (async () => { 2520 2577 try { 2521 2578 // Track the popup URL in history 2579 + let popupItemId: string | undefined; 2522 2580 try { 2523 2581 const popupTrack = trackWindowLoad(popupUrl, { 2524 2582 source: 'window-open', 2525 2583 sourceId: url, 2526 2584 windowType: 'main', 2527 2585 }); 2586 + popupItemId = popupTrack.itemId; 2528 2587 if (popupTrack.created) { 2529 2588 publish('system', PubSubScopes.GLOBAL, 'item:created', { 2530 2589 itemId: popupTrack.itemId, ··· 2545 2604 groupName: parentContext.metadata.groupName as string, 2546 2605 color: parentContext.metadata.color as string, 2547 2606 }; 2607 + // Auto-tag popup item with the group tag 2608 + if (popupItemId) { 2609 + try { 2610 + tagItem(popupItemId, groupMode.groupId); 2611 + DEBUG && console.log('[webview-popup] Auto-tagged popup item', popupItemId, 'with group', groupMode.groupId); 2612 + } catch (e) { 2613 + DEBUG && console.log('[webview-popup] Failed to auto-tag popup:', e); 2614 + } 2615 + } 2548 2616 } 2549 2617 2550 2618 // Get the source address from the parent window's registration
+3 -3
extensions/tentacles/background.js
··· 158 158 // Commands 159 159 const commandDefinitions = [ 160 160 { 161 - name: 'tentacles', 162 - description: 'Toggle tentacles easter egg on/off', 161 + name: 'help docs', 162 + description: 'Toggle help documentation overlay', 163 163 execute: async () => { 164 164 console.log('[ext:tentacles] Toggle command executed'); 165 165 return await toggle(); ··· 218 218 export default { 219 219 id: 'tentacles', 220 220 labels: { 221 - name: 'Tentacles' 221 + name: 'Help docs' 222 222 }, 223 223 init, 224 224 uninit