## Fixes
- Fix duplicate tray icon on macOS when hiding to tray - Fix tray not showing in background mode on macOS - Fix hide to tray broken on Windows/Linux - Fix Shutdown button in web UI not working
This commit is contained in:
parent
30ff4e3fb0
commit
593c788c75
6 changed files with 43 additions and 16 deletions
|
|
@ -1,3 +1,11 @@
|
|||
# v0.4.50 (2026-05-16)
|
||||
|
||||
## Fixes
|
||||
- Fix duplicate tray icon on macOS when hiding to tray
|
||||
- Fix tray not showing in background mode on macOS
|
||||
- Fix hide to tray broken on Windows/Linux
|
||||
- Fix Shutdown button in web UI not working
|
||||
|
||||
# v0.4.49 (2026-05-16)
|
||||
|
||||
## Features
|
||||
|
|
|
|||
41
cli/cli.js
41
cli/cli.js
|
|
@ -694,29 +694,48 @@ function startServer(latestVersion) {
|
|||
await startTerminalUI(port);
|
||||
// Loop continues, show menu again
|
||||
} else if (choice === "hide") {
|
||||
// Hide to tray: keep the CURRENT process alive (it already owns a
|
||||
// macOS GUI session so NSStatusItem works). Spawning a detached child
|
||||
// puts it outside the login session → systray silently fails on macOS.
|
||||
const { clearScreen } = require("./src/cli/utils/display");
|
||||
clearScreen();
|
||||
|
||||
// Survive terminal close — SIGHUP is sent when the launching shell exits
|
||||
process.removeAllListeners("SIGHUP");
|
||||
process.on("SIGHUP", () => {});
|
||||
|
||||
// Enable auto startup on OS boot
|
||||
try {
|
||||
const { enableAutoStart } = require("./src/cli/tray/autostart");
|
||||
enableAutoStart(__filename);
|
||||
} catch (e) { }
|
||||
|
||||
console.log(`\n🔔 9Router is running in tray (PID: ${process.pid})`);
|
||||
if (process.platform === "darwin") {
|
||||
// macOS: keep current process alive — spawning a detached child puts
|
||||
// it outside the login session so NSStatusItem silently fails.
|
||||
process.removeAllListeners("SIGHUP");
|
||||
process.on("SIGHUP", () => {});
|
||||
|
||||
console.log(`\n⏳ Switching to tray mode... (icon already visible in menu bar)`);
|
||||
console.log(`🔔 9Router is running in tray (PID: ${process.pid})`);
|
||||
console.log(` Server: http://${displayHost}:${port}`);
|
||||
console.log(`\n💡 You can close this terminal. Right-click tray icon to quit.\n`);
|
||||
|
||||
// Tray already init'd at startup — just keep event loop alive.
|
||||
return;
|
||||
}
|
||||
|
||||
// Windows/Linux: spawn detached bgProcess (systray works fine in child)
|
||||
console.log(`\n⏳ Starting background process... (tray icon will appear in ~3s)`);
|
||||
|
||||
const bgProcess = spawn(process.execPath, [__filename, "--tray", "--skip-update", "-p", port.toString()], {
|
||||
detached: true,
|
||||
stdio: "ignore",
|
||||
windowsHide: true,
|
||||
env: { ...process.env }
|
||||
});
|
||||
bgProcess.unref();
|
||||
|
||||
console.log(`🔔 9Router is now running in background (PID: ${bgProcess.pid})`);
|
||||
console.log(` Server: http://${displayHost}:${port}`);
|
||||
console.log(`\n💡 You can close this terminal. Right-click tray icon to quit.\n`);
|
||||
|
||||
// Tray icon already running (initTrayIcon was called above at startup).
|
||||
// Nothing more to do — event loop keeps process alive via tray + server.
|
||||
return;
|
||||
// cleanup() kills server so bgProcess can claim the port fresh
|
||||
cleanup();
|
||||
process.exit(0);
|
||||
} else if (choice === "exit") {
|
||||
isShuttingDown = true;
|
||||
console.log("\nExiting...");
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "9router",
|
||||
"version": "0.4.49",
|
||||
"version": "0.4.50",
|
||||
"description": "9Router CLI - Start and manage 9Router server",
|
||||
"bin": {
|
||||
"9router": "./cli.js"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "9router-app",
|
||||
"version": "0.4.49",
|
||||
"version": "0.4.50",
|
||||
"description": "9Router web dashboard",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
|
|
|
|||
|
|
@ -98,13 +98,13 @@
|
|||
"Console Log": "Nhật ký Console",
|
||||
"System": "Hệ thống",
|
||||
"Debug": "Gỡ lỗi",
|
||||
"Shutdown": "Tắt máy",
|
||||
"Shutdown": "Tắt ứng dụng",
|
||||
"Close Proxy": "Đóng Proxy",
|
||||
"Are you sure you want to close the proxy server?": "Bạn có chắc chắn muốn đóng máy chủ proxy không?",
|
||||
"Server Disconnected": "Máy chủ đã ngắt kết nối",
|
||||
"The proxy server has been stopped.": "Máy chủ proxy đã bị dừng.",
|
||||
"Reload Page": "Tải lại trang",
|
||||
"Service is running in terminal. You can close this web page. Shutdown will stop the service.": "Dịch vụ đang chạy trong terminal. Bạn có thể đóng trang web này. Tắt máy sẽ dừng dịch vụ.",
|
||||
"Service is running in terminal. You can close this web page. Shutdown will stop the service.": "Dịch vụ đang chạy trong terminal. Bạn có thể đóng trang web này. Tắt ứng dụng sẽ dừng dịch vụ.",
|
||||
"Manage your AI provider connections": "Quản lý kết nối nhà cung cấp AI của bạn",
|
||||
"Model combos with fallback": "Kết hợp mô hình với dự phòng",
|
||||
"Monitor your API usage, token consumption, and request logs": "Theo dõi việc sử dụng API, tiêu thụ token và nhật ký yêu cầu",
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ export default function Sidebar({ onClose }) {
|
|||
const handleShutdown = async () => {
|
||||
setIsShuttingDown(true);
|
||||
try {
|
||||
await fetch("/api/shutdown", { method: "POST" });
|
||||
await fetch("/api/version/shutdown", { method: "POST" });
|
||||
} catch (e) {
|
||||
// Expected to fail as server shuts down; ignore error
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue