| 392 | } |
| 393 | |
| 394 | async function getIdleState() { |
| 395 | let timeToCheck = (await isFocused()) ? IDLE_TIME : IDLE_TIME_IF_BLUR; |
| 396 | |
| 397 | // if not enough time passed since last active? => not idle |
| 398 | let timePassed = ~~(performance.now() - lastActive); |
| 399 | if (timePassed < timeToCheck * 1000) |
| 400 | return { |
| 401 | isIdle: false, |
| 402 | reason: "not enough time passed since last active " + timePassed, |
| 403 | }; |
| 404 | |
| 405 | // if any video / audio playing? => not idle |
| 406 | let allMedia = document.querySelectorAll("video, audio"); |
| 407 | for (let media of allMedia) { |
| 408 | if (media.duration > 0 && !media.paused) |
| 409 | return { |
| 410 | isIdle: false, |
| 411 | reason: "video / audio playing", |
| 412 | }; |
| 413 | } |
| 414 | |
| 415 | // if this tab audible? => not idle |
| 416 | let tabs = await UfsGlobal.Extension.runInBackground("chrome.tabs.query", [ |
| 417 | { |
| 418 | active: true, |
| 419 | audible: true, |
| 420 | url: location.href, |
| 421 | }, |
| 422 | ]); |
| 423 | let hasAudioPlaying = tabs?.length > 0; |
| 424 | if (hasAudioPlaying) |
| 425 | return { |
| 426 | isIdle: false, |
| 427 | reason: "this tab is audible ", |
| 428 | }; |
| 429 | |
| 430 | // if chrome.idle.queryState == active? => not idle |
| 431 | let t = Math.max(15, IDLE_TIME); |
| 432 | let state = await UfsGlobal.Extension.runInBackground( |
| 433 | "chrome.idle.queryState", |
| 434 | [t] |
| 435 | ); |
| 436 | if (state != "active") |
| 437 | return { |
| 438 | isIdle: true, |
| 439 | reason: "no system events in " + t + " secs", |
| 440 | }; |
| 441 | |
| 442 | return { |
| 443 | isIdle: true, |
| 444 | reason: "no active events in " + timeToCheck + " secs", |
| 445 | }; |
| 446 | } |
| 447 | |
| 448 | async function saveTimer() { |
| 449 | let { web_timer, host, today, value } = await getTodayTimer(); |