Skip to content

Commit

Permalink
refactor(OPDS): migration PouchDB repository to main Redux state (PR #…
Browse files Browse the repository at this point in the history
  • Loading branch information
panaC authored Apr 27, 2021
1 parent a86385c commit 58ef86d
Show file tree
Hide file tree
Showing 14 changed files with 303 additions and 145 deletions.
2 changes: 2 additions & 0 deletions src/main/db/document/opds.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,6 @@ import { Timestampable } from "readium-desktop/common/models/timestampable";
export interface OpdsFeedDocument extends Identifiable, Timestampable {
title: string;
url: string;

doNotMigrateAnymore?: boolean;
}
99 changes: 95 additions & 4 deletions src/main/db/repository/opds.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,111 @@

import { injectable } from "inversify";
import * as PouchDB from "pouchdb-core";
import { Identifiable } from "readium-desktop/common/models/identifiable";
import { OpdsFeed } from "readium-desktop/common/models/opds";
import { Timestampable } from "readium-desktop/common/models/timestampable";
import { OpdsFeedDocument } from "readium-desktop/main/db/document/opds";
import { diMainGet } from "readium-desktop/main/di";
import { opdsActions } from "readium-desktop/main/redux/actions";
import { Unsubscribe } from "redux";

import { BaseRepository, ExcludeTimestampableAndIdentifiable } from "./base";
import { ExcludeTimestampableAndIdentifiable } from "./base";

@injectable()
export class OpdsFeedRepository extends BaseRepository<OpdsFeedDocument> {
export class OpdsFeedRepository /*extends BaseRepository<OpdsFeedDocument>*/ {
db: PouchDB.Database<OpdsFeedDocument>;
idPrefix: string;
public constructor(db: PouchDB.Database<OpdsFeedDocument>) {// INJECTED!
super(db, "opds-feed");
this.db = db;

this.idPrefix = "opds-feed";
}

public async save(feed: OpdsFeed): Promise<OpdsFeedDocument> {

const store = diMainGet("store");
let unsub: Unsubscribe;
const p = new Promise<OpdsFeedDocument>(
(res) => (unsub = store.subscribe(() =>
res(store.getState().opds.catalog.find((v) =>
v.identifier === feed.identifier)))));
store.dispatch(opdsActions.addOpdsFeed.build(feed));

return p.finally(() => unsub && unsub());
}

public async get(identifier: string): Promise<OpdsFeedDocument> {
// try {
// const dbDoc = await this.db.get(this.buildId(identifier));
// return this.convertToDocument(dbDoc);
// } catch (_error) {
// throw new NotFoundError("document not found");
// }

const store = diMainGet("store");
const state = store.getState();

const pub = state.opds.catalog.find((f) => f.identifier === identifier);

return pub;

}

public async findAll(): Promise<OpdsFeedDocument[]> {
// const result = await this.db.allDocs({
// include_docs: true,
// startkey: this.idPrefix + "_",
// endkey: this.idPrefix + "_\ufff0",
// });
// return result.rows.map((row) => {
// return this.convertToDocument(row.doc);
// });
const store = diMainGet("store");
const state = store.getState();

const docs = state.opds.catalog;

return docs;
}

public async delete(identifier: string): Promise<void> {
// const dbDoc = await this.db.get(this.buildId(identifier));
// await this.db.remove(dbDoc);
const store = diMainGet("store");

let unsub: Unsubscribe;
const p = new Promise<void>(
(res) => (unsub = store.subscribe(res)));
store.dispatch(opdsActions.deleteOpdsFeed.build(identifier));

await p.finally(() => unsub && unsub());
}


public async findAllFromPouchdb() {

const result = await this.db.allDocs({
include_docs: true,
startkey: this.idPrefix + "_",
endkey: this.idPrefix + "_\ufff0",
});
return result.rows.map((row) => {
return this.convertToDocument(row.doc);
});
}

protected convertToMinimalDocument(dbDoc: PouchDB.Core.Document<OpdsFeedDocument>): Timestampable & Identifiable {
return {
identifier: dbDoc.identifier,
createdAt: dbDoc.createdAt,
updatedAt: dbDoc.updatedAt,
} as Timestampable & Identifiable;
}

protected convertToDocument(dbDoc: PouchDB.Core.Document<OpdsFeedDocument>): OpdsFeedDocument {
return Object.assign(
{},
super.convertToMinimalDocument(dbDoc),
this.convertToMinimalDocument(dbDoc),
{
title: dbDoc.title,
url: dbDoc.url,
Expand Down
2 changes: 2 additions & 0 deletions src/main/redux/actions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@ import * as publicationActions from "./publication";
import * as sessionActions from "./session";
import * as streamerActions from "./streamer/";
import * as winActions from "./win";
import * as opdsActions from "./opds";

export {
opdsActions,
appActions,
lcpActions,
netActions,
Expand Down
34 changes: 34 additions & 0 deletions src/main/redux/actions/opds/addOpdsFeed.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// ==LICENSE-BEGIN==
// Copyright 2017 European Digital Reading Lab. All rights reserved.
// Licensed to the Readium Foundation under one or more contributor license agreements.
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file exposed on Github (readium) in the project repository.
// ==LICENSE-END==

import { nanoid } from "nanoid";
import { OpdsFeed } from "readium-desktop/common/models/opds";
import { Action } from "readium-desktop/common/models/redux";
import { OpdsFeedDocument } from "readium-desktop/main/db/document/opds";

export const ID = "OPDSFEED_ADD";

// eslint-disable-next-line @typescript-eslint/no-empty-interface
interface Payload extends Array<OpdsFeedDocument> {}

export function build(...feed: Array<OpdsFeedDocument | OpdsFeed>):
Action<typeof ID, Payload> {

const docs = feed.map<OpdsFeedDocument>((v) => ({
...v,
createdAt: (v as OpdsFeedDocument).createdAt || (new Date()).getTime(),
updatedAt: (new Date()).getTime(),
identifier: v.identifier || nanoid(),
}));

return {
type: ID,
payload: docs,
};
}
build.toString = () => ID; // Redux StringableActionCreator
export type TAction = ReturnType<typeof build>;
27 changes: 27 additions & 0 deletions src/main/redux/actions/opds/deleteOpdsFeed.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// ==LICENSE-BEGIN==
// Copyright 2017 European Digital Reading Lab. All rights reserved.
// Licensed to the Readium Foundation under one or more contributor license agreements.
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file exposed on Github (readium) in the project repository.
// ==LICENSE-END==

import { Action } from "readium-desktop/common/models/redux";

export const ID = "OPDSFEED_DELETE";

interface Payload {
identifier: string;
}

export function build(identifier: string):
Action<typeof ID, Payload> {

return {
type: ID,
payload: {
identifier,
},
};
}
build.toString = () => ID; // Redux StringableActionCreator
export type TAction = ReturnType<typeof build>;
14 changes: 14 additions & 0 deletions src/main/redux/actions/opds/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// ==LICENSE-BEGIN==
// Copyright 2017 European Digital Reading Lab. All rights reserved.
// Licensed to the Readium Foundation under one or more contributor license agreements.
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file exposed on Github (readium) in the project repository.
// ==LICENSE-END==

import * as deleteOpdsFeed from "./deleteOpdsFeed";
import * as addOpdsFeed from "./addOpdsFeed";

export {
deleteOpdsFeed,
addOpdsFeed,
};
1 change: 1 addition & 0 deletions src/main/redux/middleware/persistence.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export const reduxPersistMiddleware: Middleware
|| !ramda.equals(prevState.reader, nextState.reader)
|| !ramda.equals(prevState.session, nextState.session)
|| !ramda.equals(prevState.i18n, nextState.i18n)
|| !ramda.equals(prevState.opds, nextState.opds)
) {

// dispatch a new round in middleware
Expand Down
4 changes: 4 additions & 0 deletions src/main/redux/reducers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { winRegistryReaderReducer } from "./win/registry/reader";
import { winSessionLibraryReducer } from "./win/session/library";
import { winSessionReaderReducer } from "./win/session/reader";
import { winModeReducer } from "../../../common/redux/reducers/winModeReducer";
import { opdsDbReducers } from "./opds/db";

export const rootReducer = combineReducers<RootState>({
session: sessionReducer,
Expand Down Expand Up @@ -64,4 +65,7 @@ export const rootReducer = combineReducers<RootState>({
),
}),
keyboard: keyboardReducer,
opds: combineReducers({
catalog: opdsDbReducers,
}),
});
69 changes: 69 additions & 0 deletions src/main/redux/reducers/opds/db.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// ==LICENSE-BEGIN==
// Copyright 2017 European Digital Reading Lab. All rights reserved.
// Licensed to the Readium Foundation under one or more contributor license agreements.
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file exposed on Github (readium) in the project repository.
// ==LICENSE-END==

import { clone } from "ramda";
import { OpdsFeedDocument } from "readium-desktop/main/db/document/opds";
import { opdsActions } from "readium-desktop/main/redux/actions";

const initialState: OpdsFeedDocument[] = [];

export function opdsDbReducers(
state: OpdsFeedDocument[] = initialState,
action: opdsActions.addOpdsFeed.TAction
| opdsActions.deleteOpdsFeed.TAction,
): OpdsFeedDocument[] {
switch (action.type) {

case opdsActions.addOpdsFeed.ID: {

let newState = state;
for (const doc of action.payload) {

const { identifier } = doc;
const idx = newState.findIndex((v) => v.identifier === identifier);

const newDoc = clone(doc);
newDoc.doNotMigrateAnymore = true;

if (newState[idx]) {
newState = [
...newState.slice(0, idx),
...[
newDoc,
],
...newState.slice(idx + 1),
];
} else {
newState = [
...newState,
...[
newDoc,
],
];
}
}
return newState;
}

case opdsActions.deleteOpdsFeed.ID: {

const identifier = action.payload.identifier;
const idx = state.findIndex((v) => v.identifier === identifier);

if (state[idx]) {
return [
...state.slice(0, idx),
...state.slice(idx + 1),
];
}
return state;
}

default:
return state;
}
}
4 changes: 2 additions & 2 deletions src/main/redux/sagas/keyboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ function setShortcuts(action: keyboardActions.setShortcuts.TAction) {
debug("Keyboard shortcuts saving:", action.payload.shortcuts);
keyboardShortcuts.saveUser(action.payload.shortcuts);
} else {
debug("Keyboard shortcuts NOT saving (defaults):", action.payload.shortcuts);
debug("Keyboard shortcuts NOT saving (defaults):" /*action.payload.shortcuts*/);
}

}
Expand All @@ -44,7 +44,7 @@ function* keyboardReload(action: keyboardActions.reloadShortcuts.TAction) {
}
const okay = action.payload.defaults || keyboardShortcuts.loadUser();

debug(`Keyboard shortcuts reload JSON (defaults: ${action.payload.defaults}) => ${okay}`);
debug(`Keyboard shortcuts reload JSON (defaults: ${/*action.payload.defaults*/""}) => ${okay}`);

// if (DEBUG_KEYBOARD) {
// const jsonDiff = require("json-diff");
Expand Down
1 change: 1 addition & 0 deletions src/main/redux/sagas/persist.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ const persistStateToFs = async (nextState: RootState) => {
reader: nextState.reader,
session: nextState.session,
i18n: nextState.i18n,
opds: nextState.opds,
},
});
debug("end of persist reduxState in disk");
Expand Down
4 changes: 4 additions & 0 deletions src/main/redux/states/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import { ReaderConfig, ReaderMode } from "readium-desktop/common/models/reader";
import { I18NState } from "readium-desktop/common/redux/states/i18n";
import { KeyboardState } from "readium-desktop/common/redux/states/keyboard";
import { OpdsFeedDocument } from "readium-desktop/main/db/document/opds";
import { TPQueueState } from "readium-desktop/utils/redux-reducers/pqueue.reducer";

import { AppState } from "./app";
Expand Down Expand Up @@ -43,4 +44,7 @@ export interface RootState {
lastReadingQueue: TPQueueState;
};
keyboard: KeyboardState;
opds: {
catalog: OpdsFeedDocument[];
}
}
Loading

0 comments on commit 58ef86d

Please sign in to comment.