Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions cmd/desktop/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,9 @@ func (a *App) UpdateConfig(configJSON string) error {
return a.settings.UpdateConfig(configJSON, a.proxy)
}
func (a *App) UpdatePort(port int) error { return a.settings.UpdatePort(port) }
func (a *App) UpdateNetwork(port int, listenAddr string) error {
return a.settings.UpdateNetwork(port, listenAddr)
}
func (a *App) GetSystemLanguage() string { return a.settings.GetSystemLanguage() }
func (a *App) GetLanguage() string { return a.settings.GetLanguage() }
func (a *App) SetLanguage(language string) error { return a.settings.SetLanguage(language) }
Expand Down
12 changes: 9 additions & 3 deletions cmd/desktop/frontend/src/i18n/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,16 @@ export default {
changePort: 'Change Port',
port: 'Port',
portLabel: 'Port (1-65535):',
portNote: 'Note: Changing port requires application restart',
listenAddrLabel: 'Listen address:',
listenAddrPlaceholder: 'e.g., 127.0.0.1',
listenAddrPresetPublic: 'Public 0.0.0.0',
listenAddrPresetLAN: 'LAN 192.168.0.0',
Copy link

Copilot AI Jan 15, 2026

Choose a reason for hiding this comment

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

The preset value '192.168.0.0' is a network address, not a valid host IP to bind to. This should likely be '192.168.0.1' or another valid host address in the private range. Binding to .0.0 addresses (network addresses) may fail or produce unexpected behavior depending on the OS.

Suggested change
listenAddrPresetLAN: 'LAN 192.168.0.0',
listenAddrPresetLAN: 'LAN 192.168.0.1',

Copilot uses AI. Check for mistakes.
listenAddrPresetLocal: 'Local 127.0.0.1',
listenAddrInvalid: 'Please enter a valid listen address',
portNote: 'Note: Changing port or listen address requires application restart',
portInvalid: 'Please enter a valid port number (1-65535)',
portUpdateSuccess: 'Port updated successfully! Please restart the application for changes to take effect.',
portUpdateFailed: 'Failed to update port: {error}',
portUpdateSuccess: 'Port and listen address updated successfully! Please restart the application for changes to take effect.',
portUpdateFailed: 'Failed to update port or listen address: {error}',
requiredFields: 'Please fill in all required fields',
modelRequired: 'Model field is required for {transformer} transformer',
saveFailed: 'Failed to save: {error}',
Expand Down
12 changes: 9 additions & 3 deletions cmd/desktop/frontend/src/i18n/zh-CN.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,16 @@ export default {
changePort: '修改端口',
port: '端口',
portLabel: '端口号 (1-65535):',
portNote: '注意:修改端口号需要重启应用',
listenAddrLabel: '监听地址:',
listenAddrPlaceholder: '例如:127.0.0.1',
listenAddrPresetPublic: '公网 0.0.0.0',
listenAddrPresetLAN: '局域网 192.168.0.0',
Copy link

Copilot AI Jan 15, 2026

Choose a reason for hiding this comment

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

The preset value '192.168.0.0' is a network address, not a valid host IP to bind to. This should likely be '192.168.0.1' or another valid host address in the private range. Binding to .0.0 addresses (network addresses) may fail or produce unexpected behavior depending on the OS.

Suggested change
listenAddrPresetLAN: '局域网 192.168.0.0',
listenAddrPresetLAN: '局域网 192.168.0.1',

Copilot uses AI. Check for mistakes.
listenAddrPresetLocal: '本地 127.0.0.1',
listenAddrInvalid: '请输入有效的监听地址',
portNote: '注意:修改端口号或监听地址需要重启应用',
portInvalid: '请输入有效的端口号(1-65535)',
portUpdateSuccess: '端口修改成功!请重启应用以使更改生效。',
portUpdateFailed: '端口修改失败:{error}',
portUpdateSuccess: '端口和监听地址修改成功!请重启应用以使更改生效。',
portUpdateFailed: '端口或监听地址修改失败:{error}',
requiredFields: '请填写所有必填项',
modelRequired: '使用 {transformer} 转换器时,模型字段为必填项',
saveFailed: '保存失败:{error}',
Expand Down
2 changes: 2 additions & 0 deletions cmd/desktop/frontend/src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import {
showEditPortModal,
savePort,
closePortModal,
setListenAddrPreset,
showWelcomeModal,
closeWelcomeModal,
showWelcomeModalIfFirstTime,
Expand Down Expand Up @@ -177,6 +178,7 @@ window.toggleModelDropdown = toggleModelDropdown;
window.showEditPortModal = showEditPortModal;
window.savePort = savePort;
window.closePortModal = closePortModal;
window.setListenAddrPreset = setListenAddrPreset;
window.showWelcomeModal = showWelcomeModal;
window.closeWelcomeModal = closeWelcomeModal;
window.showChangelogModal = showChangelogModal;
Expand Down
7 changes: 6 additions & 1 deletion cmd/desktop/frontend/src/modules/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ export async function loadConfig() {
const configStr = await window.go.main.App.GetConfig();
const config = JSON.parse(configStr);

document.getElementById('proxyPort').textContent = config.port;
const listenAddr = config.listenAddr || '127.0.0.1';
document.getElementById('proxyPort').textContent = `${listenAddr}:${config.port}`;
document.getElementById('totalEndpoints').textContent = config.endpoints.length;

const activeCount = config.endpoints.filter(ep => ep.enabled !== false).length;
Expand All @@ -32,6 +33,10 @@ export async function updatePort(port) {
await window.go.main.App.UpdatePort(port);
}

export async function updateNetwork(port, listenAddr) {
await window.go.main.App.UpdateNetwork(port, listenAddr);
}

export async function addEndpoint(name, url, key, transformer, model, remark) {
await window.go.main.App.AddEndpoint(name, url, key, transformer, model, remark || '');
}
Expand Down
23 changes: 21 additions & 2 deletions cmd/desktop/frontend/src/modules/modal.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { t } from '../i18n/index.js';
import { escapeHtml } from '../utils/format.js';
import { addEndpoint, updateEndpoint, removeEndpoint, testEndpoint, testEndpointLight, updatePort } from './config.js';
import { addEndpoint, updateEndpoint, removeEndpoint, testEndpoint, testEndpointLight, updateNetwork } from './config.js';
Copy link

Copilot AI Jan 15, 2026

Choose a reason for hiding this comment

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

Unused import testEndpoint.

Suggested change
import { addEndpoint, updateEndpoint, removeEndpoint, testEndpoint, testEndpointLight, updateNetwork } from './config.js';
import { addEndpoint, updateEndpoint, removeEndpoint, testEndpointLight, updateNetwork } from './config.js';

Copilot uses AI. Check for mistakes.
import { setTestState, clearTestState, saveEndpointTestStatus } from './endpoints.js';

let currentEditIndex = -1;
Expand Down Expand Up @@ -345,19 +345,30 @@ export async function showEditPortModal() {
const config = JSON.parse(configStr);

document.getElementById('portInput').value = config.port;
const listenAddrInput = document.getElementById('listenAddrInput');
if (listenAddrInput) {
listenAddrInput.value = config.listenAddr || '127.0.0.1';
}
document.getElementById('portModal').classList.add('active');
}

export async function savePort() {
const port = parseInt(document.getElementById('portInput').value);
const listenAddrInput = document.getElementById('listenAddrInput');
const listenAddr = (listenAddrInput?.value || '').trim() || '127.0.0.1';

if (!port || port < 1 || port > 65535) {
showNotification(t('modal.portInvalid'), 'error');
return;
}

if (!listenAddr || /\s/.test(listenAddr)) {
Copy link

Copilot AI Jan 15, 2026

Choose a reason for hiding this comment

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

The validation only checks for empty values and whitespace. Consider validating that the listen address is a valid IP address or hostname. Invalid addresses like "999.999.999.999" or malformed hostnames will pass this check and only fail at runtime when the server attempts to bind.

Copilot uses AI. Check for mistakes.
showNotification(t('modal.listenAddrInvalid'), 'error');
return;
}

try {
await updatePort(port);
await updateNetwork(port, listenAddr);
closePortModal();
window.loadConfig();
showNotification(t('modal.portUpdateSuccess'), 'success');
Expand All @@ -370,6 +381,14 @@ export function closePortModal() {
document.getElementById('portModal').classList.remove('active');
}

export function setListenAddrPreset(addr) {
const input = document.getElementById('listenAddrInput');
if (input) {
input.value = addr;
input.focus();
}
}


// ========== 加群二维码URL配置 ==========
// 上传到图床后填写URL,过期时直接替换图床文件即可自动更新
Expand Down
9 changes: 9 additions & 0 deletions cmd/desktop/frontend/src/modules/ui.js
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,15 @@ export function initUI() {
<label><span class="required">*</span>${t('modal.portLabel')}</label>
<input type="number" id="portInput" min="1" max="65535" placeholder="3000">
</div>
<div class="form-group">
<label><span class="required">*</span>${t('modal.listenAddrLabel')}</label>
<input type="text" id="listenAddrInput" placeholder="${t('modal.listenAddrPlaceholder')}">
<div class="listen-addr-presets">
<button class="preset-chip" onclick="window.setListenAddrPreset('0.0.0.0')">${t('modal.listenAddrPresetPublic')}</button>
<button class="preset-chip" onclick="window.setListenAddrPreset('192.168.0.0')">${t('modal.listenAddrPresetLAN')}</button>
Copy link

Copilot AI Jan 15, 2026

Choose a reason for hiding this comment

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

The preset value '192.168.0.0' is a network address, not a valid host IP to bind to. This should likely be '192.168.0.1' or use '0.0.0.0' to bind to all interfaces on the local machine. Network addresses ending in .0.0 are typically reserved and may not bind correctly.

Suggested change
<button class="preset-chip" onclick="window.setListenAddrPreset('192.168.0.0')">${t('modal.listenAddrPresetLAN')}</button>
<button class="preset-chip" onclick="window.setListenAddrPreset('192.168.0.1')">${t('modal.listenAddrPresetLAN')}</button>

Copilot uses AI. Check for mistakes.
<button class="preset-chip" onclick="window.setListenAddrPreset('127.0.0.1')">${t('modal.listenAddrPresetLocal')}</button>
</div>
</div>
<p style="color: #666; font-size: 14px; margin-top: 10px;">
⚠️ ${t('modal.portNote')}
</p>
Expand Down
25 changes: 25 additions & 0 deletions cmd/desktop/frontend/src/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -1399,6 +1399,31 @@ body {
font-family: 'Monaco', 'Menlo', 'Courier New', monospace;
}

/* Listen address presets */
.listen-addr-presets {
display: flex;
flex-wrap: wrap;
gap: 8px;
margin-top: 8px;
}

.preset-chip {
border: 1px solid rgba(102, 126, 234, 0.35);
background: rgba(102, 126, 234, 0.08);
color: #4c51bf;
padding: 6px 10px;
border-radius: 8px;
font-size: 13px;
cursor: pointer;
transition: all 0.2s ease;
}

.preset-chip:hover {
background: rgba(102, 126, 234, 0.15);
border-color: rgba(102, 126, 234, 0.6);
transform: translateY(-1px);
}

/* Endpoint Toggle Button */
.endpoint-toggle-btn {
padding: 0 10px;
Expand Down
2 changes: 2 additions & 0 deletions cmd/desktop/frontend/wailsjs/go/main/App.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,8 @@ export function UpdateEndpoint(arg1:number,arg2:string,arg3:string,arg4:string,a

export function UpdateLocalBackupDir(arg1:string):Promise<void>;

export function UpdateNetwork(arg1:number,arg2:string):Promise<void>;

export function UpdatePort(arg1:number):Promise<void>;

export function UpdateS3BackupConfig(arg1:string,arg2:string,arg3:string,arg4:string,arg5:string,arg6:string,arg7:string,arg8:boolean,arg9:boolean):Promise<void>;
Expand Down
4 changes: 4 additions & 0 deletions cmd/desktop/frontend/wailsjs/go/main/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,10 @@ export function UpdateLocalBackupDir(arg1) {
return window['go']['main']['App']['UpdateLocalBackupDir'](arg1);
}

export function UpdateNetwork(arg1, arg2) {
return window['go']['main']['App']['UpdateNetwork'](arg1, arg2);
}

export function UpdatePort(arg1) {
return window['go']['main']['App']['UpdatePort'](arg1);
}
Expand Down
Loading
Loading