Skip to content

Commit b346217

Browse files
committed
feat: semi
1 parent b673edf commit b346217

22 files changed

Lines changed: 855 additions & 27 deletions

File tree

.vscode/settings.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
"js/ts.format.insertSpaceAfterCommaDelimiter": true,
1414
"js/ts.preferences.quoteStyle": "single",
1515
"js/ts.format.semicolons": "remove",
16+
"js/ts.preferences.preferTypeOnlyAutoImports": true,
1617
"js/ts.format.insertSpaceBeforeFunctionParenthesis": false,
1718
"files.eol": "\n",
1819
"cSpell.words": [

package.json

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,33 +30,33 @@
3030
"license": "MIT",
3131
"devDependencies": {
3232
"@commitlint/types": "^21.2.0",
33-
"@crowdin/crowdin-api-client": "^1.56.3",
33+
"@crowdin/crowdin-api-client": "^1.56.4",
3434
"@emotion/babel-plugin": "^11.13.5",
3535
"@rsdoctor/rspack-plugin": "^1.6.3",
36-
"@rspack/cli": "^2.2.0",
37-
"@rspack/core": "^2.2.0",
36+
"@rspack/cli": "^2.2.1",
37+
"@rspack/core": "^2.2.1",
3838
"@rstest/core": "^0.11.10",
3939
"@rstest/coverage-istanbul": "^0.11.10",
4040
"@types/chrome": "0.2.7",
4141
"@types/decompress": "^4.2.7",
4242
"@types/firefox-webext-browser": "^143.0.0",
43-
"@types/node": "^26.3.0",
43+
"@types/node": "^26.4.0",
4444
"@vue/babel-plugin-jsx": "^3.0.0",
4545
"babel-loader": "^10.1.1",
4646
"commitlint": "^21.2.2",
47-
"css-loader": "^7.1.4",
47+
"css-loader": "^7.1.5",
4848
"decompress": "^4.2.1",
4949
"fake-indexeddb": "^6.2.5",
5050
"husky": "^9.1.7",
5151
"jsdom": "^30.0.1",
5252
"jszip": "^3.10.1",
53-
"knip": "^6.32.2",
53+
"knip": "^6.33.0",
5454
"postcss": "^8.5.26",
5555
"postcss-loader": "^8.2.1",
5656
"postcss-rtlcss": "^6.0.0",
5757
"puppeteer": "^25.9.0",
5858
"ts-checker-rspack-plugin": "^1.6.1",
59-
"tsx": "^4.23.12",
59+
"tsx": "^4.23.13",
6060
"typescript": "7.0.2",
6161
"unplugin-element-plus": "^0.11.2"
6262
},
@@ -67,8 +67,8 @@
6767
"element-plus": "2.14.5",
6868
"qrcode-generator": "^2.0.4",
6969
"typescript-guard": "0.2.6",
70-
"vue": "^3.5.41",
71-
"vue-router": "^5.2.0"
70+
"vue": "^3.5.42",
71+
"vue-router": "^5.3.0"
7272
},
7373
"engines": {
7474
"node": ">=22"

src/background/limit-processor.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
*/
77

88
import { listTabs, sendMsg2Tab } from "@api/chrome/tab"
9+
import optionHolder from '@service/components/option-holder'
910
import { getSite } from '@service/site-service'
1011
import { matches } from "@util/limit"
1112
import { extractHostname } from '@util/pattern'
@@ -25,6 +26,26 @@ function initDailyBroadcast() {
2526
)
2627
}
2728

29+
function anyChanged(
30+
newVal: tt4b.option.LimitOption,
31+
oldVal: tt4b.option.LimitOption,
32+
...keys: (keyof tt4b.option.LimitOption)[]
33+
) {
34+
return keys.some(key => newVal[key] !== oldVal[key])
35+
}
36+
37+
function initOptionBroadcast() {
38+
optionHolder.addChangeListener(async (newVal, oldVal) => {
39+
if (!anyChanged(newVal, oldVal, 'limitCountdown', 'limitDelayDuration')) return
40+
const tabs = await listTabs()
41+
for (const { id: tabId } of tabs) {
42+
try {
43+
tabId && await sendMsg2Tab(tabId, 'limitOptionChanged', newVal)
44+
} catch { }
45+
}
46+
})
47+
}
48+
2849
const processAskHitVisit = async (item: tt4b.limit.Item) => {
2950
let tabs = await listTabs()
3051
const { cond } = item
@@ -55,6 +76,7 @@ async function querySummary(): Promise<tt4b.limit.Summary | undefined> {
5576

5677
export default function init(dispatcher: MessageDispatcher) {
5778
initDailyBroadcast()
79+
initOptionBroadcast()
5880

5981
dispatcher
6082
.register('limit.list', selectLimit)

src/background/service/components/option-holder.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ class OptionHolder {
2727
}
2828

2929
addChangeListener(listener: ChangeListener) {
30-
listener && this.#listeners.push(listener)
30+
this.#listeners.push(listener)
3131
}
3232

3333
async set(option: Partial<tt4b.option.AllOption>): Promise<void> {
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
export const ICON_SIZE = 40
2+
export const HALF_SIZE = ICON_SIZE / 2
3+
4+
export type Position = { x: number, y: number }
5+
export type Edge = 'left' | 'right'
6+
7+
export abstract class StatefulNode<State, E extends Element> {
8+
el: E
9+
state: State | null = null
10+
11+
constructor() {
12+
this.el = this.init()
13+
}
14+
15+
protected abstract init(): E
16+
17+
render(state: State) {
18+
if (this.sameAsCurrent(state)) return
19+
this.doRender(state, this.state)
20+
this.state = state
21+
}
22+
23+
protected sameAsCurrent(newState: State) {
24+
return newState === this.state
25+
}
26+
27+
protected abstract doRender(state: State, last: State | null): void
28+
}
29+
30+
export const getViewportSize = () => ({ w: window.innerWidth, h: window.innerHeight })
31+
32+
export function clampPosition({ x, y }: Position): Position {
33+
const { w, h } = getViewportSize()
34+
return {
35+
x: Math.max(HALF_SIZE, Math.min(w - HALF_SIZE, x)),
36+
y: Math.max(HALF_SIZE, Math.min(h - HALF_SIZE, y)),
37+
}
38+
}

0 commit comments

Comments
 (0)