This commit is contained in:
2026-01-30 12:56:00 +08:00
parent 91f24cb462
commit dcbbda951e
89 changed files with 13486 additions and 72 deletions

170
ui/pages/logs.slint Normal file
View File

@@ -0,0 +1,170 @@
import { Theme, SpacingSystem, Typography } from "../theme/theme.slint";
import { Tabs, TabItem, TabContent } from "../components/tabs.slint";
export struct LogEntry {
time: string,
level: string, // "debug", "info", "warn", "error"
message: string,
}
export component LogsPage {
in property <[LogEntry]> mihomo-logs: [];
in property <[LogEntry]> app-logs: [];
in-out property <int> current-tab: 0;
callback tab-changed(int);
VerticalLayout {
padding: SpacingSystem.spacing.s4;
spacing: SpacingSystem.spacing.s4;
// Header with Tabs
HorizontalLayout {
spacing: SpacingSystem.spacing.s3;
alignment: space-between;
Text {
text: "Logs";
color: Theme.colors.foreground;
font-size: Typography.sizes.xl;
font-weight: Typography.weights.bold;
vertical-alignment: center;
}
Rectangle {
horizontal-stretch: 1;
}
}
// Tabs
Tabs {
tabs: [
{ title: "Mihomo Logs" },
{ title: "App Logs" },
];
current-index: root.current-tab;
tab-changed(index) => {
root.current-tab = index;
root.tab-changed(index);
}
// Mihomo Logs
TabContent {
index: 0;
current-index: root.current-tab;
LogView {
logs: root.mihomo-logs;
}
}
// App Logs
TabContent {
index: 1;
current-index: root.current-tab;
LogView {
logs: root.app-logs;
}
}
}
}
}
component LogView {
in property <[LogEntry]> logs: [];
Rectangle {
background: Theme.colors.background;
border-radius: SpacingSystem.radius.md;
border-width: 1px;
border-color: Theme.colors.border;
ScrollView {
VerticalLayout {
padding: SpacingSystem.spacing.s2;
spacing: 0;
for log[index] in root.logs: LogRow {
log-entry: log;
odd: Math.mod(index, 2) == 1;
}
}
}
}
}
component LogRow {
in property <LogEntry> log-entry;
in property ool> odd: false;
private property <bool> hovered: false;
private property <color> level-color: log-entry.level == "error" ? #ef4444 :
log-entry.level == "warn" ? #eab308 :
log-entry.level == "info" ? #3b82f6 :
log-entry.level == "debug" ? #6b7280 :
Theme.colors.muted-foreground;
height: 24px;
states [
hovered when root.hovered: {
container.background: Theme.colors.muted.transparentize(0.5);
}
odd when root.odd && !root.hovered: {
container.background: Theme.colors.muted.transparentize(0.8);
}
]
container := Rectangle {
background: transparent;
border-radius: SpacingSystem.radius.sm;
animate background { duration: 150ms; }
HorizontalLayout {
padding-left: SpacingSystem.spacing.s2;
padding-right: SpacingSystem.spacing.s2;
spacing: SpacingSystem.spacing.s2;
// Time
Text {
text: root.log-entry.time;
color: Theme.colors.muted-foreground;
font-size: 11px;
font-family: "monospace";
vertical-alignment: center;
width: 80px;
}
// Level
Text {
text: root.log-entry.level;
color: root.level-color;
font-size: 11px;
font-family: "monospace";
font-weight: Typography.weights.bold;
vertical-alignment: center;
width: 60px;
}
// Message
Text {
text: root.log-entry.message;
color: Theme.colors.foreground;
font-size: 11px;
font-family: "ospace";
vertical-alignment: center;
overflow: elide;
}
}
touch := TouchArea {
moved => {
root.hovered = self.has-hover;
}
}
}
}