Skip to content

feat: add options panel #88

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 18 additions & 5 deletions src/content/background.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,18 @@
const NS_PER_MS = 1000 * 1000;

// TODO: read from settings
const INTERVAL_PROCESS_UPDATE = 5; // seconds

// TODO: read from settings
const MAX_BUFFER_ENTRIES = 60 / INTERVAL_PROCESS_UPDATE * 5; // 5 minutes

class TaskManager extends Object {
constructor() {
super();

// TODO: Set enabled status based on global setting and selected sidebar
// process pane.
Comment on lines -13 to -14
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lets keep those comments that are not addressed with your PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assumed these comments referred to the boolean buttons we added here:
image

Since we're handling this logic in option.js, I thought they were no longer needed.

this.includeThreads = true;
this.includeWindows = true;

this.interval_process_update = INTERVAL_PROCESS_UPDATE;
this.max_buffer_entries = MAX_BUFFER_ENTRIES;

this.lastSnapshotTime;
this.processesBuffer = [];
Expand Down Expand Up @@ -49,6 +46,10 @@ class TaskManager extends Object {
return this.platformInfo.os;
}

updateMaxBufferEntries() {
this.max_buffer_entries = 300 / this.interval_process_update;
}

async createProcessInfoAlarm() {
if (browser.alarms.get("get-process-info")) {
browser.alarms.clear("get-process-info");
Expand All @@ -70,7 +71,19 @@ class TaskManager extends Object {
switch (request.name) {
case "set-update-interval":
this.interval_process_update = request.interval;
this.updateMaxBufferEntries();
this.createProcessInfoAlarm();
break;

case "set-include-threads":
this.includeThreads = !this.includeThreads;
await this.refreshProcesses();
break;

case "set-include-windows":
this.includeWindows = !this.includeWindows;
await this.refreshProcesses();
break;
}
}

Expand Down Expand Up @@ -132,7 +145,7 @@ class TaskManager extends Object {
});

this.processesBuffer.push(mappedProcesses);
if (this.processesBuffer.length > MAX_BUFFER_ENTRIES) {
if (this.processesBuffer.length > this.max_buffer_entries) {
this.processesBuffer.splice(0, 1);
}
}
Expand Down
34 changes: 34 additions & 0 deletions src/content/options.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<!DOCTYPE html>

<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="options.css" />
</head>

<body>
<div class="options-container">
<div class="option-row">
<label>Update Interval (s):</label>
<input id="update-interval-slider" type="range" min="1" max="5" value="5"/>
<input id="update-interval-value" type="text" readonly/>
</div>

<div class="option-row">
<label class="checkbox-label">
Transfer Pages (Windows)
<input id="transfer-pages" type="checkbox" checked/>
</label>
</div>

<div class="option-row">
<label class="checkbox-label">
Transfer Threads
<input id="transfer-threads" type="checkbox" checked/>
</label>
</div>
</div>
<script src="options.js"></script>
</body>

</html>
34 changes: 34 additions & 0 deletions src/content/options.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
const updateIntervalSlider = document.getElementById("update-interval-slider");
const updateIntervalValue = document.getElementById("update-interval-value");
const transferThreadsCheckbox = document.getElementById("transfer-threads");
const transferWindowsCheckbox = document.getElementById("transfer-pages");

function updateInterval(ev) {
browser.runtime.sendMessage({
name: "set-update-interval",
interval: parseInt(ev.target.value),
})
}

function updateThreadsTransfer() {
browser.runtime.sendMessage({
name: "set-include-threads"
});
console.log("updateThreadsTransfer");
}

function updateWindowsTransfer() {
browser.runtime.sendMessage({
name: "set-include-windows"
});
console.log("updateWindowsTransfer");
}

updateIntervalSlider.addEventListener("change", updateInterval);
updateIntervalSlider.addEventListener("input", ev => {
updateIntervalValue.value = ev.target.value;
});
updateIntervalValue.value = updateIntervalSlider.value;

transferThreadsCheckbox.addEventListener("change", updateThreadsTransfer);
transferWindowsCheckbox.addEventListener("change", updateWindowsTransfer);
17 changes: 0 additions & 17 deletions src/content/popup.html

This file was deleted.

15 changes: 0 additions & 15 deletions src/content/popup.js

This file was deleted.

71 changes: 71 additions & 0 deletions src/content/sidebar.css
Original file line number Diff line number Diff line change
Expand Up @@ -290,3 +290,74 @@ td:last-child {
width: 65px;
text-align: right;
}

#options-button {
position: absolute;
top: 5px;
left: 5px;
width: 24px;
height: 24px;
z-index: 100;
}

#options-button img {
width: 16px;
height: 16px;
filter: invert(30%);
transition: filter 0.2s ease;
}

#options-button:hover img {
filter: invert(0%);
}

#popup-container {
position: absolute;
top: 24px;
left: 0;
width: 250px;
min-width: 250px;
background-color: #f0f0f0;
border: 1px solid #ccc;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
z-index: 101;
padding: 10px;
box-sizing: border-box;
}

.options-container {
padding: 8px;
width: 100%;
}

.option-row {
display: flex;
align-items: center;
margin-bottom: 8px;
padding: 0 4px;
gap: 8px;
}

.checkbox-label {
display: flex;
align-items: center;
justify-content: space-between;
flex: 1;
cursor: pointer;
}

.checkbox-label input[type="checkbox"] {
margin: 0;
}

#update-interval-slider {
flex: 1;
min-width: 100px;
max-width: 200px;
}

#update-interval-value {
width: 2ch;
text-align: center;
border: 1px solid #ccc;
}
6 changes: 6 additions & 0 deletions src/content/sidebar.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@

<body>
<div id="sidebar-content">
<a href="#" id="options-button">
<img src="../icons/options-gear.svg" alt="options" />
</a>
<div id="history">
<h1>cpu load (#: <span id="cpu-count"></span>)</h1>
<hr/>
Expand Down Expand Up @@ -75,6 +78,9 @@ <h1>cpu load (#: <span id="cpu-count"></span>)</h1>
</table>
</div>
</div>

<div id="popup-container" style="display: none;">
</div>
</div>

</body>
Expand Down
35 changes: 35 additions & 0 deletions src/content/sidebar.js
Original file line number Diff line number Diff line change
Expand Up @@ -392,10 +392,45 @@ window.addEventListener("load", async () => {
for (tab of detailTabs) {
tab.addEventListener("click", selectDetailsPane);
}

const popupContainer = document.getElementById("popup-container");
let popupLoaded = false;

document.getElementById("options-button").addEventListener("click", async () => {
if (!popupLoaded) {
try {
const response = await fetch(browser.runtime.getURL("content/options.html"));
const popupContent = await response.text();
popupContainer.innerHTML = popupContent;

const script = document.createElement('script');
script.src = browser.runtime.getURL("content/options.js");
document.head.appendChild(script);

popupLoaded = true;
} catch (error) {
console.error("Failed to fetch options.html:", error);
return;
}
}

popupContainer.style.display = popupContainer.style.display === "none" ? "block" : "none";
});
}, { once: true });

window.addEventListener("resize", () => {
historyChartWidth = historyChart.clientWidth;
historyChartDeltaX = Math.round((historyChartWidth - 4) / (60 - 1));
updateDetailsPane();
});

document.addEventListener("click", (event) => {
const popupContainer = document.getElementById("popup-container");
const optionsButton = document.getElementById("options-button");

if (popupContainer.style.display === "block" &&
!popupContainer.contains(event.target) &&
!optionsButton.contains(event.target)) {
popupContainer.style.display = "none";
}
});
1 change: 1 addition & 0 deletions src/icons/options-gear.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.