refactor: 抽取NetCommon.qml消除跨组件重复代码

新建 package/components/NetCommon.qml 聚合公共颜色定义(主题感知色
+强调色)和工具函数(isPhysicalIf/formatSpeed/formatTotal/downloadValueColor)。

networkview.qml、NetworkPopup.qml、TrafficChartWindow.qml 删除各自
的重复定义改为引用 common.xxx,净删除91行重复代码。downloadValueColor
由属性绑定改为函数(调用方传速度值)。视觉行为零变化。
This commit is contained in:
2026-07-24 11:00:02 +08:00
parent 36200e7c50
commit 110032f3c9
5 changed files with 140 additions and 154 deletions
+3 -9
View File
@@ -55,15 +55,9 @@
## 二、代码质量 / 可维护性 ## 二、代码质量 / 可维护性
**11. 大量重复代码跨组件复制** **11. ~~大量重复代码跨组件复制~~ ✅ 已修复**
以下代码在 `networkview.qml``NetworkPopup.qml`完全重复,`formatSpeed` 还在 `TrafficChartWindow.qml` 中第三份拷贝 ~~`networkview.qml` 和 `NetworkPopup.qml` 中重复颜色定义、`isPhysicalIf`、`formatSpeed`、`formatTotal` 等,`formatSpeed` 还在 `TrafficChartWindow.qml` 中第三份拷贝。~~
- `isPhysicalIf()` 函数 已新建 `package/components/NetCommon.qml` 聚合所有公共颜色与函数。3 个文件删除重复定义改为引用 `common.xxx`,净删除 91 行重复代码。`downloadValueColor` 由属性绑定改为函数(调用方传速度值)。
- `sortedInterfaces` 属性
- `formatSpeed()` / `formatTotal()` 函数
- 全套调色板定义(`basePalette``primaryText``accentBlue`…)
- `downloadValueColor` / `uploadValueColor`
改一处需同步改 2-3 处,极易遗漏。应抽取为公共 QML 文件(如 `Theme.qml` 单例 + `Format.js`)。
**12. 死代码:`interfaceStats` 属性未被使用** **12. 死代码:`interfaceStats` 属性未被使用**
`networkview.qml:43` 绑定了 `interfaceStats` 属性,但从未在任何 UI 中读取。C++ 侧的 `interfaceStats()` 函数和 `Q_PROPERTY` 也是死代码。且其 `QStringList``|` 分隔符编码结构化数据的方式本身也很脆弱。 `networkview.qml:43` 绑定了 `interfaceStats` 属性,但从未在任何 UI 中读取。C++ 侧的 `interfaceStats()` 函数和 `Q_PROPERTY` 也是死代码。且其 `QStringList``|` 分隔符编码结构化数据的方式本身也很脆弱。
+82
View File
@@ -0,0 +1,82 @@
// SPDX-FileCopyrightText: 2026 Jokul
//
// SPDX-License-Identifier: LGPL-3.0-or-later
// 网络监控插件的公共颜色与格式化函数
// 消除 networkview.qml 与 NetworkPopup.qml、TrafficChartWindow.qml 之间的重复定义:
// 以下颜色与函数此前在各组件内各持一份拷贝,改一处需同步多处;
// 现集中到本文件,各组件实例化 NetCommon { id: common } 后统一经 common.xxx 访问
// 设计原因:
// - 颜色统一派生自 DTK 系统调色板(windowText),跟随系统深浅主题自动适配。
// 不采用 DockPalette.iconTextPalette:实测其不随系统深色主题变化,
// 深色模式下返回深色文字(黑底黑字)、浅色模式下返回浅色文字(白底白字),方向相反;
// DTK.palette.windowText 则与面板/弹窗背景同步。主题切换时 DTK.paletteChanged
// 自动触发属性绑定重新求值(QtObject 内绑定 DTK.palette 与 Item 内行为一致,已实测验证)
// - 函数与颜色分离:downloadValueColor 依赖调用方的速度值,提取为函数由调用方传入,
// 消除对组件上下文的依赖;sortedInterfaces 依赖各组件自身的接口列表,仍留在各组件内
import QtQuick 2.15
import org.deepin.dtk 1.0
QtObject {
// ---- 主题感知颜色(派生自 DTK 系统调色板)----
// baseTextColor 为中间基准色,以下各级文字/卡片颜色均由它加透明度派生
readonly property color baseTextColor: DTK.palette.windowText
readonly property color primaryText: Qt.rgba(baseTextColor.r, baseTextColor.g, baseTextColor.b, 0.95)
readonly property color secondaryText: Qt.rgba(baseTextColor.r, baseTextColor.g, baseTextColor.b, 0.80)
readonly property color tertiaryText: Qt.rgba(baseTextColor.r, baseTextColor.g, baseTextColor.b, 0.65)
readonly property color cardBackground: Qt.rgba(baseTextColor.r, baseTextColor.g, baseTextColor.b, 0.06)
readonly property color cardBorder: Qt.rgba(baseTextColor.r, baseTextColor.g, baseTextColor.b, 0.10)
// ---- 强调色:下载蓝、上传绿,是面板与任务栏的主视觉区分 ----
readonly property color accentBlue: Qt.rgba(20 / 255, 80 / 255, 160 / 255, 1)
readonly property color accentBlueLight: Qt.rgba(20 / 255, 80 / 255, 160 / 255, 0.12)
readonly property color accentGreen: Qt.rgba(22 / 255, 163 / 255, 74 / 255, 1)
readonly property color accentGreenLight: Qt.rgba(22 / 255, 163 / 255, 74 / 255, 0.12)
// ---- 高速警示色:下载速度超过阈值时由蓝转橙再转红 ----
readonly property color accentOrange: Qt.rgba(245 / 255, 158 / 255, 11 / 255, 1)
readonly property color accentRed: Qt.rgba(220 / 255, 38 / 255, 38 / 255, 1)
// 下载值颜色:保留原有阈值逻辑(>10MB/s 红、>1MB/s 橙、否则蓝),仅作用于下载值
// 原为各组件内的属性绑定(依赖组件自身的 downloadSpeed),提取为公共函数后
// 由调用方传入速度值;在绑定表达式中调用时,绑定仍随速度变化自动重算,行为不变
function downloadValueColor(downloadSpeed) {
if (downloadSpeed > 10 * 1024 * 1024) return accentRed
if (downloadSpeed > 1 * 1024 * 1024) return accentOrange
return accentBlue
}
// 上传值颜色:固定绿色,不做高速警示
readonly property color uploadValueColor: accentGreen
// 判断是否为物理网卡(QML 侧排序用,与 C++ isPhysicalInterface 逻辑一致)
function isPhysicalIf(name) {
return name.startsWith("wlp") || name.startsWith("wlan")
|| name.startsWith("enp") || name.startsWith("eth")
}
// 格式化速度显示(带单位,用于弹出面板,信息更完整)
// 最小单位为 KB,与 networkview.qml 的 formatSpeedShort 保持一致;所有级别保留 2 位小数
function formatSpeed(bytesPerSec) {
if (bytesPerSec < 1024 * 1024) {
return (bytesPerSec / 1024).toFixed(2) + " KB/s"
} else if (bytesPerSec < 1024 * 1024 * 1024) {
return (bytesPerSec / (1024 * 1024)).toFixed(2) + " MB/s"
} else {
return (bytesPerSec / (1024 * 1024 * 1024)).toFixed(2) + " GB/s"
}
}
// 格式化总量显示(用于弹出面板的累计统计)
function formatTotal(bytes) {
if (bytes < 1024) {
return bytes.toFixed(0) + " B"
} else if (bytes < 1024 * 1024) {
return (bytes / 1024).toFixed(1) + " KB"
} else if (bytes < 1024 * 1024 * 1024) {
return (bytes / (1024 * 1024)).toFixed(1) + " MB"
} else {
return (bytes / (1024 * 1024 * 1024)).toFixed(2) + " GB"
}
}
}
+30 -67
View File
@@ -4,7 +4,8 @@
// 网络速度监控弹窗内容组件 // 网络速度监控弹窗内容组件
// 展示实时速度、总量统计、网卡切换 chip 列表; // 展示实时速度、总量统计、网卡切换 chip 列表;
// 由 networkview.qml 的 PanelPopup 实例化,传入 applet 属性,内部自行派生颜色和数据 // 由 networkview.qml 的 PanelPopup 实例化,传入 applet 属性
// 颜色与格式化函数统一取自同目录 NetCommon.qmlcommon.xxx),数据由 applet 提供
// 设计原因:PanelPopup 是 dock 上下文类型,不能作为独立组件根元素, // 设计原因:PanelPopup 是 dock 上下文类型,不能作为独立组件根元素,
// 因此本组件用 Control 作为根,由 networkview.qml 的 PanelPopup 包裹 // 因此本组件用 Control 作为根,由 networkview.qml 的 PanelPopup 包裹
@@ -13,10 +14,15 @@ import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15 import QtQuick.Layouts 1.15
import org.deepin.ds.dock 1.0 import org.deepin.ds.dock 1.0
import org.deepin.dtk 1.0 import org.deepin.dtk 1.0
import "."
Control { Control {
id: popup id: popup
// 公共颜色与格式化函数:集中定义于同目录 NetCommon.qml
// 与 networkview.qml、TrafficChartWindow 共享同一份实现,消除跨组件重复定义
NetCommon { id: common }
// C++ 后端对象,提供速度/接口/IP 等所有数据 // C++ 后端对象,提供速度/接口/IP 等所有数据
property var applet: null property var applet: null
@@ -32,54 +38,36 @@ Control {
readonly property string ipv6Address: applet ? (applet.ipv6Address || "") : "" readonly property string ipv6Address: applet ? (applet.ipv6Address || "") : ""
readonly property var networkInterfaces: applet ? (applet.networkInterfaces || []) : [] readonly property var networkInterfaces: applet ? (applet.networkInterfaces || []) : []
// 弹窗颜色派生自 DTK 系统调色板windowText),而非 DockPalette.iconTextPalette。 // 弹窗颜色别名:转发 common 的公共颜色(派生自 DTK 系统调色板 windowText
// 设计原因:PanelPopup 背景跟随系统主题(深色模式下变黑),但 DockPalette.iconTextPalette // 主题适配的设计原因见 NetCommon.qml 文件头注释),保持下游 popup.xxx 引用不变
// 反映的是任务栏图标文字色,不随系统深色主题变化,导致深色模式下弹窗黑底黑字。 readonly property color primaryText: common.primaryText
// DTK.palette.windowText 在深色模式下为浅色文字、浅色模式下为深色文字,与弹窗背景同步。 readonly property color secondaryText: common.secondaryText
// 主题切换时 DTK.paletteChanged 信号自动触发属性绑定重新求值。 readonly property color tertiaryText: common.tertiaryText
readonly property color baseTextColor: DTK.palette.windowText readonly property color cardBackground: common.cardBackground
readonly property color primaryText: Qt.rgba(baseTextColor.r, baseTextColor.g, baseTextColor.b, 0.95) readonly property color cardBorder: common.cardBorder
readonly property color secondaryText: Qt.rgba(baseTextColor.r, baseTextColor.g, baseTextColor.b, 0.80)
readonly property color tertiaryText: Qt.rgba(baseTextColor.r, baseTextColor.g, baseTextColor.b, 0.65)
readonly property color cardBackground: Qt.rgba(baseTextColor.r, baseTextColor.g, baseTextColor.b, 0.06)
readonly property color cardBorder: Qt.rgba(baseTextColor.r, baseTextColor.g, baseTextColor.b, 0.10)
// 强调色:下载蓝、上传绿,是面板的主视觉区分 // 强调色别名:下载蓝、上传绿,是面板的主视觉区分
readonly property color accentBlue: Qt.rgba(20 / 255, 80 / 255, 160 / 255, 1) readonly property color accentBlue: common.accentBlue
readonly property color accentBlueLight: Qt.rgba(20 / 255, 80 / 255, 160 / 255, 0.12) readonly property color accentBlueLight: common.accentBlueLight
readonly property color accentGreen: Qt.rgba(22 / 255, 163 / 255, 74 / 255, 1) readonly property color accentGreen: common.accentGreen
readonly property color accentGreenLight: Qt.rgba(22 / 255, 163 / 255, 74 / 255, 0.12) readonly property color accentGreenLight: common.accentGreenLight
// 高速警示色:下载速度超过阈值时由蓝转橙再转红
readonly property color accentOrange: Qt.rgba(245 / 255, 158 / 255, 11 / 255, 1)
readonly property color accentRed: Qt.rgba(220 / 255, 38 / 255, 38 / 255, 1)
// 下载值颜色:保留原有阈值逻辑(>10MB/s 红、>1MB/s 橙、否则蓝),仅作用于下载值
readonly property color downloadValueColor: {
if (downloadSpeed > 10 * 1024 * 1024) return accentRed
if (downloadSpeed > 1 * 1024 * 1024) return accentOrange
return accentBlue
}
// 上传值颜色:固定绿色,不做高速警示 // 上传值颜色:固定绿色,不做高速警示
readonly property color uploadValueColor: accentGreen // 下载值颜色带阈值逻辑(>10MB/s 红、>1MB/s 橙、否则蓝),已提取为
// common.downloadValueColor(speed) 函数,在使用处直接传入 downloadSpeed 调用
// 判断是否为物理网卡(QML 侧排序用,与 C++ isPhysicalInterface 逻辑一致) readonly property color uploadValueColor: common.uploadValueColor
function isPhysicalIf(name) {
return name.startsWith("wlp") || name.startsWith("wlan")
|| name.startsWith("enp") || name.startsWith("eth")
}
// 排序后的接口列表:物理网卡在前,虚拟网卡在后,各自按名称排序 // 排序后的接口列表:物理网卡在前,虚拟网卡在后,各自按名称排序
// 设计原因:保持稳定排序,活动接口不再移到最前,避免切换网卡时 chip 顺序跳动; // 设计原因:保持稳定排序,活动接口不再移到最前,避免切换网卡时 chip 顺序跳动;
// 活动 chip 若被截断,由 chipFlickable 自动滚动露出完整样式 // 活动 chip 若被截断,由 chipFlickable 自动滚动露出完整样式
// 物理网卡判断逻辑共用 common.isPhysicalIf(与 C++ isPhysicalInterface 一致)
readonly property var sortedInterfaces: { readonly property var sortedInterfaces: {
if (!popup.ready || popup.networkInterfaces.length === 0) return [] if (!popup.ready || popup.networkInterfaces.length === 0) return []
var physical = [] var physical = []
var virtual = [] var virtual = []
for (var i = 0; i < popup.networkInterfaces.length; i++) { for (var i = 0; i < popup.networkInterfaces.length; i++) {
var name = popup.networkInterfaces[i] var name = popup.networkInterfaces[i]
if (popup.isPhysicalIf(name)) physical.push(name) if (common.isPhysicalIf(name)) physical.push(name)
else virtual.push(name) else virtual.push(name)
} }
physical.sort() physical.sort()
@@ -87,31 +75,6 @@ Control {
return physical.concat(virtual) return physical.concat(virtual)
} }
// 格式化速度显示(带单位,用于弹出面板,信息更完整)
// 最小单位为 KB,与 formatSpeedShort 保持一致;所有级别保留 2 位小数
function formatSpeed(bytesPerSec) {
if (bytesPerSec < 1024 * 1024) {
return (bytesPerSec / 1024).toFixed(2) + " KB/s"
} else if (bytesPerSec < 1024 * 1024 * 1024) {
return (bytesPerSec / (1024 * 1024)).toFixed(2) + " MB/s"
} else {
return (bytesPerSec / (1024 * 1024 * 1024)).toFixed(2) + " GB/s"
}
}
// 格式化总量显示(用于弹出面板的累计统计)
function formatTotal(bytes) {
if (bytes < 1024) {
return bytes.toFixed(0) + " B"
} else if (bytes < 1024 * 1024) {
return (bytes / 1024).toFixed(1) + " KB"
} else if (bytes < 1024 * 1024 * 1024) {
return (bytes / (1024 * 1024)).toFixed(1) + " MB"
} else {
return (bytes / (1024 * 1024 * 1024)).toFixed(2) + " GB"
}
}
// 供外部调用:popup 打开时滚动到活动 chip // 供外部调用:popup 打开时滚动到活动 chip
function scrollToActiveChip(animated) { function scrollToActiveChip(animated) {
chipFlickable.scrollToActiveChip(animated) chipFlickable.scrollToActiveChip(animated)
@@ -231,10 +194,10 @@ Control {
} }
Text { Text {
text: popup.formatSpeed(popup.downloadSpeed) text: common.formatSpeed(popup.downloadSpeed)
font.pixelSize: 18 font.pixelSize: 18
font.weight: Font.Bold font.weight: Font.Bold
color: popup.downloadValueColor color: common.downloadValueColor(popup.downloadSpeed)
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
} }
} }
@@ -288,7 +251,7 @@ Control {
} }
Text { Text {
text: popup.formatSpeed(popup.uploadSpeed) text: common.formatSpeed(popup.uploadSpeed)
font.pixelSize: 18 font.pixelSize: 18
font.weight: Font.Bold font.weight: Font.Bold
color: popup.uploadValueColor color: popup.uploadValueColor
@@ -323,13 +286,13 @@ Control {
} }
Text { Text {
text: "↓ " + popup.formatTotal(popup.totalDownload) text: "↓ " + common.formatTotal(popup.totalDownload)
font.pixelSize: 12 font.pixelSize: 12
color: popup.primaryText color: popup.primaryText
} }
Text { Text {
text: "↑ " + popup.formatTotal(popup.totalUpload) text: "↑ " + common.formatTotal(popup.totalUpload)
font.pixelSize: 12 font.pixelSize: 12
color: popup.primaryText color: popup.primaryText
} }
+11 -15
View File
@@ -16,10 +16,15 @@
import QtQuick 2.15 import QtQuick 2.15
import QtQuick.Layouts 1.15 import QtQuick.Layouts 1.15
import QtQuick.Window 2.15 import QtQuick.Window 2.15
import "."
Window { Window {
id: root id: root
// 公共格式化函数:集中定义于同目录 NetCommon.qml
// 与 networkview.qml、NetworkPopup 共享同一份实现,消除跨组件重复定义
NetCommon { id: common }
// 对外依赖:关闭按钮 hover 态文字高亮色,由父组件传入 // 对外依赖:关闭按钮 hover 态文字高亮色,由父组件传入
// 默认值与 networkview.qml 中 root.accentRed 一致,确保独立可用 // 默认值与 networkview.qml 中 root.accentRed 一致,确保独立可用
property color accentColor: Qt.rgba(220 / 255, 38 / 255, 38 / 255, 1) property color accentColor: Qt.rgba(220 / 255, 38 / 255, 38 / 255, 1)
@@ -102,17 +107,8 @@ Window {
} }
} }
// 格式化速度显示(带单位,最小 KB,保留 2 位小数) // 格式化速度显示:统一调用 common.formatSpeed(带单位,最小 KB,保留 2 位小数)
// 与 networkview.qml 的 formatSpeed 同实现;组件内自带一份保证独立可用 // 与 networkview.qml / NetworkPopup 共用 NetCommon 中的同一份实现
function formatSpeed(bytesPerSec) {
if (bytesPerSec < 1024 * 1024) {
return (bytesPerSec / 1024).toFixed(2) + " KB/s"
} else if (bytesPerSec < 1024 * 1024 * 1024) {
return (bytesPerSec / (1024 * 1024)).toFixed(2) + " MB/s"
} else {
return (bytesPerSec / (1024 * 1024 * 1024)).toFixed(2) + " GB/s"
}
}
// Y 轴上限取整:将 v 向上取整到 1/2/5 × 10^n 序列 // Y 轴上限取整:将 v 向上取整到 1/2/5 × 10^n 序列
// 设计原因:使刻度值为易读的整数(如 12345 -> 2000080000 -> 100000), // 设计原因:使刻度值为易读的整数(如 12345 -> 2000080000 -> 100000),
@@ -308,7 +304,7 @@ Window {
Text { Text {
// applet 为空时兜底为 0,保证独立预览不报错 // applet 为空时兜底为 0,保证独立预览不报错
text: root.formatSpeed(root.applet ? root.applet.downloadSpeed : 0) text: common.formatSpeed(root.applet ? root.applet.downloadSpeed : 0)
font.pixelSize: 12 font.pixelSize: 12
color: root.textPrimary color: root.textPrimary
} }
@@ -323,7 +319,7 @@ Window {
} }
Text { Text {
text: root.formatSpeed(root.applet ? root.applet.uploadSpeed : 0) text: common.formatSpeed(root.applet ? root.applet.uploadSpeed : 0)
font.pixelSize: 12 font.pixelSize: 12
color: root.textPrimary color: root.textPrimary
} }
@@ -560,8 +556,8 @@ Window {
var idx = root.hoverIndex var idx = root.hoverIndex
var upVal = idx < ul.length ? ul[idx].y : 0 var upVal = idx < ul.length ? ul[idx].y : 0
root.hoverHint = Qt.formatDateTime(new Date(dl[idx].x * 1000), "HH:mm:ss") root.hoverHint = Qt.formatDateTime(new Date(dl[idx].x * 1000), "HH:mm:ss")
+ " ↓" + root.formatSpeed(dl[idx].y) + " ↓" + common.formatSpeed(dl[idx].y)
+ " ↑" + root.formatSpeed(upVal) + " ↑" + common.formatSpeed(upVal)
canvas.requestPaint() canvas.requestPaint()
} }
+14 -63
View File
@@ -42,22 +42,21 @@ AppletItem {
readonly property var networkInterfaces: applet ? (applet.networkInterfaces || []) : [] readonly property var networkInterfaces: applet ? (applet.networkInterfaces || []) : []
readonly property var interfaceStats: applet ? (applet.interfaceStats || []) : [] readonly property var interfaceStats: applet ? (applet.interfaceStats || []) : []
// 判断是否为物理网卡(QML 侧排序用,与 C++ isPhysicalInterface 逻辑一致) // 公共颜色与格式化函数:集中定义于 components/NetCommon.qml(随 import "components" 引入),
function isPhysicalIf(name) { // 与 NetworkPopup、TrafficChartWindow 共享同一份实现,消除跨组件重复定义
return name.startsWith("wlp") || name.startsWith("wlan") NetCommon { id: common }
|| name.startsWith("enp") || name.startsWith("eth")
}
// 排序后的接口列表:物理网卡在前,虚拟网卡在后,各自按名称排序 // 排序后的接口列表:物理网卡在前,虚拟网卡在后,各自按名称排序
// 设计原因:保持稳定排序,活动接口不再移到最前,避免切换网卡时 chip 顺序跳动; // 设计原因:保持稳定排序,活动接口不再移到最前,避免切换网卡时 chip 顺序跳动;
// 活动 chip 若被截断,由 chipFlickable 自动滚动露出完整样式 // 活动 chip 若被截断,由 chipFlickable 自动滚动露出完整样式
// 物理网卡判断逻辑共用 common.isPhysicalIf(与 C++ isPhysicalInterface 一致)
readonly property var sortedInterfaces: { readonly property var sortedInterfaces: {
if (!root.ready || root.networkInterfaces.length === 0) return [] if (!root.ready || root.networkInterfaces.length === 0) return []
var physical = [] var physical = []
var virtual = [] var virtual = []
for (var i = 0; i < root.networkInterfaces.length; i++) { for (var i = 0; i < root.networkInterfaces.length; i++) {
var name = root.networkInterfaces[i] var name = root.networkInterfaces[i]
if (root.isPhysicalIf(name)) physical.push(name) if (common.isPhysicalIf(name)) physical.push(name)
else virtual.push(name) else virtual.push(name)
} }
physical.sort() physical.sort()
@@ -79,43 +78,15 @@ AppletItem {
} }
} }
// 带单位的速度/总量格式化函数(formatSpeed / formatTotal)已移至 NetCommon
// 本文件未直接使用;弹窗与图表窗口经 common.formatSpeed / common.formatTotal 调用
// 格式化速度显示(带单位,用于弹出面板,信息更完整) // 颜色别名:转发 common 的公共颜色,保持下游 root.xxx 引用不变。
// 最小单位为 KB,与 formatSpeedShort 保持一致;所有级别保留 2 位小数 // 仅保留本文件实际使用的两个(primaryText 供 speedTextColor 回退、
function formatSpeed(bytesPerSec) { // accentRed 传入各独立窗口);其余公共颜色本文件未用,不再重复定义。
if (bytesPerSec < 1024 * 1024) { // 颜色派生逻辑与主题适配的设计原因见 NetCommon.qml 文件头注释
return (bytesPerSec / 1024).toFixed(2) + " KB/s" readonly property color primaryText: common.primaryText
} else if (bytesPerSec < 1024 * 1024 * 1024) { readonly property color accentRed: common.accentRed
return (bytesPerSec / (1024 * 1024)).toFixed(2) + " MB/s"
} else {
return (bytesPerSec / (1024 * 1024 * 1024)).toFixed(2) + " GB/s"
}
}
// 格式化总量显示(用于弹出面板的累计统计)
function formatTotal(bytes) {
if (bytes < 1024) {
return bytes.toFixed(0) + " B"
} else if (bytes < 1024 * 1024) {
return (bytes / 1024).toFixed(1) + " KB"
} else if (bytes < 1024 * 1024 * 1024) {
return (bytes / (1024 * 1024)).toFixed(1) + " MB"
} else {
return (bytes / (1024 * 1024 * 1024)).toFixed(2) + " GB"
}
}
// 任务栏图标颜色派生自 DTK 系统调色板(windowText),跟随系统主题适配。
// 设计原因:原用 DockPalette.iconTextPalette,但实测其不随系统深色主题变化,
// 深色模式下返回深色文字(黑底黑字)、浅色模式下返回浅色文字(白底白字),方向相反。
// DTK.palette.windowText 在深色模式下为浅色、浅色模式下为深色,与任务栏背景匹配。
// 注意:仅用于任务栏图标区(speedTextColor 回退),弹窗和独立窗口各自派生颜色。
readonly property color baseTextColor: DTK.palette.windowText
readonly property color primaryText: Qt.rgba(baseTextColor.r, baseTextColor.g, baseTextColor.b, 0.95)
readonly property color secondaryText: Qt.rgba(baseTextColor.r, baseTextColor.g, baseTextColor.b, 0.80)
readonly property color tertiaryText: Qt.rgba(baseTextColor.r, baseTextColor.g, baseTextColor.b, 0.65)
readonly property color cardBackground: Qt.rgba(baseTextColor.r, baseTextColor.g, baseTextColor.b, 0.06)
readonly property color cardBorder: Qt.rgba(baseTextColor.r, baseTextColor.g, baseTextColor.b, 0.10)
// 深色模式检测:用 DTK 系统调色板的窗口背景亮度判定,而非 DockPalette。 // 深色模式检测:用 DTK 系统调色板的窗口背景亮度判定,而非 DockPalette。
// 设计原因:DockPalette.iconTextPalette 反映的是任务栏图标文字色,不随系统深色主题变化; // 设计原因:DockPalette.iconTextPalette 反映的是任务栏图标文字色,不随系统深色主题变化;
@@ -124,26 +95,6 @@ AppletItem {
// 检测结果通过属性注入各独立窗口(AboutWindow 等独立 Window 无法访问 dock 上下文的 DockPalette // 检测结果通过属性注入各独立窗口(AboutWindow 等独立 Window 无法访问 dock 上下文的 DockPalette
readonly property bool isDarkMode: DTK.palette.window.hslLightness < 0.5 readonly property bool isDarkMode: DTK.palette.window.hslLightness < 0.5
// 强调色:下载蓝、上传绿,是面板与任务栏的主视觉区分
readonly property color accentBlue: Qt.rgba(20 / 255, 80 / 255, 160 / 255, 1)
readonly property color accentBlueLight: Qt.rgba(20 / 255, 80 / 255, 160 / 255, 0.12)
readonly property color accentGreen: Qt.rgba(22 / 255, 163 / 255, 74 / 255, 1)
readonly property color accentGreenLight: Qt.rgba(22 / 255, 163 / 255, 74 / 255, 0.12)
// 高速警示色:下载速度超过阈值时由蓝转橙再转红
readonly property color accentOrange: Qt.rgba(245 / 255, 158 / 255, 11 / 255, 1)
readonly property color accentRed: Qt.rgba(220 / 255, 38 / 255, 38 / 255, 1)
// 下载值颜色:保留原有阈值逻辑(>10MB/s 红、>1MB/s 橙、否则蓝),仅作用于下载值
readonly property color downloadValueColor: {
if (downloadSpeed > 10 * 1024 * 1024) return accentRed
if (downloadSpeed > 1 * 1024 * 1024) return accentOrange
return accentBlue
}
// 上传值颜色:固定绿色,不做高速警示
readonly property color uploadValueColor: accentGreen
// 任务栏网速数值字体色:用户自定义色优先(持久化),未设置时跟随系统主题 // 任务栏网速数值字体色:用户自定义色优先(持久化),未设置时跟随系统主题
// 设计原因:primaryText 派生自 DTK.palette.windowText,深浅色系统主题自动适配; // 设计原因:primaryText 派生自 DTK.palette.windowText,深浅色系统主题自动适配;
// 用户主动选色后覆盖,空串回退到 primaryText 保持自适应 // 用户主动选色后覆盖,空串回退到 primaryText 保持自适应