FreeTube/src/renderer/store/modules/settings.js

221 lines
6.0 KiB
JavaScript

import { settingsDb } from '../datastores'
/**
* NOTE: If someone wants to add a new setting to the app,
* all that needs to be done in this file is adding
* the setting name and its default value to the `state` object
*
* The respective getter, mutation (setter) and action (updater) will
* be automatically generated with the following pattern:
*
* Setting: example
* Getter: getExample
* Mutation: setExample
* Action: updateExample
*
* For more details on this, see the expanded exemplification below
*
* If, for whatever reason, the setting needs less or more
* functionality than what these auto-generated functions can provide,
* then that setting and its necessary functions must be manually added
* only AFTER the generic ones have been auto-generated
* Example: `usingElectron` (doesn't need an action)
*
* The same rule applies for standalone getters, mutations and actions
* Example: `grabUserSettings` (standalone action)
*/
const state = {
currentTheme: 'lightRed',
uiScale: 100,
backendFallback: true,
checkForUpdates: true,
checkForBlogPosts: true,
backendPreference: 'local',
landingPage: 'subscriptions',
region: 'US',
listType: 'grid',
thumbnailPreference: '',
invidiousInstance: 'https://invidious.snopyta.org',
defaultProfile: 'allChannels',
barColor: false,
enableSearchSuggestions: true,
rememberHistory: true,
saveWatchedProgress: true,
removeVideoMetaFiles: true,
autoplayVideos: true,
autoplayPlaylists: true,
playNextVideo: false,
enableSubtitles: true,
forceLocalBackendForLegacy: false,
proxyVideos: false,
defaultTheatreMode: false,
defaultInterval: 5,
defaultVolume: 1,
defaultPlayback: 1,
defaultVideoFormat: 'dash',
defaultQuality: '720',
defaultCaptionSettings: '{}',
useProxy: false,
proxyProtocol: 'socks5',
proxyHostname: '127.0.0.1',
proxyPort: '9050',
debugMode: false,
disableSmoothScrolling: false,
hideWatchedSubs: false,
useRssFeeds: false,
hideVideoViews: false,
hideVideoLikesAndDislikes: false,
hideChannelSubscriptions: false,
hideCommentLikes: false,
hideRecommendedVideos: false,
hideTrendingVideos: false,
hidePopularVideos: false,
hidePlaylists: false,
hideLiveChat: false,
hideActiveSubscriptions: false,
videoVolumeMouseScroll: false,
useSponsorBlock: false,
sponsorBlockUrl: 'https://sponsor.ajay.app',
sponsorBlockShowSkippedToast: true,
displayVideoPlayButton: true
}
const getters = {}
const mutations = {}
const actions = {}
/**
* Build getters, mutations and actions for every setting id
* e.g.:
* Setting id: uiScale
* Getter:
* getUiScale: (state) => state.uiScale
* Mutation:
* setUiScale: (state, uiScaleValue) => state.uiScale = uiScaleValue
* Action:
* updateUiScale: ({ commit }, uiScaleValue) => {
* await settingsDb.update(
* { _id: 'uiScale' },
* { _id: 'uiScale', value: uiScaleValue },
* { upsert: true },
* (err, _) => {
* commit('setUiScale', uiScaleValue)
* }
* )
*/
for (const settingId of Object.keys(state)) {
const capitalizedSettingId =
settingId.replace(/^\w/, (c) => c.toUpperCase())
const getterId = 'get' + capitalizedSettingId
const mutationId = 'set' + capitalizedSettingId
const actionId = 'update' + capitalizedSettingId
getters[getterId] = (state) => state[settingId]
mutations[mutationId] = (state, value) => { state[settingId] = value }
actions[actionId] = ({ commit }, value) => {
settingsDb.update(
{ _id: settingId },
{ _id: settingId, value: value },
{ upsert: true },
(err, _) => {
if (!err) {
commit(mutationId, value)
if (getters.getUsingElectron) {
const { ipcRenderer } = require('electron')
// Propagate setting values to all other existing windows
ipcRenderer.send('syncSetting', {
_id: settingId, value: value
})
}
}
}
)
}
}
// Custom state
Object.assign(state, {
// Add `usingElectron` to the state
usingElectron: window?.process?.type === 'renderer'
})
// Custom getters
Object.assign(getters, {
// Getter for `usingElectron`
getUsingElectron: (state) => state.usingElectron
})
// Custom mutations
// Object.assign(mutations, {})
// Custom actions
Object.assign(actions, {
// Add `grabUserSettings` to actions
grabUserSettings: ({ commit, getters }) => {
return new Promise((resolve, reject) => {
settingsDb.find(
{ _id: { $ne: 'bounds' } },
(err, userSettings) => {
if (err) {
reject(err)
return
}
const specialSettings = new Map([
['uiScale',
(value) => {
if (getters.getUsingElectron) {
const { webFrame } = require('electron')
webFrame.setZoomFactor(parseInt(value) / 100)
}
commit('setUiScale', value)
}
],
['defaultVolume',
(value) => {
sessionStorage.setItem('volume', value)
commit('setDefaultVolume', value)
}
]
])
for (const setting of userSettings) {
if (specialSettings.has(setting._id)) {
const specialSettingHandler = specialSettings.get(setting._id)
specialSettingHandler(setting.value)
continue
}
const capitalizedSettingId =
setting._id.replace(/^\w/, (c) => c.toUpperCase())
commit('set' + capitalizedSettingId, setting.value)
}
resolve()
}
)
})
},
setUpListenerToSyncSettings: ({ commit, getters }) => {
if (getters.getUsingElectron) {
const { ipcRenderer } = require('electron')
ipcRenderer.on('syncSetting', (_, setting) => {
const capitalizedSettingId =
setting._id.replace(/^\w/, (c) => c.toUpperCase())
commit('set' + capitalizedSettingId, setting.value)
})
}
}
})
export default {
state,
getters,
actions,
mutations
}