From 753a1c01156037e365ad8a4ba21237e6d725b125 Mon Sep 17 00:00:00 2001 From: Niels Date: Sun, 5 Apr 2020 16:55:50 +0200 Subject: [PATCH 1/4] Added the ability to see connectors that have been downloaded before (favorites) --- src/app/ElectronBootstrap.js | 3 +- .../frontend@classic-dark/connectors.html | 42 ++++++++++-- src/web/mjs/HakuNeko.mjs | 7 ++ src/web/mjs/engine/Favorites.mjs | 66 +++++++++++++++++++ 4 files changed, 111 insertions(+), 7 deletions(-) create mode 100644 src/web/mjs/engine/Favorites.mjs diff --git a/src/app/ElectronBootstrap.js b/src/app/ElectronBootstrap.js index d407140114..35067f9043 100644 --- a/src/app/ElectronBootstrap.js +++ b/src/app/ElectronBootstrap.js @@ -30,7 +30,8 @@ module.exports = class ElectronBootstrap { ]; this._directoryMap = { 'cache': this._configuration.applicationCacheDirectory, - 'plugins': this._configuration.applicationUserPluginsDirectory + 'plugins': this._configuration.applicationUserPluginsDirectory, + 'root': this._configuration.applicationUserDataDirectory }; this._appIcon; this._minimizeToTray = false; // only supported when tray is shown diff --git a/src/web/lib/hakuneko/frontend@classic-dark/connectors.html b/src/web/lib/hakuneko/frontend@classic-dark/connectors.html index ae4cfa9160..b13741ec9f 100644 --- a/src/web/lib/hakuneko/frontend@classic-dark/connectors.html +++ b/src/web/lib/hakuneko/frontend@classic-dark/connectors.html @@ -212,6 +212,34 @@ +
+
+ + +
+
+ +
+
@@ -248,14 +276,16 @@ this.popupVisibility = false; // list of all available connectors this.connectorList = []; + this.favoriteList = []; // load connectors this.set( 'connectorList', Engine.Connectors ); + this.set( 'favoriteList', Engine.Favorites ); this.tags = this.getAvailableTags(); this.selectedTags = []; } /** - * + * */ getAvailableTags() { let tags = this.connectorList.reduce( ( accumulator, connector ) => { @@ -322,7 +352,7 @@ evt.cancelBubble = true; evt.stopPropagation(); } - + /** * */ @@ -330,7 +360,7 @@ let item = evt.model.item; this._openLink(evt, item.url); } - + /** * */ @@ -338,7 +368,7 @@ let links = evt.model.item.links; this._openLink(evt, links ? links.login : undefined); } - + /** * */ @@ -348,7 +378,7 @@ } /** - * + * */ toggleTag( event ) { event.model.item.selected = !event.model.item.selected; @@ -402,7 +432,7 @@ } /** - * + * */ clearFilters() { this.tags.forEach( tag => tag.selected = false); diff --git a/src/web/mjs/HakuNeko.mjs b/src/web/mjs/HakuNeko.mjs index 981a926192..2c5eaef243 100644 --- a/src/web/mjs/HakuNeko.mjs +++ b/src/web/mjs/HakuNeko.mjs @@ -7,6 +7,7 @@ import BookmarkImporter from './engine/BookmarkImporter.mjs'; import BookmarkManager from './engine/BookmarkManager.mjs'; import ChaptermarkManager from './engine/ChaptermarkManager.mjs'; import Connectors from './engine/Connectors.mjs'; +import Favorites from './engine/Favorites.mjs'; import DownloadManager from './engine/DownloadManager.mjs'; //import HistoryWorker from './engine/HistoryWorker.mjs' import Request from './engine/Request.mjs'; @@ -29,6 +30,7 @@ export default class HakuNeko { this._settings = new Settings(); this._request = new Request(ipc, this._settings); this._connectors = new Connectors(ipc); + this._favorites = new Favorites(ipc); this._storage = new Storage(); this._bookmarkManager = new BookmarkManager(this._settings, new BookmarkImporter()); this._chaptermarkManager = new ChaptermarkManager(this._settings); @@ -51,6 +53,7 @@ export default class HakuNeko { async initialize() { await this._connectors.initialize(); + await this._favorites.initialize(); } get Blacklist() { @@ -69,6 +72,10 @@ export default class HakuNeko { return this._connectors.list; } + get Favorites() { + return this._favorites.list; + } + get DownloadManager() { return this._downloadManager; } diff --git a/src/web/mjs/engine/Favorites.mjs b/src/web/mjs/engine/Favorites.mjs new file mode 100644 index 0000000000..4c2be0cfaa --- /dev/null +++ b/src/web/mjs/engine/Favorites.mjs @@ -0,0 +1,66 @@ +export default class Favorites { + + constructor(ipc) { + ipc.listen('on-connector-protocol-handler', this._onConnectorProtocolHandler.bind(this)); + this._list = []; + } + + async _loadPlugins(uri) { + try { + let response = await fetch(uri); + let data = await response.json(); + let cc = data.filter(plugin => plugin.startsWith('hakuneko.mangas.')); + let connectorName = []; + cc.forEach(file => { + let name = file.substr(file.indexOf('.', 15)+1); + connectorName.push("hakuneko://cache/mjs/connectors/" + name + ".mjs"); + }); + return connectorName; + } catch(error) { + //console.warn(error); + return []; + } + } + + async initialize() { + let favoritePlugins = await this._loadPlugins('hakuneko://root/'); + await this.register(favoritePlugins); + } + + get list() { + return this._list; + } + + async register(files) { + try { + for(let file of files) { + try { + let module = await import(file); + let connector = new module.default(); + if(this._list.find(c => c.id === connector.id)) { + console.warn(`The connector "${connector.label}" with ID "${connector.id}" is already registered`); + } else { + this._list.push(connector); + } + } catch(error) { + console.warn(`Failed to load connector "${file}"`, error); + } + } + this._list.sort( ( a, b ) => { + return ( a.label.toLowerCase() < b.label.toLowerCase() ? -1 : 1 ); + } ); + } catch(error) { + console.warn(`Failed to load connector`, error); + } + } + + async _onConnectorProtocolHandler(request) { + try { + let uri = new URL(request.url); + return this._list.find(connector => connector.id === uri.hostname).handleConnectorURI(uri); + } catch(error) { + console.error(error); + return undefined; + } + } +} \ No newline at end of file From 0a3a65756dfe413dbc95adb4df5fdb155698b4fe Mon Sep 17 00:00:00 2001 From: Strengers Date: Tue, 7 Apr 2020 11:51:38 +0200 Subject: [PATCH 2/4] started implementing changes based on ronny his feedback, wip --- .../frontend@classic-dark/connectors.html | 2 +- src/web/mjs/HakuNeko.mjs | 2 +- src/web/mjs/engine/Connectors.mjs | 7 +++++++ src/web/mjs/engine/Storage.mjs | 17 +++++++++++++++++ 4 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/web/lib/hakuneko/frontend@classic-dark/connectors.html b/src/web/lib/hakuneko/frontend@classic-dark/connectors.html index b13741ec9f..0dc44372d8 100644 --- a/src/web/lib/hakuneko/frontend@classic-dark/connectors.html +++ b/src/web/lib/hakuneko/frontend@classic-dark/connectors.html @@ -279,7 +279,7 @@ this.favoriteList = []; // load connectors this.set( 'connectorList', Engine.Connectors ); - this.set( 'favoriteList', Engine.Favorites ); + this.set( 'favoriteList', Engine.Storage.downloadedConnectors ); this.tags = this.getAvailableTags(); this.selectedTags = []; } diff --git a/src/web/mjs/HakuNeko.mjs b/src/web/mjs/HakuNeko.mjs index 2c5eaef243..64c161cbee 100644 --- a/src/web/mjs/HakuNeko.mjs +++ b/src/web/mjs/HakuNeko.mjs @@ -73,7 +73,7 @@ export default class HakuNeko { } get Favorites() { - return this._favorites.list; + return this._connectors.favoriteList; } get DownloadManager() { diff --git a/src/web/mjs/engine/Connectors.mjs b/src/web/mjs/engine/Connectors.mjs index ee6d094555..893480a04c 100644 --- a/src/web/mjs/engine/Connectors.mjs +++ b/src/web/mjs/engine/Connectors.mjs @@ -3,6 +3,7 @@ export default class Connectors { constructor(ipc) { ipc.listen('on-connector-protocol-handler', this._onConnectorProtocolHandler.bind(this)); this._list = []; + this._favList = []; } async _loadPlugins(uri) { @@ -24,16 +25,22 @@ export default class Connectors { ]; let userPlugins = await this._loadPlugins('hakuneko://plugins/'); let internalPlugins = await this._loadPlugins('hakuneko://cache/mjs/connectors/'); + let favoritePlugins = Storage.downloadedConnectors; await this.register(systemPlugins); await this.register(userPlugins); await this.register(internalPlugins); + await this.register(favoritePlugins); } get list() { return this._list; } + get favoriteList() { + return this._favList; + } + async register(files) { try { for(let file of files) { diff --git a/src/web/mjs/engine/Storage.mjs b/src/web/mjs/engine/Storage.mjs index 4eb5446310..9a3f957664 100644 --- a/src/web/mjs/engine/Storage.mjs +++ b/src/web/mjs/engine/Storage.mjs @@ -30,6 +30,7 @@ export default class Storage { this.fs = require( 'fs' ); this.path = require( 'path' ); this.config = this.path.join( electron.remote.app.getPath( 'userData' ), 'hakuneko.' ); + this.root = electron.remote.app.getPath( 'userData'); this.temp = this.path.join( require( 'os' ).tmpdir(), 'hakuneko' ); this._createDirectoryChain( this.temp ); @@ -911,4 +912,20 @@ export default class Storage { } ); } ); } + + get downloadedConnectors() { + //since this is a async function, isn't hakuneko startup waiting for this to be ran first? + //seems like performance drain + let rootDirectoryEntries = this._readDirectoryEntries(this.root); + let arrayFiltered = []; + rootDirectoryEntries.then(function(arrayRaw){ + arrayRaw = arrayRaw.filter(plugin => plugin.startsWith('hakuneko.mangas.')); + arrayRaw.forEach(file => { + arrayFiltered.push(file.substr(file.indexOf('.', 15)+1)); + }); + return arrayFiltered; + }) + + + } } \ No newline at end of file From e1996683769dcc6166f2094fe432c9469eec8cfc Mon Sep 17 00:00:00 2001 From: Niels Date: Tue, 7 Apr 2020 13:30:51 +0200 Subject: [PATCH 3/4] working version based on received feedback, review needed --- src/app/ElectronBootstrap.js | 3 +- .../frontend@classic-dark/connectors.html | 4 +- src/web/mjs/HakuNeko.mjs | 6 +- src/web/mjs/engine/Connectors.mjs | 35 ++++++++-- src/web/mjs/engine/Favorites.mjs | 66 ------------------- src/web/mjs/engine/Storage.mjs | 10 ++- 6 files changed, 38 insertions(+), 86 deletions(-) delete mode 100644 src/web/mjs/engine/Favorites.mjs diff --git a/src/app/ElectronBootstrap.js b/src/app/ElectronBootstrap.js index 35067f9043..d407140114 100644 --- a/src/app/ElectronBootstrap.js +++ b/src/app/ElectronBootstrap.js @@ -30,8 +30,7 @@ module.exports = class ElectronBootstrap { ]; this._directoryMap = { 'cache': this._configuration.applicationCacheDirectory, - 'plugins': this._configuration.applicationUserPluginsDirectory, - 'root': this._configuration.applicationUserDataDirectory + 'plugins': this._configuration.applicationUserPluginsDirectory }; this._appIcon; this._minimizeToTray = false; // only supported when tray is shown diff --git a/src/web/lib/hakuneko/frontend@classic-dark/connectors.html b/src/web/lib/hakuneko/frontend@classic-dark/connectors.html index 0dc44372d8..166e05c95a 100644 --- a/src/web/lib/hakuneko/frontend@classic-dark/connectors.html +++ b/src/web/lib/hakuneko/frontend@classic-dark/connectors.html @@ -279,9 +279,11 @@ this.favoriteList = []; // load connectors this.set( 'connectorList', Engine.Connectors ); - this.set( 'favoriteList', Engine.Storage.downloadedConnectors ); + this.set( 'favoriteList', Engine.Favorites ); this.tags = this.getAvailableTags(); this.selectedTags = []; + console.log(this.connectorList); + console.log(this.favoriteList); } /** diff --git a/src/web/mjs/HakuNeko.mjs b/src/web/mjs/HakuNeko.mjs index 64c161cbee..1a2ebc0766 100644 --- a/src/web/mjs/HakuNeko.mjs +++ b/src/web/mjs/HakuNeko.mjs @@ -7,7 +7,6 @@ import BookmarkImporter from './engine/BookmarkImporter.mjs'; import BookmarkManager from './engine/BookmarkManager.mjs'; import ChaptermarkManager from './engine/ChaptermarkManager.mjs'; import Connectors from './engine/Connectors.mjs'; -import Favorites from './engine/Favorites.mjs'; import DownloadManager from './engine/DownloadManager.mjs'; //import HistoryWorker from './engine/HistoryWorker.mjs' import Request from './engine/Request.mjs'; @@ -23,14 +22,12 @@ export default class HakuNeko { this._version = Version; this._enums = Enums; - let ipc = new InterProcessCommunication(); this._blacklist = new Blacklist(); this._downloadManager = new DownloadManager(); this._settings = new Settings(); this._request = new Request(ipc, this._settings); this._connectors = new Connectors(ipc); - this._favorites = new Favorites(ipc); this._storage = new Storage(); this._bookmarkManager = new BookmarkManager(this._settings, new BookmarkImporter()); this._chaptermarkManager = new ChaptermarkManager(this._settings); @@ -53,7 +50,6 @@ export default class HakuNeko { async initialize() { await this._connectors.initialize(); - await this._favorites.initialize(); } get Blacklist() { @@ -73,7 +69,7 @@ export default class HakuNeko { } get Favorites() { - return this._connectors.favoriteList; + return this._connectors.favlist; } get DownloadManager() { diff --git a/src/web/mjs/engine/Connectors.mjs b/src/web/mjs/engine/Connectors.mjs index 893480a04c..e70d7f2bcf 100644 --- a/src/web/mjs/engine/Connectors.mjs +++ b/src/web/mjs/engine/Connectors.mjs @@ -3,7 +3,7 @@ export default class Connectors { constructor(ipc) { ipc.listen('on-connector-protocol-handler', this._onConnectorProtocolHandler.bind(this)); this._list = []; - this._favList = []; + this._favlist = []; } async _loadPlugins(uri) { @@ -25,20 +25,20 @@ export default class Connectors { ]; let userPlugins = await this._loadPlugins('hakuneko://plugins/'); let internalPlugins = await this._loadPlugins('hakuneko://cache/mjs/connectors/'); - let favoritePlugins = Storage.downloadedConnectors; + let favoritePlugins = Engine.Storage.downloadedConnectors; await this.register(systemPlugins); await this.register(userPlugins); await this.register(internalPlugins); - await this.register(favoritePlugins); + await this.registerfav(favoritePlugins); } get list() { return this._list; } - get favoriteList() { - return this._favList; + get favlist() { + return this._favlist; } async register(files) { @@ -63,7 +63,30 @@ export default class Connectors { console.warn(`Failed to load connector`, error); } } - + + async registerfav(files) { + try { + for(let file of files) { + try { + let module = await import(file); + let connector = new module.default(); + if(this._favlist.find(c => c.id === connector.id)) { + console.warn(`The connector "${connector.label}" with ID "${connector.id}" is already registered`); + } else { + this._favlist.push(connector); + } + } catch(error) { + console.warn(`Failed to load connector "${file}"`, error); + } + } + this._favlist.sort( ( a, b ) => { + return ( a.label.toLowerCase() < b.label.toLowerCase() ? -1 : 1 ); + } ); + } catch(error) { + console.warn(`Failed to load connector`, error); + } + } + async _onConnectorProtocolHandler(request) { try { let uri = new URL(request.url); diff --git a/src/web/mjs/engine/Favorites.mjs b/src/web/mjs/engine/Favorites.mjs deleted file mode 100644 index 4c2be0cfaa..0000000000 --- a/src/web/mjs/engine/Favorites.mjs +++ /dev/null @@ -1,66 +0,0 @@ -export default class Favorites { - - constructor(ipc) { - ipc.listen('on-connector-protocol-handler', this._onConnectorProtocolHandler.bind(this)); - this._list = []; - } - - async _loadPlugins(uri) { - try { - let response = await fetch(uri); - let data = await response.json(); - let cc = data.filter(plugin => plugin.startsWith('hakuneko.mangas.')); - let connectorName = []; - cc.forEach(file => { - let name = file.substr(file.indexOf('.', 15)+1); - connectorName.push("hakuneko://cache/mjs/connectors/" + name + ".mjs"); - }); - return connectorName; - } catch(error) { - //console.warn(error); - return []; - } - } - - async initialize() { - let favoritePlugins = await this._loadPlugins('hakuneko://root/'); - await this.register(favoritePlugins); - } - - get list() { - return this._list; - } - - async register(files) { - try { - for(let file of files) { - try { - let module = await import(file); - let connector = new module.default(); - if(this._list.find(c => c.id === connector.id)) { - console.warn(`The connector "${connector.label}" with ID "${connector.id}" is already registered`); - } else { - this._list.push(connector); - } - } catch(error) { - console.warn(`Failed to load connector "${file}"`, error); - } - } - this._list.sort( ( a, b ) => { - return ( a.label.toLowerCase() < b.label.toLowerCase() ? -1 : 1 ); - } ); - } catch(error) { - console.warn(`Failed to load connector`, error); - } - } - - async _onConnectorProtocolHandler(request) { - try { - let uri = new URL(request.url); - return this._list.find(connector => connector.id === uri.hostname).handleConnectorURI(uri); - } catch(error) { - console.error(error); - return undefined; - } - } -} \ No newline at end of file diff --git a/src/web/mjs/engine/Storage.mjs b/src/web/mjs/engine/Storage.mjs index 9a3f957664..e7e38a443a 100644 --- a/src/web/mjs/engine/Storage.mjs +++ b/src/web/mjs/engine/Storage.mjs @@ -918,14 +918,12 @@ export default class Storage { //seems like performance drain let rootDirectoryEntries = this._readDirectoryEntries(this.root); let arrayFiltered = []; - rootDirectoryEntries.then(function(arrayRaw){ + rootDirectoryEntries.then(function(arrayRaw) { arrayRaw = arrayRaw.filter(plugin => plugin.startsWith('hakuneko.mangas.')); arrayRaw.forEach(file => { - arrayFiltered.push(file.substr(file.indexOf('.', 15)+1)); + arrayFiltered.push('hakuneko://cache/mjs/connectors/' + file.substr(file.indexOf('.', 15)+1) + '.mjs'); }); - return arrayFiltered; - }) - - + }); + return arrayFiltered; } } \ No newline at end of file From cf345bb72382290da888708b0632058d2987e378 Mon Sep 17 00:00:00 2001 From: Niels Date: Tue, 7 Apr 2020 14:43:30 +0200 Subject: [PATCH 4/4] clean up and light theme --- .../frontend@classic-dark/connectors.html | 2 - .../frontend@classic-light/connectors.html | 42 ++++++++++++++++--- 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/src/web/lib/hakuneko/frontend@classic-dark/connectors.html b/src/web/lib/hakuneko/frontend@classic-dark/connectors.html index 166e05c95a..b13741ec9f 100644 --- a/src/web/lib/hakuneko/frontend@classic-dark/connectors.html +++ b/src/web/lib/hakuneko/frontend@classic-dark/connectors.html @@ -282,8 +282,6 @@ this.set( 'favoriteList', Engine.Favorites ); this.tags = this.getAvailableTags(); this.selectedTags = []; - console.log(this.connectorList); - console.log(this.favoriteList); } /** diff --git a/src/web/lib/hakuneko/frontend@classic-light/connectors.html b/src/web/lib/hakuneko/frontend@classic-light/connectors.html index ae4cfa9160..b13741ec9f 100644 --- a/src/web/lib/hakuneko/frontend@classic-light/connectors.html +++ b/src/web/lib/hakuneko/frontend@classic-light/connectors.html @@ -212,6 +212,34 @@ +
+
+ + +
+
+ +
+
@@ -248,14 +276,16 @@ this.popupVisibility = false; // list of all available connectors this.connectorList = []; + this.favoriteList = []; // load connectors this.set( 'connectorList', Engine.Connectors ); + this.set( 'favoriteList', Engine.Favorites ); this.tags = this.getAvailableTags(); this.selectedTags = []; } /** - * + * */ getAvailableTags() { let tags = this.connectorList.reduce( ( accumulator, connector ) => { @@ -322,7 +352,7 @@ evt.cancelBubble = true; evt.stopPropagation(); } - + /** * */ @@ -330,7 +360,7 @@ let item = evt.model.item; this._openLink(evt, item.url); } - + /** * */ @@ -338,7 +368,7 @@ let links = evt.model.item.links; this._openLink(evt, links ? links.login : undefined); } - + /** * */ @@ -348,7 +378,7 @@ } /** - * + * */ toggleTag( event ) { event.model.item.selected = !event.model.item.selected; @@ -402,7 +432,7 @@ } /** - * + * */ clearFilters() { this.tags.forEach( tag => tag.selected = false);