diff --git a/src/components/SettingsPanel.vue b/src/components/SettingsPanel.vue index 2957c86..6cbfeb1 100644 --- a/src/components/SettingsPanel.vue +++ b/src/components/SettingsPanel.vue @@ -46,6 +46,7 @@

{{ t('filter') }}

{{ t('filter-desc') }} + (?)

diff --git a/src/composables/data.ts b/src/composables/data.ts index 93e4371..176917a 100644 --- a/src/composables/data.ts +++ b/src/composables/data.ts @@ -1,5 +1,6 @@ import { AfterFetchContext, MaybeRef, UseFetchOptions } from '@vueuse/core'; import psl from 'psl'; +import { getTypedFilter } from '../utils/filter'; export type GreasyforkScriptUser = { id: number; @@ -97,7 +98,11 @@ export function useDataList() { settings.value.nsfw ? sleazyfork.value ?? [] : [] ) ?? [] ).filter((item) => - settings.value.filter.every((keywords) => !item.name.includes(keywords)) + settings.value.filter.every((keywords) => { + const filter = getTypedFilter(keywords); + if (filter.type === 'title') return !filter.regexp.test(item.name); + else return item.users.every((user) => !filter.regexp.test(user.name)); + }) ); }); diff --git a/src/locales/en.json b/src/locales/en.json index b3b0962..b25bcad 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -21,7 +21,8 @@ "nsfw": "NSFW", "nsfw-desc": "Show Sleazyfork's result in list", "filter": "Filter", - "filter-desc": "Filter user script with specific content in title", + "filter-desc": "Filter user script with specific content in title or specific developer", + "filter-tips": "use title: to filter title or author: for developer, title for default", "time-ago": { "just-now": "just now", "past": "{n} ago", diff --git a/src/locales/zh.json b/src/locales/zh.json index 73610bb..b2104d9 100644 --- a/src/locales/zh.json +++ b/src/locales/zh.json @@ -21,7 +21,8 @@ "nsfw": "成人内容", "nsfw-desc": "列表中展示Sleazyfork的搜索结果", "filter": "过滤", - "filter-desc": "过滤标题含有指定内容的用户脚本", + "filter-desc": "过滤标题含有指定内容或指定开发者的用户脚本", + "filter-tips": "使用title:过滤标题或是author:指定开发者,没有相关描述则默认过滤标题,支持正则表达式", "time-ago": { "just-now": "就在刚刚", "past": "{n}前", diff --git a/src/utils/filter.ts b/src/utils/filter.ts new file mode 100644 index 0000000..3b04571 --- /dev/null +++ b/src/utils/filter.ts @@ -0,0 +1,29 @@ +type AuthorFilterLiteral = `author:${string}`; +type TitleFilterLiteral = `title:${string}`; +type Filter = { type: 'author' | 'title'; regexp: RegExp }; + +const AUTHOR_REGEX = /^author:(\S+)$/; +const TITLE_REGEX = /^title:(\S+)$/; + +export function isAuthorFilter(filter: string): filter is AuthorFilterLiteral { + return !!filter.match(AUTHOR_REGEX); +} + +export function isTitleFilter(filter: string): filter is TitleFilterLiteral { + return !!filter.match(TITLE_REGEX); +} + +export function getTypedFilter(filter: string): Filter { + if (filter.includes(':')) { + if (isAuthorFilter(filter)) { + const regexp = new RegExp(filter.match(AUTHOR_REGEX)?.[1]!); + return { type: 'author', regexp }; + } else { + return getTypedFilter(filter.match(TITLE_REGEX)?.[1]!); + } + } + return { + type: 'title', + regexp: new RegExp(filter) + }; +}