Skip to content

Commit 7930f5b

Browse files
committed
Support weekly limit(#306)
1 parent b5f6f95 commit 7930f5b

File tree

60 files changed

+674
-393
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+674
-393
lines changed

src/app/components/About/Description.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ import { ElCard, ElDescriptions, ElDescriptionsItem, ElDivider, ElSpace, ElText
99
import { defineComponent, StyleValue } from "vue"
1010
import InstallationLink from "./InstallationLink"
1111
import packageInfo, { AUTHOR_EMAIL } from "@src/package"
12-
import { locale } from "@i18n"
1312
import "./description.sass"
1413
import metaService from "@service/meta-service"
1514
import DescLink from "./DescLink"
15+
import { locale } from "@i18n"
1616

1717
const INSTALLATION_STYLE: StyleValue = {
1818
display: "flex",

src/app/components/Analysis/components/Summary/Calendar/Wrapper.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import {
1414
EffectScatterSeriesOption
1515
} from "echarts"
1616
import { formatTime, getAllDatesBetween, getWeeksAgo, parseTime } from "@util/time"
17-
import { locale } from "@i18n"
1817
import { EffectScatterChart } from "echarts/charts"
1918
import { SVGRenderer } from "echarts/renderers"
2019
import { use } from "echarts/core"
@@ -23,6 +22,7 @@ import { groupBy, rotate } from "@util/array"
2322
import { t } from "@app/locale"
2423
import { getRegularTextColor, getSecondaryTextColor } from "@util/style"
2524
import { periodFormatter } from "@app/util/time"
25+
import { locale } from "@i18n"
2626

2727
type EcOption = ComposeOption<
2828
| EffectScatterSeriesOption

src/app/components/Dashboard/components/Calendar/Wrapper.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,7 @@ use([
2121
])
2222

2323
import { EchartsWrapper } from "@hooks"
24-
import { formatPeriodCommon, getAllDatesBetween, MILL_PER_HOUR } from "@util/time"
25-
import { locale } from "@i18n"
24+
import { formatPeriodCommon, getAllDatesBetween, MILL_PER_HOUR, MILL_PER_MINUTE } from "@util/time"
2625
import { groupBy, rotate, sum } from "@util/array"
2726
import { t } from "@app/locale"
2827
import { getPrimaryTextColor } from "@util/style"
@@ -31,6 +30,7 @@ import { getAppPageUrl } from "@util/constant/url"
3130
import { REPORT_ROUTE } from "@app/router/constants"
3231
import { createTabAfterCurrent } from "@api/chrome/tab"
3332
import { getStepColors } from "@app/util/echarts"
33+
import { locale } from "@i18n"
3434

3535
type _Value = [
3636
x: number,
@@ -109,8 +109,8 @@ type Piece = {
109109
color?: string
110110
}
111111

112-
const minOf = (min: number) => min * 60 * 1000
113-
const hourOf = (hour: number) => hour * 60 * 60 * 1000
112+
const minOf = (min: number) => min * MILL_PER_MINUTE
113+
const hourOf = (hour: number) => hour * MILL_PER_HOUR
114114

115115
const ALL_PIECES: Piece[] = [
116116
{ min: 1, max: minOf(10), label: "<10m" },

src/app/components/DataManage/ClearPanel/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { defineComponent } from "vue"
1010
import { t } from "@app/locale"
1111
import { alertProps } from "../common"
1212
import ClearFilter from "./ClearFilter"
13-
import { MILL_PER_DAY } from "@util/time"
13+
import { MILL_PER_DAY, MILL_PER_SECOND } from "@util/time"
1414
import statService, { StatQueryParam } from "@service/stat-service"
1515

1616
type FilterOption = {
@@ -54,7 +54,7 @@ function assertQueryParam(range: Vector<2>, mustInteger?: boolean): boolean {
5454
}
5555

5656
const str2Num = (str: string, defaultVal?: number) => (str && str !== '') ? parseInt(str) : defaultVal
57-
const seconds2Milliseconds = (a: number) => a * 1000
57+
const seconds2Milliseconds = (a: number) => a * MILL_PER_SECOND
5858

5959
function checkParam(option: FilterOption): StatQueryParam | undefined {
6060
const { focus = [null, null], time = [null, null] } = option || {}

src/app/components/DataManage/Migration/ImportOtherButton/processor.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import { fillExist } from "@service/components/import-processor"
99
import { AUTHOR_EMAIL } from "@src/package"
1010
import { extractHostname, isBrowserUrl } from "@util/pattern"
11-
import { formatTime } from "@util/time"
11+
import { formatTimeYMD, MILL_PER_SECOND } from "@util/time"
1212

1313
export type OtherExtension =
1414
| "webtime_tracker"
@@ -52,7 +52,7 @@ async function parseWebActivityTimeTracker(file: File): Promise<timer.imported.R
5252
const [year, month, day] = date.split('/')
5353
!year || !month || !day && throwError()
5454
const realDate = `${year}${month.length == 2 ? month : '0' + month}${day.length == 2 ? day : '0' + day}`
55-
return { host, date: realDate, focus: parseInt(seconds) * 1000 }
55+
return { host, date: realDate, focus: parseInt(seconds) * MILL_PER_SECOND }
5656
})
5757
return rows
5858
}
@@ -89,7 +89,7 @@ async function parseWebtimeTracker(file: File): Promise<timer.imported.Row[]> {
8989
.map(([host, date, seconds]) => ({
9090
host,
9191
date,
92-
focus: seconds * 1000
92+
focus: seconds * MILL_PER_SECOND
9393
} as timer.imported.Row))
9494
return rows
9595
} else if (isCsvFile(file)) {
@@ -103,7 +103,7 @@ async function parseWebtimeTracker(file: File): Promise<timer.imported.Row[]> {
103103
for (let i = 1; i < colHeaders?.length; i++) {
104104
const seconds = Number.parseInt(cells[i])
105105
const date = cvtWebtimeTrackerDate(colHeaders[i])
106-
seconds && date && rows.push({ host, date, focus: seconds * 1000 })
106+
seconds && date && rows.push({ host, date, focus: seconds * MILL_PER_SECOND })
107107
}
108108
})
109109
return rows
@@ -120,7 +120,7 @@ function parseHistoryTrendsUnlimitedLine(line: string, data: { [dateAndHost: str
120120
// Backup data
121121
let date: string;
122122
try {
123-
date = formatTime(parseFloat(tsMaybe.substring(1)), "{y}{m}{d}")
123+
date = formatTimeYMD(parseFloat(tsMaybe.substring(1)))
124124
} catch {
125125
console.error("Invalid line: " + line)
126126
return;

src/app/components/Habit/components/Site/Distribution/Wrapper.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ const baseLegendTitle = (): TitleComponentOption => ({
126126
})
127127

128128
function generateOption(bizOption: BizOption): EcOption {
129-
let { rows, dateRange } = bizOption || {}
129+
let { rows = [], dateRange } = bizOption || {}
130130
const [averageLen, _, exclusiveDate] = computeAverageLen(dateRange)
131131
if (exclusiveDate) {
132132
rows = rows.filter(r => r.date !== exclusiveDate)

src/app/components/Habit/components/Site/common.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,7 @@
88
import type { TitleComponentOption } from "echarts/components"
99

1010
import { getRegularTextColor } from "@util/style"
11-
import { generateSiteLabel } from "@util/site"
12-
import { periodFormatter } from "@app/util/time"
13-
import { formatTime, getDayLength, isSameDay } from "@util/time"
11+
import { formatTimeYMD, getDayLength, isSameDay } from "@util/time"
1412

1513
export const generateTitleOption = (text: string): TitleComponentOption => {
1614
const secondaryTextColor = getRegularTextColor()
@@ -42,7 +40,7 @@ export const computeAverageLen = (dateRange: [Date, Date] = [null, null]): [numb
4240
const dateDiff = getDayLength(start, end)
4341
const endIsTody = isSameDay(end, new Date())
4442
if (endIsTody) {
45-
return [dateDiff - 1, true, formatTime(end, "{y}{m}{d}")]
43+
return [dateDiff - 1, true, formatTimeYMD(end)]
4644
} else {
4745
return [dateDiff, false, null]
4846
}

src/app/components/Limit/LimitModify/Sop/Step3/TimeInput.tsx

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ function computeLimitInfo2Second(hour: number, minute: number, second: number):
6565
const _default = defineComponent({
6666
props: {
6767
modelValue: Number,
68+
hourMax: Number
6869
},
6970
emits: {
7071
change: (_val: number) => true
@@ -83,12 +84,13 @@ const _default = defineComponent({
8384
const limitTime = computed(() => computeLimitInfo2Second(hour.value, minute.value, second.value))
8485
watch(limitTime, () => ctx.emit('change', limitTime.value))
8586

86-
return () => <div class="limit-time-input">
87-
<UnitInput modelValue={hour.value} onChange={setHour} unit="H" max={23} />
88-
<UnitInput modelValue={minute.value} onChange={setMinute} unit="M" max={59} />
89-
<UnitInput modelValue={second.value} onChange={setSecond} unit="S" max={59} />
90-
</div>
91-
87+
return () => (
88+
<div class="limit-time-input">
89+
<UnitInput modelValue={hour.value} onChange={setHour} unit="H" max={props.hourMax ?? 23} />
90+
<UnitInput modelValue={minute.value} onChange={setMinute} unit="M" max={59} />
91+
<UnitInput modelValue={second.value} onChange={setSecond} unit="S" max={59} />
92+
</div>
93+
)
9294
}
9395
})
9496

src/app/components/Limit/LimitModify/Sop/Step3/index.tsx

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,24 +14,38 @@ import { useShadow } from "@hooks"
1414
import { StepFromInstance } from "../common"
1515
import "./style.sass"
1616

17+
type Value = Pick<timer.limit.Item, 'time' | 'visitTime' | 'weekly' | 'periods'>
18+
19+
const MAX_HOUR_WEEKLY = 7 * 24 - 1
20+
1721
const _default = defineComponent({
1822
props: {
1923
time: Number,
2024
visitTime: Number,
25+
weekly: Number,
2126
periods: Array as PropType<timer.limit.Period[]>,
2227
},
2328
emits: {
24-
change: (_time: number, _visitTime: number, _periods: Vector<2>[]) => true,
29+
change: (_val: Value) => true,
2530
},
2631
setup(props, ctx) {
2732
const [time, setTime] = useShadow(() => props.time)
33+
const [weekly, setWeekly] = useShadow(() => props.weekly)
2834
const [visitTime, setVisitTime] = useShadow(() => props.visitTime)
2935
const [periods, setPeriods] = useShadow(() => props.periods, [])
3036

31-
watch([time, visitTime, periods], () => ctx.emit("change", time.value, visitTime.value, periods.value))
37+
watch([time, visitTime, periods, weekly], () => {
38+
const val: Value = {
39+
time: time.value,
40+
visitTime: visitTime.value,
41+
weekly: weekly.value,
42+
periods: periods.value,
43+
}
44+
ctx.emit("change", val)
45+
})
3246

3347
const validate = () => {
34-
if (!time.value && !visitTime.value && !periods.value?.length) {
48+
if (!time.value && !visitTime.value && !periods.value?.length && !weekly.value) {
3549
ElMessage.error(t(msg => msg.limit.message.noRule))
3650
return false
3751
}
@@ -44,6 +58,13 @@ const _default = defineComponent({
4458
<ElFormItem label={t(msg => msg.limit.item.time)}>
4559
<TimeInput modelValue={time.value} onChange={setTime} />
4660
</ElFormItem>
61+
<ElFormItem label={t(msg => msg.limit.item.weekly)}>
62+
<TimeInput
63+
modelValue={weekly.value}
64+
onChange={setWeekly}
65+
hourMax={MAX_HOUR_WEEKLY}
66+
/>
67+
</ElFormItem>
4768
<ElFormItem label={t(msg => msg.limit.item.visitTime)}>
4869
<TimeInput modelValue={visitTime.value} onChange={setVisitTime} />
4970
</ElFormItem>

src/app/components/Limit/LimitModify/Sop/index.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ export type SopInstance = {
2828
const createInitial = (): Required<Omit<timer.limit.Rule, 'id' | 'allowDelay'>> => ({
2929
name: null,
3030
time: 3600,
31+
weekly: null,
3132
cond: [],
3233
visitTime: null,
3334
periods: null,
@@ -102,12 +103,14 @@ const _default = defineComponent({
102103
v-show={step.value === 2}
103104
ref={stepInstances[2]}
104105
time={data.time}
106+
weekly={data.weekly}
105107
visitTime={data.visitTime}
106108
periods={data.periods}
107-
onChange={(time, visitTime, periods) => {
109+
onChange={({ time, visitTime, periods, weekly }) => {
108110
data.time = time
109111
data.visitTime = visitTime
110112
data.periods = periods
113+
data.weekly = weekly
111114
}}
112115
/>
113116
</div>

src/app/components/Limit/LimitModify/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,10 @@ const _default = defineComponent({
3232
let modifyingItem: timer.limit.Rule = undefined
3333

3434
const handleSave = async (rule: timer.limit.Rule) => {
35-
const { cond, enabled, name, time, visitTime, periods, weekdays } = rule
35+
const { cond, enabled, name, time, weekly, visitTime, periods, weekdays } = rule
3636
const toSave: timer.limit.Rule = {
3737
...modifyingItem || {},
38-
cond, enabled, name, time, visitTime, weekdays,
38+
cond, enabled, name, time, weekly, visitTime, weekdays,
3939
// Object to array
4040
periods: periods?.map(i => [i?.[0], i?.[1]]),
4141
}

src/app/components/Limit/LimitTable/column/LimitOperationColumn.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ import { Delete, Edit } from "@element-plus/icons-vue"
99
import { ElButton, ElMessageBox, ElTableColumn } from "element-plus"
1010
import { defineComponent } from "vue"
1111
import { t } from "@app/locale"
12-
import optionService from "@service/option-service"
1312
import { locale } from "@i18n"
13+
import optionService from "@service/option-service"
1414
import { ElTableRowScope } from "@src/element-ui/table"
1515
import { judgeVerificationRequired, processVerification } from "@app/util/limit"
1616

@@ -34,8 +34,7 @@ async function handleDelete(row: timer.limit.Item, callback: () => void) {
3434
async function handleModify(row: timer.limit.Item, callback: () => void) {
3535
let promise: Promise<void> = undefined
3636
if (await judgeVerificationRequired(row)) {
37-
const option =
38-
(await optionService.getAllOption()) as timer.option.DailyLimitOption
37+
const option = (await optionService.getAllOption()) as timer.option.DailyLimitOption
3938
promise = processVerification(option)
4039
promise ? promise.then(callback).catch(() => { }) : callback()
4140
} else {

0 commit comments

Comments
 (0)