Make Wx.switch_account emit granular progress events through an
optional callback, so the caller (apis.auth.switch_wechat_account)
can fan them out to SSE / polling endpoints.
Behaviour changes:
- Replace the 60-second asyncio.sleep on token-expired path with an
immediate return + explicit 'failed' stage, so the front-end can
surface 'please re-scan QR' instead of waiting a minute.
- The 120-second queue drain is now configurable via SWITCH_MAX_WAIT
env var (default unchanged).
- Each phase (stopping_queues / checking_token / starting_browser /
clicking / done / failed) emits (stage, message, progress).
- finally clause no longer unconditionally calls self.cleanup_resources
+ self.Close; it only restores queues. Resource cleanup is the
caller's responsibility if needed.
- Stage messages map to UI-friendly Chinese (e.g. '打开账号面板…',
'找到 N 个可切换账号,正在选择…', '切换成功:<name>').
No breaking signature change: the existing sync callers that pass only
'username' still work because progress_callback defaults to None.
When WeChat public platform is reached via a locally detected Chrome
binary on Windows, the platform's anti-bot triggers and the QR code
fails to load (二维码加载超时). Allow users to force a specific
Playwright browser (webkit/chromium/firefox/msedge) via the
BROWSER_TYPE environment variable, bypassing the heuristic that
overrides the default browser_type with the local Chrome path.
Example:
BROWSER_TYPE=webkit python main.py
This restores cross-platform portability: explicit user preference
takes precedence over auto-detection, while the existing default
(Playwright webkit when no Chrome is detected) is unchanged.