Skip to content

Feature/dependency upgrade by ezroar reviewed - #369

Open
WhiteFang5 wants to merge 52 commits into
masterfrom
feature/dependency-upgrade-by-ezroar-reviewed
Open

Feature/dependency upgrade by ezroar reviewed#369
WhiteFang5 wants to merge 52 commits into
masterfrom
feature/dependency-upgrade-by-ezroar-reviewed

Conversation

@WhiteFang5

@WhiteFang5 WhiteFang5 commented Jul 27, 2026

Copy link
Copy Markdown
Member

Pulled the code created by Ezroar (see PR #365) to the main repo to allow reviewing and comment resolution right away without depending on Ezroar to fix things reviewers find/want to see changed.

Upgrade Summary by Ezroar:

PoE Overlay Full Dependency Upgrade Summary

This document summarizes the comprehensive dependency upgrade performed on the PoE Overlay project.

Version Changes

Package Previous Current
Electron 8.3.1 28.3.3
Angular 9.1.3 17.3.12
Angular Material 9.x 17.3.10
TypeScript 3.8.3 5.3.3
RxJS 6.5.5 7.8.0
Node.js 12+ 18.13.0+
electron-builder 22.x 24.13.3
electron-updater 4.x 6.1.7
electron-log 4.x 5.1.0

Replaced Native Modules

Previous Replacement Reason
iohook uiohook-napi 1.5.0 iohook is unmaintained, no Electron 28 support
active-win node-window-manager 2.2.2 active-win is ESM-only, incompatible with Electron's CJS
custom-electron-titlebar Custom HTML titlebar Incompatible with Electron 28 context isolation

Breaking Changes & Fixes

Electron 28 — Context Isolation

Electron 28 enables contextIsolation by default. The renderer process can no longer access Node.js or Electron APIs directly.

Solution: Added a preload script using contextBridge.exposeInMainWorld() to create a typed electronAPI bridge.

  • New file: electron/preload.ts — defines all whitelisted IPC channels and exposes them via window.electronAPI
  • New file: src/app/core/type/electron-api.type.ts — TypeScript interface for the bridge
  • All renderer services refactored to use window.electronAPI instead of require('electron').ipcRenderer
  • Added IPC handlers in main.ts for: window management, clipboard, shell, global shortcuts, game detection, logging, keyboard/mouse automation
  • webPreferences updated to contextIsolation: true, nodeIntegration: false, sandbox: false

Services updated:
ElectronProvider, AppService, WindowService, BrowserService, GameService, LoggerService, ShortcutService, ClipboardService, KeyboardService, MouseService, TradeNotificationsService, StashGridService

Electron 28 — IPC Serialization

Electron 28 is stricter about IPC argument types.

  • undefined arguments cause "conversion failure from undefined" errors — fixed with !!poe.active coercion
  • loadURL(), shell.openExternal(), autoUpdater.checkForUpdates() now return promises — added .catch() handlers throughout main.ts and electron/auto-updater.ts
  • Added global process.on('unhandledRejection') handler as a safety net

Electron 28 — Window Behaviour

  • Focus-stealing loop: BrowserWindow.show() steals focus from PoE, causing rapid active/inactive detection cycling. Fixed by using showInactive() in the window-show IPC handler.
  • setAlwaysOnTop(flag, level): level can no longer be undefined — added guard to only pass it when defined
  • isMinimized: Now a method, not a property — fixed in the open-route handler
  • Child window close handler: Added null safety for win?.moveTop() and try/catch around event.reply() (sender webContents may be destroyed)
  • Tray double-click: Changed direct win.webContents.send() to the guarded send() helper

RxJS 7 — debounce(() => EMPTY) Breaking Change

In RxJS 6, debounce(() => EMPTY) emitted the buffered value when the inner observable completed. In RxJS 7, completion silently drops the value.

This caused the overlay to never become visible — registerVisibleChange() in OverlayComponent used debounce((show) => show ? EMPTY : timer(1500)), which swallowed all show=true signals. Fixed by replacing EMPTY with timer(0).

RxJS 7 — Other Migration

  • Replaced deprecated flatMapmergeMap in 30+ files
  • Updated operator import paths where needed

Angular Material 17 — MDC Component Migration

Angular Material v15+ migrated all components to use MDC (Material Design Components) internally, changing all CSS class names. Updated all selectors across 14 SCSS files:

Legacy Selector MDC Selector
.mat-card .mat-mdc-card
.mat-dialog-container .mat-mdc-dialog-container
.mat-dialog-content .mat-mdc-dialog-content
.mat-dialog-actions .mat-mdc-dialog-actions
.mat-form-field .mat-mdc-form-field
.mat-slide-toggle .mat-mdc-slide-toggle
.mat-slider .mat-mdc-slider
.mat-tooltip .mat-mdc-tooltip .mdc-tooltip__surface
.mat-snack-bar-container .mat-mdc-snack-bar-container + .mdc-snackbar__surface
.mat-progress-bar-* .mdc-linear-progress__*
.mat-raised-button .mat-mdc-raised-button
.mat-stroked-button .mat-mdc-outlined-button
.mat-flat-button .mat-mdc-flat-button
.mat-standard-chip .mat-mdc-chip
.mat-form-field-prefix/suffix .mat-mdc-form-field-icon-prefix/suffix

Additional Angular Material fixes:

  • mat-stretch-tabs attribute → [mat-stretch-tabs]="true" binding
  • Added flexbox layout for settings panel content scrolling within titlebar + action bar

Native Module Replacements

iohookuiohook-napi (electron/hook.ts)

  • Updated event handling to match the new API format
  • Event types and key codes are compatible

active-winnode-window-manager (electron/window.ts)

  • Rewrote active window detection using windowManager.getActiveWindow()
  • Window path, title, bounds, and process ID accessed via the node-window-manager Window API
  • Added requestAccessibility() with try/catch (required on macOS, no-op on Windows)

robotjs (electron/robot.ts)

  • Added VK_TO_KEY_NAME mapping to translate numeric virtual key codes from uiohook-napi to the string key names expected by robotjs (e.g. 0x44'd', 0xA0'shift')

Cloudflare Login Fix

The custom User-Agent header (PoEOverlayCommunityFork/x.x.x) was applied to all HTTP requests, including BrowserWindow page loads. Cloudflare flagged these as bot traffic, blocking the PoE login page.

Fixed by only applying the custom UA to API requests (/api/ URLs and XHR), letting page loads use the default Chromium user-agent.

Settings Window — Custom Titlebar

Replaced custom-electron-titlebar with a simple HTML/CSS titlebar (draggable title area with close button, matching the dark theme).

Overlay — Input Value Clipping

<input> elements in the evaluate overlay weren't inheriting the PoE-themed font. Width calculated using ch units mismatched with the browser default font. Fixed by adding font: inherit; padding: 0 to item-frame-value-input.component.scss.

Cross-Window IPC

With context isolation enabled, child windows (settings, periodic-update-thread) can no longer share state directly. Added IPC channel forwarding in main.ts for: settings changes, trade notifications, stash grid, vendor recipes, account updates.

TSLint → ESLint

  • Created .eslintrc.json with Angular ESLint configuration
  • Updated angular.json to use @angular-eslint/builder:lint
  • Deleted tslint.json

Build Configuration

  • Removed deprecated Angular build options (extractCss, namedChunks, vendorChunk)
  • Updated Node.js engine requirement to >=18.13.0
  • Fixed BrowserModuleCommonModule in shared modules

Getting Started

# Install dependencies (required after upgrade)
npm install

# Rebuild native modules for Electron 28
npm run electron:rebuild

# Run linting
npm run ng:lint

# Run tests
npm run ng:test

# Development mode
npm run start

# Build for Windows
npm run electron:windows

# Build for Linux
npm run electron:linux

Manual Testing Checklist

Due to the scope of changes, manual testing is critical:

Basic Functionality

  • App launches without errors
  • Overlay appears and is transparent
  • Settings window opens from tray icon
  • Settings panel styling renders correctly (dark theme, cards, toggles, sliders)

Window Behaviour

  • Window transparency works (click-through when not over UI)
  • Always-on-top functionality works
  • Game window detection (overlay shows when PoE is active)
  • Overlay doesn't steal focus from PoE (no flashing)

Input Handling

  • Global shortcuts register and trigger (Ctrl+D for evaluate, F5, etc.)
  • Ctrl+MouseWheel zoom works
  • Clipboard operations work (copy item text)

Account & Login

  • PoE login page loads (Cloudflare doesn't block it)
  • Account authentication completes successfully
  • Characters and leagues populate after login

Automation Features

  • Mouse automation (stash grid clicks)
  • Keyboard automation (trade commands)
  • Trade companion notifications work

UI Components

  • Evaluate overlay displays with correct stat values
  • Material dialogs and menus render correctly
  • Charts display (price distribution)
  • Translations load properly

Known Considerations

  1. Native Modules: After pulling these changes, always run npm run electron:rebuild to ensure native modules are compiled for the correct Electron version.

  2. Context Isolation: All Electron APIs are now accessed through window.electronAPI. Direct require('electron') calls in renderer code will not work.

  3. WSL Build: Building from WSL may hit memory limits or native module compilation issues. Build from a Windows terminal for production builds.

ezroar and others added 17 commits January 23, 2026 18:03
- Deleted stale package-lock.json that referenced old robotjs/iohook
- Regenerated with new @jitsi/robotjs and uiohook-napi dependencies
- Updated karma-base.conf.js: karma-coverage-istanbul-reporter → karma-coverage
- Renamed structure.type.d.ts → structure.type.ts for proper module export

Co-Authored-By: Claude Opus 4.5 <[email protected]>
- Update ElectronProvider API usage (provideIpcRenderer → provideElectronAPI)
- Fix Angular Material mat-slider to new API with matSliderThumb input
- Migrate _theme.scss to Angular Material v15+ theming with @use syntax
- Fix JSON imports to use default imports instead of named exports
- Add Subject<void> type parameters for RxJS strict mode
- Add $any() casts for strict template type checking
- Rename .d.ts type files to .ts for proper module exports
- Remove deprecated Node.js util import (isNullOrUndefined)
- Fix zone.js import path for newer version

Co-Authored-By: Claude Opus 4.5 <[email protected]>
- Add electron/preload.ts to tsconfig.serve.json so it gets compiled
  (preload is a separate entry point, never imported by main.ts)
- Fix preload path in main.ts to always use electron/preload.js
- Replace custom-electron-titlebar with HTML titlebar in settings
  window (window.require() unavailable with contextIsolation: true)
- Add cross-window IPC forwarding in main.ts for thread control
  channels (thread-pause, settings-changed, etc.)
- Add missing channels to preload send() whitelist

Co-Authored-By: Claude Opus 4.6 <[email protected]>
- Use cross-env for NODE_OPTIONS in package.json scripts (cross-platform)
- Fix ESLint/TSLint errors: switch-case scoping, strict equality,
  Object -> object type, no-input-rename directive
- Fix RxJS variable hoisting issues in stash-grid.service.ts
- Fix async pipe negation in evaluate-dialog template
- Update test infrastructure: remove require.context, add mock
  ElectronAPI and LocalForage providers, add test specs for services
- Add @app/testing path alias in tsconfig.json

Co-Authored-By: Claude Opus 4.6 <[email protected]>
When windowSetAlwaysOnTop(false) is called without a level, the
preload sends undefined as the level arg. Electron 28's native
setAlwaysOnTop validates arg 2 as a string when 3 args are passed,
throwing "A string was expected". Only pass level/relativeLevel when
level is truthy.

Also harden shell-open-external and log handlers with type guards.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
The old custom robotjs fork accepted Windows virtual key codes as
numbers (e.g. 0x43 for 'C'). The new @jitsi/robotjs requires string
key names (e.g. 'c'). Add a VK-to-key-name mapping to convert numeric
codes before passing them to robotjs.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
- Replace debounce(() => EMPTY) with debounce(() => timer(0)) in overlay
  visibility pipeline. RxJS 7 changed debounce behavior: inner observable
  completion no longer emits buffered values, causing window.show() to
  never fire.
- Add font:inherit to item-frame-value-input so ch-based width calculation
  matches the actual rendered font, fixing clipped stat numbers.
- Fix requestAccessibility() crash guard for non-macOS platforms.
- Fix send() error handler referencing wrong variable name (args vs
  additionalArgs).
- Add debug logging for game detection, shortcut registration, and
  window show/hide (throttled to avoid log spam).

Co-Authored-By: Claude Opus 4.6 <[email protected]>
- Use showInactive() instead of show() for the overlay window to prevent
  stealing focus from PoE, which caused a rapid active/inactive flashing
  loop.
- Coerce poe.active to boolean (!!poe.active) before sending via IPC to
  avoid Electron 28 serialization failure on undefined values.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
…ections

Update all CSS selectors from legacy .mat-* to .mat-mdc-* for Angular Material
v15+ MDC migration. Fix unhandled promise rejections in auto-updater and main
process (loadURL, shell.openExternal). Fix isMinimized property→method call,
child window close handler null safety, and tray double-click crash.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Only apply the custom PoEOverlayCommunityFork user-agent to API and XHR
requests. Page loads (login, trade search) now use the default Chromium
user-agent, preventing Cloudflare from flagging them as bot traffic.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Cloudflare's JS challenge also checks navigator.userAgent, not just the
HTTP header. Remove "Electron/x.x.x" and "poe-overlay/x.x.x" from the
in-page user agent on spawned BrowserWindows so login pages pass
Cloudflare verification.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
… import

Cloudflare Turnstile blocks Electron's embedded browser from completing
verification. Instead, open the PoE login page in the user's default
browser and let them paste their POESESSID cookie to authenticate.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
- Bump version 0.8.39 → 0.9.0 to reflect the major dependency upgrade
  (Electron 8→28, Angular 9→17, new IPC architecture, native module replacements)
- Add CHANGELOG entry for 0.9.0
- Fix evaluate-dialog: default privateLeague$ to false; add null-safety and
  error handler in checkPrivateLeague() so a failed league lookup doesn't
  leave the flag in an incorrect state

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
- karma-base.conf.js: add headless Chrome flags for WSL compatibility
- spec_helper.spec.ts: add global beforeEach(resetTestingModule) so the
  TestBed instantiated by beforeAll doesn't block the first spec from
  calling configureTestingModule
- mock-electron-api.ts: add missing setSessionCookie/getSessionCookie spies
- 7 component specs: migrate ElectronProviderFake from Electron 8 IPC API
  (provideRemote/provideIpcRenderer) to new provideElectronAPI()
- user-settings-form.component.spec.ts: use MockElectronProvider instead of
  null-returning fake (AppService.isAutoLaunchEnabled calls electronAPI.once)
- evaluate-dialog.component.spec.ts: fix MatDialogRef null -> {close: ()=>{}}
- item-price-prediction.service.spec.ts: correct mock currencyId 'exalted'
  -> 'exa' to match mock data; add leagueId: 'Delirium' to context init
- item-search-analyze.service.spec.ts: add leagueId: 'Delirium' to context init
- window.service.spec.ts: add explicit resetTestingModule in beforeEach

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
@WhiteFang5 WhiteFang5 self-assigned this Jul 27, 2026
Comment thread src/app/core/service/browser.service.ts Outdated
this.window.removeAllListeners()
// Note: In the new architecture, we can't remove all listeners on the window
// We would need to track specific listeners and remove them individually
console.warn('removeAllListeners is no longer supported in context-isolated mode')

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably be fixed/implemented accordingly (and this method removed)

WhiteFang5 and others added 18 commits July 29, 2026 21:02
…ed by cloudflare when using the login feature
…ved redundant cookie IPC channels; Changed some titles/tooltips mentioning 'poe overlay' to now also mentioned 'community fork'; Fixed some IPC channel reply and communication issues
…cat' to the list of currencies to obtain from poe ninja; Added support for 'Sanctum Relics' and 'Enshrouded' exchange rates (obtained from poe ninja)
…ebug purposes); Fixed an issue with shortcuts being registered multiple times (and thus triggering multiple times)
@WhiteFang5
WhiteFang5 force-pushed the feature/dependency-upgrade-by-ezroar-reviewed branch 2 times, most recently from 89e06cd to 17caedb Compare August 3, 2026 19:28
@WhiteFang5
WhiteFang5 force-pushed the feature/dependency-upgrade-by-ezroar-reviewed branch from 17caedb to 4e3ee51 Compare August 3, 2026 19:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants