forked from bin456789/reinstall
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlogviewer.html
More file actions
159 lines (135 loc) · 4.48 KB
/
logviewer.html
File metadata and controls
159 lines (135 loc) · 4.48 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
<!DOCTYPE html>
<html>
<head>
<title>Reinstall Logs</title>
<style>
body {
margin: 0;
padding: 0;
overflow: hidden;
}
#log-container {
height: calc(100vh);
margin: 0;
padding: 8px;
overflow-y: scroll;
}
#scroll-to-bottom {
position: fixed;
bottom: 24px;
right: 24px;
background-color: #0099FF;
color: #fff;
border: none;
cursor: pointer;
display: none;
width: 48px;
height: 48px;
border-radius: 50%;
}
#scroll-to-bottom:hover {
background-color: #00CCFF;
}
#scroll-to-bottom svg {
fill: #fff;
}
.done {
background-color: #cfc;
}
.error {
background-color: #fcc;
}
</style>
</head>
<body>
<pre id="log-container"></pre>
<button id="scroll-to-bottom">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path d="M5 10l7 7 7-7H5z" />
</svg>
</button>
<script
src="https://mirrors.sustech.edu.cn/cdnjs/ajax/libs/reconnecting-websocket/1.0.0/reconnecting-websocket.min.js"
type="application/javascript"></script>
<script>
const logContainer = document.getElementById('log-container');
const scrollToBottomButton = document.getElementById('scroll-to-bottom');
let shouldScrollToBottom = true;
// 缓冲区相关
let messageBuffer = [];
let flushScheduled = false;
const BUFFER_FLUSH_INTERVAL = 100; // 毫秒
const BUFFER_MAX_SIZE = 50; // 最大缓冲消息数
scrollToBottomButton.addEventListener('click', () => {
logContainer.scrollTop = logContainer.scrollHeight;
});
logContainer.addEventListener('scroll', () => {
const isAtBottom = Math.ceil(logContainer.scrollTop + logContainer.clientHeight) >= logContainer.scrollHeight;
if (isAtBottom) {
scrollToBottomButton.style.display = 'none';
} else {
scrollToBottomButton.style.display = 'block';
}
shouldScrollToBottom = isAtBottom;
});
// 刷新缓冲区到 DOM
function flushBuffer() {
if (messageBuffer.length === 0) {
flushScheduled = false;
return;
}
// 批量更新文本内容
const batchText = messageBuffer.join('\n');
logContainer.textContent += '\n' + batchText;
// 检查状态变化(优先级:error > done > start)
if (batchText.includes('***** ERROR *****')) {
document.body.className = 'error';
} else if (batchText.includes('***** DONE *****')) {
document.body.className = 'done';
} else if (batchText.includes('***** START TRANS *****')) {
document.body.className = '';
}
// 自动滚动
if (shouldScrollToBottom) {
logContainer.scrollTop = logContainer.scrollHeight;
}
// 清空缓冲区
messageBuffer = [];
flushScheduled = false;
}
// 调度刷新
function scheduleFlush() {
if (!flushScheduled) {
flushScheduled = true;
requestAnimationFrame(() => {
setTimeout(flushBuffer, BUFFER_FLUSH_INTERVAL);
});
}
}
// 添加消息到缓冲区
function bufferMessage(message) {
messageBuffer.push(message);
// 如果缓冲区满了,立即刷新
if (messageBuffer.length >= BUFFER_MAX_SIZE) {
if (flushScheduled) {
// 取消之前的调度,立即刷新
flushScheduled = false;
}
flushBuffer();
} else {
scheduleFlush();
}
}
var ws = new ReconnectingWebSocket('ws://' + location.host + '/');
ws.onopen = function () {
bufferMessage('WebSocket Connected.');
};
ws.onclose = function () {
bufferMessage('WebSocket Disconnected.');
};
ws.onmessage = function (event) {
bufferMessage(event.data);
};
</script>
</body>
</html>