Skip to content

Commit 7b6da97

Browse files
authored
feat: exclude sites for whitelist (#348)
1 parent 4633189 commit 7b6da97

File tree

31 files changed

+299
-198
lines changed

31 files changed

+299
-198
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
.DS_Store
2+
13
node_modules
24
.idea
35
dist*

package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,15 @@
3232
"@babel/plugin-transform-modules-commonjs": "^7.27.1",
3333
"@babel/preset-env": "^7.28.3",
3434
"@crowdin/crowdin-api-client": "^1.48.3",
35-
"@rsdoctor/rspack-plugin": "^1.3.1",
35+
"@rsdoctor/rspack-plugin": "^1.3.2",
3636
"@rspack/cli": "^1.5.8",
3737
"@rspack/core": "^1.5.8",
3838
"@swc/core": "^1.13.5",
3939
"@swc/jest": "^0.2.39",
40-
"@types/chrome": "0.1.22",
40+
"@types/chrome": "0.1.24",
4141
"@types/decompress": "^4.2.7",
4242
"@types/jest": "^30.0.0",
43-
"@types/node": "^24.7.0",
43+
"@types/node": "^24.7.2",
4444
"@types/punycode": "^2.1.4",
4545
"@vue/babel-plugin-jsx": "^2.0.1",
4646
"babel-loader": "^10.0.0",
@@ -54,7 +54,7 @@
5454
"postcss": "^8.5.6",
5555
"postcss-loader": "^8.2.0",
5656
"postcss-rtlcss": "^5.7.1",
57-
"puppeteer": "^24.23.0",
57+
"puppeteer": "^24.24.0",
5858
"sass": "^1.93.2",
5959
"sass-loader": "^16.0.5",
6060
"style-loader": "^4.0.0",

src/background/badge-manager.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { listTabs } from "@api/chrome/tab"
1010
import { getFocusedNormalWindow } from "@api/chrome/window"
1111
import statDatabase from "@db/stat-database"
1212
import optionHolder from "@service/components/option-holder"
13-
import whitelistHolder from "@service/components/whitelist-holder"
13+
import whitelistHolder from "@service/whitelist/holder"
1414
import { IS_ANDROID } from "@util/constant/environment"
1515
import { extractHostname, isBrowserUrl } from "@util/pattern"
1616
import { MILL_PER_HOUR, MILL_PER_MINUTE, MILL_PER_SECOND } from "@util/time"

src/background/content-script-handler.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ import { executeScript } from "@api/chrome/script"
99
import { createTab } from "@api/chrome/tab"
1010
import { ANALYSIS_ROUTE, LIMIT_ROUTE } from "@app/router/constants"
1111
import optionHolder from "@service/components/option-holder"
12-
import whitelistHolder from "@service/components/whitelist-holder"
1312
import limitService from "@service/limit-service"
1413
import siteService from "@service/site-service"
1514
import { saveTimelineEvent } from '@service/timeline-service'
15+
import whitelistHolder from "@service/whitelist/holder"
1616
import { getAppPageUrl } from "@util/constant/url"
1717
import { extractFileHost, extractHostname } from "@util/pattern"
1818
import badgeManager from "./badge-manager"

src/background/migrator/whitelist-initializer.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
import whitelistService from "@service/whitelist-service"
1+
import whitelistService from "@service/whitelist/service"
22
import { type Migrator } from "./common"
33

44
export default class WhitelistInitializer implements Migrator {
55
onInstall(): void {
6-
whitelistService.add('localhost:*')
6+
whitelistService.add('localhost:*/**')
77
}
88

99
onUpdate(version: string): void {

src/background/track-server.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import { getTab, listTabs, sendMsg2Tab } from "@api/chrome/tab"
22
import { getWindow } from "@api/chrome/window"
33
import optionHolder from "@service/components/option-holder"
4-
import whitelistHolder from "@service/components/whitelist-holder"
54
import itemService, { type ItemIncContext } from "@service/item-service"
65
import limitService from "@service/limit-service"
76
import periodService from "@service/period-service"
7+
import whitelistHolder from "@service/whitelist/holder"
88
import { IS_ANDROID } from "@util/constant/environment"
99
import { extractHostname } from "@util/pattern"
1010
import { formatTimeYMD, getStartOfDay, MILL_PER_DAY } from "@util/time"

src/i18n/message/app/whitelist-resource.json

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
{
22
"zh_CN": {
3-
"addConfirmMsg": "{url} 加入白名单后,将不再统计该网站的数据",
3+
"addConfirmMsg": "{url} 将被加入至白名单",
44
"removeConfirmMsg": "{url} 将从白名单中移除",
55
"duplicateMsg": "已存在白名单中",
66
"infoAlertTitle": "你可以在这里配置网站白名单",
77
"infoAlert0": "白名单内网站的上网时长和打开次数不会被统计",
88
"infoAlert1": "白名单内网站的上网时间也不会被限制",
9+
"infoAlert2": "您可以使用通配符 (*) 匹配多个站点,例如 *.example.com/**,并使用 + 作为前缀排除站点,例如 +need.example.com/**",
910
"errorInput": "域名格式错误"
1011
},
1112
"zh_TW": {
12-
"addConfirmMsg": "{url} 加入白名單後,將停止統計此網站的瀏覽資料",
13+
"addConfirmMsg": "{url} 將會被加入白名單。",
1314
"removeConfirmMsg": "確定要將 {url} 從白名單移除嗎?",
1415
"duplicateMsg": "此網址已存在於白名單中",
1516
"infoAlertTitle": "網站白名單設定",
@@ -18,16 +19,17 @@
1819
"errorInput": "網域名稱格式錯誤"
1920
},
2021
"en": {
21-
"addConfirmMsg": "{url} won't be counted after added into the whitelist any more.",
22+
"addConfirmMsg": "{url} will be added to the whitelist.",
2223
"removeConfirmMsg": "{url} will be removed from the whitelist.",
2324
"duplicateMsg": "Duplicated",
2425
"infoAlertTitle": "You can whitelist sites on this page",
2526
"infoAlert0": "Whitelisted sites will not be counted",
2627
"infoAlert1": "Whitelisted sites will not be restricted",
28+
"infoAlert2": "You can use a wildcards(*) to match multiple sites, such as *.example.com/**, and use + as a prefix to exclude sites, such as +need.example.com/**",
2729
"errorInput": "Invalid site URL"
2830
},
2931
"ja": {
30-
"addConfirmMsg": "{url} がホワイトリストに追加されると、このWebサイトの統計はカウントされなくなります",
32+
"addConfirmMsg": "{url} がホワイトリストに追加されます",
3133
"removeConfirmMsg": "{url} はホワイトリストから削除されます",
3234
"duplicateMsg": "繰り返される",
3335
"infoAlertTitle": "このページでサイトのホワイトリストを設定できます",
@@ -36,7 +38,7 @@
3638
"errorInput": "無効なURL"
3739
},
3840
"pt_PT": {
39-
"addConfirmMsg": "{url} não será contabilizado após ser adicionado à lista de permissões.",
41+
"addConfirmMsg": "{url} será adicionado à lista de permissões.",
4042
"removeConfirmMsg": "{url} será removido da lista de permissões.",
4143
"duplicateMsg": "Duplicado",
4244
"infoAlertTitle": "Pode adicionar sites à lista de permissões nesta página",
@@ -45,7 +47,7 @@
4547
"errorInput": "URL do site inválido"
4648
},
4749
"uk": {
48-
"addConfirmMsg": "{url} не враховуватиметься після додавання до білого списку.",
50+
"addConfirmMsg": "{url} буде додано до білого списку.",
4951
"removeConfirmMsg": "{url} буде вилучено з білого списку.",
5052
"duplicateMsg": "Дублікат",
5153
"infoAlertTitle": "На цій сторінці ви можете налаштувати білий список сайтів",
@@ -54,7 +56,7 @@
5456
"errorInput": "Неприпустима URL-адреса сайту"
5557
},
5658
"es": {
57-
"addConfirmMsg": "{url} no se contará después de agregarlo a la lista blanca.",
59+
"addConfirmMsg": "{url} se agregará a la lista blanca.",
5860
"removeConfirmMsg": "{url} será eliminado de la lista blanca.",
5961
"duplicateMsg": "Duplicado",
6062
"infoAlertTitle": "Puedes configurar una lista blanca de sitios en esta página",
@@ -63,7 +65,7 @@
6365
"errorInput": "URL del sitio inválida"
6466
},
6567
"de": {
66-
"addConfirmMsg": "{url} wird nach dem Hinzufügen zur Whitelist nicht mehr gezählt.",
68+
"addConfirmMsg": "{url} wird zur Whitelist hinzugefügt.",
6769
"removeConfirmMsg": "{url} wird von der Whitelist entfernt.",
6870
"duplicateMsg": "Dupliziert",
6971
"infoAlertTitle": "Sie können eine Whitelist vonseiten auf dieser Seite festlegen",
@@ -72,7 +74,7 @@
7274
"errorInput": "Ungültige Seiten-URL"
7375
},
7476
"fr": {
75-
"addConfirmMsg": "{url} ne sera plus compté après avoir été ajouté à la liste blanche.",
77+
"addConfirmMsg": "{url} sera ajouté à la liste blanche.",
7678
"removeConfirmMsg": "{url} sera supprimé de la liste blanche.",
7779
"duplicateMsg": "Doublon",
7880
"infoAlertTitle": "Vous pouvez ajouter des sites à la liste blanche sur cette page",
@@ -81,7 +83,7 @@
8183
"errorInput": "URL du site invalide"
8284
},
8385
"ru": {
84-
"addConfirmMsg": "{url} больше не будет учитываться после добавления в белый список.",
86+
"addConfirmMsg": "{url} будет добавлен в белый список.",
8587
"removeConfirmMsg": "{url} будет удален из белого списка.",
8688
"duplicateMsg": "Дублированный",
8789
"infoAlertTitle": "Вы можете добавить сайты в белый список на этой странице",
@@ -90,7 +92,7 @@
9092
"errorInput": "Неверный URL-адрес сайта"
9193
},
9294
"ar": {
93-
"addConfirmMsg": "لن يتم احتساب {url} بعد إضافته إلى القائمة البيضاء بعد الآن.",
95+
"addConfirmMsg": "سيتم إضافة {url} إلى القائمة البيضاء.",
9496
"removeConfirmMsg": "سيتم إزالة {url} من القائمة البيضاء.",
9597
"duplicateMsg": "مكررة",
9698
"infoAlertTitle": "يمكنك إضافة المواقع إلى القائمة البيضاء في هذه الصفحة",

src/i18n/message/app/whitelist.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ export type WhitelistMessage = {
1414
infoAlertTitle: string
1515
infoAlert0: string
1616
infoAlert1: string
17+
infoAlert2: string
1718
errorInput: string
1819
}
1920

src/pages/app/components/Limit/LimitModify/Sop/Step2.tsx

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { t } from "@app/locale"
99
import { Delete, WarnTriangleFilled } from "@element-plus/icons-vue"
1010
import { useState } from "@hooks"
1111
import Flex from "@pages/components/Flex"
12+
import { EXCLUDING_PREFIX } from '@util/constant/remain-host'
1213
import { cleanCond } from "@util/limit"
1314
import { ElButton, ElDivider, ElIcon, ElInput, ElLink, ElMessage, ElScrollbar, ElText, type ScrollbarInstance } from "element-plus"
1415
import { type StyleValue, defineComponent, ref } from "vue"
@@ -46,10 +47,7 @@ const _default = defineComponent(() => {
4647
onKeydown={ev => (ev as KeyboardEvent)?.code === "Enter" && handleAdd()}
4748
v-slots={{
4849
append: () => (
49-
<ElButton
50-
onClick={handleAdd}
51-
style={{ display: 'flex' } satisfies StyleValue}
52-
>
50+
<ElButton onClick={handleAdd} style={{ display: 'flex' } satisfies StyleValue}>
5351
{t(msg => msg.button.add)}
5452
</ElButton>
5553
)
@@ -72,7 +70,7 @@ const _default = defineComponent(() => {
7270
padding='0 20px'
7371
style={{ backgroundColor: 'var(--el-fill-color)', borderRadius: 'var(--el-border-radius-large)' }}
7472
>
75-
<ElText type="primary">{url}</ElText>
73+
<ElText type={url.startsWith(EXCLUDING_PREFIX) ? 'info' : 'primary'}>{url}</ElText>
7674
<ElLink icon={Delete} type="danger" onClick={() => handleRemove(idx)} />
7775
</Flex>
7876
))}

src/pages/app/components/Limit/LimitTest.tsx

Lines changed: 14 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -8,48 +8,36 @@
88
import { t } from "@app/locale"
99
import { useState, useSwitch } from "@hooks"
1010
import limitService from "@service/limit-service"
11-
import { AlertProps, ElAlert, ElButton, ElDialog, ElFormItem, ElInput } from "element-plus"
11+
import { ElButton, ElDialog, ElFormItem, ElInput } from "element-plus"
1212
import { computed, defineComponent } from "vue"
13+
import AlertLines, { type AlertLinesProps } from '../common/AlertLines'
1314
import { type TestInstance } from "./context"
1415

15-
function computeResultTitle(url: string | undefined, inputting: boolean, matched: timer.limit.Rule[]): string {
16+
function computeResult(url: string | undefined, inputting: boolean, matched: timer.limit.Rule[]): AlertLinesProps {
1617
if (!url) {
17-
return t(msg => msg.limit.message.inputTestUrl)
18+
return { type: 'info', title: msg => msg.limit.message.inputTestUrl }
1819
}
1920
if (inputting) {
20-
return t(msg => msg.limit.message.clickTestButton, { buttonText: t(msg => msg.button.test) })
21+
const title = t(msg => msg.limit.message.clickTestButton, { buttonText: t(msg => msg.button.test) })
22+
return { type: 'info', title }
2123
}
2224
if (!matched?.length) {
23-
return t(msg => msg.limit.message.noRuleMatched)
25+
return { type: 'warning', title: msg => msg.limit.message.noRuleMatched }
2426
} else {
25-
return t(msg => msg.limit.message.rulesMatched)
26-
}
27-
}
28-
29-
function computeResultDesc(url: string | undefined, inputting: boolean, matched: timer.limit.Rule[]): string[] {
30-
if (!url || inputting || !matched?.length) {
31-
return []
32-
}
33-
return matched.map(m => m.name)
34-
}
35-
36-
type _ResultType = AlertProps['type']
37-
38-
function computeResultType(url: string | undefined, inputting: boolean, matched: timer.limit.Rule[]): _ResultType {
39-
if (!url || inputting) {
40-
return 'info'
27+
return {
28+
type: 'success',
29+
title: msg => msg.limit.message.rulesMatched,
30+
lines: matched.map(m => m.name)
31+
}
4132
}
42-
return matched?.length ? 'success' : 'warning'
4333
}
4434

4535
const _default = defineComponent((_props, ctx) => {
4636
const [url, , clearUrl] = useState<string>()
4737
const [matched, , clearMatched] = useState<timer.limit.Rule[]>([])
4838
const [visible, open, close] = useSwitch()
4939
const [urlInputting, startInput, endInput] = useSwitch(true)
50-
const resultTitle = computed(() => computeResultTitle(url.value, urlInputting.value, matched.value))
51-
const resultType = computed(() => computeResultType(url.value, urlInputting.value, matched.value))
52-
const resultDesc = computed(() => computeResultDesc(url.value, urlInputting.value, matched.value))
40+
const result = computed(() => computeResult(url.value, urlInputting.value, matched.value))
5341

5442
const changeInput = (newVal?: string) => {
5543
startInput()
@@ -88,9 +76,7 @@ const _default = defineComponent((_props, ctx) => {
8876
}}
8977
/>
9078
</ElFormItem>
91-
<ElAlert closable={false} type={resultType.value} title={resultTitle.value}>
92-
{resultDesc.value.map(desc => <li>{desc}</li>)}
93-
</ElAlert>
79+
<AlertLines {...result.value} />
9480
</ElDialog>
9581
)
9682
})

0 commit comments

Comments
 (0)