Chore+Refactor: Replace `nedb` package with `nedb-promises`

The 'nedb' package is unmaintained (last update was 5 years ago) and
has a couple of high severity vulnerabilities.

In addition, the use of callbacks is somewhat cumbersome for
the project's current workflow.

Therefore, I've decided to replace it with the 'nedb-promises' package,
which, internally, makes use of a maintained fork of 'nedb' and
wraps its API with Promises.
This commit is contained in:
Svallinn 2021-06-17 04:16:52 +01:00
parent 73c198a30c
commit be11e3d8cb
No known key found for this signature in database
GPG Key ID: 09FB527F34037CCA
8 changed files with 329 additions and 399 deletions

55
package-lock.json generated
View File

@ -3577,6 +3577,21 @@
"fastq": "^1.6.0" "fastq": "^1.6.0"
} }
}, },
"@seald-io/binary-search-tree": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@seald-io/binary-search-tree/-/binary-search-tree-1.0.2.tgz",
"integrity": "sha512-+pYGvPFAk7wUR+ONMOlc6A+LUN4kOCFwyPLjyaeS7wVibADPHWYJNYsNtyIAwjF1AXQkuaXElnIc4XjKt55QZA=="
},
"@seald-io/nedb": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/@seald-io/nedb/-/nedb-2.0.3.tgz",
"integrity": "sha512-NLnaDav050gnAMM8mnKQE9oH3F9RzGdKornukxLJ7BCf2YXEWndTf3Bmd+1mOqFs5DZnTY0SRigIwVXd8L39Xg==",
"requires": {
"@seald-io/binary-search-tree": "^1.0.2",
"async": "0.2.10",
"localforage": "^1.9.0"
}
},
"@silvermine/videojs-quality-selector": { "@silvermine/videojs-quality-selector": {
"version": "1.2.5", "version": "1.2.5",
"resolved": "https://registry.npmjs.org/@silvermine/videojs-quality-selector/-/videojs-quality-selector-1.2.5.tgz", "resolved": "https://registry.npmjs.org/@silvermine/videojs-quality-selector/-/videojs-quality-selector-1.2.5.tgz",
@ -5449,21 +5464,6 @@
"integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
"dev": true "dev": true
}, },
"binary-search-tree": {
"version": "0.2.5",
"resolved": "https://registry.npmjs.org/binary-search-tree/-/binary-search-tree-0.2.5.tgz",
"integrity": "sha1-fbs7IQ/coIJFDa0jNMMErzm9x4Q=",
"requires": {
"underscore": "~1.4.4"
},
"dependencies": {
"underscore": {
"version": "1.4.4",
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.4.4.tgz",
"integrity": "sha1-YaajIBBiKvoHljvzJSA88SI51gQ="
}
}
},
"bindings": { "bindings": {
"version": "1.5.0", "version": "1.5.0",
"resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
@ -12841,7 +12841,8 @@
"minimist": { "minimist": {
"version": "1.2.5", "version": "1.2.5",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
"dev": true
}, },
"minipass": { "minipass": {
"version": "3.1.3", "version": "3.1.3",
@ -12887,6 +12888,7 @@
"version": "0.5.5", "version": "0.5.5",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
"integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
"dev": true,
"requires": { "requires": {
"minimist": "^1.2.5" "minimist": "^1.2.5"
} }
@ -12988,23 +12990,12 @@
"integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
"dev": true "dev": true
}, },
"nedb": { "nedb-promises": {
"version": "1.8.0", "version": "5.0.0",
"resolved": "https://registry.npmjs.org/nedb/-/nedb-1.8.0.tgz", "resolved": "https://registry.npmjs.org/nedb-promises/-/nedb-promises-5.0.0.tgz",
"integrity": "sha1-DjUCzYLABNU1WkPJ5VV3vXvZHYg=", "integrity": "sha512-PZ+V+1RScHr3mZHflAMMkx35naGHKVVGtqLwdK2aado7uN2HcIcubiaVlE/X8BTa34RnIHmusVM+VeTj/pnfew==",
"requires": { "requires": {
"async": "0.2.10", "@seald-io/nedb": "^2.0.3"
"binary-search-tree": "0.2.5",
"localforage": "^1.3.0",
"mkdirp": "~0.5.1",
"underscore": "~1.4.4"
},
"dependencies": {
"underscore": {
"version": "1.4.4",
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.4.4.tgz",
"integrity": "sha1-YaajIBBiKvoHljvzJSA88SI51gQ="
}
} }
}, },
"needle": { "needle": {

View File

@ -26,7 +26,7 @@
"lodash.uniqwith": "^4.5.0", "lodash.uniqwith": "^4.5.0",
"marked": "^2.1.1", "marked": "^2.1.1",
"material-design-icons": "^3.0.1", "material-design-icons": "^3.0.1",
"nedb": "^1.8.0", "nedb-promises": "^5.0.0",
"node-forge": "^0.10.0", "node-forge": "^0.10.0",
"opml-to-json": "^1.0.1", "opml-to-json": "^1.0.1",
"rss-parser": "^3.12.0", "rss-parser": "^3.12.0",

View File

@ -2,7 +2,7 @@ import {
app, BrowserWindow, dialog, Menu, ipcMain, app, BrowserWindow, dialog, Menu, ipcMain,
powerSaveBlocker, screen, session, shell powerSaveBlocker, screen, session, shell
} from 'electron' } from 'electron'
import Datastore from 'nedb' import Datastore from 'nedb-promises'
import path from 'path' import path from 'path'
import cp from 'child_process' import cp from 'child_process'
@ -23,7 +23,7 @@ function runApp() {
const localDataStorage = app.getPath('userData') // Grabs the userdata directory based on the user's OS const localDataStorage = app.getPath('userData') // Grabs the userdata directory based on the user's OS
const settingsDb = new Datastore({ const settingsDb = Datastore.create({
filename: localDataStorage + '/settings.db', filename: localDataStorage + '/settings.db',
autoload: true autoload: true
}) })
@ -83,86 +83,88 @@ function runApp() {
}) })
} }
app.on('ready', (_, __) => { app.on('ready', async (_, __) => {
settingsDb.find({ let docArray
$or: [ try {
{ _id: 'disableSmoothScrolling' }, docArray = await settingsDb.find({
{ _id: 'useProxy' }, $or: [
{ _id: 'proxyProtocol' }, { _id: 'disableSmoothScrolling' },
{ _id: 'proxyHostname' }, { _id: 'useProxy' },
{ _id: 'proxyPort' } { _id: 'proxyProtocol' },
] { _id: 'proxyHostname' },
}, function (err, doc) { { _id: 'proxyPort' }
if (err) { ]
app.exit()
return
}
let disableSmoothScrolling = false
let useProxy = false
let proxyProtocol = 'socks5'
let proxyHostname = '127.0.0.1'
let proxyPort = '9050'
if (typeof doc === 'object' && doc.length > 0) {
doc.forEach((dbItem) => {
switch (dbItem._id) {
case 'disableSmoothScrolling':
disableSmoothScrolling = dbItem.value
break
case 'useProxy':
useProxy = dbItem.value
break
case 'proxyProtocol':
proxyProtocol = dbItem.value
break
case 'proxyHostname':
proxyHostname = dbItem.value
break
case 'proxyPort':
proxyPort = dbItem.value
break
}
})
}
if (disableSmoothScrolling) {
app.commandLine.appendSwitch('disable-smooth-scrolling')
} else {
app.commandLine.appendSwitch('enable-smooth-scrolling')
}
if (useProxy) {
session.defaultSession.setProxy({
proxyRules: `${proxyProtocol}://${proxyHostname}:${proxyPort}`
})
}
// Set CONSENT cookie on reasonable domains
const consentCookieDomains = [
'http://www.youtube.com',
'https://www.youtube.com',
'http://youtube.com',
'https://youtube.com'
]
consentCookieDomains.forEach(url => {
session.defaultSession.cookies.set({
url: url,
name: 'CONSENT',
value: 'YES+'
})
}) })
} catch (err) {
console.error(err)
app.exit()
return
}
createWindow() let disableSmoothScrolling = false
let useProxy = false
let proxyProtocol = 'socks5'
let proxyHostname = '127.0.0.1'
let proxyPort = '9050'
if (isDev) { if (docArray?.length > 0) {
installDevTools() docArray.forEach((doc) => {
} switch (doc._id) {
case 'disableSmoothScrolling':
disableSmoothScrolling = doc.value
break
case 'useProxy':
useProxy = doc.value
break
case 'proxyProtocol':
proxyProtocol = doc.value
break
case 'proxyHostname':
proxyHostname = doc.value
break
case 'proxyPort':
proxyPort = doc.value
break
}
})
}
if (isDebug) { if (disableSmoothScrolling) {
mainWindow.webContents.openDevTools() app.commandLine.appendSwitch('disable-smooth-scrolling')
} } else {
app.commandLine.appendSwitch('enable-smooth-scrolling')
}
if (useProxy) {
session.defaultSession.setProxy({
proxyRules: `${proxyProtocol}://${proxyHostname}:${proxyPort}`
})
}
// Set CONSENT cookie on reasonable domains
const consentCookieDomains = [
'http://www.youtube.com',
'https://www.youtube.com',
'http://youtube.com',
'https://youtube.com'
]
consentCookieDomains.forEach(url => {
session.defaultSession.cookies.set({
url: url,
name: 'CONSENT',
value: 'YES+'
})
}) })
await createWindow()
if (isDev) {
installDevTools()
}
if (isDebug) {
mainWindow.webContents.openDevTools()
}
}) })
async function installDevTools() { async function installDevTools() {
@ -175,7 +177,7 @@ function runApp() {
} }
} }
function createWindow(replaceMainWindow = true) { async function createWindow(replaceMainWindow = true) {
/** /**
* Initial window options * Initial window options
*/ */
@ -206,18 +208,9 @@ function runApp() {
height: 800 height: 800
}) })
settingsDb.findOne({ const boundsDoc = await settingsDb.findOne({ _id: 'bounds' })
_id: 'bounds' if (typeof boundsDoc?.value === 'object') {
}, function (err, doc) { const { maximized, ...bounds } = boundsDoc.value
if (doc === null || err) {
return
}
if (typeof doc !== 'object' || typeof doc.value !== 'object') {
return
}
const { maximized, ...bounds } = doc.value
const allDisplaysSummaryWidth = screen const allDisplaysSummaryWidth = screen
.getAllDisplays() .getAllDisplays()
.reduce((accumulator, { size: { width } }) => accumulator + width, 0) .reduce((accumulator, { size: { width } }) => accumulator + width, 0)
@ -233,7 +226,7 @@ function runApp() {
if (maximized) { if (maximized) {
newWindow.maximize() newWindow.maximize()
} }
}) }
// If called multiple times // If called multiple times
// Duplicate menu items will be added // Duplicate menu items will be added
@ -274,18 +267,19 @@ function runApp() {
} }
// Save closing window bounds & maximized status // Save closing window bounds & maximized status
ipcMain.on('setBounds', (event) => { ipcMain.on('setBounds', async (event) => {
const value = { const value = {
...mainWindow.getNormalBounds(), ...mainWindow.getNormalBounds(),
maximized: mainWindow.isMaximized() maximized: mainWindow.isMaximized()
} }
settingsDb.update( await settingsDb.update(
{ _id: 'bounds' }, { _id: 'bounds' },
{ _id: 'bounds', value }, { _id: 'bounds', value },
{ upsert: true }, { upsert: true }
() => { event.returnValue = 0 }
) )
event.returnValue = 0
}) })
ipcMain.on('appReady', () => { ipcMain.on('appReady', () => {

View File

@ -1,4 +1,4 @@
import Datastore from 'nedb' import Datastore from 'nedb-promises'
// Initialize all datastores and export their references // Initialize all datastores and export their references
// Current dbs: // Current dbs:
@ -7,36 +7,34 @@ import Datastore from 'nedb'
// `playlists.db` // `playlists.db`
// `history.db` // `history.db`
let buildFileName = null
// Check if using Electron // Check if using Electron
let userDataPath
const usingElectron = window?.process?.type === 'renderer' const usingElectron = window?.process?.type === 'renderer'
if (usingElectron) { if (usingElectron) {
const { ipcRenderer } = require('electron') const { ipcRenderer } = require('electron')
userDataPath = ipcRenderer.sendSync('getUserDataPathSync') const userDataPath = ipcRenderer.sendSync('getUserDataPathSync')
buildFileName = (dbName) => userDataPath + '/' + dbName + '.db'
} else {
buildFileName = (dbName) => dbName + '.db'
} }
const buildFileName = (dbName) => { const settingsDb = Datastore.create({
return usingElectron
? userDataPath + '/' + dbName + '.db'
: dbName + '.db'
}
const settingsDb = new Datastore({
filename: buildFileName('settings'), filename: buildFileName('settings'),
autoload: true autoload: true
}) })
const playlistsDb = new Datastore({ const playlistsDb = Datastore.create({
filename: buildFileName('playlists'), filename: buildFileName('playlists'),
autoload: true autoload: true
}) })
const profilesDb = new Datastore({ const profilesDb = Datastore.create({
filename: buildFileName('profiles'), filename: buildFileName('profiles'),
autoload: true autoload: true
}) })
const historyDb = new Datastore({ const historyDb = Datastore.create({
filename: buildFileName('history'), filename: buildFileName('history'),
autoload: true autoload: true
}) })

View File

@ -11,57 +11,46 @@ const getters = {
} }
const actions = { const actions = {
grabHistory ({ commit }) { async grabHistory({ commit }) {
historyDb.find({}).sort({ const results = await historyDb.find({}).sort({ timeWatched: -1 })
timeWatched: -1 commit('setHistoryCache', results)
}).exec((err, results) => {
if (err) {
console.log(err)
return
}
commit('setHistoryCache', results)
})
}, },
updateHistory ({ dispatch }, videoData) { async updateHistory({ dispatch }, videoData) {
historyDb.update({ videoId: videoData.videoId }, videoData, { upsert: true }, (err, numReplaced) => { await historyDb.update(
if (!err) { { videoId: videoData.videoId },
dispatch('grabHistory') videoData,
} { upsert: true }
}) )
dispatch('grabHistory')
}, },
removeFromHistory ({ dispatch }, videoId) { async removeFromHistory({ dispatch }, videoId) {
historyDb.remove({ videoId: videoId }, (err, numReplaced) => { await historyDb.remove({ videoId: videoId })
if (!err) { dispatch('grabHistory')
dispatch('grabHistory')
}
})
}, },
removeAllHistory ({ dispatch }) { async removeAllHistory({ dispatch }) {
historyDb.remove({}, { multi: true }, (err, numReplaced) => { await historyDb.remove({}, { multi: true })
if (!err) { dispatch('grabHistory')
dispatch('grabHistory')
}
})
}, },
updateWatchProgress ({ dispatch }, videoData) { async updateWatchProgress({ dispatch }, videoData) {
historyDb.update({ videoId: videoData.videoId }, { $set: { watchProgress: videoData.watchProgress } }, { upsert: true }, (err, numReplaced) => { await historyDb.update(
if (!err) { { videoId: videoData.videoId },
dispatch('grabHistory') { $set: { watchProgress: videoData.watchProgress } },
} { upsert: true }
}) )
dispatch('grabHistory')
}, },
compactHistory (_) { compactHistory(_) {
historyDb.persistence.compactDatafile() historyDb.persistence.compactDatafile()
} }
} }
const mutations = { const mutations = {
setHistoryCache (state, historyCache) { setHistoryCache(state, historyCache) {
state.historyCache = historyCache state.historyCache = historyCache
} }
} }

View File

@ -24,156 +24,146 @@ const getters = {
} }
const actions = { const actions = {
addPlaylist ({ commit }, payload) { async addPlaylist({ commit }, payload) {
playlistsDb.insert(payload, (err, payload) => { await playlistsDb.insert(payload)
if (err) { commit('addPlaylist', payload)
console.error(err)
} else {
commit('addPlaylist', payload)
}
})
}, },
addPlaylists ({ commit }, payload) {
playlistsDb.insert(payload, (err, payload) => { async addPlaylists({ commit }, payload) {
if (err) { await playlistsDb.insert(payload)
console.error(err) commit('addPlaylists', payload)
} else {
commit('addPlaylists', payload)
}
})
}, },
addVideo ({ commit }, payload) {
playlistsDb.update({ playlistName: payload.playlistName }, { $push: { videos: payload.videoData } }, { upsert: true }, err => { async addVideo({ commit }, payload) {
if (err) { await playlistsDb.update(
console.error(err) { playlistName: payload.playlistName },
} else { { $push: { videos: payload.videoData } },
commit('addVideo', payload) { upsert: true }
} )
}) commit('addVideo', payload)
}, },
addVideos ({ commit }, payload) {
playlistsDb.update({ _id: payload.playlistId }, { $push: { videos: { $each: payload.videosIds } } }, { upsert: true }, err => { async addVideos({ commit }, payload) {
if (err) { await playlistsDb.update(
console.error(err) { _id: payload.playlistId },
} else { { $push: { videos: { $each: payload.videosIds } } },
commit('addVideos', payload) { upsert: true }
} )
}) commit('addVideos', payload)
}, },
grabAllPlaylists({ commit, dispatch }) {
playlistsDb.find({}, (err, payload) => { async grabAllPlaylists({ commit, dispatch }) {
if (err) { const payload = await playlistsDb.find({})
console.error(err) if (payload.length === 0) {
} else { commit('setAllPlaylists', state.playlists)
if (payload.length === 0) { dispatch('addPlaylists', payload)
commit('setAllPlaylists', state.playlists) } else {
dispatch('addPlaylists', payload) commit('setAllPlaylists', payload)
} else { }
commit('setAllPlaylists', payload)
}
}
})
}, },
removeAllPlaylists ({ commit }) {
playlistsDb.remove({ protected: { $ne: true } }, err => { async removeAllPlaylists({ commit }) {
if (err) { await playlistsDb.remove({ protected: { $ne: true } })
console.error(err) commit('removeAllPlaylists')
} else {
commit('removeAllPlaylists')
}
})
}, },
removeAllVideos ({ commit }, playlistName) {
playlistsDb.update({ playlistName: playlistName }, { $set: { videos: [] } }, { upsert: true }, err => { async removeAllVideos({ commit }, playlistName) {
if (err) { await playlistsDb.update(
console.error(err) { playlistName: playlistName },
} else { { $set: { videos: [] } },
commit('removeAllVideos', playlistName) { upsert: true }
} )
}) commit('removeAllVideos', playlistName)
}, },
removePlaylist ({ commit }, playlistId) {
playlistsDb.remove({ _id: playlistId, protected: { $ne: true } }, (err, playlistId) => { async removePlaylist({ commit }, playlistId) {
if (err) { await playlistsDb.remove({
console.error(err) _id: playlistId,
} else { protected: { $ne: true }
commit('removePlaylist', playlistId)
}
}) })
commit('removePlaylist', playlistId)
}, },
removePlaylists ({ commit }, playlistIds) {
playlistsDb.remove({ _id: { $in: playlistIds }, protected: { $ne: true } }, (err, playlistIds) => { async removePlaylists({ commit }, playlistIds) {
if (err) { await playlistsDb.remove({
console.error(err) _id: { $in: playlistIds },
} else { protected: { $ne: true }
commit('removePlaylists', playlistIds)
}
}) })
commit('removePlaylists', playlistIds)
}, },
removeVideo ({ commit }, payload) {
playlistsDb.update({ playlistName: payload.playlistName }, { $pull: { videos: { videoId: payload.videoId } } }, { upsert: true }, (err, numRemoved) => { async removeVideo({ commit }, payload) {
if (err) { await playlistsDb.update(
console.error(err) { playlistName: payload.playlistName },
} else { { $pull: { videos: { videoId: payload.videoId } } },
commit('removeVideo', payload) { upsert: true }
} )
}) commit('removeVideo', payload)
}, },
removeVideos ({ commit }, payload) {
playlistsDb.update({ _id: payload.playlistName }, { $pull: { videos: { $in: payload.videoId } } }, { upsert: true }, err => { async removeVideos({ commit }, payload) {
if (err) { await playlistsDb.update(
console.error(err) { _id: payload.playlistName },
} else { { $pull: { videos: { $in: payload.videoId } } },
commit('removeVideos', payload) { upsert: true }
} )
}) commit('removeVideos', payload)
} }
} }
const mutations = { const mutations = {
addPlaylist (state, payload) { addPlaylist(state, payload) {
state.playlists.push(payload) state.playlists.push(payload)
}, },
addPlaylists (state, payload) {
addPlaylists(state, payload) {
state.playlists = state.playlists.concat(payload) state.playlists = state.playlists.concat(payload)
}, },
addVideo (state, payload) {
addVideo(state, payload) {
const playlist = state.playlists.find(playlist => playlist.playlistName === payload.playlistName) const playlist = state.playlists.find(playlist => playlist.playlistName === payload.playlistName)
if (playlist) { if (playlist) {
playlist.videos.push(payload.videoData) playlist.videos.push(payload.videoData)
} }
}, },
addVideos (state, payload) {
addVideos(state, payload) {
const playlist = state.playlists.find(playlist => playlist._id === payload.playlistId) const playlist = state.playlists.find(playlist => playlist._id === payload.playlistId)
if (playlist) { if (playlist) {
playlist.videos = playlist.videos.concat(payload.playlistIds) playlist.videos = playlist.videos.concat(payload.playlistIds)
} }
}, },
removeAllPlaylists (state) {
removeAllPlaylists(state) {
state.playlists = state.playlists.filter(playlist => playlist.protected !== true) state.playlists = state.playlists.filter(playlist => playlist.protected !== true)
}, },
removeAllVideos (state, playlistName) {
removeAllVideos(state, playlistName) {
const playlist = state.playlists.find(playlist => playlist.playlistName === playlistName) const playlist = state.playlists.find(playlist => playlist.playlistName === playlistName)
if (playlist) { if (playlist) {
playlist.videos = [] playlist.videos = []
} }
}, },
removeVideo (state, payload) {
removeVideo(state, payload) {
const playlist = state.playlists.findIndex(playlist => playlist.playlistName === payload.playlistName) const playlist = state.playlists.findIndex(playlist => playlist.playlistName === payload.playlistName)
if (playlist !== -1) { if (playlist !== -1) {
state.playlists[playlist].videos = state.playlists[playlist].videos.filter(video => video.videoId !== payload.videoId) state.playlists[playlist].videos = state.playlists[playlist].videos.filter(video => video.videoId !== payload.videoId)
} }
}, },
removeVideos (state, payload) {
removeVideos(state, payload) {
const playlist = state.playlists.findIndex(playlist => playlist._id === payload.playlistId) const playlist = state.playlists.findIndex(playlist => playlist._id === payload.playlistId)
if (playlist !== -1) { if (playlist !== -1) {
playlist.videos = playlist.videos.filter(video => payload.videoId.indexOf(video) === -1) playlist.videos = playlist.videos.filter(video => payload.videoId.indexOf(video) === -1)
} }
}, },
removePlaylist (state, playlistId) {
removePlaylist(state, playlistId) {
state.playlists = state.playlists.filter(playlist => playlist._id !== playlistId || playlist.protected) state.playlists = state.playlists.filter(playlist => playlist._id !== playlistId || playlist.protected)
}, },
setAllPlaylists (state, payload) {
setAllPlaylists(state, payload) {
state.playlists = payload state.playlists = payload
} }
} }

View File

@ -22,60 +22,45 @@ const getters = {
} }
const actions = { const actions = {
grabAllProfiles ({ rootState, dispatch, commit }, defaultName = null) { async grabAllProfiles({ rootState, dispatch, commit }, defaultName = null) {
return new Promise((resolve, reject) => { let profiles = await profilesDb.find({})
profilesDb.find({}, (err, results) => { if (profiles.length === 0) {
if (!err) { dispatch('createDefaultProfile', defaultName)
if (results.length === 0) { return
dispatch('createDefaultProfile', defaultName) }
} else { // We want the primary profile to always be first
// We want the primary profile to always be first // So sort with that then sort alphabetically by profile name
// So sort with that then sort alphabetically by profile name profiles = profiles.sort((a, b) => {
const profiles = results.sort((a, b) => { if (a._id === 'allChannels') {
if (a._id === 'allChannels') { return -1
return -1 }
}
if (b._id === 'allChannels') { if (b._id === 'allChannels') {
return 1 return 1
} }
return b.name - a.name return b.name - a.name
})
if (state.profileList.length < profiles.length) {
const profileIndex = profiles.findIndex((profile) => {
return profile._id === rootState.settings.defaultProfile
})
if (profileIndex !== -1) {
commit('setActiveProfile', profileIndex)
}
}
commit('setProfileList', profiles)
}
resolve()
} else {
reject(err)
}
})
}) })
if (state.profileList.length < profiles.length) {
const profileIndex = profiles.findIndex((profile) => {
return profile._id === rootState.settings.defaultProfile
})
if (profileIndex !== -1) {
commit('setActiveProfile', profileIndex)
}
}
commit('setProfileList', profiles)
}, },
grabProfileInfo (_, profileId) { async grabProfileInfo(_, profileId) {
return new Promise((resolve, reject) => { console.log(profileId)
console.log(profileId) return await profilesDb.findOne({ _id: profileId })
profilesDb.findOne({ _id: profileId }, (err, results) => {
if (!err) {
resolve(results)
}
})
})
}, },
async createDefaultProfile ({ dispatch }, defaultName) { async createDefaultProfile({ dispatch }, defaultName) {
const randomColor = await dispatch('getRandomColor') const randomColor = await dispatch('getRandomColor')
const textColor = await dispatch('calculateColorLuminance', randomColor) const textColor = await dispatch('calculateColorLuminance', randomColor)
const defaultProfile = { const defaultProfile = {
@ -86,51 +71,47 @@ const actions = {
subscriptions: [] subscriptions: []
} }
profilesDb.update({ _id: 'allChannels' }, defaultProfile, { upsert: true }, (err, numReplaced) => { await profilesDb.update(
if (!err) { { _id: 'allChannels' },
dispatch('grabAllProfiles') defaultProfile,
} { upsert: true }
}) )
dispatch('grabAllProfiles')
}, },
updateProfile ({ dispatch }, profile) { async updateProfile({ dispatch }, profile) {
profilesDb.update({ _id: profile._id }, profile, { upsert: true }, (err, numReplaced) => { await profilesDb.update(
if (!err) { { _id: profile._id },
dispatch('grabAllProfiles') profile,
} { upsert: true }
}) )
dispatch('grabAllProfiles')
}, },
insertProfile ({ dispatch }, profile) { async insertProfile({ dispatch }, profile) {
profilesDb.insert(profile, (err, newDocs) => { await profilesDb.insert(profile)
if (!err) { dispatch('grabAllProfiles')
dispatch('grabAllProfiles')
}
})
}, },
removeProfile ({ dispatch }, profileId) { async removeProfile({ dispatch }, profileId) {
profilesDb.remove({ _id: profileId }, (err, numReplaced) => { await profilesDb.remove({ _id: profileId })
if (!err) { dispatch('grabAllProfiles')
dispatch('grabAllProfiles')
}
})
}, },
compactProfiles (_) { compactProfiles(_) {
profilesDb.persistence.compactDatafile() profilesDb.persistence.compactDatafile()
}, },
updateActiveProfile ({ commit }, index) { updateActiveProfile({ commit }, index) {
commit('setActiveProfile', index) commit('setActiveProfile', index)
} }
} }
const mutations = { const mutations = {
setProfileList (state, profileList) { setProfileList(state, profileList) {
state.profileList = profileList state.profileList = profileList
}, },
setActiveProfile (state, activeProfile) { setActiveProfile(state, activeProfile) {
state.activeProfile = activeProfile state.activeProfile = activeProfile
} }
} }

View File

@ -264,29 +264,19 @@ Object.assign(customGetters, {
/**********/ /**********/
const customActions = { const customActions = {
grabUserSettings: ({ commit, dispatch, getters }) => { grabUserSettings: async ({ commit, dispatch, getters }) => {
return new Promise((resolve, reject) => { const userSettings = await settingsDb.find({
settingsDb.find( _id: { $ne: 'bounds' }
{ _id: { $ne: 'bounds' } },
(err, userSettings) => {
if (err) {
reject(err)
return
}
for (const setting of userSettings) {
const { _id, value } = setting
if (getters.settingHasSideEffects(_id)) {
dispatch(defaultSideEffectsTriggerId(_id), value)
}
commit(defaultMutationId(_id), value)
}
resolve()
}
)
}) })
for (const setting of userSettings) {
const { _id, value } = setting
if (getters.settingHasSideEffects(_id)) {
dispatch(defaultSideEffectsTriggerId(_id), value)
}
commit(defaultMutationId(_id), value)
}
}, },
setUpListenerToSyncSettings: ({ commit, dispatch, getters }) => { setUpListenerToSyncSettings: ({ commit, dispatch, getters }) => {
@ -347,34 +337,31 @@ for (const settingId of Object.keys(state)) {
actions[triggerId] = stateWithSideEffects[settingId].sideEffectsHandler actions[triggerId] = stateWithSideEffects[settingId].sideEffectsHandler
} }
actions[updaterId] = ({ commit, dispatch, getters }, value) => { actions[updaterId] = async ({ commit, dispatch, getters }, value) => {
settingsDb.update( await settingsDb.update(
{ _id: settingId }, { _id: settingId },
{ _id: settingId, value: value }, { _id: settingId, value: value },
{ upsert: true }, { upsert: true }
(err, _) => {
if (err) return
const {
getUsingElectron: usingElectron,
settingHasSideEffects
} = getters
if (settingHasSideEffects(settingId)) {
dispatch(triggerId, value)
}
commit(mutationId, value)
if (usingElectron) {
const { ipcRenderer } = require('electron')
// Propagate settings to all other existing windows
ipcRenderer.send('syncSetting', {
_id: settingId, value: value
})
}
}
) )
const {
getUsingElectron: usingElectron,
settingHasSideEffects
} = getters
if (settingHasSideEffects(settingId)) {
dispatch(triggerId, value)
}
commit(mutationId, value)
if (usingElectron) {
const { ipcRenderer } = require('electron')
// Propagate settings to all other existing windows
ipcRenderer.send('syncSetting', {
_id: settingId, value: value
})
}
} }
} }