diff --git a/README.md b/README.md index 938cfc2..fcd3386 100644 --- a/README.md +++ b/README.md @@ -71,7 +71,7 @@ npm run package-win - [React](https://github.com/facebook/react) - [Redux](https://github.com/reduxjs/redux) - [Fluent UI](https://github.com/microsoft/fluentui) -- [NeDB](https://github.com/louischatriot/nedb) +- [Lovefield](https://github.com/google/lovefield) - [Mercury Parser](https://github.com/postlight/mercury-parser) ### License diff --git a/package-lock.json b/package-lock.json index 4c988df..0b16223 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "fluent-reader", - "version": "0.7.4", + "version": "0.8.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 861299f..7b8edc7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "fluent-reader", - "version": "0.7.4", + "version": "0.8.0", "description": "Modern desktop RSS reader", "main": "./dist/electron.js", "scripts": { @@ -16,6 +16,7 @@ "keywords": [], "author": "Haoyuan Liu", "license": "BSD-3-Clause", + "repository": "github:yang991178/fluent-reader", "build": { "appId": "me.hyliu.fluentreader", "productName": "Fluent Reader", diff --git a/src/components/nav.tsx b/src/components/nav.tsx index 0c73071..9a8e9fd 100644 --- a/src/components/nav.tsx +++ b/src/components/nav.tsx @@ -64,15 +64,13 @@ class Nav extends React.Component { this.props.markAllRead() break case "F7": - if (!this.props.state.menu || getWindowBreakpoint()) - this.props.logs() + if (!this.props.itemShown) this.props.logs() break case "F8": - if (!this.props.state.menu || getWindowBreakpoint()) - this.props.views() + if (!this.props.itemShown) this.props.views() break case "F9": - this.props.settings() + if (!this.props.itemShown) this.props.settings() break } } diff --git a/src/containers/article-container.tsx b/src/containers/article-container.tsx index 01e00d2..7eb11aa 100644 --- a/src/containers/article-container.tsx +++ b/src/containers/article-container.tsx @@ -35,6 +35,7 @@ const mapDispatchToProps = (dispatch: AppDispatch) => { toggleStarred: (item: RSSItem) => dispatch(toggleStarred(item)), toggleHidden: (item: RSSItem) => { if (!item.hidden) dispatch(dismissItem()) + if (!item.hasRead && !item.hidden) dispatch(markRead(item)) dispatch(toggleHidden(item)) }, textMenu: (position: [number, number], text: string, url: string) => dispatch(openTextMenu(position, text, url)), diff --git a/src/main/update-scripts.ts b/src/main/update-scripts.ts index 9ff974c..fd49327 100644 --- a/src/main/update-scripts.ts +++ b/src/main/update-scripts.ts @@ -7,9 +7,13 @@ export default function performUpdate(store: Store) { let useNeDB = store.get("useNeDB", undefined) let currentVersion = app.getVersion() - if (useNeDB === undefined && version !== null) { - const revs = version.split(".").map(s => parseInt(s)) - store.set("useNeDB", (revs[0] === 0 && revs[1] < 8) || !app.isPackaged) + if (useNeDB === undefined) { + if (version !== null) { + const revs = version.split(".").map(s => parseInt(s)) + store.set("useNeDB", (revs[0] === 0 && revs[1] < 8) || !app.isPackaged) + } else { + store.set("useNeDB", false) + } } if (version != currentVersion) { store.set("version", currentVersion) diff --git a/src/scripts/db.ts b/src/scripts/db.ts index b12f021..45ea345 100644 --- a/src/scripts/db.ts +++ b/src/scripts/db.ts @@ -1,3 +1,4 @@ +import intl from "react-intl-universal" import Datastore from "nedb" import lf from "lovefield" import { RSSSource } from "./models/source" @@ -49,6 +50,12 @@ export async function init() { itemsDB = await idbSchema.connect() items = itemsDB.getSchema().table("items") if (window.settings.getNeDBStatus()) { + await migrateNeDB() + } +} + +async function migrateNeDB() { + try { const sdb = new Datastore({ filename: "sources", autoload: true, @@ -82,6 +89,9 @@ export async function init() { }) const iRows = itemDocs.map(doc => { if (doc.serviceRef !== undefined) doc.serviceRef = String(doc.serviceRef) + if (!doc.title) doc.title = intl.get("article.untitled") + if (!doc.content) doc.content = "" + if (!doc.snippet) doc.snippet = "" delete doc._id doc.starred = Boolean(doc.starred) doc.hidden = Boolean(doc.hidden) @@ -95,5 +105,8 @@ export async function init() { window.settings.setNeDBStatus(false) sdb.remove({}, { multi: true }, () => { sdb.persistence.compactDatafile() }) idb.remove({}, { multi: true }, () => { idb.persistence.compactDatafile() }) + } catch (err) { + window.utils.showErrorBox("An error has occured during update. Please report this error on GitHub.", String(err)) + window.utils.closeWindow() } } diff --git a/src/scripts/models/item.ts b/src/scripts/models/item.ts index b1b4473..581b208 100644 --- a/src/scripts/models/item.ts +++ b/src/scripts/models/item.ts @@ -303,11 +303,7 @@ const toggleStarredDone = (item: RSSItem): ItemActionTypes => ({ export function toggleStarred(item: RSSItem): AppThunk { return (dispatch) => { - if (item.starred) { - db.itemsDB.update(db.items).where(db.items._id.eq(item._id)).set(db.items.starred, false).exec() - } else { - db.itemsDB.update(db.items).where(db.items._id.eq(item._id)).set(db.items.starred, true).exec() - } + db.itemsDB.update(db.items).where(db.items._id.eq(item._id)).set(db.items.starred, !item.starred).exec() dispatch(toggleStarredDone(item)) if (item.serviceRef) { const hooks = dispatch(getServiceHooks()) @@ -324,11 +320,7 @@ const toggleHiddenDone = (item: RSSItem): ItemActionTypes => ({ export function toggleHidden(item: RSSItem): AppThunk { return (dispatch) => { - if (item.hidden) { - db.itemsDB.update(db.items).where(db.items._id.eq(item._id)).set(db.items.hidden, false).exec() - } else { - db.itemsDB.update(db.items).where(db.items._id.eq(item._id)).set(db.items.hidden, true).exec() - } + db.itemsDB.update(db.items).where(db.items._id.eq(item._id)).set(db.items.hidden, !item.hidden).exec() dispatch(toggleHiddenDone(item)) } } @@ -348,7 +340,7 @@ export function itemShortcuts(item: RSSItem, e: KeyboardEvent): AppThunk { dispatch(toggleStarred(item)) break case "h": case "H": - if (!item.hasRead) dispatch(markRead(item)) + if (!item.hasRead && !item.hidden) dispatch(markRead(item)) dispatch(toggleHidden(item)) break } diff --git a/src/scripts/models/services/feedbin.ts b/src/scripts/models/services/feedbin.ts index 6f07724..e8e54c2 100644 --- a/src/scripts/models/services/feedbin.ts +++ b/src/scripts/models/services/feedbin.ts @@ -191,7 +191,8 @@ export const feedbinServiceHooks: ServiceHooks = { if (date) { predicates.push(before ? db.items.date.lte(date) : db.items.date.gte(date)) } - const rows = await db.itemsDB.select(db.items.serviceRef).where(lf.op.and.apply(null, predicates)).exec() + const query = lf.op.and.apply(null, predicates) + const rows = await db.itemsDB.select(db.items.serviceRef).from(db.items).where(query).exec() const refs = rows.map(row => parseInt(row["serviceRef"])) markItems(configs, "unread", "DELETE", refs) }, diff --git a/src/scripts/models/source.ts b/src/scripts/models/source.ts index d93417d..cc860ff 100644 --- a/src/scripts/models/source.ts +++ b/src/scripts/models/source.ts @@ -223,8 +223,9 @@ export function insertSource(source: RSSSource): AppThunk> { try { const inserted = (await db.sourcesDB.insert().into(db.sources).values([row]).exec()) as RSSSource[] resolve(inserted[0]) - } catch { - reject(intl.get("sources.exist")) + } catch (err) { + if (err.code === 201) reject(intl.get("sources.exist")) + else reject(err) } }) })