mirror of
https://github.com/yang991178/fluent-reader.git
synced 2025-02-26 08:27:38 +01:00
update services, fix json and ui drag
This commit is contained in:
parent
c6439c5f6d
commit
9318b1c3ce
2
dist/styles/global.css
vendored
2
dist/styles/global.css
vendored
@ -237,7 +237,7 @@ body.darwin .btn-group .seperator {
|
||||
height: var(--navHeight);
|
||||
line-height: var(--navHeight);
|
||||
}
|
||||
body.darwin.not-fullscreen #root > nav .btn-group .btn:first-of-type {
|
||||
body.darwin.not-fullscreen #root > nav .btn-group:first-of-type {
|
||||
margin-left: 72px;
|
||||
}
|
||||
#root > nav .btn-group .btn.system {
|
||||
|
@ -17,7 +17,6 @@ import {
|
||||
} from "@fluentui/react"
|
||||
import DangerButton from "../../utils/danger-button"
|
||||
import { urlTest } from "../../../scripts/utils"
|
||||
import LiteExporter from "./lite-exporter"
|
||||
import { MinifluxConfigs } from "../../../scripts/models/services/miniflux"
|
||||
|
||||
type MinifluxConfigsTabState = {
|
||||
|
@ -18,7 +18,6 @@ import {
|
||||
} from "@fluentui/react"
|
||||
import DangerButton from "../../utils/danger-button"
|
||||
import { urlTest } from "../../../scripts/utils"
|
||||
import LiteExporter from "./lite-exporter"
|
||||
|
||||
type NextcloudConfigsTabState = {
|
||||
existing: boolean
|
||||
@ -129,17 +128,14 @@ class NextcloudConfigsTab extends React.Component<
|
||||
</MessageBar>
|
||||
)}
|
||||
<Stack horizontalAlign="center" style={{ marginTop: 48 }}>
|
||||
<svg
|
||||
<Icon
|
||||
iconName="AlignLeft"
|
||||
style={{
|
||||
fill: "var(--black)",
|
||||
width: 32,
|
||||
color: "var(--black)",
|
||||
fontSize: 32,
|
||||
userSelect: "none",
|
||||
strokeWidth:4.15602
|
||||
}}
|
||||
viewBox="0 0 120 120">
|
||||
<path
|
||||
d="M 6.1560215,2 C 3.8535856,2 2,3.8535856 2,6.1560215 v 8.3120425 c 0,2.302436 1.8535856,4.156022 4.1560215,4.156022 H 114.21258 c 2.30244,0 4.15602,-1.853586 4.15602,-4.156022 V 6.1560215 C 118.3686,3.8535856 116.51502,2 114.21258,2 Z m 0,33.248172 C 3.8535856,35.248172 2,37.101757 2,39.404193 v 8.312043 c 0,2.302436 1.8535856,4.156022 4.1560215,4.156022 H 80.964408 c 2.302436,0 4.156021,-1.853586 4.156021,-4.156022 v -8.312043 c 0,-2.302436 -1.853585,-4.156021 -4.156021,-4.156021 z m 0,33.248172 C 3.8535856,68.496344 2,70.349929 2,72.652365 v 8.312043 c 0,2.302436 1.8535856,4.156021 4.1560215,4.156021 H 105.90054 c 2.30243,0 4.15602,-1.853585 4.15602,-4.156021 v -8.312043 c 0,-2.302436 -1.85359,-4.156021 -4.15602,-4.156021 z m 0,33.248176 C 3.8535856,101.74452 2,103.5981 2,105.90054 v 8.31204 c 0,2.30244 1.8535856,4.15602 4.1560215,4.15602 H 56.028279 c 2.302436,0 4.156022,-1.85358 4.156022,-4.15602 v -8.31204 c 0,-2.30244 -1.853586,-4.15602 -4.156022,-4.15602 z"/>
|
||||
</svg>
|
||||
/>
|
||||
<Label style={{ margin: "8px 0 36px" }}>Nextcloud</Label>
|
||||
<Stack className="login-form" horizontal>
|
||||
<Stack.Item>
|
||||
@ -161,7 +157,7 @@ class NextcloudConfigsTab extends React.Component<
|
||||
</Stack>
|
||||
<Stack className="login-form" horizontal>
|
||||
<Stack.Item>
|
||||
<Label>User</Label>
|
||||
<Label>{intl.get("service.username")}</Label>
|
||||
</Stack.Item>
|
||||
<Stack.Item grow>
|
||||
<TextField
|
||||
@ -241,9 +237,6 @@ class NextcloudConfigsTab extends React.Component<
|
||||
)}
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
{this.state.existing && (
|
||||
<LiteExporter serviceConfigs={this.props.configs} />
|
||||
)}
|
||||
</Stack>
|
||||
</>
|
||||
)
|
||||
|
@ -41,8 +41,8 @@
|
||||
"refresh": "Načíst znovu",
|
||||
"markAllRead": "Označit vše jako přečtené",
|
||||
"notifications": "Notifikace",
|
||||
"view": "Zobrazit"
|
||||
"settings": "Nastavení"
|
||||
"view": "Zobrazit",
|
||||
"settings": "Nastavení",
|
||||
"minimize": "Maximalizovat",
|
||||
"maximize": "Minimalizovat"
|
||||
},
|
||||
|
@ -128,18 +128,18 @@ export const minifluxServiceHooks: ServiceHooks = {
|
||||
// fetch entries from after the last fetched id (if exists)
|
||||
// limit by quantity and maximum safe integer (id)
|
||||
// NOTE: miniflux endpoint /entries default order with "published at", and does not offer "created_at"
|
||||
// but does offer id sort, directly correlated with "created". some feeds give strange published_at.
|
||||
// but does offer id sort, directly correlated with "created". some feeds give strange published_at.
|
||||
|
||||
fetchItems: () => async (_, getState) => {
|
||||
const state = getState()
|
||||
const configs = state.service as MinifluxConfigs
|
||||
let items: Entry[] = new Array()
|
||||
const items: Entry[] = new Array()
|
||||
let entriesResponse: Entries
|
||||
|
||||
// parameters
|
||||
configs.lastId = configs.lastId ?? 0
|
||||
// intermediate
|
||||
const quantity = 100
|
||||
const quantity = 125
|
||||
let continueId: number
|
||||
|
||||
do {
|
||||
@ -147,37 +147,28 @@ export const minifluxServiceHooks: ServiceHooks = {
|
||||
if (continueId) {
|
||||
entriesResponse = await fetchAPI(
|
||||
configs,
|
||||
`entries?
|
||||
order=id
|
||||
&direction=desc
|
||||
&after_entry_id=${configs.lastId}
|
||||
&before_entry_id=${continueId}
|
||||
&limit=${quantity}`
|
||||
`entries?order=id&direction=desc&after_entry_id=${configs.lastId}&before_entry_id=${continueId}&limit=${quantity}`
|
||||
).then(response => response.json())
|
||||
} else {
|
||||
entriesResponse = await fetchAPI(
|
||||
configs,
|
||||
`entries?
|
||||
order=id
|
||||
&direction=desc
|
||||
&after_entry_id=${configs.lastId}
|
||||
&limit=${quantity}`
|
||||
`entries?order=id&direction=desc&after_entry_id=${configs.lastId}&limit=${quantity}`
|
||||
).then(response => response.json())
|
||||
}
|
||||
|
||||
items = entriesResponse.entries.concat(items)
|
||||
items.push(...entriesResponse.entries)
|
||||
continueId = items[items.length - 1].id
|
||||
} catch {
|
||||
break
|
||||
}
|
||||
} while (
|
||||
entriesResponse.entries &&
|
||||
entriesResponse.total === 100 &&
|
||||
entriesResponse.total >= quantity &&
|
||||
items.length < configs.fetchLimit
|
||||
)
|
||||
|
||||
// break/return nothing if no new items acquired
|
||||
if (items.length == 0) return [[], configs]
|
||||
if (items.length === 0) return [[], configs]
|
||||
configs.lastId = items[0].id
|
||||
|
||||
// get sources that possess ref/id given by service, associate new items
|
||||
@ -245,7 +236,10 @@ export const minifluxServiceHooks: ServiceHooks = {
|
||||
configs,
|
||||
"entries?starred=true"
|
||||
).then(response => response.json())
|
||||
const [unread, starred] = await Promise.all([unreadPromise, starredPromise])
|
||||
const [unread, starred] = await Promise.all([
|
||||
unreadPromise,
|
||||
starredPromise,
|
||||
])
|
||||
|
||||
return [
|
||||
new Set(unread.entries.map((entry: Entry) => String(entry.id))),
|
||||
@ -257,9 +251,9 @@ export const minifluxServiceHooks: ServiceHooks = {
|
||||
if (!item.serviceRef) return
|
||||
|
||||
const body = `{
|
||||
"entry_ids": [${item.serviceRef}],
|
||||
"status": "read"
|
||||
}`
|
||||
"entry_ids": [${item.serviceRef}],
|
||||
"status": "read"
|
||||
}`
|
||||
|
||||
const response = await fetchAPI(
|
||||
getState().service as MinifluxConfigs,
|
||||
@ -275,9 +269,9 @@ export const minifluxServiceHooks: ServiceHooks = {
|
||||
if (!item.serviceRef) return
|
||||
|
||||
const body = `{
|
||||
"entry_ids": [${item.serviceRef}],
|
||||
"status": "unread"
|
||||
}`
|
||||
"entry_ids": [${item.serviceRef}],
|
||||
"status": "unread"
|
||||
}`
|
||||
await fetchAPI(
|
||||
getState().service as MinifluxConfigs,
|
||||
"entries",
|
||||
@ -296,7 +290,8 @@ export const minifluxServiceHooks: ServiceHooks = {
|
||||
// if null, state consulted for context sids
|
||||
|
||||
markAllRead: (sids, date, before) => async (_, getState) => {
|
||||
let refs: string[]
|
||||
const state = getState()
|
||||
const configs = state.service as MinifluxConfigs
|
||||
|
||||
if (date) {
|
||||
const predicates: lf.Predicate[] = [
|
||||
@ -311,26 +306,24 @@ export const minifluxServiceHooks: ServiceHooks = {
|
||||
.from(db.items)
|
||||
.where(query)
|
||||
.exec()
|
||||
refs = rows.map(row => row["serviceRef"])
|
||||
const refs = rows.map(row => row["serviceRef"])
|
||||
const body = `{
|
||||
"entry_ids": [${refs}],
|
||||
"status": "read"
|
||||
}`
|
||||
await fetchAPI(configs, "entries", "PUT", body)
|
||||
} else {
|
||||
const state = getState()
|
||||
const items = state.feeds[state.page.feedId].iids
|
||||
.map(iid => state.items[iid])
|
||||
.filter(item => item.serviceRef && !item.hasRead)
|
||||
refs = items.map(item => item.serviceRef)
|
||||
const sources = state.sources
|
||||
await Promise.all(
|
||||
sids.map(sid =>
|
||||
fetchAPI(
|
||||
configs,
|
||||
`feeds/${sources[sid]?.serviceRef}/mark-all-as-read`,
|
||||
"PUT"
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
const body = `{
|
||||
"entry_ids": [${refs}],
|
||||
"status": "read"
|
||||
}`
|
||||
|
||||
await fetchAPI(
|
||||
getState().service as MinifluxConfigs,
|
||||
"entries",
|
||||
"PUT",
|
||||
body
|
||||
)
|
||||
},
|
||||
|
||||
star: (item: RSSItem) => async (_, getState) => {
|
||||
|
@ -98,7 +98,10 @@ export const nextcloudServiceHooks: ServiceHooks = {
|
||||
source.iconurl = s.faviconLink
|
||||
source.serviceRef = String(s.id)
|
||||
if (s.folderId && groupsByTagId.has(String(s.folderId))) {
|
||||
groupsMap.set(String(s.id), groupsByTagId.get(String(s.folderId)))
|
||||
groupsMap.set(
|
||||
String(s.id),
|
||||
groupsByTagId.get(String(s.folderId))
|
||||
)
|
||||
}
|
||||
return source
|
||||
})
|
||||
@ -107,7 +110,7 @@ export const nextcloudServiceHooks: ServiceHooks = {
|
||||
|
||||
syncItems: () => async (_, getState) => {
|
||||
const configs = getState().service as NextcloudConfigs
|
||||
const [unreadResponse, starredResponse]= await Promise.all([
|
||||
const [unreadResponse, starredResponse] = await Promise.all([
|
||||
fetchAPI(configs, "/items?getRead=false&type=3&batchSize=-1"),
|
||||
fetchAPI(configs, "/items?getRead=true&type=2&batchSize=-1"),
|
||||
])
|
||||
@ -133,19 +136,14 @@ export const nextcloudServiceHooks: ServiceHooks = {
|
||||
//first sync
|
||||
let min = Number.MAX_SAFE_INTEGER
|
||||
do {
|
||||
try {
|
||||
const response = await fetchAPI(
|
||||
configs,
|
||||
"/items?getRead=true&type=3&batchSize=125&offset=" + min
|
||||
)
|
||||
if (response.status !== 200) throw APIError()
|
||||
lastFetched = await response.json()
|
||||
items = [ ...items, ...lastFetched.items]
|
||||
min = lastFetched.items.reduce((m, n) => Math.min(m, n.id), min)
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
break
|
||||
}
|
||||
const response = await fetchAPI(
|
||||
configs,
|
||||
"/items?getRead=true&type=3&batchSize=125&offset=" + min
|
||||
)
|
||||
if (response.status !== 200) throw APIError()
|
||||
lastFetched = await response.json()
|
||||
items = [...items, ...lastFetched.items]
|
||||
min = lastFetched.items.reduce((m, n) => Math.min(m, n.id), min)
|
||||
} while (
|
||||
lastFetched.items &&
|
||||
lastFetched.items.length >= 125 &&
|
||||
@ -155,18 +153,14 @@ export const nextcloudServiceHooks: ServiceHooks = {
|
||||
//incremental sync
|
||||
const response = await fetchAPI(
|
||||
configs,
|
||||
"/items/updated?lastModified="+configs.lastModified+"&type=3"
|
||||
"/items/updated?lastModified=" +
|
||||
configs.lastModified +
|
||||
"&type=3"
|
||||
)
|
||||
if (response.status !== 200) throw APIError()
|
||||
lastFetched = (await response.json()).items
|
||||
items.push(
|
||||
...lastFetched.filter(
|
||||
i => i.id > configs.lastId
|
||||
)
|
||||
)
|
||||
|
||||
items.push(...lastFetched.filter(i => i.id > configs.lastId))
|
||||
}
|
||||
const previousLastModified = configs.lastModified
|
||||
configs.lastModified = items.reduce(
|
||||
(m, n) => Math.max(m, n.lastModified),
|
||||
configs.lastModified
|
||||
@ -175,7 +169,6 @@ export const nextcloudServiceHooks: ServiceHooks = {
|
||||
(m, n) => Math.max(m, n.id),
|
||||
configs.lastId
|
||||
)
|
||||
console.log("last modified from "+ previousLastModified + " to " + configs.lastModified)
|
||||
configs.lastModified++ //+1 to avoid fetching articles with same lastModified next time
|
||||
if (items.length > 0) {
|
||||
const fidMap = new Map<string, RSSSource>()
|
||||
@ -184,7 +177,7 @@ export const nextcloudServiceHooks: ServiceHooks = {
|
||||
fidMap.set(source.serviceRef, source)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const parsedItems = new Array<RSSItem>()
|
||||
items.forEach(i => {
|
||||
if (i.body === null || i.url === null) return
|
||||
@ -196,8 +189,8 @@ export const nextcloudServiceHooks: ServiceHooks = {
|
||||
source: source.sid,
|
||||
title: i.title,
|
||||
link: i.url,
|
||||
date: new Date(i.pubDate*1000),
|
||||
fetchedDate: new Date(i.pubDate*1000),
|
||||
date: new Date(i.pubDate * 1000),
|
||||
fetchedDate: new Date(),
|
||||
content: i.body,
|
||||
snippet: dom.documentElement.textContent.trim(),
|
||||
creator: i.author,
|
||||
@ -207,7 +200,7 @@ export const nextcloudServiceHooks: ServiceHooks = {
|
||||
notify: false,
|
||||
serviceRef: String(i.id),
|
||||
} as RSSItem
|
||||
if (i.enclosureLink ) {
|
||||
if (i.enclosureLink) {
|
||||
item.thumb = i.enclosureLink
|
||||
} else {
|
||||
let baseEl = dom.createElement("base")
|
||||
@ -235,7 +228,7 @@ export const nextcloudServiceHooks: ServiceHooks = {
|
||||
"POST",
|
||||
[i.id]
|
||||
)
|
||||
|
||||
|
||||
parsedItems.push(item)
|
||||
})
|
||||
return [parsedItems, configs]
|
||||
|
Loading…
x
Reference in New Issue
Block a user