fix: Windows兼容 + Textual 8.x + MD3 SVG图标替代emoji
1. Windows: reuse_port 仅非win32平台启用 2. Textual 8.2.7: refresh() 加 **kwargs 兼容 repaint 参数 3. WebUI: 设置页/插件页 emoji → SVG (fill:currentColor 日夜间适配) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -526,5 +526,27 @@
|
||||
"framework.command.execute"
|
||||
],
|
||||
"timestamp": 35916.627558381
|
||||
},
|
||||
"b9fd53b0": {
|
||||
"plugin_name": "example_plugin",
|
||||
"permissions": [
|
||||
"plugin.example.read",
|
||||
"plugin.example.write",
|
||||
"plugin.example.execute",
|
||||
"framework.event.subscribe",
|
||||
"framework.command.execute"
|
||||
],
|
||||
"timestamp": 36350.458260715
|
||||
},
|
||||
"930a37d0": {
|
||||
"plugin_name": "sentinel",
|
||||
"permissions": [
|
||||
"plugin.sentinel.read",
|
||||
"plugin.sentinel.write",
|
||||
"plugin.network.access",
|
||||
"framework.event.subscribe",
|
||||
"framework.command.execute"
|
||||
],
|
||||
"timestamp": 36350.46484983
|
||||
}
|
||||
}
|
||||
@@ -101,7 +101,7 @@ commands:
|
||||
permissions:
|
||||
- framework.command.test
|
||||
source: internal
|
||||
last_updated: 35916.559043798
|
||||
last_updated: 36350.43103134
|
||||
plugin_commands:
|
||||
example_plugin:
|
||||
echo: *id001
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
http_port: 4200
|
||||
last_updated: 35916.617063641
|
||||
last_updated: 36350.460163059
|
||||
plugin_routes:
|
||||
example_plugin:
|
||||
- methods:
|
||||
|
||||
@@ -2,10 +2,10 @@ author: SenSu Team
|
||||
description: 🛡️ 多节点 SenSu 集群性能监控 — 实时仪表盘 + 节点管理
|
||||
name: Sentinel
|
||||
nodes:
|
||||
- api_key: sk-035259bb700b17ae51cfd50a717b27281b1a5347b2aa4723
|
||||
- api_key: ''
|
||||
enabled: true
|
||||
id: node-3733a070
|
||||
name: 本地容器
|
||||
name: PLK110
|
||||
notes: LocalBian
|
||||
url: http://127.0.0.1:4200
|
||||
settings:
|
||||
|
||||
@@ -48,11 +48,15 @@ class InternetService:
|
||||
self.http_runner = web.AppRunner(self.http_app)
|
||||
await self.http_runner.setup()
|
||||
|
||||
# SO_REUSEPORT: Linux/macOS only, Windows 不支持
|
||||
import sys as _sys
|
||||
_reuse_port = _sys.platform != "win32"
|
||||
|
||||
# 1. 启动 HTTP 站点
|
||||
try:
|
||||
self.site = web.TCPSite(
|
||||
self.http_runner, self.http_host, self.http_port,
|
||||
reuse_address=True, reuse_port=True
|
||||
self.http_runner, self.http_host, self.http_port,
|
||||
reuse_address=True, reuse_port=_reuse_port,
|
||||
)
|
||||
await self.site.start()
|
||||
logger.info(f"✅ HTTP 服务已绑定: {self.http_host}:{self.http_port}")
|
||||
@@ -60,12 +64,12 @@ class InternetService:
|
||||
logger.error(f"❌ HTTP 端口 {self.http_port} 绑定失败: {e}")
|
||||
await self.http_runner.cleanup()
|
||||
return False
|
||||
|
||||
|
||||
# 2. 启动 WebSocket 站点 (独立端口)
|
||||
try:
|
||||
self.ws_site = web.TCPSite(
|
||||
self.http_runner, self.ws_host, self.ws_port,
|
||||
reuse_address=True, reuse_port=True
|
||||
self.http_runner, self.ws_host, self.ws_port,
|
||||
reuse_address=True, reuse_port=_reuse_port,
|
||||
)
|
||||
await self.ws_site.start()
|
||||
logger.info(f"✅ WebSocket 服务已绑定: {self.ws_host}:{self.ws_port}")
|
||||
|
||||
@@ -425,7 +425,7 @@ class SystemMonitor(Static):
|
||||
def set_collector(self, c):
|
||||
self._collector = c
|
||||
|
||||
def refresh(self):
|
||||
def refresh(self, **kwargs):
|
||||
"""由外部 asyncio task 驱动刷新(比 set_interval 更抗 Android 挂起)"""
|
||||
self._refresh_stats()
|
||||
try:
|
||||
@@ -479,7 +479,7 @@ class PluginStatusPanel(Static):
|
||||
def set_plugin_service(self, svc):
|
||||
self._plugin_service = svc
|
||||
|
||||
def refresh(self):
|
||||
def refresh(self, **kwargs):
|
||||
"""由外部 asyncio task 驱动刷新"""
|
||||
self._refresh()
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<div class="plugin-page-root" style="padding:16px">
|
||||
<h2 style="margin:0 0 12px 0">🔌 插件管理</h2>
|
||||
<h2 style="margin:0 0 12px 0"><svg width="22" height="22" viewBox="0 0 24 24" style="vertical-align:-4px;margin-right:6px"><path fill="currentColor" d="M20.5 11H19V7c0-1.1-.9-2-2-2h-4V3.5C13 2.12 11.88 1 10.5 1S8 2.12 8 3.5V5H4c-1.1 0-1.99.9-1.99 2v3.8H3.5c1.49 0 2.7 1.21 2.7 2.7s-1.21 2.7-2.7 2.7H2V20c0 1.1.9 2 2 2h3.8v-1.5c0-1.49 1.21-2.7 2.7-2.7 1.49 0 2.7 1.21 2.7 2.7V22H17c1.1 0 2-.9 2-2v-4h1.5c1.38 0 2.5-1.12 2.5-2.5S21.88 11 20.5 11z"/></svg>插件管理</h2>
|
||||
|
||||
<!-- ── 统计卡片 ── -->
|
||||
<div id="stats-card" style="display:flex;gap:12px;margin-bottom:16px;flex-wrap:wrap">
|
||||
@@ -12,7 +12,7 @@
|
||||
<!-- ── 导入区域 ── -->
|
||||
<div style="display:flex;gap:16px;margin-bottom:16px;flex-wrap:wrap;align-items:stretch">
|
||||
<div class="import-card">
|
||||
<div class="card-title">📦 导入 ZIP 包</div>
|
||||
<div class="card-title"><svg width="18" height="18" viewBox="0 0 24 24" style="vertical-align:-3px;margin-right:4px"><path fill="currentColor" d="M20 6h-8l-2-2H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2zm0 12H4V6h5.17l2 2H20v10z"/></svg>导入 ZIP 包</div>
|
||||
<label class="file-label" for="zip-file">选择 .zip 文件</label>
|
||||
<input type="file" id="zip-file" accept=".zip" class="file-input">
|
||||
<div class="card-actions">
|
||||
@@ -21,7 +21,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="import-card">
|
||||
<div class="card-title">📥 Git Clone 安装</div>
|
||||
<div class="card-title"><svg width="18" height="18" viewBox="0 0 24 24" style="vertical-align:-3px;margin-right:4px"><path fill="currentColor" d="M9.4 16.6L4.8 12l4.6-4.6L8 6l-6 6 6 6 1.4-1.4zm5.2 0l4.6-4.6-4.6-4.6L16 6l6 6-6 6-1.4-1.4z"/></svg>Git Clone 安装</div>
|
||||
<input id="git-url" class="text-input" placeholder="https://github.com/user/repo.git">
|
||||
<div class="card-actions">
|
||||
<button class="btn btn-sm btn-filled" onclick="importGit()">Clone 安装</button>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<div class="plugin-page-root">
|
||||
<h2>⚙ 框架设置</h2>
|
||||
<h2><svg width="22" height="22" viewBox="0 0 24 24" style="vertical-align:-4px;margin-right:6px"><path fill="currentColor" d="M19.14 12.94c.04-.3.06-.61.06-.94 0-.32-.02-.64-.07-.94l2.03-1.58a.49.49 0 00.12-.61l-1.92-3.32a.49.49 0 00-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94L14.4 2.81a.484.484 0 00-.41-.3h-3.98c-.2 0-.38.13-.45.32l-.36 2.54c-.59.24-1.13.57-1.62.94l-2.39-.96a.49.49 0 00-.59.22L2.74 8.87c-.12.21-.08.47.12.61l2.03 1.58c-.05.3-.07.62-.07.94s.02.64.07.94l-2.03 1.58a.49.49 0 00-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.19.24.31.44.31h3.98c.2 0 .38-.13.45-.32l.36-2.54c.59-.24 1.13-.56 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.07-.47-.12-.61l-2.01-1.58zM12 15.6c-1.98 0-3.6-1.62-3.6-3.6s1.62-3.6 3.6-3.6 3.6 1.62 3.6 3.6-1.62 3.6-3.6 3.6z"/></svg>框架设置</h2>
|
||||
|
||||
<!-- ── 版本与更新 ── -->
|
||||
<div class="card" style="margin-bottom:24px">
|
||||
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:12px">
|
||||
<h3 style="margin:0">🔄 版本与更新</h3>
|
||||
<h3 style="margin:0"><svg width="20" height="20" viewBox="0 0 24 24" style="vertical-align:-4px;margin-right:6px"><path fill="currentColor" d="M17.65 6.35C16.2 4.9 14.21 4 12 4c-4.42 0-7.99 3.58-7.99 8s3.57 8 7.99 8c3.73 0 6.84-2.55 7.73-6h-2.08c-.82 2.33-3.04 4-5.65 4-3.31 0-6-2.69-6-6s2.69-6 6-6c1.66 0 3.14.69 4.22 1.78L13 11h7V4l-2.35 2.35z"/></svg>版本与更新</h3>
|
||||
</div>
|
||||
<div id="update-area">
|
||||
<div style="display:flex;gap:12px;align-items:center;flex-wrap:wrap">
|
||||
@@ -17,7 +17,7 @@
|
||||
</div>
|
||||
<div style="margin-top:16px;border-top:1px solid var(--border);padding-top:12px">
|
||||
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:8px">
|
||||
<h4 style="margin:0">📦 备份管理</h4>
|
||||
<h4 style="margin:0"><svg width="18" height="18" viewBox="0 0 24 24" style="vertical-align:-3px;margin-right:4px"><path fill="currentColor" d="M20 6h-8l-2-2H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2zm0 12H4V6h5.17l2 2H20v10z"/></svg>备份管理</h4>
|
||||
<button class="btn btn-sm btn-outlined" onclick="loadBackups()">刷新列表</button>
|
||||
</div>
|
||||
<div id="backup-list"><span style="color:var(--text-dim);font-size:.85rem">加载中...</span></div>
|
||||
@@ -27,7 +27,7 @@
|
||||
<!-- ── API Key 管理 ── -->
|
||||
<div class="card" style="margin-bottom:24px">
|
||||
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:16px">
|
||||
<h3 style="margin:0">🔑 API Key 管理</h3>
|
||||
<h3 style="margin:0"><svg width="20" height="20" viewBox="0 0 24 24" style="vertical-align:-4px;margin-right:6px"><path fill="currentColor" d="M12.65 10C11.83 7.67 9.61 6 7 6c-3.31 0-6 2.69-6 6s2.69 6 6 6c2.61 0 4.83-1.67 5.65-4H17v4h4v-4h2v-4H12.65zM7 14c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2z"/></svg>API Key 管理</h3>
|
||||
<button class="btn btn-filled" onclick="showCreateKey()">+ 创建 Key</button>
|
||||
</div>
|
||||
<p style="color:var(--text-dim);font-size:.85rem;margin-bottom:12px">
|
||||
|
||||
Reference in New Issue
Block a user