filter by creator

This commit is contained in:
刘浩远 2020-08-24 20:51:36 +08:00
parent f2d5ca0171
commit 7141be86ad
5 changed files with 38 additions and 13 deletions

View File

@ -30,11 +30,12 @@ type RulesTabState = {
selectedRules: number[]
editIndex: number
regex: string
fullSearch: boolean
searchType: number
caseSensitive: boolean
match: boolean
actionKeys: string[]
mockTitle: string
mockCreator: string
mockContent: string
mockResult: string
}
@ -52,11 +53,12 @@ class RulesTab extends React.Component<RulesTabProps, RulesTabState> {
selectedRules: [],
editIndex: -1,
regex: "",
fullSearch: false,
searchType: 0,
caseSensitive: false,
match: true,
actionKeys: [],
mockTitle: "",
mockCreator: "",
mockContent: "",
mockResult: ""
}
@ -103,9 +105,14 @@ class RulesTab extends React.Component<RulesTabProps, RulesTabState> {
}
initRuleEdit = (rule: SourceRule = null) => {
let searchType = 0
if (rule) {
if (rule.filter.type & FilterType.FullSearch) searchType = 1
else if (rule.filter.type & FilterType.CreatorSearch) searchType = 2
}
this.setState({
regex: rule ? rule.filter.search : "",
fullSearch: rule ? Boolean(rule.filter.type & FilterType.FullSearch) : false,
searchType: searchType,
caseSensitive: rule ? !(rule.filter.type & FilterType.CaseInsensitive) : false,
match: rule ? rule.match : true,
actionKeys: rule ? RuleActions.toKeys(rule.actions) : []
@ -157,16 +164,17 @@ class RulesTab extends React.Component<RulesTabProps, RulesTabState> {
this.rulesSelection.setAllSelected(false)
this.setState({
sid: item.key as string, selectedRules: [], editIndex: -1,
mockTitle: "", mockContent: "", mockResult: ""
mockTitle: "", mockCreator: "", mockContent: "", mockResult: ""
})
}
searchOptions = (): IDropdownOption[] => [
{ key: 0, text: intl.get("rules.title") },
{ key: 1, text: intl.get("rules.fullSearch") }
{ key: 1, text: intl.get("rules.fullSearch") },
{ key: 2, text: intl.get("rules.creator") },
]
onSearchOptionChange = (_, item: IDropdownOption) => {
this.setState({ fullSearch: Boolean(item.key) })
this.setState({ searchType: item.key as number })
}
matchOptions = (): IDropdownOption[] => [
@ -207,7 +215,11 @@ class RulesTab extends React.Component<RulesTabProps, RulesTabState> {
}
saveRule = () => {
let rule = new SourceRule(this.state.regex, this.state.actionKeys, this.state.fullSearch, this.state.caseSensitive, this.state.match)
let filterType = FilterType.Default | FilterType.ShowHidden
if (!this.state.caseSensitive) filterType |= FilterType.CaseInsensitive
if (this.state.searchType === 1) filterType |= FilterType.FullSearch
else if (this.state.searchType === 2) filterType |= FilterType.CreatorSearch
let rule = new SourceRule(this.state.regex, this.state.actionKeys, filterType, this.state.match)
let source = this.props.sources[parseInt(this.state.sid)]
let rules = source.rules ? [ ...source.rules ] : []
if (this.state.editIndex === -1) {
@ -263,6 +275,7 @@ class RulesTab extends React.Component<RulesTabProps, RulesTabState> {
let source = this.props.sources[parseInt(this.state.sid)]
let item = new RSSItem(parsed as Parser.Item, source)
item.snippet = this.state.mockContent
item.creator = this.state.mockCreator
SourceRule.applyAll(this.getSourceRules(), item)
let result = []
result.push(intl.get(item.hasRead ? "article.markRead" : "article.markUnread"))
@ -319,7 +332,7 @@ class RulesTab extends React.Component<RulesTabProps, RulesTabState> {
<Stack.Item>
<Dropdown
options={this.searchOptions()}
selectedKey={this.state.fullSearch ? 1 : 0}
selectedKey={this.state.searchType}
onChange={this.onSearchOptionChange}
style={{width: 140}} />
</Stack.Item>
@ -393,6 +406,15 @@ class RulesTab extends React.Component<RulesTabProps, RulesTabState> {
value={this.state.mockTitle}
onChange={this.handleInputChange} />
</Stack.Item>
<Stack.Item grow>
<TextField
name="mockCreator"
placeholder={intl.get("rules.creator")}
value={this.state.mockCreator}
onChange={this.handleInputChange} />
</Stack.Item>
</Stack>
<Stack horizontal>
<Stack.Item grow>
<TextField
name="mockContent"

View File

@ -174,6 +174,7 @@
"title": "Title",
"content": "Content",
"fullSearch": "Title or content",
"creator": "Author",
"match": "matches",
"notMatch": "doesn't match",
"regex": "Regular expression",

View File

@ -172,6 +172,7 @@
"title": "标题",
"content": "正文",
"fullSearch": "标题或正文",
"creator": "作者",
"match": "匹配",
"notMatch": "不匹配",
"regex": "正则表达式",

View File

@ -1,6 +1,6 @@
import * as db from "../db"
import { SourceActionTypes, INIT_SOURCES, ADD_SOURCE, DELETE_SOURCE } from "./source"
import { ItemActionTypes, FETCH_ITEMS, RSSItem, MARK_READ, MARK_UNREAD, TOGGLE_STARRED, TOGGLE_HIDDEN, applyItemReduction, ItemState, MARK_ALL_READ } from "./item"
import { ItemActionTypes, FETCH_ITEMS, RSSItem, MARK_READ, MARK_UNREAD, TOGGLE_STARRED, TOGGLE_HIDDEN, applyItemReduction } from "./item"
import { ActionStatus, AppThunk, mergeSortedArrays } from "../utils"
import { PageActionTypes, SELECT_PAGE, PageType, APPLY_FILTER } from "./page"
@ -11,6 +11,7 @@ export enum FilterType {
ShowHidden = 1 << 2,
FullSearch = 1 << 3,
CaseInsensitive = 1 << 4,
CreatorSearch = 1 << 5,
Default = ShowRead | ShowNotStarred,
UnreadOnly = ShowNotStarred,
@ -65,6 +66,8 @@ export class FeedFilter {
const regex = RegExp(filter.search, flags)
if (type & FilterType.FullSearch) {
flag = flag && (regex.test(item.title) || regex.test(item.snippet))
} else if (type & FilterType.CreatorSearch) {
flag = flag && (regex.test(item.creator || ""))
} else {
flag = flag && regex.test(item.title)
}

View File

@ -65,10 +65,8 @@ export class SourceRule {
match: boolean
actions: RuleActions
constructor(regex: string, actions: string[], fullSearch: boolean, caseSensitive: boolean, match: boolean) {
this.filter = new FeedFilter(FilterType.Default | FilterType.ShowHidden, regex)
if (fullSearch) this.filter.type |= FilterType.FullSearch
if (!caseSensitive) this.filter.type |= FilterType.CaseInsensitive
constructor(regex: string, actions: string[], filter: FilterType, match: boolean) {
this.filter = new FeedFilter(filter, regex)
this.match = match
this.actions = RuleActions.fromKeys(actions)
}