Skip to content
Merged
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
26 changes: 13 additions & 13 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,31 +29,31 @@
"license": "MIT",
"devDependencies": {
"@babel/plugin-transform-modules-commonjs": "^7.27.1",
"@babel/preset-env": "^7.27.2",
"@crowdin/crowdin-api-client": "^1.45.0",
"@rsdoctor/rspack-plugin": "^1.1.4",
"@rspack/cli": "^1.3.15",
"@rspack/core": "^1.3.15",
"@swc/core": "^1.12.5",
"@swc/jest": "^0.2.38",
"@babel/preset-env": "^7.28.0",
"@crowdin/crowdin-api-client": "^1.46.0",
"@rsdoctor/rspack-plugin": "^1.1.8",
"@rspack/cli": "^1.4.8",
"@rspack/core": "^1.4.8",
"@swc/core": "^1.13.1",
"@swc/jest": "^0.2.39",
"@types/chrome": "0.1.1",
"@types/decompress": "^4.2.7",
"@types/jest": "^30.0.0",
"@types/node": "^24.0.3",
"@types/node": "^24.0.15",
"@types/punycode": "^2.1.4",
"@vue/babel-plugin-jsx": "^1.4.0",
"babel-loader": "^10.0.0",
"commitlint": "^19.8.1",
"css-loader": "^7.1.2",
"decompress": "^4.2.1",
"husky": "^9.1.7",
"jest": "^30.0.2",
"jest-environment-jsdom": "^30.0.2",
"jest": "^30.0.4",
"jest-environment-jsdom": "^30.0.4",
"jest-junit": "^16.0.0",
"postcss": "^8.5.6",
"postcss-loader": "^8.1.1",
"postcss-rtlcss": "^5.7.1",
"puppeteer": "^24.10.2",
"puppeteer": "^24.14.0",
"sass": "^1.89.2",
"sass-loader": "^16.0.5",
"style-loader": "^4.0.0",
Expand All @@ -64,11 +64,11 @@
"url-loader": "^4.1.1"
},
"optionalDependencies": {
"web-ext": "^8.8.0"
"web-ext": "^8.9.0"
},
"dependencies": {
"@element-plus/icons-vue": "^2.3.1",
"@vueuse/core": "^13.4.0",
"@vueuse/core": "^13.5.0",
"countup.js": "^2.9.0",
"echarts": "^5.6.0",
"element-plus": "2.10.4",
Expand Down
14 changes: 7 additions & 7 deletions src/content-script/limit/modal/components/Footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ import { TAG_NAME } from "@cs/limit/element"
import { t } from "@cs/locale"
import { Plus, Timer } from "@element-plus/icons-vue"
import optionHolder from "@service/components/option-holder"
import { meetTimeLimit } from "@util/limit"
import { meetTimeLimit } from '@util/limit'
import { ElButton } from "element-plus"
import { computed, defineComponent } from "vue"
import { useDelayHandler, useReason, useRule } from "../context"

async function handleMore5Minutes(rule: timer.limit.Item, callback: () => void) {
async function handleMore5Minutes(rule: timer.limit.Item | null, callback: () => void) {
let promise: Promise<void> | undefined = undefined
const ele = document.querySelector(TAG_NAME)?.shadowRoot?.querySelector('body')
if (await judgeVerificationRequired(rule)) {
if (rule && await judgeVerificationRequired(rule)) {
const option = await optionHolder.get()
promise = processVerification(option, { appendTo: ele ?? undefined })
promise ? promise.then(callback).catch(() => { }) : callback()
Expand All @@ -29,16 +29,16 @@ const _default = defineComponent(() => {
const { type, allowDelay, delayCount = 0 } = reason.value || {}
if (!allowDelay) return false

const { time, weekly, visit, waste, weeklyWaste } = rule.value || {}
const { time, weekly, visitTime, waste, weeklyWaste } = rule.value || {}
let realLimit = 0, realWaste = 0
if (type === 'DAILY') {
realLimit = time ?? 0
realWaste = waste
realWaste = waste ?? 0
} else if (type === 'WEEKLY') {
realLimit = weekly ?? 0
realWaste = weeklyWaste
realWaste = weeklyWaste ?? 0
} else if (type === 'VISIT') {
realLimit = visit
realLimit = visitTime ?? 0
realWaste = reason.value?.getVisitTime?.() ?? 0
} else {
return false
Expand Down
6 changes: 3 additions & 3 deletions src/content-script/limit/modal/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ const DELAY_HANDLER_KEY = 'delay_handler'

export const provideReason = (app: App<Element>): Ref<LimitReason | undefined> => {
const reason = ref<LimitReason>()
app?.provide(REASON_KEY, reason)
app.provide(REASON_KEY, reason)
return reason
}

export const useReason = () => inject(REASON_KEY) as Ref<LimitReason>
export const useReason = () => inject(REASON_KEY) as Ref<LimitReason | undefined>

export const provideRule = () => {
const reason = useReason()
Expand All @@ -33,7 +33,7 @@ export const provideRule = () => {
provide(RULE_KEY, rule)
}

export const useRule = () => inject(RULE_KEY) as Ref<timer.limit.Item>
export const useRule = () => inject(RULE_KEY) as Ref<timer.limit.Item | null>

export const provideDelayHandler = (app: App<Element>, handlers: () => void) => {
app?.provide(DELAY_HANDLER_KEY, handlers)
Expand Down
17 changes: 13 additions & 4 deletions src/content-script/limit/modal/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,13 @@ const createHeader = () => {
}

class ScreenLocker {
private beforeOverflow: string | undefined

private doLock() {
if (document?.documentElement) {
const ele = document?.documentElement
this.beforeOverflow = undefined
if (ele) {
this.beforeOverflow = ele.style.overflow
document.documentElement.style.setProperty('overflow', 'hidden', 'important')
}
}
Expand All @@ -60,7 +65,7 @@ class ScreenLocker {

unlock() {
if (document?.documentElement) {
document.documentElement.style.overflow = ''
document.documentElement.style.overflow = this.beforeOverflow ?? ''
}
}
}
Expand All @@ -78,6 +83,7 @@ class ModalInstance implements MaskModal {
screenLocker = new ScreenLocker()

constructor(url: string) {
(window as any)['__modal__'] = this
this.url = url
}

Expand Down Expand Up @@ -115,8 +121,11 @@ class ModalInstance implements MaskModal {
}

private refresh() {
const reason = this.reasons?.[0]
reason ? this.show(reason) : this.hide()
setTimeout(() => {
// update vue ref in another micro task
const reason = this.reasons?.[0]
reason ? this.show(reason) : this.hide()
})
}

private async init() {
Expand Down
17 changes: 8 additions & 9 deletions src/pages/app/components/About/index.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import { defineComponent } from "vue"
import { type FunctionalComponent } from "vue"
import ContentContainer from "../common/ContentContainer"
import Description from "./Description"

const _default = defineComponent({
render: () => (
<ContentContainer>
<Description />
</ContentContainer>
)
})
const About: FunctionalComponent = () => (
<ContentContainer>
<Description />
</ContentContainer>
)
About.displayName = 'About'

export default _default
export default About
43 changes: 21 additions & 22 deletions src/pages/app/components/HelpUs/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,32 @@ import { Pointer } from "@element-plus/icons-vue"
import Box from "@pages/components/Box"
import { CROWDIN_HOMEPAGE } from "@util/constant/url"
import { ElAlert, ElButton, ElCard } from "element-plus"
import { defineComponent } from "vue"
import { type FunctionalComponent } from "vue"
import ContentContainer from "../common/ContentContainer"
import MemberList from "./MemberList"
import ProgressList from "./ProgressList"

const handleJump = () => createTabAfterCurrent(CROWDIN_HOMEPAGE)

const HelpUs = defineComponent(() => {
return () => (
<ContentContainer>
<ElCard>
<ElAlert type="info" title={t(msg => msg.helpUs.title)}>
<li>{t(msg => msg.helpUs.alert.l1)}</li>
<li>{t(msg => msg.helpUs.alert.l2)}</li>
<li>{t(msg => msg.helpUs.alert.l3)}</li>
<li>{t(msg => msg.helpUs.alert.l4)}</li>
</ElAlert>
<Box marginBlock={30}>
<ElButton type="primary" size="large" icon={Pointer} onClick={handleJump}>
{t(msg => msg.helpUs.button)}
</ElButton>
</Box>
<ProgressList />
<MemberList />
</ElCard>
</ContentContainer>
)
})
const HelpUs: FunctionalComponent = () => (
<ContentContainer>
<ElCard>
<ElAlert type="info" title={t(msg => msg.helpUs.title)}>
<li>{t(msg => msg.helpUs.alert.l1)}</li>
<li>{t(msg => msg.helpUs.alert.l2)}</li>
<li>{t(msg => msg.helpUs.alert.l3)}</li>
<li>{t(msg => msg.helpUs.alert.l4)}</li>
</ElAlert>
<Box marginBlock={30}>
<ElButton type="primary" size="large" icon={Pointer} onClick={handleJump}>
{t(msg => msg.helpUs.button)}
</ElButton>
</Box>
<ProgressList />
<MemberList />
</ElCard>
</ContentContainer>
)
HelpUs.displayName = 'HelpUs'

export default HelpUs
25 changes: 12 additions & 13 deletions src/pages/app/components/RuleMerge/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,21 @@

import Flex from "@pages/components/Flex"
import { ElCard } from "element-plus"
import { defineComponent } from "vue"
import { type FunctionalComponent } from "vue"
import ContentContainer from "../common/ContentContainer"
import AlertInfo from "./AlertInfo"
import ItemList from "./ItemList"

const RuleMerge = defineComponent(() => {
return () => (
<ContentContainer>
<ElCard>
<Flex column gap={20}>
<AlertInfo />
<ItemList />
</Flex>
</ElCard>
</ContentContainer>
)
})
const RuleMerge: FunctionalComponent = () => (
<ContentContainer>
<ElCard>
<Flex column gap={20}>
<AlertInfo />
<ItemList />
</Flex>
</ElCard>
</ContentContainer>
)
RuleMerge.displayName = 'RuleMerge'

export default RuleMerge
39 changes: 19 additions & 20 deletions src/pages/app/components/Whitelist/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,28 +8,27 @@
import { t } from "@app/locale"
import Flex from "@pages/components/Flex"
import { ElAlert, ElCard } from "element-plus"
import { defineComponent } from "vue"
import { type FunctionalComponent } from "vue"
import ContentContainer from "../common/ContentContainer"
import WhitePanel from "./WhitePanel"

const Whitelist = defineComponent(() => {
return () => (
<ContentContainer>
<ElCard>
<Flex gap={20} column>
<ElAlert
title={t(msg => msg.whitelist.infoAlertTitle)}
style={{ padding: "15px 25px" }}
closable={false}
>
<li>{t(msg => msg.whitelist.infoAlert0)}</li>
<li>{t(msg => msg.whitelist.infoAlert1)}</li>
</ElAlert>
<WhitePanel />
</Flex>
</ElCard>
</ContentContainer>
)
})
const Whitelist: FunctionalComponent = () => (
<ContentContainer>
<ElCard>
<Flex gap={20} column>
<ElAlert
title={t(msg => msg.whitelist.infoAlertTitle)}
style={{ padding: "15px 25px" }}
closable={false}
>
<li>{t(msg => msg.whitelist.infoAlert0)}</li>
<li>{t(msg => msg.whitelist.infoAlert1)}</li>
</ElAlert>
<WhitePanel />
</Flex>
</ElCard>
</ContentContainer>
)
Whitelist.displayName = 'Whitelist'

export default Whitelist
18 changes: 13 additions & 5 deletions test-e2e/limit/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,27 +25,34 @@ export async function createLimitRule(rule: timer.limit.Rule, page: Page) {
await sleep(.1)
const { time, weekly, visitTime, count, weeklyCount } = rule || {}
const timeInputs = await page.$$('.el-dialog .el-date-editor input')
await fillTimeLimit(time!, timeInputs[0], page)
await fillTimeLimit(weekly!, timeInputs[1], page)
await fillTimeLimit(visitTime!, timeInputs[2], page)
await fillTimeLimit(time, timeInputs[0], page)
await fillTimeLimit(weekly, timeInputs[1], page)
await fillTimeLimit(visitTime, timeInputs[2], page)
const visitInputs = await page.$$('.el-dialog .el-input-number input')
await fillVisitLimit(count!, visitInputs[0], page)
await fillVisitLimit(weeklyCount!, visitInputs[1], page)

// 4. Save
await sleep(.3)
await page.click('.el-dialog .el-button.el-button--success')
if (rule.allowDelay) {
await page.waitForSelector('.el-table__body .el-table__row td:nth-child(9) .el-switch')
await page.evaluate(async () => {
document.querySelector<HTMLElement>('.el-table__body .el-table__row td:nth-child(9) .el-switch')?.click()
})
await sleep(.3)
}
}

export async function fillTimeLimit(value: number, input: ElementHandle<HTMLInputElement>, page: Page): Promise<void> {
export async function fillTimeLimit(value: number | undefined, input: ElementHandle<HTMLInputElement>, page: Page): Promise<void> {
value = value ?? 0
const hour = Math.floor(value / 3600)
value = value - hour * 3600
const minute = Math.floor(value / 60)
const second = value - minute * 60
await input.click()
await sleep(.5)
const panel = await page.$('.el-popper div.el-time-panel')
const panel = await page.$('.el-popper:not([style*="display:none"]):not([style*="display: none"]) div.el-time-panel')
await panel!.evaluate(async (el, hour, minute, second) => {
const hourSpinner = el.querySelector('.el-scrollbar:first-child .el-scrollbar__wrap')
hourSpinner!.scrollTo(0, hour * 32)
Expand All @@ -58,6 +65,7 @@ export async function fillTimeLimit(value: number, input: ElementHandle<HTMLInpu
const confirmBtn = el.querySelector('.el-time-panel__footer .el-time-panel__btn.confirm') as HTMLButtonElement
confirmBtn.click()
}, hour, minute, second)
await sleep(.2)
}

export async function fillVisitLimit(value: number, input: ElementHandle<HTMLInputElement>, page: Page) {
Expand Down
Loading