store filter type & xml charset detection
This commit is contained in:
parent
c6420d1ec8
commit
e0f1b4e6e5
|
@ -89,6 +89,13 @@ const settingsBridge = {
|
|||
ipcRenderer.invoke("set-service-configs", configs)
|
||||
},
|
||||
|
||||
getFilterType: (): number => {
|
||||
return ipcRenderer.sendSync("get-filter-type")
|
||||
},
|
||||
setFilterType: (filterType: number) => {
|
||||
ipcRenderer.invoke("set-filter-type", filterType)
|
||||
},
|
||||
|
||||
getAll: () => {
|
||||
return ipcRenderer.sendSync("get-all-settings") as Object
|
||||
},
|
||||
|
|
|
@ -145,3 +145,11 @@ ipcMain.on("get-service-configs", (event) => {
|
|||
ipcMain.handle("set-service-configs", (_, configs: ServiceConfigs) => {
|
||||
store.set(SERVICE_CONFIGS_STORE_KEY, configs)
|
||||
})
|
||||
|
||||
const FILTER_TYPE_STORE_KEY = "filterType"
|
||||
ipcMain.on("get-filter-type", (event) => {
|
||||
event.returnValue = store.get(FILTER_TYPE_STORE_KEY, null)
|
||||
})
|
||||
ipcMain.handle("set-filter-type", (_, filterType: number) => {
|
||||
store.set(FILTER_TYPE_STORE_KEY, filterType)
|
||||
})
|
||||
|
|
|
@ -65,4 +65,5 @@ export type SchemaTypes = {
|
|||
fetchInterval: number
|
||||
searchEngine: SearchEngines
|
||||
serviceConfigs: ServiceConfigs
|
||||
filterType: number
|
||||
}
|
||||
|
|
|
@ -12,16 +12,19 @@ export enum FilterType {
|
|||
FullSearch = 1 << 3,
|
||||
CaseInsensitive = 1 << 4,
|
||||
|
||||
Default = ShowRead | ShowNotStarred | CaseInsensitive,
|
||||
Default = ShowRead | ShowNotStarred,
|
||||
UnreadOnly = ShowNotStarred,
|
||||
StarredOnly = ShowRead,
|
||||
Toggles = ShowHidden | FullSearch
|
||||
Toggles = ShowHidden | FullSearch | CaseInsensitive,
|
||||
}
|
||||
export class FeedFilter {
|
||||
type: FilterType
|
||||
search: string
|
||||
|
||||
constructor(type=FilterType.Default, search="") {
|
||||
constructor(type: FilterType = null, search="") {
|
||||
if (type === null && (type = window.settings.getFilterType()) === null) {
|
||||
type = FilterType.Default | FilterType.CaseInsensitive
|
||||
}
|
||||
this.type = type
|
||||
this.search = search
|
||||
}
|
||||
|
|
|
@ -174,7 +174,9 @@ const applyFilterDone = (filter: FeedFilter): PageActionTypes => ({
|
|||
})
|
||||
|
||||
function applyFilter(filter: FeedFilter): AppThunk {
|
||||
return (dispatch) => {
|
||||
return (dispatch, getState) => {
|
||||
const oldFilterType = getState().page.filter.type
|
||||
if (filter.type !== oldFilterType) window.settings.setFilterType(filter.type)
|
||||
dispatch(applyFilterDone(filter))
|
||||
dispatch(initFeeds(true))
|
||||
}
|
||||
|
|
|
@ -68,7 +68,7 @@ export class SourceRule {
|
|||
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
|
||||
if (!caseSensitive) this.filter.type |= FilterType.CaseInsensitive
|
||||
this.match = match
|
||||
this.actions = RuleActions.fromKeys(actions)
|
||||
}
|
||||
|
|
|
@ -29,17 +29,21 @@ const rssParser = new Parser({
|
|||
})
|
||||
|
||||
const CHARSET_RE = /charset=([^()<>@,;:\"/[\]?.=\s]*)/i
|
||||
const XML_ENCODING_RE = /^<\?xml.+encoding="(.+)".*\?>\s*\n/i
|
||||
export async function decodeFetchResponse(response: Response, isHTML = false) {
|
||||
const buffer = await response.arrayBuffer()
|
||||
const ctype = response.headers.has("content-type") && response.headers.get("content-type")
|
||||
const charset = (ctype && CHARSET_RE.test(ctype)) ? CHARSET_RE.exec(ctype)[1] : undefined
|
||||
const decoder = new TextDecoder(charset)
|
||||
let content = decoder.decode(buffer)
|
||||
if (charset === undefined && isHTML) {
|
||||
const dom = domParser.parseFromString(content, "text/html")
|
||||
const meta = dom.querySelector("meta[charset]")
|
||||
if (meta) {
|
||||
content = (new TextDecoder(meta.getAttribute("charset"))).decode(buffer)
|
||||
let charset = (ctype && CHARSET_RE.test(ctype)) ? CHARSET_RE.exec(ctype)[1] : undefined
|
||||
let content = (new TextDecoder(charset)).decode(buffer)
|
||||
if (charset === undefined) {
|
||||
if (isHTML) {
|
||||
const dom = domParser.parseFromString(content, "text/html")
|
||||
charset = dom.querySelector("meta[charset]")?.getAttribute("charset")?.toLowerCase()
|
||||
} else {
|
||||
charset = (XML_ENCODING_RE.test(content) && XML_ENCODING_RE.exec(content)[1])?.toLowerCase()
|
||||
}
|
||||
if (charset && charset !== "utf-8" && charset !== "utf8") {
|
||||
content = (new TextDecoder(charset)).decode(buffer)
|
||||
}
|
||||
}
|
||||
return content
|
||||
|
|
Loading…
Reference in New Issue