fix popup ui

This commit is contained in:
go0p
2026-08-06 15:11:35 +08:00
committed by go0p
parent 08c12c2959
commit c9660ae269
7 changed files with 495 additions and 127 deletions
+38 -1
View File
@@ -1,11 +1,32 @@
import { browser, type Browser } from 'wxt/browser';
import {ContentActionType, ProxyActionType} from '@/types/action';
import { getCurrentProxyMode, switchProxyMode } from '@/utils/proxy';
import { getProxyConfig, saveProxyConfig } from '@/utils/storage';
import type { ProxyConfig } from '@/types/proxy';
// 固定的代理模式配置
const FIXED_MODES = [
{
id: 'direct',
name: '[直接连接]',
proxyType: 'direct',
enabled: false
},
{
id: 'system',
name: '[系统代理]',
proxyType: 'system',
enabled: false
}
];
export default defineBackground({
type: 'module',
main() {
async main() {
// 初始化固定模式的代理配置
await initializeFixedModes();
// 初始化代理状态监听
browser.runtime.onMessage.addListener((message: any, sender: Browser.runtime.MessageSender, sendResponse: (response?: any) => void) => {
if (message.action === ProxyActionType.GET_PROXY_STATUS) {
@@ -34,3 +55,19 @@ export default defineBackground({
console.log('代理管理后台服务已启动');
},
});
// 初始化固定模式的代理配置
async function initializeFixedModes() {
try {
// 确保固定模式的配置已保存到数据库
for (const modeConfig of FIXED_MODES) {
const existingConfig = await getProxyConfig(modeConfig.id);
if (!existingConfig) {
console.log(`初始化固定模式配置: ${modeConfig.id}`);
await saveProxyConfig(modeConfig as ProxyConfig);
}
}
} catch (error) {
console.error('初始化固定模式配置失败:', error);
}
}
+20
View File
@@ -60,6 +60,26 @@
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}
.add-proxy-card .ant-modal-footer {
display: flex;
justify-content: flex-end;
padding: 10px 24px;
border-top: 1px solid #f0f0f0;
}
.add-proxy-card .ant-modal-footer button {
margin-left: 8px;
}
.required-label::before {
content: '* ';
color: #ff4d4f;
}
.ant-form-item-label > label.ant-form-item-required:not(.ant-form-item-required-mark-optional)::before {
display: none !important;
}
.ant-space {
width: 100%;
}
+162 -47
View File
@@ -47,20 +47,68 @@ export default function App() {
try {
setLoading(true);
const newProxy: ProxyConfig = {
const newProxy: Partial<ProxyConfig> = {
id: uuidv4(),
name: values.name,
proxyType: "fixed_servers",
scheme: values.proxyType,
host: values.host,
port: Number(values.port),
enabled: false
};
if (values.proxyType === 'fixed_servers') {
newProxy.proxyType = 'fixed_servers';
newProxy.scheme = values.scheme;
newProxy.host = values.host;
newProxy.port = Number(values.port);
// 处理不经过代理的地址
if (values.bypassList) {
newProxy.bypassList = values.bypassList
.split('\n')
.map((line: string) => line.trim())
.filter((line: string) => line.length > 0);
} else {
newProxy.bypassList = [];
}
} else if (values.proxyType === 'pac_script') {
newProxy.proxyType = 'pac_script';
newProxy.mode = 'pac_script';
// 处理PAC脚本匹配域名
if (values.matchList) {
newProxy.matchList = values.matchList
.split('\n')
.map((line: string) => line.trim())
.filter((line: string) => line.length > 0);
}
// 创建PAC脚本
newProxy.pacScript = {
data: `function FindProxyForURL(url, host) {
// 匹配域名列表
const domains = ${JSON.stringify(newProxy.matchList || [])};
// 检查是否匹配任何域名
for (let i = 0; i < domains.length; i++) {
const domain = domains[i];
// 支持通配符
if (domain.startsWith('*.') && host.endsWith(domain.substring(1))) {
return 'PROXY ${values.host}:${values.port}';
} else if (host === domain) {
return 'PROXY ${values.host}:${values.port}';
}
}
// 默认直接连接
return 'DIRECT';
}`,
mandatory: true
};
}
// 添加认证信息
if (values.username) newProxy.username = values.username;
if (values.password) newProxy.password = values.password;
await saveProxyConfig(newProxy);
await saveProxyConfig(newProxy as ProxyConfig);
// 重新加载代理列表
await loadProxies();
@@ -111,6 +159,12 @@ export default function App() {
// 重新加载代理列表
await loadProxies();
// 通知后台脚本
browser.runtime.sendMessage({
action: ContentActionType.PROXY_CONFIGS_UPDATED,
source: 'options'
});
} catch (error) {
console.error(`Error activating proxy ${id}:`, error);
}
@@ -179,9 +233,14 @@ export default function App() {
key={proxy.id}
actions={[
<Button
type="primary"
type={proxy.enabled ? "default" : "primary"}
onClick={() => handleActivate(proxy.id)}
disabled={proxy.enabled}
style={proxy.enabled ? {
backgroundColor: "#F28B44",
color: "white",
borderColor: "#F28B44"
} : undefined}
>
{proxy.enabled ? '已启用' : '启用'}
</Button>,
@@ -207,7 +266,19 @@ export default function App() {
open={isModalOpen}
className='add-proxy-card'
onCancel={handleCancel}
footer={null}
footer={[
<Button key="cancel" onClick={handleCancel}>
Cancel
</Button>,
<Button
key="submit"
type="primary"
onClick={() => form.submit()}
loading={loading}
>
OK
</Button>
]}
destroyOnClose
>
<Form
@@ -217,45 +288,101 @@ export default function App() {
>
<Form.Item
name="name"
label="代理名称"
label={<span className="required-label">名称</span>}
rules={[{ required: true, message: '请输入代理名称' }]}
>
<Input placeholder="例如: 公司内网代理" />
<Input placeholder="为此代理添加一个名称" />
</Form.Item>
<Form.Item
name="proxyType"
label="代理类型"
initialValue="http"
label={<span className="required-label">类型</span>}
initialValue="fixed_servers"
rules={[{ required: true, message: '请选择代理类型' }]}
>
<Select>
<Option value="http">HTTP</Option>
<Option value="https">HTTPS</Option>
<Option value="socks4">SOCKS4</Option>
<Option value="socks5">SOCKS5</Option>
<Option value="fixed_servers">代理服务器</Option>
<Option value="pac_script">PAC 脚本</Option>
</Select>
</Form.Item>
<Space style={{ display: 'flex' }}>
<Form.Item
name="host"
label="主机地址"
rules={[{ required: true, message: '请输入主机地址' }]}
style={{ flex: 3 }}
>
<Input placeholder="例如: proxy.example.com 或 192.168.1.100" />
</Form.Item>
<Form.Item
name="port"
label="端口"
rules={[{ required: true, message: '请输入端口' }]}
style={{ flex: 1 }}
>
<Input placeholder="例如: 8080" />
</Form.Item>
</Space>
<Form.Item
noStyle
shouldUpdate={(prevValues, currentValues) => prevValues.proxyType !== currentValues.proxyType}
>
{({ getFieldValue }) => {
const proxyType = getFieldValue('proxyType');
if (proxyType === 'fixed_servers') {
return (
<>
<Form.Item
name="scheme"
label={<span className="required-label">协议</span>}
initialValue="http"
rules={[{ required: true, message: '请选择代理协议' }]}
>
<Select>
<Option value="http">HTTP</Option>
<Option value="https">HTTPS</Option>
<Option value="socks4">SOCKS4</Option>
<Option value="socks5">SOCKS5</Option>
</Select>
</Form.Item>
<Form.Item
name="host"
label={<span className="required-label">主机</span>}
rules={[{ required: true, message: '请输入主机地址' }]}
>
<Input placeholder="127.0.0.1" />
</Form.Item>
<Form.Item
name="port"
label={<span className="required-label">端口</span>}
rules={[{ required: true, message: '请输入端口' }]}
>
<Input placeholder="8080" />
</Form.Item>
<Form.Item
name="bypassList"
label="不经过代理的地址"
>
<Input.TextArea
rows={4}
placeholder={`例如:
localhost
127.0.0.1
*.example.com`}
/>
<div style={{ marginTop: 8, fontSize: 12, color: '#999' }}>每行一个地址,支持通配符 *</div>
</Form.Item>
</>
);
} else if (proxyType === 'pac_script') {
return (
<>
<Form.Item
name="matchList"
label={<span className="required-label">匹配域名</span>}
rules={[{ required: true, message: '请输入至少一个匹配域名' }]}
>
<Input.TextArea
rows={4}
placeholder={`例如:
*.example.com
google.com
github.com`}
/>
<div style={{ marginTop: 8, fontSize: 12, color: '#999' }}>每行一个域名,支持通配符 *</div>
</Form.Item>
</>
);
}
return null;
}}
</Form.Item>
<Space style={{ display: 'flex' }}>
<Form.Item
@@ -274,18 +401,6 @@ export default function App() {
<Input.Password placeholder="认证密码" />
</Form.Item>
</Space>
<Form.Item>
<Button
type="primary"
htmlType="submit"
icon={<PlusOutlined />}
loading={loading}
block
>
添加代理
</Button>
</Form.Item>
</Form>
</Modal>
</Content>