Skip to content

Commit 50d2cf6

Browse files
committed
Feat: Whether to count when idle
1 parent 48b90a6 commit 50d2cf6

File tree

8 files changed

+112
-27
lines changed

8 files changed

+112
-27
lines changed

global.d.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,5 +35,12 @@ declare namespace Timer {
3535
displayBadgeText: boolean
3636
}
3737

38-
type Option = PopupOption & AppearanceOption
38+
type StatisticsOption = {
39+
/**
40+
* Count when idle
41+
*/
42+
countWhenIdle: boolean
43+
}
44+
45+
type Option = PopupOption & AppearanceOption & StatisticsOption
3946
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { ElCard, ElSwitch, ElTooltip } from "element-plus"
2+
import optionService from "../../../../service/option-service"
3+
import { defaultStatistics } from "../../../../util/constant/option"
4+
import { defineComponent, h, Ref, ref } from "vue"
5+
import { t } from "../../../locale"
6+
import { renderHeader, renderOptionItem, tagText } from "../common"
7+
8+
const optionRef: Ref<Timer.StatisticsOption> = ref(defaultStatistics())
9+
10+
function updateOptionVal(key: keyof Timer.StatisticsOption, newVal: boolean) {
11+
const value = optionRef.value
12+
value[key] = newVal
13+
optionService.setStatisticsOption(value)
14+
}
15+
16+
const countWhenIdle = () => h(ElSwitch, {
17+
modelValue: optionRef.value.countWhenIdle,
18+
onChange: (newVal: boolean) => updateOptionVal('countWhenIdle', newVal)
19+
})
20+
21+
const options = () => [
22+
renderOptionItem({
23+
input: countWhenIdle(),
24+
idleTime: tagText(msg => msg.option.statistics.idleTime),
25+
info: h(ElTooltip, { content: t(msg => msg.option.statistics.idleTimeInfo) }, { default: () => h('i', { class: 'el-icon-info' }) })
26+
}, msg => msg.statistics.countWhenIdle, t(msg => msg.option.no))
27+
]
28+
29+
const _default = defineComponent(() => {
30+
return () => h(ElCard, {}, {
31+
header: () => renderHeader(
32+
msg => msg.statistics.title,
33+
() => optionService.setStatisticsOption(optionRef.value = defaultStatistics())),
34+
default: options
35+
})
36+
})
37+
38+
export default _default

src/app/components/option/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import { defineComponent, h } from 'vue'
22
import Popup from './components/popup'
33
import Appearance from './components/appearance'
4+
import Statistics from './components/statistics'
45
import './style'
56

67
export default defineComponent(() => {
78
return () => h('div',
89
{ class: 'option-container' },
9-
[h(Popup), h(Appearance)]
10+
[h(Statistics), h(Popup), h(Appearance)]
1011
)
1112
})

src/app/locale/components/option.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@ export type OptionMessage = {
1919
icon: string
2020
badgeTextContent: string
2121
}
22+
statistics: {
23+
title: string
24+
countWhenIdle: string
25+
idleTime: string
26+
idleTimeInfo: string
27+
}
2228
resetButton: string
2329
resetSuccess: string
2430
defaultValue: string
@@ -42,6 +48,12 @@ const _default: Messages<OptionMessage> = {
4248
icon: '扩展图标',
4349
badgeTextContent: '当前网站的今日浏览时长'
4450
},
51+
statistics: {
52+
title: '统计',
53+
countWhenIdle: '{input} 是否统计 {idleTime} {info}',
54+
idleTime: '休眠时间',
55+
idleTimeInfo: '长时间不操作(比如全屏观看视频),浏览器会自动进入休眠状态'
56+
},
4557
resetButton: '恢复默认',
4658
resetSuccess: '成功重置为默认值',
4759
defaultValue: '默认值: {default}'
@@ -63,6 +75,12 @@ const _default: Messages<OptionMessage> = {
6375
icon: 'the icon of extension',
6476
badgeTextContent: 'the browsing time of current website'
6577
},
78+
statistics: {
79+
title: 'Statistics',
80+
countWhenIdle: '{input} Whether to count {idleTime} {info}',
81+
idleTime: 'idle time',
82+
idleTimeInfo: 'If you do not operate for a long time (such as watching a video in full screen), the browser will automatically enter the idle state'
83+
},
6684
resetButton: 'Reset',
6785
resetSuccess: 'Reset to default successfully!',
6886
defaultValue: 'Default: {default}'
@@ -85,6 +103,12 @@ const _default: Messages<OptionMessage> = {
85103
icon: 'the icon of extension',
86104
badgeTextContent: 'the browsing time of current website'
87105
},
106+
statistics: {
107+
title: '統計',
108+
countWhenIdle: '{input} Whether to count {idleTime} {info}',
109+
idleTime: 'idle time',
110+
idleTimeInfo: 'If you do not operate for a long time (such as watching a video in full screen), the browser will automatically enter the idle state'
111+
},
88112
resetButton: 'リセット',
89113
resetSuccess: 'デフォルトに正常にリセット',
90114
defaultValue: 'デフォルト値:{default}'

src/background/timer/context.ts

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import optionService from "../../service/option-service"
2+
13
export class TimeInfo {
24
focus: number
35
run: number
@@ -18,6 +20,14 @@ export class TimeInfo {
1820
this.run += another.run
1921
}
2022
}
23+
24+
25+
let countWhenIdle: boolean = false
26+
27+
const setCountWhenIdle = (op: Timer.Option) => countWhenIdle = op.countWhenIdle
28+
optionService.getAllOption().then(setCountWhenIdle)
29+
optionService.addOptionChangeListener(setCountWhenIdle)
30+
2131
/**
2232
* Context of timer
2333
*/
@@ -30,13 +40,11 @@ export default class TimerContext {
3040
* The last collect time
3141
*/
3242
lastCollectTime: number
33-
/**
34-
* Whether to time
35-
*/
36-
private timing: boolean
43+
44+
private idleState: chrome.idle.IdleState
3745

3846
constructor() {
39-
this.timing = true
47+
this.idleState = 'active'
4048
this.lastCollectTime = new Date().getTime()
4149
this.resetTimeMap()
4250
}
@@ -59,14 +67,17 @@ export default class TimerContext {
5967
return Object.entries(this.timeMap).find(([_host, { focus }]) => focus)
6068
}
6169

62-
/**
63-
* Pause timing
64-
*/
65-
pause() { this.timing = false }
66-
/**
67-
* Resume timing
68-
*/
69-
resume() { this.timing = true }
70+
setIdle(idleNow: chrome.idle.IdleState) { this.idleState = idleNow }
7071

71-
isPaused(): boolean { return !this.timing }
72+
isPaused(): boolean {
73+
if (this.idleState === 'active') {
74+
return true
75+
} else if (this.idleState === 'locked') {
76+
return false
77+
} else if (this.idleState === 'idle') {
78+
return !countWhenIdle
79+
}
80+
// Never happen
81+
return false
82+
}
7283
}

src/background/timer/idle-listener.ts

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,8 @@ import { formatTime } from "../../util/time"
22
import TimerContext from "./context"
33

44
function listen(context: TimerContext, newState: chrome.idle.IdleState) {
5-
console.log(`idle status changed: ${newState}, ${formatTime(Date.now())}`)
6-
if (newState === 'active') {
7-
context.resume()
8-
} else if (newState === 'locked') {
9-
// If locked then pause
10-
context.pause()
11-
} else if (newState === 'idle') {
12-
// do nothing
13-
}
5+
console.log(`Idle state changed:${newState}`, formatTime(new Date()))
6+
context.setIdle(newState)
147
}
158

169
/**

src/service/option-service.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import OptionDatabase from "../database/option-database"
2-
import { defaultAppearance, defaultPopup } from "../util/constant/option"
2+
import { defaultAppearance, defaultPopup, defaultStatistics } from "../util/constant/option"
33

44
const db = new OptionDatabase(chrome.storage.local)
55

66
const defaultOption = () => {
7-
return { ...defaultAppearance(), ...defaultPopup() }
7+
return { ...defaultAppearance(), ...defaultPopup(), ...defaultStatistics() }
88
}
99

1010
async function getAllOption(): Promise<Timer.Option> {
@@ -22,6 +22,10 @@ async function setAppearanceOption(option: Timer.AppearanceOption): Promise<void
2222
await setOption(option)
2323
}
2424

25+
async function setStatisticsOption(option: Timer.StatisticsOption): Promise<void> {
26+
await setOption(option)
27+
}
28+
2529
async function setOption(option: Partial<Timer.Option>): Promise<void> {
2630
const exist: Partial<Timer.Option> = await db.getOption()
2731
const toSet = defaultOption()
@@ -34,6 +38,7 @@ class OptionService {
3438
getAllOption = getAllOption
3539
setPopupOption = setPopupOption
3640
setAppearanceOption = setAppearanceOption
41+
setStatisticsOption = setStatisticsOption
3742
addOptionChangeListener = db.addOptionChangeListener
3843
}
3944

src/util/constant/option.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,10 @@ export function defaultAppearance(): Timer.AppearanceOption {
1111
displayWhitelistMenu: true,
1212
displayBadgeText: false
1313
}
14+
}
15+
16+
export function defaultStatistics(): Timer.StatisticsOption {
17+
return {
18+
countWhenIdle: false
19+
}
1420
}

0 commit comments

Comments
 (0)