mirror of
https://github.com/FreeTubeApp/FreeTube.git
synced 2025-12-05 01:10:31 +00:00
Add preload script and disable node integration in renderer processes (#7424)
This commit is contained in:
@@ -18,6 +18,7 @@ const web = process.argv.indexOf('--web') !== -1
|
||||
|
||||
let mainConfig
|
||||
let rendererConfig
|
||||
let preloadConfig
|
||||
let botGuardScriptConfig
|
||||
let webConfig
|
||||
let SHAKA_LOCALES_TO_BE_BUNDLED
|
||||
@@ -25,6 +26,7 @@ let SHAKA_LOCALES_TO_BE_BUNDLED
|
||||
if (!web) {
|
||||
mainConfig = require('./webpack.main.config')
|
||||
rendererConfig = require('./webpack.renderer.config')
|
||||
preloadConfig = require('./webpack.preload.config.js')
|
||||
botGuardScriptConfig = require('./webpack.botGuardScript.config')
|
||||
|
||||
SHAKA_LOCALES_TO_BE_BUNDLED = rendererConfig.SHAKA_LOCALES_TO_BE_BUNDLED
|
||||
@@ -132,6 +134,36 @@ function startMain() {
|
||||
})
|
||||
}
|
||||
|
||||
function startPreload() {
|
||||
const compiler = webpack(preloadConfig)
|
||||
const { name } = compiler
|
||||
|
||||
let firstTime = true
|
||||
|
||||
compiler.hooks.afterEmit.tap('afterEmit', async () => {
|
||||
console.log(`\nCompiled ${name} script!`)
|
||||
|
||||
if (firstTime) {
|
||||
firstTime = false
|
||||
} else {
|
||||
manualRestart = true
|
||||
await restartElectron()
|
||||
setTimeout(() => {
|
||||
manualRestart = false
|
||||
}, 2500)
|
||||
}
|
||||
|
||||
console.log(`\nWatching file changes for ${name} script...`)
|
||||
})
|
||||
|
||||
compiler.watch({
|
||||
aggregateTimeout: 500,
|
||||
},
|
||||
err => {
|
||||
if (err) console.error(err)
|
||||
})
|
||||
}
|
||||
|
||||
function startRenderer(callback) {
|
||||
const compiler = webpack(rendererConfig)
|
||||
const { name } = compiler
|
||||
@@ -208,6 +240,7 @@ function startWeb () {
|
||||
if (!web) {
|
||||
startRenderer(() => {
|
||||
startBotGuardScript()
|
||||
startPreload()
|
||||
startMain()
|
||||
})
|
||||
} else {
|
||||
|
||||
@@ -21,6 +21,8 @@ const paths = readdirSync(distDirectory, {
|
||||
// disallow the renderer process/browser windows to read the main.js file
|
||||
dirent.name !== 'main.js' &&
|
||||
dirent.name !== 'main.js.LICENSE.txt' &&
|
||||
// disallow the renderer process/browser windows to read the preload.js file
|
||||
dirent.name !== 'preload.js' &&
|
||||
// disallow the renderer process/browser windows to read the botGuardScript.js file
|
||||
dirent.name !== 'botGuardScript.js' &&
|
||||
// filter out any web build files, in case the dist directory contains a web build
|
||||
|
||||
34
_scripts/webpack.preload.config.js
Normal file
34
_scripts/webpack.preload.config.js
Normal file
@@ -0,0 +1,34 @@
|
||||
const path = require('path')
|
||||
|
||||
const isDevMode = process.env.NODE_ENV === 'development'
|
||||
|
||||
/** @type {import('webpack').Configuration} */
|
||||
const config = {
|
||||
name: 'preload',
|
||||
mode: process.env.NODE_ENV,
|
||||
devtool: isDevMode ? 'eval-cheap-module-source-map' : false,
|
||||
entry: {
|
||||
preload: path.join(__dirname, '../src/preload/main.js'),
|
||||
},
|
||||
infrastructureLogging: {
|
||||
// Only warnings and errors
|
||||
// level: 'none' disable logging
|
||||
// Please read https://webpack.js.org/configuration/other-options/#infrastructurelogginglevel
|
||||
level: isDevMode ? 'info' : 'none'
|
||||
},
|
||||
output: {
|
||||
path: path.join(__dirname, '../dist'),
|
||||
filename: '[name].js'
|
||||
},
|
||||
externals: [
|
||||
'electron/renderer'
|
||||
],
|
||||
externalsType: 'commonjs',
|
||||
node: {
|
||||
__dirname: false,
|
||||
__filename: false
|
||||
},
|
||||
target: 'electron-preload',
|
||||
}
|
||||
|
||||
module.exports = config
|
||||
@@ -39,7 +39,7 @@ const config = {
|
||||
level: isDevMode ? 'info' : 'none'
|
||||
},
|
||||
output: {
|
||||
libraryTarget: 'commonjs2',
|
||||
scriptType: 'text/javascript',
|
||||
path: path.join(__dirname, '../dist'),
|
||||
filename: '[name].js',
|
||||
},
|
||||
@@ -191,7 +191,7 @@ const config = {
|
||||
},
|
||||
extensions: ['.js', '.vue']
|
||||
},
|
||||
target: 'electron-renderer',
|
||||
target: 'web',
|
||||
}
|
||||
|
||||
if (isDevMode) {
|
||||
|
||||
@@ -43,9 +43,10 @@
|
||||
"lint-style": "stylelint \"src/**/*.{css,scss}\"",
|
||||
"lint-style-fix": "stylelint --fix \"src/**/*.{css,scss}\"",
|
||||
"lint-yml": "eslint --config eslint.config.mjs \"**/*.yml\" \"**/*.yaml\"",
|
||||
"pack": "run-p pack:main pack:renderer pack:botGuardScript && node _scripts/injectAllowedPaths.mjs",
|
||||
"pack": "run-p pack:main pack:renderer pack:preload pack:botGuardScript && node _scripts/injectAllowedPaths.mjs",
|
||||
"pack:main": "webpack --mode=production --node-env=production --config _scripts/webpack.main.config.js",
|
||||
"pack:renderer": "webpack --mode=production --node-env=production --config _scripts/webpack.renderer.config.js",
|
||||
"pack:preload": "webpack --mode=production --node-env=production --config _scripts/webpack.preload.config.js",
|
||||
"pack:web": "webpack --mode=production --node-env=production --config _scripts/webpack.web.config.js",
|
||||
"pack:botGuardScript": "webpack --config _scripts/webpack.botGuardScript.config.js",
|
||||
"postinstall": "yarn run --silent patch-shaka",
|
||||
|
||||
@@ -12,9 +12,6 @@ const IpcChannels = {
|
||||
APP_READY: 'app-ready',
|
||||
RELAUNCH_REQUEST: 'relaunch-request',
|
||||
|
||||
REQUEST_FULLSCREEN: 'request-fullscreen',
|
||||
REQUEST_PIP: 'request-pip',
|
||||
|
||||
SEARCH_INPUT_HANDLING_READY: 'search-input-handling-ready',
|
||||
UPDATE_SEARCH_INPUT_TEXT: 'update-search-input-text',
|
||||
|
||||
|
||||
@@ -1,323 +1,193 @@
|
||||
import { ipcRenderer } from 'electron'
|
||||
import { IpcChannels, DBActions } from '../../constants'
|
||||
import { DBActions } from '../../constants'
|
||||
|
||||
class Settings {
|
||||
static find() {
|
||||
return ipcRenderer.invoke(
|
||||
IpcChannels.DB_SETTINGS,
|
||||
{ action: DBActions.GENERAL.FIND }
|
||||
)
|
||||
return window.ftElectron.dbSettings(DBActions.GENERAL.FIND)
|
||||
}
|
||||
|
||||
static upsert(_id, value) {
|
||||
return ipcRenderer.invoke(
|
||||
IpcChannels.DB_SETTINGS,
|
||||
{ action: DBActions.GENERAL.UPSERT, data: { _id, value } }
|
||||
)
|
||||
return window.ftElectron.dbSettings(DBActions.GENERAL.UPSERT, { _id, value })
|
||||
}
|
||||
}
|
||||
|
||||
class History {
|
||||
static find() {
|
||||
return ipcRenderer.invoke(
|
||||
IpcChannels.DB_HISTORY,
|
||||
{ action: DBActions.GENERAL.FIND }
|
||||
)
|
||||
return window.ftElectron.dbHistory(DBActions.GENERAL.FIND)
|
||||
}
|
||||
|
||||
static upsert(record) {
|
||||
return ipcRenderer.invoke(
|
||||
IpcChannels.DB_HISTORY,
|
||||
{ action: DBActions.GENERAL.UPSERT, data: record }
|
||||
)
|
||||
return window.ftElectron.dbHistory(DBActions.GENERAL.UPSERT, record)
|
||||
}
|
||||
|
||||
static overwrite(records) {
|
||||
return ipcRenderer.invoke(
|
||||
IpcChannels.DB_HISTORY,
|
||||
{ action: DBActions.HISTORY.OVERWRITE, data: records }
|
||||
)
|
||||
return window.ftElectron.dbHistory(DBActions.HISTORY.OVERWRITE, records)
|
||||
}
|
||||
|
||||
static updateWatchProgress(videoId, watchProgress) {
|
||||
return ipcRenderer.invoke(
|
||||
IpcChannels.DB_HISTORY,
|
||||
{
|
||||
action: DBActions.HISTORY.UPDATE_WATCH_PROGRESS,
|
||||
data: { videoId, watchProgress }
|
||||
}
|
||||
return window.ftElectron.dbHistory(
|
||||
DBActions.HISTORY.UPDATE_WATCH_PROGRESS,
|
||||
{ videoId, watchProgress }
|
||||
)
|
||||
}
|
||||
|
||||
static updateLastViewedPlaylist(videoId, lastViewedPlaylistId, lastViewedPlaylistType, lastViewedPlaylistItemId) {
|
||||
return ipcRenderer.invoke(
|
||||
IpcChannels.DB_HISTORY,
|
||||
{
|
||||
action: DBActions.HISTORY.UPDATE_PLAYLIST,
|
||||
data: { videoId, lastViewedPlaylistId, lastViewedPlaylistType, lastViewedPlaylistItemId }
|
||||
}
|
||||
return window.ftElectron.dbHistory(
|
||||
DBActions.HISTORY.UPDATE_PLAYLIST,
|
||||
{ videoId, lastViewedPlaylistId, lastViewedPlaylistType, lastViewedPlaylistItemId }
|
||||
)
|
||||
}
|
||||
|
||||
static delete(videoId) {
|
||||
return ipcRenderer.invoke(
|
||||
IpcChannels.DB_HISTORY,
|
||||
{ action: DBActions.GENERAL.DELETE, data: videoId }
|
||||
)
|
||||
return window.ftElectron.dbHistory(DBActions.GENERAL.DELETE, videoId)
|
||||
}
|
||||
|
||||
static deleteAll() {
|
||||
return ipcRenderer.invoke(
|
||||
IpcChannels.DB_HISTORY,
|
||||
{ action: DBActions.GENERAL.DELETE_ALL }
|
||||
)
|
||||
return window.ftElectron.dbHistory(DBActions.GENERAL.DELETE_ALL)
|
||||
}
|
||||
}
|
||||
|
||||
class Profiles {
|
||||
static create(profile) {
|
||||
return ipcRenderer.invoke(
|
||||
IpcChannels.DB_PROFILES,
|
||||
{ action: DBActions.GENERAL.CREATE, data: profile }
|
||||
)
|
||||
return window.ftElectron.dbProfiles(DBActions.GENERAL.CREATE, profile)
|
||||
}
|
||||
|
||||
static find() {
|
||||
return ipcRenderer.invoke(
|
||||
IpcChannels.DB_PROFILES,
|
||||
{ action: DBActions.GENERAL.FIND }
|
||||
)
|
||||
return window.ftElectron.dbProfiles(DBActions.GENERAL.FIND)
|
||||
}
|
||||
|
||||
static upsert(profile) {
|
||||
return ipcRenderer.invoke(
|
||||
IpcChannels.DB_PROFILES,
|
||||
{ action: DBActions.GENERAL.UPSERT, data: profile }
|
||||
)
|
||||
return window.ftElectron.dbProfiles(DBActions.GENERAL.UPSERT, profile)
|
||||
}
|
||||
|
||||
static addChannelToProfiles(channel, profileIds) {
|
||||
return ipcRenderer.invoke(
|
||||
IpcChannels.DB_PROFILES,
|
||||
{
|
||||
action: DBActions.PROFILES.ADD_CHANNEL,
|
||||
data: { channel, profileIds }
|
||||
}
|
||||
)
|
||||
return window.ftElectron.dbProfiles(DBActions.PROFILES.ADD_CHANNEL, { channel, profileIds })
|
||||
}
|
||||
|
||||
static removeChannelFromProfiles(channelId, profileIds) {
|
||||
return ipcRenderer.invoke(
|
||||
IpcChannels.DB_PROFILES,
|
||||
{
|
||||
action: DBActions.PROFILES.REMOVE_CHANNEL,
|
||||
data: { channelId, profileIds }
|
||||
}
|
||||
)
|
||||
return window.ftElectron.dbProfiles(DBActions.PROFILES.REMOVE_CHANNEL, { channelId, profileIds })
|
||||
}
|
||||
|
||||
static delete(id) {
|
||||
return ipcRenderer.invoke(
|
||||
IpcChannels.DB_PROFILES,
|
||||
{ action: DBActions.GENERAL.DELETE, data: id }
|
||||
)
|
||||
return window.ftElectron.dbProfiles(DBActions.GENERAL.DELETE, id)
|
||||
}
|
||||
}
|
||||
|
||||
class Playlists {
|
||||
static create(playlists) {
|
||||
return ipcRenderer.invoke(
|
||||
IpcChannels.DB_PLAYLISTS,
|
||||
{ action: DBActions.GENERAL.CREATE, data: playlists }
|
||||
)
|
||||
return window.ftElectron.dbPlaylists(DBActions.GENERAL.CREATE, playlists)
|
||||
}
|
||||
|
||||
static find() {
|
||||
return ipcRenderer.invoke(
|
||||
IpcChannels.DB_PLAYLISTS,
|
||||
{ action: DBActions.GENERAL.FIND }
|
||||
)
|
||||
return window.ftElectron.dbPlaylists(DBActions.GENERAL.FIND)
|
||||
}
|
||||
|
||||
static upsert(playlist) {
|
||||
return ipcRenderer.invoke(
|
||||
IpcChannels.DB_PLAYLISTS,
|
||||
{ action: DBActions.GENERAL.UPSERT, data: playlist }
|
||||
)
|
||||
return window.ftElectron.dbPlaylists(DBActions.GENERAL.UPSERT, playlist)
|
||||
}
|
||||
|
||||
static upsertVideoByPlaylistId(_id, videoData) {
|
||||
return ipcRenderer.invoke(
|
||||
IpcChannels.DB_PLAYLISTS,
|
||||
{
|
||||
action: DBActions.PLAYLISTS.UPSERT_VIDEO,
|
||||
data: { _id, videoData }
|
||||
}
|
||||
)
|
||||
return window.ftElectron.dbPlaylists(DBActions.PLAYLISTS.UPSERT_VIDEO, { _id, videoData })
|
||||
}
|
||||
|
||||
static upsertVideosByPlaylistId(_id, videos) {
|
||||
return ipcRenderer.invoke(
|
||||
IpcChannels.DB_PLAYLISTS,
|
||||
{
|
||||
action: DBActions.PLAYLISTS.UPSERT_VIDEOS,
|
||||
data: { _id, videos }
|
||||
}
|
||||
)
|
||||
return window.ftElectron.dbPlaylists(DBActions.PLAYLISTS.UPSERT_VIDEOS, { _id, videos })
|
||||
}
|
||||
|
||||
static delete(_id) {
|
||||
return ipcRenderer.invoke(
|
||||
IpcChannels.DB_PLAYLISTS,
|
||||
{ action: DBActions.GENERAL.DELETE, data: _id }
|
||||
)
|
||||
return window.ftElectron.dbPlaylists(DBActions.GENERAL.DELETE, _id)
|
||||
}
|
||||
|
||||
static deleteVideoIdByPlaylistId(_id, videoId, playlistItemId) {
|
||||
return ipcRenderer.invoke(
|
||||
IpcChannels.DB_PLAYLISTS,
|
||||
{
|
||||
action: DBActions.PLAYLISTS.DELETE_VIDEO_ID,
|
||||
data: { _id, videoId, playlistItemId }
|
||||
}
|
||||
return window.ftElectron.dbPlaylists(
|
||||
DBActions.PLAYLISTS.DELETE_VIDEO_ID,
|
||||
{ _id, videoId, playlistItemId }
|
||||
)
|
||||
}
|
||||
|
||||
static deleteVideoIdsByPlaylistId(_id, playlistItemIds) {
|
||||
return ipcRenderer.invoke(
|
||||
IpcChannels.DB_PLAYLISTS,
|
||||
{
|
||||
action: DBActions.PLAYLISTS.DELETE_VIDEO_IDS,
|
||||
data: { _id, playlistItemIds }
|
||||
}
|
||||
return window.ftElectron.dbPlaylists(
|
||||
DBActions.PLAYLISTS.DELETE_VIDEO_IDS,
|
||||
{ _id, playlistItemIds }
|
||||
)
|
||||
}
|
||||
|
||||
static deleteAllVideosByPlaylistId(_id) {
|
||||
return ipcRenderer.invoke(
|
||||
IpcChannels.DB_PLAYLISTS,
|
||||
{
|
||||
action: DBActions.PLAYLISTS.DELETE_ALL_VIDEOS,
|
||||
data: _id
|
||||
}
|
||||
)
|
||||
return window.ftElectron.dbPlaylists(DBActions.PLAYLISTS.DELETE_ALL_VIDEOS, _id)
|
||||
}
|
||||
|
||||
static deleteMultiple(ids) {
|
||||
return ipcRenderer.invoke(
|
||||
IpcChannels.DB_PLAYLISTS,
|
||||
{ action: DBActions.GENERAL.DELETE_MULTIPLE, data: ids }
|
||||
)
|
||||
return window.ftElectron.dbPlaylists(DBActions.GENERAL.DELETE_MULTIPLE, ids)
|
||||
}
|
||||
|
||||
static deleteAll() {
|
||||
return ipcRenderer.invoke(
|
||||
IpcChannels.DB_PLAYLISTS,
|
||||
{ action: DBActions.GENERAL.DELETE_ALL }
|
||||
)
|
||||
return window.ftElectron.dbPlaylists(DBActions.GENERAL.DELETE_ALL)
|
||||
}
|
||||
}
|
||||
|
||||
class SearchHistory {
|
||||
static find() {
|
||||
return ipcRenderer.invoke(
|
||||
IpcChannels.DB_SEARCH_HISTORY,
|
||||
{ action: DBActions.GENERAL.FIND }
|
||||
)
|
||||
return window.ftElectron.dbSearchHistory(DBActions.GENERAL.FIND)
|
||||
}
|
||||
|
||||
static upsert(searchHistoryEntry) {
|
||||
return ipcRenderer.invoke(
|
||||
IpcChannels.DB_SEARCH_HISTORY,
|
||||
{ action: DBActions.GENERAL.UPSERT, data: searchHistoryEntry }
|
||||
)
|
||||
return window.ftElectron.dbSearchHistory(DBActions.GENERAL.UPSERT, searchHistoryEntry)
|
||||
}
|
||||
|
||||
static delete(_id) {
|
||||
return ipcRenderer.invoke(
|
||||
IpcChannels.DB_SEARCH_HISTORY,
|
||||
{ action: DBActions.GENERAL.DELETE, data: _id }
|
||||
)
|
||||
return window.ftElectron.dbSearchHistory(DBActions.GENERAL.DELETE, _id)
|
||||
}
|
||||
|
||||
static deleteAll() {
|
||||
return ipcRenderer.invoke(
|
||||
IpcChannels.DB_SEARCH_HISTORY,
|
||||
{ action: DBActions.GENERAL.DELETE_ALL }
|
||||
)
|
||||
return window.ftElectron.dbSearchHistory(DBActions.GENERAL.DELETE_ALL)
|
||||
}
|
||||
}
|
||||
|
||||
class SubscriptionCache {
|
||||
static find() {
|
||||
return ipcRenderer.invoke(
|
||||
IpcChannels.DB_SUBSCRIPTION_CACHE,
|
||||
{ action: DBActions.GENERAL.FIND }
|
||||
)
|
||||
return window.ftElectron.dbSubscriptionCache(DBActions.GENERAL.FIND)
|
||||
}
|
||||
|
||||
static updateVideosByChannelId(channelId, entries, timestamp) {
|
||||
return ipcRenderer.invoke(
|
||||
IpcChannels.DB_SUBSCRIPTION_CACHE,
|
||||
{
|
||||
action: DBActions.SUBSCRIPTION_CACHE.UPDATE_VIDEOS_BY_CHANNEL,
|
||||
data: { channelId, entries, timestamp },
|
||||
}
|
||||
return window.ftElectron.dbSubscriptionCache(
|
||||
DBActions.SUBSCRIPTION_CACHE.UPDATE_VIDEOS_BY_CHANNEL,
|
||||
{ channelId, entries, timestamp }
|
||||
)
|
||||
}
|
||||
|
||||
static updateLiveStreamsByChannelId(channelId, entries, timestamp) {
|
||||
return ipcRenderer.invoke(
|
||||
IpcChannels.DB_SUBSCRIPTION_CACHE,
|
||||
{
|
||||
action: DBActions.SUBSCRIPTION_CACHE.UPDATE_LIVE_STREAMS_BY_CHANNEL,
|
||||
data: { channelId, entries, timestamp },
|
||||
}
|
||||
return window.ftElectron.dbSubscriptionCache(
|
||||
DBActions.SUBSCRIPTION_CACHE.UPDATE_LIVE_STREAMS_BY_CHANNEL,
|
||||
{ channelId, entries, timestamp }
|
||||
)
|
||||
}
|
||||
|
||||
static updateShortsByChannelId(channelId, entries, timestamp) {
|
||||
return ipcRenderer.invoke(
|
||||
IpcChannels.DB_SUBSCRIPTION_CACHE,
|
||||
{
|
||||
action: DBActions.SUBSCRIPTION_CACHE.UPDATE_SHORTS_BY_CHANNEL,
|
||||
data: { channelId, entries, timestamp },
|
||||
}
|
||||
return window.ftElectron.dbSubscriptionCache(
|
||||
DBActions.SUBSCRIPTION_CACHE.UPDATE_SHORTS_BY_CHANNEL,
|
||||
{ channelId, entries, timestamp }
|
||||
)
|
||||
}
|
||||
|
||||
static updateShortsWithChannelPageShortsByChannelId(channelId, entries) {
|
||||
return ipcRenderer.invoke(
|
||||
IpcChannels.DB_SUBSCRIPTION_CACHE,
|
||||
{
|
||||
action: DBActions.SUBSCRIPTION_CACHE.UPDATE_SHORTS_WITH_CHANNEL_PAGE_SHORTS_BY_CHANNEL,
|
||||
data: { channelId, entries },
|
||||
}
|
||||
return window.ftElectron.dbSubscriptionCache(
|
||||
DBActions.SUBSCRIPTION_CACHE.UPDATE_SHORTS_WITH_CHANNEL_PAGE_SHORTS_BY_CHANNEL,
|
||||
{ channelId, entries }
|
||||
)
|
||||
}
|
||||
|
||||
static updateCommunityPostsByChannelId(channelId, entries, timestamp) {
|
||||
return ipcRenderer.invoke(
|
||||
IpcChannels.DB_SUBSCRIPTION_CACHE,
|
||||
{
|
||||
action: DBActions.SUBSCRIPTION_CACHE.UPDATE_COMMUNITY_POSTS_BY_CHANNEL,
|
||||
data: { channelId, entries, timestamp },
|
||||
}
|
||||
return window.ftElectron.dbSubscriptionCache(
|
||||
DBActions.SUBSCRIPTION_CACHE.UPDATE_COMMUNITY_POSTS_BY_CHANNEL,
|
||||
{ channelId, entries, timestamp }
|
||||
)
|
||||
}
|
||||
|
||||
static deleteMultipleChannels(channelIds) {
|
||||
return ipcRenderer.invoke(
|
||||
IpcChannels.DB_SUBSCRIPTION_CACHE,
|
||||
{ action: DBActions.GENERAL.DELETE_MULTIPLE, data: channelIds }
|
||||
)
|
||||
return window.ftElectron.dbSubscriptionCache(DBActions.GENERAL.DELETE_MULTIPLE, channelIds)
|
||||
}
|
||||
|
||||
static deleteAll() {
|
||||
return ipcRenderer.invoke(
|
||||
IpcChannels.DB_SUBSCRIPTION_CACHE,
|
||||
{ action: DBActions.GENERAL.DELETE_ALL }
|
||||
)
|
||||
return window.ftElectron.dbSubscriptionCache(DBActions.GENERAL.DELETE_ALL)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -291,7 +291,7 @@ function runApp() {
|
||||
if (mainWindow.isMinimized()) mainWindow.restore()
|
||||
mainWindow.focus()
|
||||
|
||||
if (url) mainWindow.webContents.send(IpcChannels.OPEN_URL, url)
|
||||
if (url) mainWindow.webContents.send(IpcChannels.OPEN_URL, url, false)
|
||||
}
|
||||
} else {
|
||||
if (url) startupUrl = url
|
||||
@@ -760,11 +760,11 @@ function runApp() {
|
||||
autoHideMenuBar: true,
|
||||
// useContentSize: true,
|
||||
webPreferences: {
|
||||
nodeIntegration: true,
|
||||
nodeIntegrationInWorker: false,
|
||||
webSecurity: false,
|
||||
backgroundThrottling: false,
|
||||
contextIsolation: false
|
||||
preload: process.env.NODE_ENV === 'development'
|
||||
? path.resolve(__dirname, '../../dist/preload.js')
|
||||
: path.resolve(__dirname, 'preload.js')
|
||||
},
|
||||
minWidth: 340,
|
||||
minHeight: 380
|
||||
@@ -915,7 +915,7 @@ function runApp() {
|
||||
|
||||
ipcMain.on(IpcChannels.APP_READY, () => {
|
||||
if (startupUrl) {
|
||||
mainWindow.webContents.send(IpcChannels.OPEN_URL, startupUrl, { isLaunchLink: true })
|
||||
mainWindow.webContents.send(IpcChannels.OPEN_URL, startupUrl, true)
|
||||
}
|
||||
startupUrl = null
|
||||
})
|
||||
@@ -1025,18 +1025,6 @@ function runApp() {
|
||||
return app.getSystemLocale()
|
||||
})
|
||||
|
||||
// Allows programmatic toggling of fullscreen without accompanying user interaction.
|
||||
// See: https://developer.mozilla.org/en-US/docs/Web/Security/User_activation#transient_activation
|
||||
ipcMain.on(IpcChannels.REQUEST_FULLSCREEN, ({ sender }) => {
|
||||
sender.executeJavaScript('document.querySelector("video.player").ui.getControls().toggleFullScreen()', true)
|
||||
})
|
||||
|
||||
// Allows programmatic toggling of picture-in-picture mode without accompanying user interaction.
|
||||
// See: https://developer.mozilla.org/en-US/docs/Web/Security/User_activation#transient_activation
|
||||
ipcMain.on(IpcChannels.REQUEST_PIP, ({ sender }) => {
|
||||
sender.executeJavaScript('document.querySelector("video.player").ui.getControls().togglePiP()', true)
|
||||
})
|
||||
|
||||
ipcMain.handle(IpcChannels.GET_SCREENSHOT_FALLBACK_FOLDER, (event) => {
|
||||
if (!isFreeTubeUrl(event.senderFrame.url)) {
|
||||
return
|
||||
@@ -1204,8 +1192,8 @@ function runApp() {
|
||||
})
|
||||
})
|
||||
|
||||
ipcMain.on(IpcChannels.OPEN_IN_EXTERNAL_PLAYER, (_, payload) => {
|
||||
const child = cp.spawn(payload.executable, payload.args, { detached: true, stdio: 'ignore' })
|
||||
ipcMain.on(IpcChannels.OPEN_IN_EXTERNAL_PLAYER, (_, executable, args) => {
|
||||
const child = cp.spawn(executable, args, { detached: true, stdio: 'ignore' })
|
||||
child.unref()
|
||||
})
|
||||
|
||||
@@ -1777,7 +1765,7 @@ function runApp() {
|
||||
event.preventDefault()
|
||||
|
||||
if (mainWindow && mainWindow.webContents) {
|
||||
mainWindow.webContents.send(IpcChannels.OPEN_URL, baseUrl(url))
|
||||
mainWindow.webContents.send(IpcChannels.OPEN_URL, baseUrl(url), false)
|
||||
} else {
|
||||
startupUrl = baseUrl(url)
|
||||
if (app.isReady()) createWindow()
|
||||
@@ -1844,10 +1832,7 @@ function runApp() {
|
||||
return
|
||||
}
|
||||
|
||||
browserWindow.webContents.send(
|
||||
IpcChannels.CHANGE_VIEW,
|
||||
{ route: path }
|
||||
)
|
||||
browserWindow.webContents.send(IpcChannels.CHANGE_VIEW, path)
|
||||
}
|
||||
|
||||
async function setMenu() {
|
||||
|
||||
302
src/preload/interface.js
Normal file
302
src/preload/interface.js
Normal file
@@ -0,0 +1,302 @@
|
||||
import { ipcRenderer, webFrame } from 'electron/renderer'
|
||||
import { IpcChannels } from '../constants.js'
|
||||
|
||||
/**
|
||||
* Linux fix for dynamically updating theme preference, this works on
|
||||
* all systems running the electron app.
|
||||
*/
|
||||
ipcRenderer.on(IpcChannels.NATIVE_THEME_UPDATE, (_, shouldUseDarkColors) => {
|
||||
webFrame.executeJavaScript(`document.body.dataset.systemTheme = "${shouldUseDarkColors ? 'dark' : 'light'}"`).catch()
|
||||
})
|
||||
|
||||
let currentUpdateSearchInputTextListener
|
||||
|
||||
export default {
|
||||
/**
|
||||
* @returns {Promise<string>}
|
||||
*/
|
||||
getSystemLocale: () => {
|
||||
return ipcRenderer.invoke(IpcChannels.GET_SYSTEM_LOCALE)
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {string} path
|
||||
* @param {Record<string, string> | null | undefined} query
|
||||
* @param {string | null | undefined} searchQueryText
|
||||
*/
|
||||
openInNewWindow: (path, query, searchQueryText) => {
|
||||
ipcRenderer.send(IpcChannels.CREATE_NEW_WINDOW, path, query, searchQueryText)
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {string} url
|
||||
*/
|
||||
enableProxy: (url) => {
|
||||
ipcRenderer.send(IpcChannels.ENABLE_PROXY, url)
|
||||
},
|
||||
|
||||
disableProxy: () => {
|
||||
ipcRenderer.send(IpcChannels.DISABLE_PROXY)
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {string} authorization
|
||||
* @param {string} url
|
||||
*/
|
||||
setInvidiousAuthorization: (authorization, url) => {
|
||||
ipcRenderer.send(IpcChannels.SET_INVIDIOUS_AUTHORIZATION, authorization, url)
|
||||
},
|
||||
|
||||
clearInvidiousAuthorization: () => {
|
||||
ipcRenderer.send(IpcChannels.SET_INVIDIOUS_AUTHORIZATION, null)
|
||||
},
|
||||
|
||||
startPowerSaveBlocker: () => {
|
||||
ipcRenderer.send(IpcChannels.START_POWER_SAVE_BLOCKER)
|
||||
},
|
||||
|
||||
stopPowerSaveBlocker: () => {
|
||||
ipcRenderer.send(IpcChannels.STOP_POWER_SAVE_BLOCKER)
|
||||
},
|
||||
|
||||
/**
|
||||
* @returns {Promise<boolean>}
|
||||
*/
|
||||
getReplaceHttpCache: () => {
|
||||
return ipcRenderer.invoke(IpcChannels.GET_REPLACE_HTTP_CACHE)
|
||||
},
|
||||
|
||||
toggleReplaceHttpCache: () => {
|
||||
ipcRenderer.send(IpcChannels.TOGGLE_REPLACE_HTTP_CACHE)
|
||||
},
|
||||
|
||||
// Allows programmatic toggling of picture-in-picture mode without accompanying user interaction.
|
||||
// See: https://developer.mozilla.org/en-US/docs/Web/Security/User_activation#transient_activation
|
||||
requestPiP: () => {
|
||||
webFrame.executeJavaScript('document.querySelector("video.player")?.ui.getControls().togglePiP()', true).catch()
|
||||
},
|
||||
|
||||
// Allows programmatic toggling of fullscreen without accompanying user interaction.
|
||||
// See: https://developer.mozilla.org/en-US/docs/Web/Security/User_activation#transient_activation
|
||||
requestFullscreen: () => {
|
||||
webFrame.executeJavaScript('document.querySelector("video.player")?.ui.getControls().toggleFullScreen()', true).catch()
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {string} key
|
||||
* @returns {Promise<ArrayBuffer>}
|
||||
*/
|
||||
playerCacheGet: (key) => {
|
||||
return ipcRenderer.invoke(IpcChannels.PLAYER_CACHE_GET, key)
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {string} key
|
||||
* @param {ArrayBuffer} value
|
||||
*/
|
||||
playerCacheSet: async (key, value) => {
|
||||
await ipcRenderer.invoke(IpcChannels.PLAYER_CACHE_SET, key, value)
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {string} videoId
|
||||
* @param {string} visitorData
|
||||
* @param {string} context
|
||||
* @returns {Promise<{ contentPoToken: string, sessionPoToken: string }>}
|
||||
*/
|
||||
generatePoTokens: (videoId, visitorData, context) => {
|
||||
return ipcRenderer.invoke(IpcChannels.GENERATE_PO_TOKENS, videoId, visitorData, context)
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {0 | 1} kind
|
||||
*/
|
||||
chooseDefaultFolder: (kind) => {
|
||||
ipcRenderer.send(IpcChannels.CHOOSE_DEFAULT_FOLDER, kind)
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {0 | 1} kind
|
||||
* @param {string} filename
|
||||
* @param {ArrayBuffer} contents
|
||||
*/
|
||||
writeToDefaultFolder: async (kind, filename, contents) => {
|
||||
await ipcRenderer.invoke(IpcChannels.WRITE_TO_DEFAULT_FOLDER, kind, filename, contents)
|
||||
},
|
||||
|
||||
/**
|
||||
* @returns {Promise<string>}
|
||||
*/
|
||||
getScreenshotFallbackFolder: () => {
|
||||
return ipcRenderer.invoke(IpcChannels.GET_SCREENSHOT_FALLBACK_FOLDER)
|
||||
},
|
||||
|
||||
relaunch: () => {
|
||||
ipcRenderer.send(IpcChannels.RELAUNCH_REQUEST)
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {string} executable
|
||||
* @param {string} args
|
||||
*/
|
||||
openInExternalPlayer: (executable, args) => {
|
||||
ipcRenderer.send(IpcChannels.OPEN_IN_EXTERNAL_PLAYER, executable, args)
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {number} factor
|
||||
*/
|
||||
setZoomFactor: (factor) => {
|
||||
if (typeof factor === 'number' && factor > 0) {
|
||||
webFrame.setZoomFactor(factor)
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* @returns {Promise<{ label: string, value: number, active: boolean }[]>}
|
||||
*/
|
||||
getNavigationHistory: () => {
|
||||
return ipcRenderer.invoke(IpcChannels.GET_NAVIGATION_HISTORY)
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {number} action
|
||||
* @param {any} [data]
|
||||
*/
|
||||
dbSettings: (action, data) => {
|
||||
return ipcRenderer.invoke(IpcChannels.DB_SETTINGS, data ? { action, data } : { action })
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {number} action
|
||||
* @param {any} [data]
|
||||
*/
|
||||
dbHistory: (action, data) => {
|
||||
return ipcRenderer.invoke(IpcChannels.DB_HISTORY, data ? { action, data } : { action })
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {number} action
|
||||
* @param {any} [data]
|
||||
*/
|
||||
dbProfiles: (action, data) => {
|
||||
return ipcRenderer.invoke(IpcChannels.DB_PROFILES, data ? { action, data } : { action })
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {number} action
|
||||
* @param {any} [data]
|
||||
*/
|
||||
dbPlaylists: (action, data) => {
|
||||
return ipcRenderer.invoke(IpcChannels.DB_PLAYLISTS, data ? { action, data } : { action })
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {number} action
|
||||
* @param {any} [data]
|
||||
*/
|
||||
dbSearchHistory: (action, data) => {
|
||||
return ipcRenderer.invoke(IpcChannels.DB_SEARCH_HISTORY, data ? { action, data } : { action })
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {number} action
|
||||
* @param {any} [data]
|
||||
*/
|
||||
dbSubscriptionCache: (action, data) => {
|
||||
return ipcRenderer.invoke(IpcChannels.DB_SUBSCRIPTION_CACHE, data ? { action, data } : { action })
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {(route: string) => void} handler
|
||||
*/
|
||||
handleChangeView: (handler) => {
|
||||
ipcRenderer.on(IpcChannels.CHANGE_VIEW, (_, route) => {
|
||||
handler(route)
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {(url: string, isLaunchLink: boolean) => void} handler
|
||||
*/
|
||||
handleOpenUrl: (handler) => {
|
||||
ipcRenderer.on(IpcChannels.OPEN_URL, (_, url, isLaunchLink) => {
|
||||
handler(url, isLaunchLink)
|
||||
})
|
||||
ipcRenderer.send(IpcChannels.APP_READY)
|
||||
},
|
||||
|
||||
/**
|
||||
* Pass `null` to clear the handler
|
||||
* @param {(text: string) => void | null} handler
|
||||
*/
|
||||
handleUpdateSearchInputText: (handler) => {
|
||||
if (currentUpdateSearchInputTextListener) {
|
||||
ipcRenderer.off(IpcChannels.UPDATE_SEARCH_INPUT_TEXT, currentUpdateSearchInputTextListener)
|
||||
currentUpdateSearchInputTextListener = undefined
|
||||
}
|
||||
|
||||
if (handler) {
|
||||
currentUpdateSearchInputTextListener = (_, text) => {
|
||||
handler(text)
|
||||
}
|
||||
|
||||
ipcRenderer.on(IpcChannels.UPDATE_SEARCH_INPUT_TEXT, currentUpdateSearchInputTextListener)
|
||||
ipcRenderer.send(IpcChannels.SEARCH_INPUT_HANDLING_READY)
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {(event: number, data: any) => void} handler
|
||||
*/
|
||||
handleSyncSettings: (handler) => {
|
||||
ipcRenderer.on(IpcChannels.SYNC_SETTINGS, (_, { event, data }) => {
|
||||
handler(event, data)
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {(event: number, data: any) => void} handler
|
||||
*/
|
||||
handleSyncHistory: (handler) => {
|
||||
ipcRenderer.on(IpcChannels.SYNC_HISTORY, (_, { event, data }) => {
|
||||
handler(event, data)
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {(event: number, data: any) => void} handler
|
||||
*/
|
||||
handleSyncSearchHistory: (handler) => {
|
||||
ipcRenderer.on(IpcChannels.SYNC_SEARCH_HISTORY, (_, { event, data }) => {
|
||||
handler(event, data)
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {(event: number, data: any) => void} handler
|
||||
*/
|
||||
handleSyncProfiles: (handler) => {
|
||||
ipcRenderer.on(IpcChannels.SYNC_PROFILES, (_, { event, data }) => {
|
||||
handler(event, data)
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {(event: number, data: any) => void} handler
|
||||
*/
|
||||
handleSyncPlaylists: (handler) => {
|
||||
ipcRenderer.on(IpcChannels.SYNC_PLAYLISTS, (_, { event, data }) => {
|
||||
handler(event, data)
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {(event: number, data: any) => void} handler
|
||||
*/
|
||||
handleSyncSubscriptionCache: (handler) => {
|
||||
ipcRenderer.on(IpcChannels.SYNC_PLAYLISTS, (_, { event, data }) => {
|
||||
handler(event, data)
|
||||
})
|
||||
}
|
||||
}
|
||||
4
src/preload/main.js
Normal file
4
src/preload/main.js
Normal file
@@ -0,0 +1,4 @@
|
||||
import { contextBridge } from 'electron/renderer'
|
||||
import api from './interface.js'
|
||||
|
||||
contextBridge.exposeInMainWorld('ftElectron', api)
|
||||
7
src/preload/preload-interface.d.ts
vendored
Normal file
7
src/preload/preload-interface.d.ts
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
import api from './interface.js'
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
ftElectron: typeof api
|
||||
}
|
||||
}
|
||||
@@ -13,13 +13,10 @@ import FtCreatePlaylistPrompt from './components/FtCreatePlaylistPrompt/FtCreate
|
||||
import FtKeyboardShortcutPrompt from './components/FtKeyboardShortcutPrompt/FtKeyboardShortcutPrompt.vue'
|
||||
import FtSearchFilters from './components/FtSearchFilters/FtSearchFilters.vue'
|
||||
import { marked } from 'marked'
|
||||
import { IpcChannels } from '../constants'
|
||||
import packageDetails from '../../package.json'
|
||||
import { openExternalLink, openInternalPath, showToast } from './helpers/utils'
|
||||
import { translateWindowTitle } from './helpers/strings'
|
||||
|
||||
let ipcRenderer = null
|
||||
|
||||
export default defineComponent({
|
||||
name: 'App',
|
||||
components: {
|
||||
@@ -197,12 +194,10 @@ export default defineComponent({
|
||||
this.grabSearchHistoryEntries()
|
||||
|
||||
if (process.env.IS_ELECTRON) {
|
||||
ipcRenderer = require('electron').ipcRenderer
|
||||
this.setupListenersToSyncWindows()
|
||||
this.activateKeyboardShortcuts()
|
||||
this.openAllLinksExternally()
|
||||
this.enableOpenUrl()
|
||||
this.watchSystemTheme()
|
||||
await this.checkExternalPlayer()
|
||||
}
|
||||
|
||||
@@ -499,24 +494,12 @@ export default defineComponent({
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* Linux fix for dynamically updating theme preference, this works on
|
||||
* all systems running the electron app.
|
||||
*/
|
||||
watchSystemTheme: function () {
|
||||
ipcRenderer.on(IpcChannels.NATIVE_THEME_UPDATE, (event, shouldUseDarkColors) => {
|
||||
document.body.dataset.systemTheme = shouldUseDarkColors ? 'dark' : 'light'
|
||||
})
|
||||
},
|
||||
|
||||
enableOpenUrl: function () {
|
||||
ipcRenderer.on(IpcChannels.OPEN_URL, (event, url, { isLaunchLink = false } = { }) => {
|
||||
window.ftElectron.handleOpenUrl((url, isLaunchLink) => {
|
||||
if (url) {
|
||||
this.handleYoutubeLink(url, { doCreateNewWindow: this.openDeepLinksInNewWindow && !isLaunchLink })
|
||||
}
|
||||
})
|
||||
|
||||
ipcRenderer.send(IpcChannels.APP_READY)
|
||||
},
|
||||
|
||||
handleExternalLinkOpeningPromptAnswer: function (option) {
|
||||
|
||||
@@ -60,7 +60,7 @@ import FtToggleSwitch from '../ft-toggle-switch/ft-toggle-switch.vue'
|
||||
|
||||
import store from '../../store/index'
|
||||
|
||||
import { DefaultFolderKind, IpcChannels } from '../../../constants'
|
||||
import { DefaultFolderKind } from '../../../constants'
|
||||
|
||||
const DOWNLOAD_BEHAVIOR_VALUES = [
|
||||
'download',
|
||||
@@ -99,8 +99,7 @@ const downloadFolderPath = computed(() => store.getters.getDownloadFolderPath)
|
||||
|
||||
function chooseDownloadFolder() {
|
||||
if (process.env.IS_ELECTRON) {
|
||||
const { ipcRenderer } = require('electron')
|
||||
ipcRenderer.send(IpcChannels.CHOOSE_DEFAULT_FOLDER, DefaultFolderKind.DOWNLOADS)
|
||||
window.ftElectron.chooseDefaultFolder(DefaultFolderKind.DOWNLOADS)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -34,16 +34,13 @@ import FtFlexBox from '../ft-flex-box/ft-flex-box.vue'
|
||||
import FtToggleSwitch from '../ft-toggle-switch/ft-toggle-switch.vue'
|
||||
import FtPrompt from '../FtPrompt/FtPrompt.vue'
|
||||
|
||||
import { IpcChannels } from '../../../constants'
|
||||
|
||||
const replaceHttpCacheLoading = ref(true)
|
||||
const replaceHttpCache = ref(false)
|
||||
const showRestartPrompt = ref(false)
|
||||
|
||||
onMounted(async () => {
|
||||
if (process.env.IS_ELECTRON) {
|
||||
const { ipcRenderer } = require('electron')
|
||||
replaceHttpCache.value = await ipcRenderer.invoke(IpcChannels.GET_REPLACE_HTTP_CACHE)
|
||||
replaceHttpCache.value = await window.ftElectron.getReplaceHttpCache()
|
||||
}
|
||||
|
||||
replaceHttpCacheLoading.value = false
|
||||
@@ -69,8 +66,7 @@ function handleReplaceHttpCache(value) {
|
||||
}
|
||||
|
||||
if (process.env.IS_ELECTRON) {
|
||||
const { ipcRenderer } = require('electron')
|
||||
ipcRenderer.send(IpcChannels.TOGGLE_REPLACE_HTTP_CACHE)
|
||||
window.ftElectron.toggleReplaceHttpCache()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -106,7 +106,6 @@ import FtFlexBox from '../ft-flex-box/ft-flex-box.vue'
|
||||
|
||||
import store from '../../store/index'
|
||||
|
||||
import { IpcChannels } from '../../../constants'
|
||||
import { debounce, showToast } from '../../helpers/utils'
|
||||
|
||||
const { locale, t } = useI18n()
|
||||
@@ -233,8 +232,7 @@ function handleUpdateProxyPort(value) {
|
||||
|
||||
function enableProxy() {
|
||||
if (process.env.IS_ELECTRON) {
|
||||
const { ipcRenderer } = require('electron')
|
||||
ipcRenderer.send(IpcChannels.ENABLE_PROXY, proxyUrl.value)
|
||||
window.ftElectron.enableProxy(proxyUrl.value)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -242,8 +240,7 @@ const debouncedEnableProxy = debounce(enableProxy, 200)
|
||||
|
||||
function disableProxy() {
|
||||
if (process.env.IS_ELECTRON) {
|
||||
const { ipcRenderer } = require('electron')
|
||||
ipcRenderer.send(IpcChannels.DISABLE_PROXY)
|
||||
window.ftElectron.disableProxy()
|
||||
}
|
||||
|
||||
dataAvailable.value = false
|
||||
|
||||
@@ -107,7 +107,6 @@ import FtPrompt from './FtPrompt/FtPrompt.vue'
|
||||
import store from '../store/index'
|
||||
|
||||
import { colors } from '../helpers/colors'
|
||||
import { IpcChannels } from '../../constants'
|
||||
import { useColorTranslations } from '../composables/colors'
|
||||
|
||||
const { t } = useI18n()
|
||||
@@ -317,8 +316,7 @@ function handleSmoothScrolling(value) {
|
||||
store.dispatch('updateDisableSmoothScrolling',
|
||||
disableSmoothScrollingToggleValue.value
|
||||
).then(() => {
|
||||
const { ipcRenderer } = require('electron')
|
||||
ipcRenderer.send(IpcChannels.RELAUNCH_REQUEST)
|
||||
window.ftElectron.relaunch()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,7 +129,7 @@ import FtIconButton from '../ft-icon-button/ft-icon-button.vue'
|
||||
|
||||
import store from '../../store/index'
|
||||
|
||||
import { IpcChannels, KeyboardShortcuts, MOBILE_WIDTH_THRESHOLD, SEARCH_RESULTS_DISPLAY_LIMIT } from '../../../constants'
|
||||
import { KeyboardShortcuts, MOBILE_WIDTH_THRESHOLD, SEARCH_RESULTS_DISPLAY_LIMIT } from '../../../constants'
|
||||
import { debounce, localizeAndAddKeyboardShortcutToActionTitle, openInternalPath } from '../../helpers/utils'
|
||||
import { translateWindowTitle } from '../../helpers/strings'
|
||||
import { clearLocalSearchSuggestionsSession, getLocalSearchSuggestions } from '../../helpers/api/local'
|
||||
@@ -327,9 +327,7 @@ let pendingNavigationHistoryLabel = null
|
||||
async function setNavigationHistoryDropdownOptions() {
|
||||
if (process.env.IS_ELECTRON) {
|
||||
isLoadingNavigationHistory = true
|
||||
const { ipcRenderer } = require('electron')
|
||||
|
||||
const dropdownOptions = await ipcRenderer.invoke(IpcChannels.GET_NAVIGATION_HISTORY)
|
||||
const dropdownOptions = await window.ftElectron.getNavigationHistory()
|
||||
|
||||
const activeEntry = dropdownOptions.find(option => option.active)
|
||||
|
||||
@@ -618,16 +616,6 @@ function handleWindowResize() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('electron').IpcRendererEvent} event
|
||||
* @param {string} searchQueryText
|
||||
*/
|
||||
function handleUpdateSearchInputText(event, searchQueryText) {
|
||||
if (searchQueryText) {
|
||||
updateSearchInputText(searchQueryText)
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
previousWindowWidth = window.innerWidth
|
||||
if (window.innerWidth <= MOBILE_WIDTH_THRESHOLD) {
|
||||
@@ -646,9 +634,11 @@ onMounted(() => {
|
||||
if (process.env.IS_ELECTRON) {
|
||||
window.addEventListener('keydown', handleKeyboardShortcuts)
|
||||
|
||||
const { ipcRenderer } = require('electron')
|
||||
ipcRenderer.on(IpcChannels.UPDATE_SEARCH_INPUT_TEXT, handleUpdateSearchInputText)
|
||||
ipcRenderer.send(IpcChannels.SEARCH_INPUT_HANDLING_READY)
|
||||
window.ftElectron.handleUpdateSearchInputText((searchQueryText) => {
|
||||
if (searchQueryText) {
|
||||
updateSearchInputText(searchQueryText)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
@@ -658,8 +648,7 @@ onBeforeUnmount(() => {
|
||||
if (process.env.IS_ELECTRON) {
|
||||
window.removeEventListener('keydown', handleKeyboardShortcuts)
|
||||
|
||||
const { ipcRenderer } = require('electron')
|
||||
ipcRenderer.off(IpcChannels.UPDATE_SEARCH_INPUT_TEXT, handleUpdateSearchInputText)
|
||||
window.ftElectron.handleUpdateSearchInputText(null)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -3,7 +3,7 @@ import shaka from 'shaka-player'
|
||||
import { useI18n } from '../../composables/use-i18n-polyfill'
|
||||
|
||||
import store from '../../store/index'
|
||||
import { DefaultFolderKind, IpcChannels, KeyboardShortcuts } from '../../../constants'
|
||||
import { DefaultFolderKind, KeyboardShortcuts } from '../../../constants'
|
||||
import { AudioTrackSelection } from './player-components/AudioTrackSelection'
|
||||
import { FullWindowButton } from './player-components/FullWindowButton'
|
||||
import { LegacyQualitySelection } from './player-components/LegacyQualitySelection'
|
||||
@@ -1119,15 +1119,13 @@ export default defineComponent({
|
||||
|
||||
function startPowerSaveBlocker() {
|
||||
if (process.env.IS_ELECTRON) {
|
||||
const { ipcRenderer } = require('electron')
|
||||
ipcRenderer.send(IpcChannels.START_POWER_SAVE_BLOCKER)
|
||||
window.ftElectron.startPowerSaveBlocker()
|
||||
}
|
||||
}
|
||||
|
||||
function stopPowerSaveBlocker() {
|
||||
if (process.env.IS_ELECTRON) {
|
||||
const { ipcRenderer } = require('electron')
|
||||
ipcRenderer.send(IpcChannels.STOP_POWER_SAVE_BLOCKER)
|
||||
window.ftElectron.stopPowerSaveBlocker()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1165,8 +1163,7 @@ export default defineComponent({
|
||||
// PiP can only be activated once the video's readState and video track are populated
|
||||
if (startInPip && props.format !== 'audio' && ui.getControls().isPiPAllowed() && process.env.IS_ELECTRON) {
|
||||
startInPip = false
|
||||
const { ipcRenderer } = require('electron')
|
||||
ipcRenderer.send(IpcChannels.REQUEST_PIP)
|
||||
window.ftElectron.requestPiP()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1656,14 +1653,7 @@ export default defineComponent({
|
||||
} else {
|
||||
const arrayBuffer = await blob.arrayBuffer()
|
||||
|
||||
const { ipcRenderer } = require('electron')
|
||||
|
||||
await ipcRenderer.invoke(
|
||||
IpcChannels.WRITE_TO_DEFAULT_FOLDER,
|
||||
DefaultFolderKind.SCREENSHOTS,
|
||||
filenameWithExtension,
|
||||
arrayBuffer
|
||||
)
|
||||
await window.ftElectron.writeToDefaultFolder(DefaultFolderKind.SCREENSHOTS, filenameWithExtension, arrayBuffer)
|
||||
|
||||
showToast(t('Screenshot Success'))
|
||||
}
|
||||
@@ -2673,8 +2663,7 @@ export default defineComponent({
|
||||
|
||||
if (startInFullscreen && process.env.IS_ELECTRON) {
|
||||
startInFullscreen = false
|
||||
const { ipcRenderer } = require('electron')
|
||||
ipcRenderer.send(IpcChannels.REQUEST_FULLSCREEN)
|
||||
window.ftElectron.requestFullscreen()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import FtFlexBox from '../ft-flex-box/ft-flex-box.vue'
|
||||
import FtButton from '../FtButton/FtButton.vue'
|
||||
import FtInput from '../ft-input/ft-input.vue'
|
||||
import FtTooltip from '../FtTooltip/FtTooltip.vue'
|
||||
import { DefaultFolderKind, IpcChannels } from '../../../constants'
|
||||
import { DefaultFolderKind } from '../../../constants'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'PlayerSettings',
|
||||
@@ -277,8 +277,7 @@ export default defineComponent({
|
||||
|
||||
getScreenshotEmptyFolderPlaceholder: async function() {
|
||||
if (process.env.IS_ELECTRON) {
|
||||
const { ipcRenderer } = require('electron')
|
||||
return await ipcRenderer.invoke(IpcChannels.GET_SCREENSHOT_FALLBACK_FOLDER)
|
||||
return await window.ftElectron.getScreenshotFallbackFolder()
|
||||
} else {
|
||||
return ''
|
||||
}
|
||||
@@ -296,11 +295,10 @@ export default defineComponent({
|
||||
}
|
||||
},
|
||||
|
||||
chooseScreenshotFolder: async function() {
|
||||
chooseScreenshotFolder: function() {
|
||||
// only use with electron
|
||||
if (process.env.IS_ELECTRON) {
|
||||
const { ipcRenderer } = require('electron')
|
||||
ipcRenderer.send(IpcChannels.CHOOSE_DEFAULT_FOLDER, DefaultFolderKind.SCREENSHOTS)
|
||||
window.ftElectron.chooseDefaultFolder(DefaultFolderKind.SCREENSHOTS)
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -1,18 +1,10 @@
|
||||
import { IpcChannels } from '../../../constants'
|
||||
|
||||
export class PlayerCache {
|
||||
async get(key) {
|
||||
if (process.env.IS_ELECTRON) {
|
||||
const { ipcRenderer } = require('electron')
|
||||
return await ipcRenderer.invoke(IpcChannels.PLAYER_CACHE_GET, key)
|
||||
}
|
||||
return await window.ftElectron.playerCacheGet(key)
|
||||
}
|
||||
|
||||
async set(key, value) {
|
||||
if (process.env.IS_ELECTRON) {
|
||||
const { ipcRenderer } = require('electron')
|
||||
await ipcRenderer.invoke(IpcChannels.PLAYER_CACHE_SET, key, value)
|
||||
}
|
||||
await window.ftElectron.playerCacheSet(key, value)
|
||||
}
|
||||
|
||||
async remove(_key) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { ClientType, Innertube, Misc, Parser, UniversalCache, Utils, YT, YTNodes } from 'youtubei.js'
|
||||
import Autolinker from 'autolinker'
|
||||
import { IpcChannels, SEARCH_CHAR_LIMIT } from '../../../constants'
|
||||
import { SEARCH_CHAR_LIMIT } from '../../../constants'
|
||||
|
||||
import { PlayerCache } from './PlayerCache'
|
||||
import {
|
||||
@@ -206,11 +206,8 @@ export async function getLocalVideoInfo(id) {
|
||||
let sessionPoToken
|
||||
|
||||
if (process.env.IS_ELECTRON) {
|
||||
const { ipcRenderer } = require('electron')
|
||||
|
||||
try {
|
||||
({ contentPoToken, sessionPoToken } = await ipcRenderer.invoke(
|
||||
IpcChannels.GENERATE_PO_TOKENS,
|
||||
({ contentPoToken, sessionPoToken } = await window.ftElectron.generatePoTokens(
|
||||
id,
|
||||
webInnertube.session.context.client.visitorData,
|
||||
JSON.stringify(webInnertube.session.context)
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { IpcChannels } from '../../constants'
|
||||
import i18n from '../i18n/index'
|
||||
import router from '../router/index'
|
||||
import { nextTick } from 'vue'
|
||||
@@ -226,9 +225,7 @@ export async function openExternalLink(url) {
|
||||
*/
|
||||
export function openInternalPath({ path, query = undefined, doCreateNewWindow, searchQueryText = null }) {
|
||||
if (process.env.IS_ELECTRON && doCreateNewWindow) {
|
||||
const { ipcRenderer } = require('electron')
|
||||
|
||||
ipcRenderer.send(IpcChannels.CREATE_NEW_WINDOW, path, query, searchQueryText)
|
||||
window.ftElectron.openInNewWindow(path, query, searchQueryText)
|
||||
} else {
|
||||
router.push({
|
||||
path,
|
||||
@@ -532,8 +529,7 @@ export function replaceFilenameForbiddenChars(filenameOriginal) {
|
||||
export async function getSystemLocale() {
|
||||
let locale
|
||||
if (process.env.IS_ELECTRON) {
|
||||
const { ipcRenderer } = require('electron')
|
||||
locale = await ipcRenderer.invoke(IpcChannels.GET_SYSTEM_LOCALE)
|
||||
locale = await window.ftElectron.getSystemLocale()
|
||||
} else {
|
||||
if (navigator && navigator.language) {
|
||||
locale = navigator.language
|
||||
|
||||
@@ -4,7 +4,6 @@ import i18n from './i18n/index'
|
||||
import router from './router/index'
|
||||
import store from './store/index'
|
||||
import App from './App.vue'
|
||||
import { IpcChannels } from '../constants'
|
||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||
|
||||
import { register as registerSwiper } from 'swiper/element'
|
||||
@@ -278,12 +277,7 @@ Vue.use(PortalVue)
|
||||
|
||||
// to avoid accessing electron api from web app build
|
||||
if (process.env.IS_ELECTRON) {
|
||||
const { ipcRenderer } = require('electron')
|
||||
|
||||
// handle menu event updates from main script
|
||||
ipcRenderer.on(IpcChannels.CHANGE_VIEW, (event, data) => {
|
||||
if (data.route) {
|
||||
router.push(data.route)
|
||||
}
|
||||
window.ftElectron.handleChangeView((route) => {
|
||||
router.push(route)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { IpcChannels } from '../../../constants'
|
||||
import { base64EncodeUtf8, createWebURL, fetchWithTimeout, randomArrayItem } from '../../helpers/utils'
|
||||
|
||||
const state = {
|
||||
@@ -106,12 +105,10 @@ const mutations = {
|
||||
state.currentInvidiousInstanceUrl = instanceUrl
|
||||
|
||||
if (process.env.IS_ELECTRON) {
|
||||
const { ipcRenderer } = require('electron')
|
||||
|
||||
if (authorization) {
|
||||
ipcRenderer.send(IpcChannels.SET_INVIDIOUS_AUTHORIZATION, authorization, instanceUrl)
|
||||
window.ftElectron.setInvidiousAuthorization(authorization, instanceUrl)
|
||||
} else {
|
||||
ipcRenderer.send(IpcChannels.SET_INVIDIOUS_AUTHORIZATION, null)
|
||||
window.ftElectron.clearInvidiousAuthorization()
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import i18n, { loadLocale } from '../../i18n/index'
|
||||
import allLocales from '../../../../static/locales/activeLocales.json'
|
||||
import { MAIN_PROFILE_ID, IpcChannels, SyncEvents } from '../../../constants'
|
||||
import { MAIN_PROFILE_ID, SyncEvents } from '../../../constants'
|
||||
import { DBSettingHandlers } from '../../../datastores/handlers/index'
|
||||
import { getSystemLocale, showToast } from '../../helpers/utils'
|
||||
|
||||
@@ -398,8 +398,7 @@ const sideEffectHandlers = {
|
||||
|
||||
uiScale: (_, value) => {
|
||||
if (process.env.IS_ELECTRON) {
|
||||
const { webFrame } = require('electron')
|
||||
webFrame.setZoomFactor(value / 100)
|
||||
window.ftElectron.setZoomFactor(value / 100)
|
||||
}
|
||||
},
|
||||
|
||||
@@ -461,9 +460,7 @@ const customActions = {
|
||||
// Should be a root action, but we'll tolerate
|
||||
setupListenersToSyncWindows: ({ commit, dispatch }) => {
|
||||
if (process.env.IS_ELECTRON) {
|
||||
const { ipcRenderer } = require('electron')
|
||||
|
||||
ipcRenderer.on(IpcChannels.SYNC_SETTINGS, (_, { event, data }) => {
|
||||
window.ftElectron.handleSyncSettings((event, data) => {
|
||||
switch (event) {
|
||||
case SyncEvents.GENERAL.UPSERT:
|
||||
if (settingsWithSideEffects.includes(data._id)) {
|
||||
@@ -478,7 +475,7 @@ const customActions = {
|
||||
}
|
||||
})
|
||||
|
||||
ipcRenderer.on(IpcChannels.SYNC_HISTORY, (_, { event, data }) => {
|
||||
window.ftElectron.handleSyncHistory((event, data) => {
|
||||
switch (event) {
|
||||
case SyncEvents.GENERAL.UPSERT:
|
||||
commit('upsertToHistoryCache', data)
|
||||
@@ -518,7 +515,7 @@ const customActions = {
|
||||
}
|
||||
})
|
||||
|
||||
ipcRenderer.on(IpcChannels.SYNC_SEARCH_HISTORY, (_, { event, data }) => {
|
||||
window.ftElectron.handleSyncSearchHistory((event, data) => {
|
||||
switch (event) {
|
||||
case SyncEvents.GENERAL.UPSERT:
|
||||
commit('upsertSearchHistoryEntryToList', data)
|
||||
@@ -537,7 +534,7 @@ const customActions = {
|
||||
}
|
||||
})
|
||||
|
||||
ipcRenderer.on(IpcChannels.SYNC_PROFILES, (_, { event, data }) => {
|
||||
window.ftElectron.handleSyncProfiles((event, data) => {
|
||||
switch (event) {
|
||||
case SyncEvents.GENERAL.CREATE:
|
||||
commit('addProfileToList', data)
|
||||
@@ -564,7 +561,7 @@ const customActions = {
|
||||
}
|
||||
})
|
||||
|
||||
ipcRenderer.on(IpcChannels.SYNC_PLAYLISTS, (_, { event, data }) => {
|
||||
window.ftElectron.handleSyncPlaylists((event, data) => {
|
||||
switch (event) {
|
||||
case SyncEvents.GENERAL.CREATE:
|
||||
commit('addPlaylists', data)
|
||||
@@ -599,7 +596,7 @@ const customActions = {
|
||||
}
|
||||
})
|
||||
|
||||
ipcRenderer.on(IpcChannels.SYNC_SUBSCRIPTION_CACHE, (_, { event, data }) => {
|
||||
window.ftElectron.handleSyncSubscriptionCache((event, data) => {
|
||||
switch (event) {
|
||||
case SyncEvents.SUBSCRIPTION_CACHE.UPDATE_VIDEOS_BY_CHANNEL:
|
||||
commit('updateVideoCacheByChannel', data)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import i18n from '../../i18n/index'
|
||||
import { set as vueSet } from 'vue'
|
||||
|
||||
import { DefaultFolderKind, IpcChannels } from '../../../constants'
|
||||
import { DefaultFolderKind } from '../../../constants'
|
||||
import {
|
||||
CHANNEL_HANDLE_REGEX,
|
||||
createWebURL,
|
||||
@@ -260,14 +260,7 @@ const actions = {
|
||||
const arrayBuffer = await response.arrayBuffer()
|
||||
|
||||
if (process.env.IS_ELECTRON) {
|
||||
const { ipcRenderer } = require('electron')
|
||||
|
||||
await ipcRenderer.invoke(
|
||||
IpcChannels.WRITE_TO_DEFAULT_FOLDER,
|
||||
DefaultFolderKind.DOWNLOADS,
|
||||
fileName,
|
||||
arrayBuffer
|
||||
)
|
||||
await window.ftElectron.writeToDefaultFolder(DefaultFolderKind.DOWNLOADS, fileName, arrayBuffer)
|
||||
}
|
||||
|
||||
showToast(i18n.t('Downloading has completed', { videoTitle: title }))
|
||||
@@ -800,8 +793,7 @@ const actions = {
|
||||
showToast(i18n.t('Video.External Player.OpeningTemplate', { videoOrPlaylist, externalPlayer }))
|
||||
|
||||
if (process.env.IS_ELECTRON) {
|
||||
const { ipcRenderer } = require('electron')
|
||||
ipcRenderer.send(IpcChannels.OPEN_IN_EXTERNAL_PLAYER, { executable, args })
|
||||
window.ftElectron.openInExternalPlayer(executable, args)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user