Skip to content

Commit a0cb8aa

Browse files
committed
Remember scroll position.
1 parent 1dcab43 commit a0cb8aa

File tree

1 file changed

+47
-15
lines changed

1 file changed

+47
-15
lines changed

examples/device/webusb_serial/website/application.js

Lines changed: 47 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@
8989
uiSendModeBtn.addEventListener('click', () => this.toggleSendMode());
9090
uiReceivedDataClearBtn.addEventListener('click', () => this.clearReceivedData());
9191

92+
window.addEventListener('beforeunload', () => this.beforeUnloadHandler());
93+
9294
// restore state from localStorage
9395
try {
9496
this.restoreState();
@@ -102,6 +104,12 @@
102104
this.connectWebUsbSerialPort(true);
103105
}
104106

107+
beforeUnloadHandler() {
108+
// Save the scroll position of the command history and received data
109+
localStorage.setItem('commandHistoryScrollTop', uiCommandHistoryScrollbox.scrollTop);
110+
localStorage.setItem('receivedDataScrollTop', uiReceivedDataScrollbox.scrollTop);
111+
}
112+
105113
restoreState() {
106114
// Restore theme choice
107115
const savedTheme = localStorage.getItem('theme');
@@ -112,14 +120,24 @@
112120
// Restore command history
113121
let savedCommandHistory = JSON.parse(localStorage.getItem('commandHistory') || '[]');
114122
for (const cmd of savedCommandHistory) {
115-
this.appendCommandToHistory(cmd);
123+
this.addCommandToHistoryUI(cmd);
124+
}
125+
// Restore scroll position for command history
126+
const commandHistoryScrollTop = localStorage.getItem('commandHistoryScrollTop');
127+
if (commandHistoryScrollTop) {
128+
uiCommandHistoryScrollbox.scrollTop = parseInt(commandHistoryScrollTop, 10);
116129
}
117130

118131
// Restore received data
119132
let savedReceivedData = JSON.parse(localStorage.getItem('receivedData') || '[]');
120133
for (let line of savedReceivedData) {
121134
line.terminated = true;
122-
this.appendReceivedData(line);
135+
this.addReceivedDataEntryUI(line);
136+
}
137+
// Restore scroll position for received data
138+
const receivedDataScrollTop = localStorage.getItem('receivedDataScrollTop');
139+
if (receivedDataScrollTop) {
140+
uiReceivedDataScrollbox.scrollTop = parseInt(receivedDataScrollTop, 10);
123141
}
124142

125143
this.sendMode = localStorage.getItem('sendMode') || 'command';
@@ -165,9 +183,7 @@
165183
this.setTheme(nextTheme);
166184
}
167185

168-
appendCommandToHistory(commandHistoryEntry) {
169-
const wasNearBottom = uiCommandHistoryScrollbox.scrollHeight - uiCommandHistoryScrollbox.scrollTop <= uiCommandHistoryScrollbox.clientHeight + uiNearTheBottomThreshold;
170-
186+
addCommandToHistoryUI(commandHistoryEntry) {
171187
let commandHistoryEntryBtn = null;
172188

173189
let lastCommandMatched = false;
@@ -213,15 +229,19 @@
213229
this.commandHistory.shift();
214230
uiCommandHistoryScrollbox.removeChild(uiCommandHistoryScrollbox.firstElementChild);
215231
}
232+
}
233+
234+
appendNewCommandToHistory(commandHistoryEntry) {
235+
const wasNearBottom = this.isNearBottom(uiCommandHistoryScrollbox);
236+
237+
this.addCommandToHistoryUI(commandHistoryEntry);
216238

217239
// Save the command history to localStorage
218240
localStorage.setItem('commandHistory', JSON.stringify(this.commandHistory));
219241

220242
// Scroll to the new entry if near the bottom
221243
if (wasNearBottom) {
222-
requestAnimationFrame(() => {
223-
uiCommandHistoryScrollbox.scrollTop = uiCommandHistoryScrollbox.scrollHeight;
224-
});
244+
this.scrollToBottom(uiCommandHistoryScrollbox);
225245
}
226246
}
227247

@@ -232,9 +252,17 @@
232252
this.setStatus('Command history cleared', 'info');
233253
}
234254

235-
appendReceivedData(receivedDataEntry) {
236-
const wasNearBottom = uiReceivedDataScrollbox.scrollHeight - uiReceivedDataScrollbox.scrollTop <= uiReceivedDataScrollbox.clientHeight + uiNearTheBottomThreshold;
255+
isNearBottom(container) {
256+
return container.scrollHeight - container.scrollTop <= container.clientHeight + uiNearTheBottomThreshold;
257+
}
258+
259+
scrollToBottom(container) {
260+
requestAnimationFrame(() => {
261+
container.scrollTop = container.scrollHeight;
262+
});
263+
}
237264

265+
addReceivedDataEntryUI(receivedDataEntry) {
238266
let newReceivedDataEntries = [];
239267
let updateLastReceivedDataEntry = false;
240268
if (this.receivedData.length <= 0) {
@@ -306,15 +334,19 @@
306334
this.receivedData.shift();
307335
uiReceivedDataScrollbox.removeChild(uiReceivedDataScrollbox.firstElementChild);
308336
}
337+
}
338+
339+
appendNewReceivedData(receivedDataEntry) {
340+
const wasNearBottom = this.isNearBottom(uiReceivedDataScrollbox);
341+
342+
this.addReceivedDataEntryUI(receivedDataEntry);
309343

310344
// Save the received data to localStorage
311345
localStorage.setItem('receivedData', JSON.stringify(this.receivedData));
312346

313347
// Scroll to the new entry if near the bottom
314348
if (wasNearBottom) {
315-
requestAnimationFrame(() => {
316-
uiReceivedDataScrollbox.scrollTop = uiReceivedDataScrollbox.scrollHeight;
317-
});
349+
this.scrollToBottom(uiReceivedDataScrollbox);
318350
}
319351
}
320352

@@ -382,7 +414,7 @@
382414

383415
let text = this.textDecoder.decode(dataView);
384416
let receivedDataEntry = new ReceivedDataEntry(text);
385-
this.appendReceivedData(receivedDataEntry);
417+
this.appendNewReceivedData(receivedDataEntry);
386418
}
387419

388420
async onReceiveError(error) {
@@ -651,7 +683,7 @@
651683
this.uiCommandHistoryIndex = -1;
652684
let history_cmd_text = sendText.replace(/[\r\n]+$/, '');
653685
let history_entry = new CommandHistoryEntry(history_cmd_text);
654-
this.appendCommandToHistory(history_entry);
686+
this.appendNewCommandToHistory(history_entry);
655687
uiCommandLineInput.value = '';
656688
} catch (error) {
657689
this.setStatus(`Send error: ${error.message}`, 'error');

0 commit comments

Comments
 (0)