Add idle sample (#961)
* Add idle sample * Fix typo * Fix onStateChanged threshold * Add README.md * Update file structure * Remove tabs permission * Update api-samples/idle/README.md Co-authored-by: amysteamdev <37001393+AmySteam@users.noreply.github.com> * Update api-samples/idle/service-worker.js Co-authored-by: amysteamdev <37001393+AmySteam@users.noreply.github.com> * Update api-samples/idle/README.md Co-authored-by: amysteamdev <37001393+AmySteam@users.noreply.github.com> * Update api-samples/idle/README.md Co-authored-by: amysteamdev <37001393+AmySteam@users.noreply.github.com> --------- Co-authored-by: amysteamdev <37001393+AmySteam@users.noreply.github.com>
This commit is contained in:
Родитель
b4a018418d
Коммит
50e377c44c
|
@ -0,0 +1,19 @@
|
|||
# chrome.idle
|
||||
|
||||
This sample demonstrates how to use the [`chrome.idle`](https://developer.chrome.com/docs/extensions/reference/idle/) API.
|
||||
|
||||
## Overview
|
||||
|
||||
In this sample, the `chrome.idle` API detects and stores the history of the user's idle state.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
The detection interval of [`chrome.idle.onStateChanged`](https://developer.chrome.com/docs/extensions/reference/idle/#event-onStateChanged) event needs to be modified using the [`chrome.idle.setDetectionInterval`](https://developer.chrome.com/docs/extensions/reference/idle/#method-setDetectionInterval) method.
|
||||
|
||||
The idle state history is stored in the [`chrome.storage.session`](https://developer.chrome.com/docs/extensions/reference/storage/#property-session) storage area.
|
||||
|
||||
## Running this extension
|
||||
|
||||
1. Clone this repository.
|
||||
2. Load this directory in Chrome as an [unpacked extension](https://developer.chrome.com/docs/extensions/mv3/getstarted/development-basics/#load-unpacked).
|
||||
3. Click the extension's action icon to open the window.
|
|
@ -0,0 +1,41 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
body {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
padding: 0 1em;
|
||||
box-sizing: border-box;
|
||||
font: 13px Arial;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Idle API Demonstration</h1>
|
||||
<h2>Current state</h2>
|
||||
<p>
|
||||
Idle threshold:
|
||||
<select id="idle-threshold">
|
||||
<option selected value="15">15</option>
|
||||
<option value="30">30</option>
|
||||
<option value="60">60</option>
|
||||
</select>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<code
|
||||
>chrome.idle.queryState(<strong id="idle-set-threshold"></strong>,
|
||||
...);</code
|
||||
>
|
||||
-
|
||||
<span id="idle-state"></span>
|
||||
</p>
|
||||
<p>Last state change: <span id="idle-laststate"></span></p>
|
||||
|
||||
<h2>Idle changes:</h2>
|
||||
<ul id="idle-history"></ul>
|
||||
<script src="history.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,102 @@
|
|||
/**
|
||||
* Convert a state and time into a nice styled chunk of HTML.
|
||||
*/
|
||||
function renderState(state, time) {
|
||||
const now = Date.now();
|
||||
const diff = Math.round((time - now) / 1000);
|
||||
const str =
|
||||
diff == 0
|
||||
? 'now'
|
||||
: Math.abs(diff) + ' seconds ' + (diff > 0 ? 'from now' : 'ago');
|
||||
const col = state == 'active' ? '#009900' : '#990000';
|
||||
return "<b style='color: " + col + "'>" + state + '</b> ' + str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates DOM and injects a rendered state into the page.
|
||||
*/
|
||||
function renderItem(state, time, parent) {
|
||||
const dom_item = document.createElement('li');
|
||||
dom_item.innerHTML = renderState(state, time);
|
||||
parent.appendChild(dom_item);
|
||||
}
|
||||
|
||||
// Store previous state so we can show deltas. This is important
|
||||
// because the API currently doesn't fire idle messages, and we'd
|
||||
// like to keep track of last time we went idle.
|
||||
let laststate = null;
|
||||
let laststatetime = null;
|
||||
|
||||
/**
|
||||
* Checks the current state of the browser.
|
||||
*/
|
||||
async function checkState() {
|
||||
const threshold = parseInt(document.querySelector('#idle-threshold').value);
|
||||
const dom_threshold = document.querySelector('#idle-set-threshold');
|
||||
dom_threshold.innerText = threshold;
|
||||
|
||||
// Request the state based off of the user-supplied threshold.
|
||||
chrome.idle.queryState(threshold, function (state) {
|
||||
const time = new Date();
|
||||
if (laststate != state) {
|
||||
laststate = state;
|
||||
laststatetime = time;
|
||||
}
|
||||
|
||||
// Keep rendering results so we get a nice "seconds elapsed" view.
|
||||
const dom_result = document.querySelector('#idle-state');
|
||||
dom_result.innerHTML = renderState(state, time);
|
||||
const dom_laststate = document.querySelector('#idle-laststate');
|
||||
dom_laststate.innerHTML = renderState(laststate, laststatetime);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the data gathered by the background service worker - should show a log
|
||||
* of "active" states.
|
||||
*/
|
||||
async function renderHistory() {
|
||||
const dom_history = document.querySelector('#idle-history');
|
||||
dom_history.innerHTML = '';
|
||||
const { history_log } = await chrome.storage.session.get(['history_log']);
|
||||
if (!history_log) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (let i = 0; i < history_log.length; i++) {
|
||||
const data = history_log[i];
|
||||
renderItem(data['state'], data['time'], dom_history);
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', async function () {
|
||||
// Set the threshold to the last value the user set, or 15 if not set.
|
||||
let { threshold: stored_threshold } = await chrome.storage.local.get([
|
||||
'threshold'
|
||||
]);
|
||||
if (!stored_threshold || ![15, 30, 60].includes(stored_threshold)) {
|
||||
stored_threshold = 15;
|
||||
}
|
||||
|
||||
document.querySelector(
|
||||
`#idle-threshold option[value="${stored_threshold}"]`
|
||||
).selected = true;
|
||||
chrome.idle.setDetectionInterval(stored_threshold);
|
||||
|
||||
document
|
||||
.querySelector('#idle-threshold')
|
||||
.addEventListener('change', function (e) {
|
||||
const threshold = parseInt(e.target.value);
|
||||
chrome.storage.local.set({ threshold: threshold });
|
||||
chrome.idle.setDetectionInterval(threshold);
|
||||
});
|
||||
|
||||
// Check every second (even though this is overkill - minimum idle
|
||||
// threshold is 15 seconds) so that the numbers appear to be counting up.
|
||||
checkState();
|
||||
window.setInterval(checkState, 1000);
|
||||
|
||||
// Check every second (see above).
|
||||
renderHistory();
|
||||
window.setInterval(renderHistory, 1000);
|
||||
});
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"name": "Idle - Simple Example",
|
||||
"version": "1.0.1",
|
||||
"description": "Demonstrates the Idle API",
|
||||
"background": {
|
||||
"service_worker": "service-worker.js"
|
||||
},
|
||||
"permissions": ["idle", "storage"],
|
||||
"action": {
|
||||
"default_icon": "sample-19.png"
|
||||
},
|
||||
"icons": {
|
||||
"16": "sample-16.png",
|
||||
"48": "sample-48.png",
|
||||
"128": "sample-128.png"
|
||||
},
|
||||
"manifest_version": 3
|
||||
}
|
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 1.1 KiB |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 478 B |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 130 B |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 471 B |
|
@ -0,0 +1,27 @@
|
|||
/**
|
||||
* Stores a state every time it changes, up to 20 items.
|
||||
*/
|
||||
chrome.idle.onStateChanged.addListener(async function (newstate) {
|
||||
let { history_log } = await chrome.storage.session.get(['history_log']);
|
||||
if (!history_log) {
|
||||
history_log = [];
|
||||
}
|
||||
const time = Date.now();
|
||||
if (history_log.length >= 20) {
|
||||
history_log.pop();
|
||||
}
|
||||
history_log.unshift({ state: newstate, time: time });
|
||||
chrome.storage.session.set({ history_log: history_log });
|
||||
});
|
||||
|
||||
/**
|
||||
* Opens history.html when the browser action is clicked.
|
||||
*/
|
||||
chrome.action.onClicked.addListener(function () {
|
||||
chrome.windows.create({
|
||||
url: 'history.html',
|
||||
width: 700,
|
||||
height: 600,
|
||||
type: 'popup'
|
||||
});
|
||||
});
|
Загрузка…
Ссылка в новой задаче