2021-05-22 01:49:48 +02:00
|
|
|
import {
|
2021-06-16 05:50:30 +02:00
|
|
|
app, BrowserWindow, dialog, Menu, ipcMain,
|
2022-12-13 10:39:22 +01:00
|
|
|
powerSaveBlocker, screen, session, shell,
|
|
|
|
nativeTheme, net, protocol, clipboard
|
2021-05-22 01:49:48 +02:00
|
|
|
} from 'electron'
|
2021-06-07 02:38:06 +02:00
|
|
|
import path from 'path'
|
2021-06-13 17:31:43 +02:00
|
|
|
import cp from 'child_process'
|
2020-02-16 19:30:00 +01:00
|
|
|
|
Store Revamp / Full database synchronization across windows (#1833)
* History: Refactor history module
* Profiles: Refactor profiles module
* IPC: Move channel ids to their own file and make them constants
* IPC: Replace single sync channel for one channel per sync type
* Everywhere: Replace default profile id magic strings with constant ref
* Profiles: Refactor `activeProfile` property from store
This commit makes it so that `activeProfile`'s getter returns
the entire profile, while the related update function only needs
the profile id (instead of the previously used array index)
to change the currently active profile.
This change was made due to inconsistency regarding the active profile
when creating new profiles.
If a new profile coincidentally landed in the current active profile's
array index after sorting, the app would mistakenly change to it
without any action from the user apart from the profile's creation.
Turning the profile id into the selector instead solves this issue.
* Revert "Store: Implement history synchronization between windows"
This reverts commit 99b61e617873412eb393d8f4dfccd8f8c172021f.
This is necessary for an upcoming improved implementation of the
history synchronization.
* History: Remove unused mutation
* Everywhere: Create abstract database handlers
The project now utilizes abstract handlers to fetch, modify
or otherwise manipulate data from the database.
This facilitates 3 aspects of the app, in addition of
making them future proof:
- Switching database libraries is now trivial
Since most of the app utilizes the abstract handlers, it's incredibly
easily to change to a different DB library.
Hypothetically, all that would need to be done is to simply replace the
the file containing the base handlers, while the rest of the app
would go unchanged.
- Syncing logic between Electron and web is now properly separated
There are now two distinct DB handling APIs: the Electron one and
the web one.
The app doesn't need to manually choose the API, because it's detected
which platform is being utilized on import.
- All Electron windows now share the same database instance
This provides a single source of truth, improving consistency
regarding data manipulation and windows synchronization.
As a sidenote, syncing implementation has been left as is
(web unimplemented; Electron only syncs settings, remaining
datastore syncing will be implemented in the upcoming commits).
* Electron/History: Implement history synchronization
* Profiles: Implement suplementary profile creation logic
* ft-profile-edit: Small fix on profile name missing display
* Electron/Profiles: Implement profile synchronization
* Electron/Playlists: Implement playlist synchronization
2021-12-15 19:42:24 +01:00
|
|
|
import { IpcChannels, DBActions, SyncEvents } from '../constants'
|
|
|
|
import baseHandlers from '../datastores/handlers/base'
|
2022-10-25 04:33:08 +02:00
|
|
|
import { extractExpiryTimestamp, ImageCache } from './ImageCache'
|
|
|
|
import { existsSync } from 'fs'
|
Store Revamp / Full database synchronization across windows (#1833)
* History: Refactor history module
* Profiles: Refactor profiles module
* IPC: Move channel ids to their own file and make them constants
* IPC: Replace single sync channel for one channel per sync type
* Everywhere: Replace default profile id magic strings with constant ref
* Profiles: Refactor `activeProfile` property from store
This commit makes it so that `activeProfile`'s getter returns
the entire profile, while the related update function only needs
the profile id (instead of the previously used array index)
to change the currently active profile.
This change was made due to inconsistency regarding the active profile
when creating new profiles.
If a new profile coincidentally landed in the current active profile's
array index after sorting, the app would mistakenly change to it
without any action from the user apart from the profile's creation.
Turning the profile id into the selector instead solves this issue.
* Revert "Store: Implement history synchronization between windows"
This reverts commit 99b61e617873412eb393d8f4dfccd8f8c172021f.
This is necessary for an upcoming improved implementation of the
history synchronization.
* History: Remove unused mutation
* Everywhere: Create abstract database handlers
The project now utilizes abstract handlers to fetch, modify
or otherwise manipulate data from the database.
This facilitates 3 aspects of the app, in addition of
making them future proof:
- Switching database libraries is now trivial
Since most of the app utilizes the abstract handlers, it's incredibly
easily to change to a different DB library.
Hypothetically, all that would need to be done is to simply replace the
the file containing the base handlers, while the rest of the app
would go unchanged.
- Syncing logic between Electron and web is now properly separated
There are now two distinct DB handling APIs: the Electron one and
the web one.
The app doesn't need to manually choose the API, because it's detected
which platform is being utilized on import.
- All Electron windows now share the same database instance
This provides a single source of truth, improving consistency
regarding data manipulation and windows synchronization.
As a sidenote, syncing implementation has been left as is
(web unimplemented; Electron only syncs settings, remaining
datastore syncing will be implemented in the upcoming commits).
* Electron/History: Implement history synchronization
* Profiles: Implement suplementary profile creation logic
* ft-profile-edit: Small fix on profile name missing display
* Electron/Profiles: Implement profile synchronization
* Electron/Playlists: Implement playlist synchronization
2021-12-15 19:42:24 +01:00
|
|
|
|
2023-07-03 04:39:18 +02:00
|
|
|
import packageDetails from '../../package.json'
|
|
|
|
|
2021-03-07 17:07:09 +01:00
|
|
|
if (process.argv.includes('--version')) {
|
2021-06-07 02:38:06 +02:00
|
|
|
app.exit()
|
2020-10-15 15:33:25 +02:00
|
|
|
} else {
|
2021-03-07 17:07:09 +01:00
|
|
|
runApp()
|
2020-10-15 15:33:25 +02:00
|
|
|
}
|
2020-10-04 22:31:07 +02:00
|
|
|
|
2021-03-07 17:07:09 +01:00
|
|
|
function runApp() {
|
|
|
|
require('electron-context-menu')({
|
|
|
|
showSearchWithGoogle: false,
|
|
|
|
showSaveImageAs: true,
|
|
|
|
showCopyImageAddress: true,
|
2022-12-01 08:46:33 +01:00
|
|
|
showSelectAll: false,
|
2022-12-13 10:39:22 +01:00
|
|
|
showCopyLink: false,
|
Stats for nerds (#1867)
* transition duration of 0.5s added to watched videos
* small code reformating
* extra white spaces deleted
* typo in the word transition corrected
* original whitespaces respected
* transition added when hovering end
* video stat components started and properties chosen
* ft-video-stats integraded into the video player for dev and debugging
* using a timer to get video stats and a method to update the statistic every second
* getting statistic from vhs and adaptativeFormat
* frame drop capture
* stats capture in the form of event
* useless comment deleted
* stats render with a for loop in the template
* stats correctly displayed
* overlay stats added
* video stats component deleted
* video stats component deleted inside template video player
* video stats component fully deleted
* modal solution working need more styling and code messy
* lint
* modal working with stats
* keyboard shortcut for stats
* lint fix
* network state is now a string
* new line deleted
* useless whitespace deleted
* package-lock.json remove and ignore
* keyboard shortcut restricted to up arrow
* stats overlay made larger
* align to left corner
* useless formatting of string deleted
* renaming of variable formatedStrats for formattedStats
* keyboard shortcut made into a variable
* lint-fix
* key change for i
* label translated
* whitespace added for gitignore
* lock file not ignored
* videoId stat deleted
* ft-video-player.js, en-US.yaml, fr-FR.yaml: changing percentage stats display
changing the display for percentage stats for the format 'x%' instead of 'xx.xx'
* ft-video-player.js, en-US.yaml, fr-FR.yaml: network state video statistic deleted
* ft-video-player.js: made stats modal background color darker
* ft-video-player.js, en-US.yaml, fr-FR.yaml: video id are now related to the one of youtube
* ft-video-player.js, en-US.yaml, fr-FR.yaml: stats displayed made closet to the youtube implementation
the name are capitalized, the order of display is changed and fps is combined with viewport
* lint-fix
* en-US.yaml, fr-FR.yaml: network state possibilities deleted because not used
* package.json.lock: deleted
* ft-video-player.js: formated_stats renamed for formatted_stats
* lock file deleted
* index.js, ft-video-player.js: handling of right click context menu
via electon ipc bus an event is send to tell the vue component to show the stats modal
* ft-video-player.js, index.js: renaming of video stats display event and definition of it as a variable
* index.js, en-US.yaml: inconsistant capitalization of video statistics label solved
* index.js: pluralized video stats
* ft-video-player.js: fix right click undefined this.player
change the arrow function inside the closure for a function with a bind to this
* ft-video-player.js: handling of the case when this.player is not defined
the property this.stats.display.activated as been added and manage when the to show the stats. In this way in the runtime (it is still refered in the run time but it is capture in an event loop) with dont have to refer to this.player so when it is not defined it doesnt affect the behavior.
* lint fix
* src/renderer/components/ft-video-player/ft-video-player.js: modal.close move into the display event of the statistic context
* lint fix
* src/renderer/components/ft-video-player/ft-video-player.js, static/locales/en-US.yaml, static/locales/fr-FR.yaml: better capitalization of the stats labels
* static/locales/en-US.yaml: fps capitalized
* static/locales/fr-FR.yaml, static/locales/en-US.yaml: capitalized label
2021-11-23 12:34:04 +01:00
|
|
|
prepend: (defaultActions, parameters, browserWindow) => [
|
|
|
|
{
|
2022-10-11 03:26:31 +02:00
|
|
|
label: 'Show / Hide Video Statistics',
|
Stats for nerds (#1867)
* transition duration of 0.5s added to watched videos
* small code reformating
* extra white spaces deleted
* typo in the word transition corrected
* original whitespaces respected
* transition added when hovering end
* video stat components started and properties chosen
* ft-video-stats integraded into the video player for dev and debugging
* using a timer to get video stats and a method to update the statistic every second
* getting statistic from vhs and adaptativeFormat
* frame drop capture
* stats capture in the form of event
* useless comment deleted
* stats render with a for loop in the template
* stats correctly displayed
* overlay stats added
* video stats component deleted
* video stats component deleted inside template video player
* video stats component fully deleted
* modal solution working need more styling and code messy
* lint
* modal working with stats
* keyboard shortcut for stats
* lint fix
* network state is now a string
* new line deleted
* useless whitespace deleted
* package-lock.json remove and ignore
* keyboard shortcut restricted to up arrow
* stats overlay made larger
* align to left corner
* useless formatting of string deleted
* renaming of variable formatedStrats for formattedStats
* keyboard shortcut made into a variable
* lint-fix
* key change for i
* label translated
* whitespace added for gitignore
* lock file not ignored
* videoId stat deleted
* ft-video-player.js, en-US.yaml, fr-FR.yaml: changing percentage stats display
changing the display for percentage stats for the format 'x%' instead of 'xx.xx'
* ft-video-player.js, en-US.yaml, fr-FR.yaml: network state video statistic deleted
* ft-video-player.js: made stats modal background color darker
* ft-video-player.js, en-US.yaml, fr-FR.yaml: video id are now related to the one of youtube
* ft-video-player.js, en-US.yaml, fr-FR.yaml: stats displayed made closet to the youtube implementation
the name are capitalized, the order of display is changed and fps is combined with viewport
* lint-fix
* en-US.yaml, fr-FR.yaml: network state possibilities deleted because not used
* package.json.lock: deleted
* ft-video-player.js: formated_stats renamed for formatted_stats
* lock file deleted
* index.js, ft-video-player.js: handling of right click context menu
via electon ipc bus an event is send to tell the vue component to show the stats modal
* ft-video-player.js, index.js: renaming of video stats display event and definition of it as a variable
* index.js, en-US.yaml: inconsistant capitalization of video statistics label solved
* index.js: pluralized video stats
* ft-video-player.js: fix right click undefined this.player
change the arrow function inside the closure for a function with a bind to this
* ft-video-player.js: handling of the case when this.player is not defined
the property this.stats.display.activated as been added and manage when the to show the stats. In this way in the runtime (it is still refered in the run time but it is capture in an event loop) with dont have to refer to this.player so when it is not defined it doesnt affect the behavior.
* lint fix
* src/renderer/components/ft-video-player/ft-video-player.js: modal.close move into the display event of the statistic context
* lint fix
* src/renderer/components/ft-video-player/ft-video-player.js, static/locales/en-US.yaml, static/locales/fr-FR.yaml: better capitalization of the stats labels
* static/locales/en-US.yaml: fps capitalized
* static/locales/fr-FR.yaml, static/locales/en-US.yaml: capitalized label
2021-11-23 12:34:04 +01:00
|
|
|
visible: parameters.mediaType === 'video',
|
|
|
|
click: () => {
|
2022-02-19 23:17:58 +01:00
|
|
|
browserWindow.webContents.send('showVideoStatistics')
|
Stats for nerds (#1867)
* transition duration of 0.5s added to watched videos
* small code reformating
* extra white spaces deleted
* typo in the word transition corrected
* original whitespaces respected
* transition added when hovering end
* video stat components started and properties chosen
* ft-video-stats integraded into the video player for dev and debugging
* using a timer to get video stats and a method to update the statistic every second
* getting statistic from vhs and adaptativeFormat
* frame drop capture
* stats capture in the form of event
* useless comment deleted
* stats render with a for loop in the template
* stats correctly displayed
* overlay stats added
* video stats component deleted
* video stats component deleted inside template video player
* video stats component fully deleted
* modal solution working need more styling and code messy
* lint
* modal working with stats
* keyboard shortcut for stats
* lint fix
* network state is now a string
* new line deleted
* useless whitespace deleted
* package-lock.json remove and ignore
* keyboard shortcut restricted to up arrow
* stats overlay made larger
* align to left corner
* useless formatting of string deleted
* renaming of variable formatedStrats for formattedStats
* keyboard shortcut made into a variable
* lint-fix
* key change for i
* label translated
* whitespace added for gitignore
* lock file not ignored
* videoId stat deleted
* ft-video-player.js, en-US.yaml, fr-FR.yaml: changing percentage stats display
changing the display for percentage stats for the format 'x%' instead of 'xx.xx'
* ft-video-player.js, en-US.yaml, fr-FR.yaml: network state video statistic deleted
* ft-video-player.js: made stats modal background color darker
* ft-video-player.js, en-US.yaml, fr-FR.yaml: video id are now related to the one of youtube
* ft-video-player.js, en-US.yaml, fr-FR.yaml: stats displayed made closet to the youtube implementation
the name are capitalized, the order of display is changed and fps is combined with viewport
* lint-fix
* en-US.yaml, fr-FR.yaml: network state possibilities deleted because not used
* package.json.lock: deleted
* ft-video-player.js: formated_stats renamed for formatted_stats
* lock file deleted
* index.js, ft-video-player.js: handling of right click context menu
via electon ipc bus an event is send to tell the vue component to show the stats modal
* ft-video-player.js, index.js: renaming of video stats display event and definition of it as a variable
* index.js, en-US.yaml: inconsistant capitalization of video statistics label solved
* index.js: pluralized video stats
* ft-video-player.js: fix right click undefined this.player
change the arrow function inside the closure for a function with a bind to this
* ft-video-player.js: handling of the case when this.player is not defined
the property this.stats.display.activated as been added and manage when the to show the stats. In this way in the runtime (it is still refered in the run time but it is capture in an event loop) with dont have to refer to this.player so when it is not defined it doesnt affect the behavior.
* lint fix
* src/renderer/components/ft-video-player/ft-video-player.js: modal.close move into the display event of the statistic context
* lint fix
* src/renderer/components/ft-video-player/ft-video-player.js, static/locales/en-US.yaml, static/locales/fr-FR.yaml: better capitalization of the stats labels
* static/locales/en-US.yaml: fps capitalized
* static/locales/fr-FR.yaml, static/locales/en-US.yaml: capitalized label
2021-11-23 12:34:04 +01:00
|
|
|
}
|
2022-09-22 15:03:18 +02:00
|
|
|
},
|
|
|
|
{
|
|
|
|
label: 'Open in a New Window',
|
2022-11-21 22:29:24 +01:00
|
|
|
// Only show the option for in-app URLs and not external ones
|
|
|
|
visible: parameters.linkURL.split('#')[0] === browserWindow.webContents.getURL().split('#')[0],
|
2022-09-22 15:03:18 +02:00
|
|
|
click: () => {
|
|
|
|
createWindow({ replaceMainWindow: false, windowStartupUrl: parameters.linkURL, showWindowNow: true })
|
|
|
|
}
|
2022-12-01 08:46:33 +01:00
|
|
|
},
|
|
|
|
// Only show select all in text fields
|
|
|
|
{
|
|
|
|
label: 'Select All',
|
|
|
|
enabled: parameters.editFlags.canSelectAll,
|
|
|
|
visible: parameters.isEditable,
|
|
|
|
click: () => {
|
|
|
|
browserWindow.webContents.selectAll()
|
|
|
|
}
|
Stats for nerds (#1867)
* transition duration of 0.5s added to watched videos
* small code reformating
* extra white spaces deleted
* typo in the word transition corrected
* original whitespaces respected
* transition added when hovering end
* video stat components started and properties chosen
* ft-video-stats integraded into the video player for dev and debugging
* using a timer to get video stats and a method to update the statistic every second
* getting statistic from vhs and adaptativeFormat
* frame drop capture
* stats capture in the form of event
* useless comment deleted
* stats render with a for loop in the template
* stats correctly displayed
* overlay stats added
* video stats component deleted
* video stats component deleted inside template video player
* video stats component fully deleted
* modal solution working need more styling and code messy
* lint
* modal working with stats
* keyboard shortcut for stats
* lint fix
* network state is now a string
* new line deleted
* useless whitespace deleted
* package-lock.json remove and ignore
* keyboard shortcut restricted to up arrow
* stats overlay made larger
* align to left corner
* useless formatting of string deleted
* renaming of variable formatedStrats for formattedStats
* keyboard shortcut made into a variable
* lint-fix
* key change for i
* label translated
* whitespace added for gitignore
* lock file not ignored
* videoId stat deleted
* ft-video-player.js, en-US.yaml, fr-FR.yaml: changing percentage stats display
changing the display for percentage stats for the format 'x%' instead of 'xx.xx'
* ft-video-player.js, en-US.yaml, fr-FR.yaml: network state video statistic deleted
* ft-video-player.js: made stats modal background color darker
* ft-video-player.js, en-US.yaml, fr-FR.yaml: video id are now related to the one of youtube
* ft-video-player.js, en-US.yaml, fr-FR.yaml: stats displayed made closet to the youtube implementation
the name are capitalized, the order of display is changed and fps is combined with viewport
* lint-fix
* en-US.yaml, fr-FR.yaml: network state possibilities deleted because not used
* package.json.lock: deleted
* ft-video-player.js: formated_stats renamed for formatted_stats
* lock file deleted
* index.js, ft-video-player.js: handling of right click context menu
via electon ipc bus an event is send to tell the vue component to show the stats modal
* ft-video-player.js, index.js: renaming of video stats display event and definition of it as a variable
* index.js, en-US.yaml: inconsistant capitalization of video statistics label solved
* index.js: pluralized video stats
* ft-video-player.js: fix right click undefined this.player
change the arrow function inside the closure for a function with a bind to this
* ft-video-player.js: handling of the case when this.player is not defined
the property this.stats.display.activated as been added and manage when the to show the stats. In this way in the runtime (it is still refered in the run time but it is capture in an event loop) with dont have to refer to this.player so when it is not defined it doesnt affect the behavior.
* lint fix
* src/renderer/components/ft-video-player/ft-video-player.js: modal.close move into the display event of the statistic context
* lint fix
* src/renderer/components/ft-video-player/ft-video-player.js, static/locales/en-US.yaml, static/locales/fr-FR.yaml: better capitalization of the stats labels
* static/locales/en-US.yaml: fps capitalized
* static/locales/fr-FR.yaml, static/locales/en-US.yaml: capitalized label
2021-11-23 12:34:04 +01:00
|
|
|
}
|
2022-12-13 10:39:22 +01:00
|
|
|
],
|
|
|
|
// only show the copy link entry for external links and the /playlist, /channel and /watch in-app URLs
|
2022-12-14 02:18:36 +01:00
|
|
|
// the /playlist, /channel and /watch in-app URLs get transformed to their equivalent YouTube or Invidious URLs
|
2022-12-13 10:39:22 +01:00
|
|
|
append: (defaultActions, parameters, browserWindow) => {
|
|
|
|
let visible = false
|
|
|
|
const urlParts = parameters.linkURL.split('#')
|
|
|
|
const isInAppUrl = urlParts[0] === browserWindow.webContents.getURL().split('#')[0]
|
|
|
|
|
|
|
|
if (parameters.linkURL.length > 0) {
|
|
|
|
if (isInAppUrl) {
|
|
|
|
const path = urlParts[1]
|
|
|
|
|
|
|
|
if (path) {
|
|
|
|
visible = ['/playlist', '/channel', '/watch'].some(p => path.startsWith(p))
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
visible = true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-12-14 02:18:36 +01:00
|
|
|
const copy = (url) => {
|
|
|
|
if (parameters.linkText) {
|
|
|
|
clipboard.write({
|
|
|
|
bookmark: parameters.linkText,
|
|
|
|
text: url
|
|
|
|
})
|
|
|
|
} else {
|
|
|
|
clipboard.writeText(url)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const transformURL = (toYouTube) => {
|
|
|
|
let origin
|
|
|
|
|
|
|
|
if (toYouTube) {
|
|
|
|
origin = 'https://www.youtube.com'
|
|
|
|
} else {
|
|
|
|
origin = 'https://redirect.invidious.io'
|
|
|
|
}
|
|
|
|
|
|
|
|
const [path, query] = urlParts[1].split('?')
|
|
|
|
const [route, id] = path.split('/').filter(p => p)
|
|
|
|
|
|
|
|
switch (route) {
|
|
|
|
case 'playlist':
|
|
|
|
return `${origin}/playlist?list=${id}`
|
|
|
|
case 'channel':
|
|
|
|
return `${origin}/channel/${id}`
|
|
|
|
case 'watch': {
|
|
|
|
let url
|
|
|
|
|
|
|
|
if (toYouTube) {
|
|
|
|
url = `https://youtu.be/${id}`
|
|
|
|
} else {
|
|
|
|
url = `https://redirect.invidious.io/watch?v=${id}`
|
|
|
|
}
|
|
|
|
|
|
|
|
if (query) {
|
|
|
|
const params = new URLSearchParams(query)
|
|
|
|
const newParams = new URLSearchParams()
|
|
|
|
let hasParams = false
|
|
|
|
|
|
|
|
if (params.has('playlistId')) {
|
|
|
|
newParams.set('list', params.get('playlistId'))
|
|
|
|
hasParams = true
|
|
|
|
}
|
|
|
|
|
|
|
|
if (params.has('timestamp')) {
|
|
|
|
newParams.set('t', params.get('timestamp'))
|
|
|
|
hasParams = true
|
|
|
|
}
|
|
|
|
|
|
|
|
if (hasParams) {
|
|
|
|
url += '?' + newParams.toString()
|
2022-12-13 10:39:22 +01:00
|
|
|
}
|
|
|
|
}
|
2022-12-14 02:18:36 +01:00
|
|
|
|
|
|
|
return url
|
2022-12-13 10:39:22 +01:00
|
|
|
}
|
2022-12-14 02:18:36 +01:00
|
|
|
}
|
|
|
|
}
|
2022-12-13 10:39:22 +01:00
|
|
|
|
2022-12-14 02:18:36 +01:00
|
|
|
return [
|
|
|
|
{
|
|
|
|
label: 'Copy Lin&k',
|
|
|
|
visible: visible && !isInAppUrl,
|
|
|
|
click: () => {
|
|
|
|
copy(parameters.linkURL)
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{
|
|
|
|
label: 'Copy YouTube Link',
|
|
|
|
visible: visible && isInAppUrl,
|
|
|
|
click: () => {
|
|
|
|
copy(transformURL(true))
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{
|
|
|
|
label: 'Copy Invidious Link',
|
|
|
|
visible: visible && isInAppUrl,
|
|
|
|
click: () => {
|
|
|
|
copy(transformURL(false))
|
2022-12-13 10:39:22 +01:00
|
|
|
}
|
|
|
|
}
|
2022-12-14 02:18:36 +01:00
|
|
|
]
|
2022-12-13 10:39:22 +01:00
|
|
|
}
|
2021-03-07 17:07:09 +01:00
|
|
|
})
|
|
|
|
|
|
|
|
// disable electron warning
|
|
|
|
process.env.ELECTRON_DISABLE_SECURITY_WARNINGS = 'true'
|
|
|
|
const isDebug = process.argv.includes('--debug')
|
2022-05-11 16:30:40 +02:00
|
|
|
|
2021-03-07 17:07:09 +01:00
|
|
|
let mainWindow
|
|
|
|
let startupUrl
|
|
|
|
|
2024-01-14 16:48:19 +01:00
|
|
|
if (process.platform === 'linux') {
|
|
|
|
// Enable hardware acceleration via VA-API
|
|
|
|
// https://chromium.googlesource.com/chromium/src/+/refs/heads/main/docs/gpu/vaapi.md
|
|
|
|
app.commandLine.appendSwitch('enable-features', 'VaapiVideoDecodeLinuxGL')
|
|
|
|
}
|
2021-03-07 17:07:09 +01:00
|
|
|
|
2023-12-09 14:57:22 +01:00
|
|
|
// Work around for context menus in the devtools being displayed behind the window
|
|
|
|
// https://github.com/electron/electron/issues/38790
|
|
|
|
app.commandLine.appendSwitch('disable-features', 'WidgetLayering')
|
|
|
|
|
2022-10-25 04:33:08 +02:00
|
|
|
// command line switches need to be added before the app ready event first
|
2023-10-18 18:23:21 +02:00
|
|
|
// that means we can't use the normal settings system as that is asynchronous,
|
2022-10-25 04:33:08 +02:00
|
|
|
// doing it synchronously ensures that we add it before the event fires
|
|
|
|
const replaceHttpCache = existsSync(`${app.getPath('userData')}/experiment-replace-http-cache`)
|
|
|
|
if (replaceHttpCache) {
|
|
|
|
// the http cache causes excessive disk usage during video playback
|
|
|
|
// we've got a custom image cache to make up for disabling the http cache
|
|
|
|
// experimental as it increases RAM use in favour of reduced disk use
|
|
|
|
app.commandLine.appendSwitch('disable-http-cache')
|
|
|
|
}
|
|
|
|
|
2021-03-07 17:07:09 +01:00
|
|
|
// See: https://stackoverflow.com/questions/45570589/electron-protocol-handler-not-working-on-windows
|
|
|
|
// remove so we can register each time as we run the app.
|
|
|
|
app.removeAsDefaultProtocolClient('freetube')
|
|
|
|
|
|
|
|
// If we are running a non-packaged version of the app && on windows
|
2022-11-05 15:44:21 +01:00
|
|
|
if (process.env.NODE_ENV === 'development' && process.platform === 'win32') {
|
2021-03-07 17:07:09 +01:00
|
|
|
// Set the path of electron.exe and your app.
|
|
|
|
// These two additional parameters are only available on windows.
|
|
|
|
app.setAsDefaultProtocolClient('freetube', process.execPath, [path.resolve(process.argv[1])])
|
|
|
|
} else {
|
|
|
|
app.setAsDefaultProtocolClient('freetube')
|
|
|
|
}
|
|
|
|
|
2022-11-05 15:44:21 +01:00
|
|
|
if (process.env.NODE_ENV !== 'development') {
|
2021-06-07 02:38:06 +02:00
|
|
|
// Only allow single instance of the application
|
2021-03-07 17:07:09 +01:00
|
|
|
const gotTheLock = app.requestSingleInstanceLock()
|
2021-06-07 02:38:06 +02:00
|
|
|
if (!gotTheLock) {
|
|
|
|
app.quit()
|
|
|
|
}
|
2021-03-07 17:07:09 +01:00
|
|
|
|
2021-06-07 02:38:06 +02:00
|
|
|
app.on('second-instance', (_, commandLine, __) => {
|
|
|
|
// Someone tried to run a second instance, we should focus our window
|
|
|
|
if (mainWindow && typeof commandLine !== 'undefined') {
|
|
|
|
if (mainWindow.isMinimized()) mainWindow.restore()
|
|
|
|
mainWindow.focus()
|
2021-03-07 17:07:09 +01:00
|
|
|
|
2021-06-07 02:38:06 +02:00
|
|
|
const url = getLinkUrl(commandLine)
|
|
|
|
if (url) {
|
|
|
|
mainWindow.webContents.send('openUrl', url)
|
2020-10-15 15:33:25 +02:00
|
|
|
}
|
2021-06-07 02:38:06 +02:00
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
2020-10-04 22:31:07 +02:00
|
|
|
|
2021-06-17 05:16:52 +02:00
|
|
|
app.on('ready', async (_, __) => {
|
|
|
|
let docArray
|
|
|
|
try {
|
Store Revamp / Full database synchronization across windows (#1833)
* History: Refactor history module
* Profiles: Refactor profiles module
* IPC: Move channel ids to their own file and make them constants
* IPC: Replace single sync channel for one channel per sync type
* Everywhere: Replace default profile id magic strings with constant ref
* Profiles: Refactor `activeProfile` property from store
This commit makes it so that `activeProfile`'s getter returns
the entire profile, while the related update function only needs
the profile id (instead of the previously used array index)
to change the currently active profile.
This change was made due to inconsistency regarding the active profile
when creating new profiles.
If a new profile coincidentally landed in the current active profile's
array index after sorting, the app would mistakenly change to it
without any action from the user apart from the profile's creation.
Turning the profile id into the selector instead solves this issue.
* Revert "Store: Implement history synchronization between windows"
This reverts commit 99b61e617873412eb393d8f4dfccd8f8c172021f.
This is necessary for an upcoming improved implementation of the
history synchronization.
* History: Remove unused mutation
* Everywhere: Create abstract database handlers
The project now utilizes abstract handlers to fetch, modify
or otherwise manipulate data from the database.
This facilitates 3 aspects of the app, in addition of
making them future proof:
- Switching database libraries is now trivial
Since most of the app utilizes the abstract handlers, it's incredibly
easily to change to a different DB library.
Hypothetically, all that would need to be done is to simply replace the
the file containing the base handlers, while the rest of the app
would go unchanged.
- Syncing logic between Electron and web is now properly separated
There are now two distinct DB handling APIs: the Electron one and
the web one.
The app doesn't need to manually choose the API, because it's detected
which platform is being utilized on import.
- All Electron windows now share the same database instance
This provides a single source of truth, improving consistency
regarding data manipulation and windows synchronization.
As a sidenote, syncing implementation has been left as is
(web unimplemented; Electron only syncs settings, remaining
datastore syncing will be implemented in the upcoming commits).
* Electron/History: Implement history synchronization
* Profiles: Implement suplementary profile creation logic
* ft-profile-edit: Small fix on profile name missing display
* Electron/Profiles: Implement profile synchronization
* Electron/Playlists: Implement playlist synchronization
2021-12-15 19:42:24 +01:00
|
|
|
docArray = await baseHandlers.settings._findAppReadyRelatedSettings()
|
2021-06-17 05:16:52 +02:00
|
|
|
} catch (err) {
|
|
|
|
console.error(err)
|
|
|
|
app.exit()
|
|
|
|
return
|
|
|
|
}
|
2020-10-07 15:57:22 +02:00
|
|
|
|
2021-06-17 05:16:52 +02:00
|
|
|
let disableSmoothScrolling = false
|
|
|
|
let useProxy = false
|
|
|
|
let proxyProtocol = 'socks5'
|
|
|
|
let proxyHostname = '127.0.0.1'
|
|
|
|
let proxyPort = '9050'
|
|
|
|
|
|
|
|
if (docArray?.length > 0) {
|
|
|
|
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
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
2021-01-14 19:51:33 +01:00
|
|
|
|
2021-06-17 05:16:52 +02:00
|
|
|
if (disableSmoothScrolling) {
|
|
|
|
app.commandLine.appendSwitch('disable-smooth-scrolling')
|
|
|
|
} else {
|
|
|
|
app.commandLine.appendSwitch('enable-smooth-scrolling')
|
|
|
|
}
|
2020-10-07 15:57:22 +02:00
|
|
|
|
2021-06-17 05:16:52 +02:00
|
|
|
if (useProxy) {
|
|
|
|
session.defaultSession.setProxy({
|
|
|
|
proxyRules: `${proxyProtocol}://${proxyHostname}:${proxyPort}`
|
|
|
|
})
|
|
|
|
}
|
2021-01-14 19:51:33 +01:00
|
|
|
|
2023-07-03 04:39:18 +02:00
|
|
|
const fixedUserAgent = session.defaultSession.getUserAgent()
|
|
|
|
.split(' ')
|
|
|
|
.filter(part => !part.includes('Electron') && !part.includes(packageDetails.productName))
|
|
|
|
.join(' ')
|
|
|
|
session.defaultSession.setUserAgent(fixedUserAgent)
|
|
|
|
|
2021-06-17 05:16:52 +02:00
|
|
|
// Set CONSENT cookie on reasonable domains
|
|
|
|
const consentCookieDomains = [
|
|
|
|
'https://www.youtube.com',
|
|
|
|
'https://youtube.com'
|
|
|
|
]
|
|
|
|
consentCookieDomains.forEach(url => {
|
|
|
|
session.defaultSession.cookies.set({
|
|
|
|
url: url,
|
|
|
|
name: 'CONSENT',
|
2022-06-16 00:40:46 +02:00
|
|
|
value: 'YES+',
|
|
|
|
sameSite: 'no_restriction'
|
2021-06-16 06:03:46 +02:00
|
|
|
})
|
2021-06-17 05:16:52 +02:00
|
|
|
})
|
2021-06-16 06:03:46 +02:00
|
|
|
|
2023-10-08 15:40:58 +02:00
|
|
|
session.defaultSession.cookies.set({
|
|
|
|
url: 'https://www.youtube.com',
|
|
|
|
name: 'SOCS',
|
|
|
|
value: 'CAI',
|
|
|
|
sameSite: 'no_restriction',
|
|
|
|
})
|
|
|
|
|
2022-11-28 12:52:47 +01:00
|
|
|
// make InnerTube requests work with the fetch function
|
|
|
|
// InnerTube rejects requests if the referer isn't YouTube or empty
|
2023-07-03 04:39:18 +02:00
|
|
|
const innertubeAndMediaRequestFilter = { urls: ['https://www.youtube.com/youtubei/*', 'https://*.googlevideo.com/videoplayback?*'] }
|
|
|
|
|
2023-08-12 04:39:28 +02:00
|
|
|
session.defaultSession.webRequest.onBeforeSendHeaders(innertubeAndMediaRequestFilter, ({ requestHeaders, url, resourceType }, callback) => {
|
2023-07-03 04:39:18 +02:00
|
|
|
requestHeaders.Referer = 'https://www.youtube.com/'
|
|
|
|
requestHeaders.Origin = 'https://www.youtube.com'
|
|
|
|
|
|
|
|
if (url.startsWith('https://www.youtube.com/youtubei/')) {
|
|
|
|
requestHeaders['Sec-Fetch-Site'] = 'same-origin'
|
|
|
|
} else {
|
|
|
|
// YouTube doesn't send the Content-Type header for the media requests, so we shouldn't either
|
|
|
|
delete requestHeaders['Content-Type']
|
|
|
|
}
|
2022-11-28 12:52:47 +01:00
|
|
|
|
2023-08-12 04:39:28 +02:00
|
|
|
// YouTube throttles the adaptive formats if you request a chunk larger than 10MiB.
|
|
|
|
// For the DASH formats we are fine as video.js doesn't seem to ever request chunks that big.
|
|
|
|
// The legacy formats don't have any chunk size limits.
|
|
|
|
// For the audio formats we need to handle it ourselves, as the browser requests the entire audio file,
|
2023-10-18 18:23:21 +02:00
|
|
|
// which means that for most videos that are longer than 10 mins, we get throttled, as the audio track file sizes surpass that 10MiB limit.
|
2023-08-12 04:39:28 +02:00
|
|
|
|
|
|
|
// This code checks if the file is larger than the limit, by checking the `clen` query param,
|
|
|
|
// which YouTube helpfully populates with the content length for us.
|
|
|
|
// If it does surpass that limit, it then checks if the requested range is larger than the limit
|
|
|
|
// (seeking right at the end of the video, would result in a small enough range to be under the chunk limit)
|
|
|
|
// if that surpasses the limit too, it then limits the requested range to 10MiB, by setting the range to `start-${start + 10MiB}`.
|
|
|
|
if (resourceType === 'media' && url.includes('&mime=audio') && requestHeaders.Range) {
|
|
|
|
const TEN_MIB = 10 * 1024 * 1024
|
|
|
|
|
|
|
|
const contentLength = parseInt(new URL(url).searchParams.get('clen'))
|
|
|
|
|
|
|
|
if (contentLength > TEN_MIB) {
|
|
|
|
const [startStr, endStr] = requestHeaders.Range.split('=')[1].split('-')
|
|
|
|
|
|
|
|
const start = parseInt(startStr)
|
|
|
|
|
|
|
|
// handle open ended ranges like `0-` and `1234-`
|
|
|
|
const end = endStr.length === 0 ? contentLength : parseInt(endStr)
|
|
|
|
|
|
|
|
if (end - start > TEN_MIB) {
|
|
|
|
const newEnd = start + TEN_MIB
|
|
|
|
|
|
|
|
requestHeaders.Range = `bytes=${start}-${newEnd}`
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-01-03 19:19:41 +01:00
|
|
|
// eslint-disable-next-line n/no-callback-literal
|
2022-11-28 12:52:47 +01:00
|
|
|
callback({ requestHeaders })
|
|
|
|
})
|
|
|
|
|
2023-10-08 15:40:58 +02:00
|
|
|
// when we create a real session on the watch page, youtube returns tracking cookies, which we definitely don't want
|
|
|
|
const trackingCookieRequestFilter = { urls: ['https://www.youtube.com/sw.js_data', 'https://www.youtube.com/iframe_api'] }
|
|
|
|
|
|
|
|
session.defaultSession.webRequest.onHeadersReceived(trackingCookieRequestFilter, ({ responseHeaders }, callback) => {
|
|
|
|
if (responseHeaders) {
|
|
|
|
delete responseHeaders['set-cookie']
|
|
|
|
}
|
|
|
|
// eslint-disable-next-line n/no-callback-literal
|
|
|
|
callback({ responseHeaders })
|
|
|
|
})
|
|
|
|
|
2022-10-25 04:33:08 +02:00
|
|
|
if (replaceHttpCache) {
|
|
|
|
// in-memory image cache
|
|
|
|
|
|
|
|
const imageCache = new ImageCache()
|
|
|
|
|
2023-10-20 23:39:07 +02:00
|
|
|
protocol.handle('imagecache', (request) => {
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
const url = decodeURIComponent(request.url.substring(13))
|
|
|
|
if (imageCache.has(url)) {
|
|
|
|
const cached = imageCache.get(url)
|
|
|
|
|
|
|
|
resolve(new Response(cached.data, {
|
|
|
|
headers: { 'content-type': cached.mimeType }
|
|
|
|
}))
|
|
|
|
return
|
|
|
|
}
|
2022-10-25 04:33:08 +02:00
|
|
|
|
2023-10-20 23:39:07 +02:00
|
|
|
const newRequest = net.request({
|
|
|
|
method: request.method,
|
|
|
|
url
|
|
|
|
})
|
2022-10-25 04:33:08 +02:00
|
|
|
|
2023-10-20 23:39:07 +02:00
|
|
|
// Electron doesn't allow certain headers to be set:
|
|
|
|
// https://www.electronjs.org/docs/latest/api/client-request#requestsetheadername-value
|
|
|
|
// also blacklist Origin and Referrer as we don't want to let YouTube know about them
|
|
|
|
const blacklistedHeaders = ['content-length', 'host', 'trailer', 'te', 'upgrade', 'cookie2', 'keep-alive', 'transfer-encoding', 'origin', 'referrer']
|
2022-10-25 04:33:08 +02:00
|
|
|
|
2023-10-20 23:39:07 +02:00
|
|
|
for (const header of Object.keys(request.headers)) {
|
|
|
|
if (!blacklistedHeaders.includes(header.toLowerCase())) {
|
|
|
|
newRequest.setHeader(header, request.headers[header])
|
|
|
|
}
|
2022-10-25 04:33:08 +02:00
|
|
|
}
|
|
|
|
|
2023-10-20 23:39:07 +02:00
|
|
|
newRequest.on('response', (response) => {
|
|
|
|
const chunks = []
|
|
|
|
response.on('data', (chunk) => {
|
|
|
|
chunks.push(chunk)
|
|
|
|
})
|
2022-10-25 04:33:08 +02:00
|
|
|
|
2023-10-20 23:39:07 +02:00
|
|
|
response.on('end', () => {
|
|
|
|
const data = Buffer.concat(chunks)
|
2022-10-25 04:33:08 +02:00
|
|
|
|
2023-10-20 23:39:07 +02:00
|
|
|
const expiryTimestamp = extractExpiryTimestamp(response.headers)
|
|
|
|
const mimeType = response.headers['content-type']
|
2022-10-25 04:33:08 +02:00
|
|
|
|
2023-10-20 23:39:07 +02:00
|
|
|
imageCache.add(url, mimeType, data, expiryTimestamp)
|
2022-10-25 04:33:08 +02:00
|
|
|
|
2023-10-20 23:39:07 +02:00
|
|
|
resolve(new Response(data, {
|
|
|
|
headers: { 'content-type': mimeType }
|
|
|
|
}))
|
2022-10-25 04:33:08 +02:00
|
|
|
})
|
|
|
|
|
2023-10-20 23:39:07 +02:00
|
|
|
response.on('error', (error) => {
|
|
|
|
console.error('image cache error', error)
|
|
|
|
reject(error)
|
2022-10-25 04:33:08 +02:00
|
|
|
})
|
2023-10-20 23:39:07 +02:00
|
|
|
})
|
2022-10-25 04:33:08 +02:00
|
|
|
|
2023-10-20 23:39:07 +02:00
|
|
|
newRequest.on('error', (err) => {
|
|
|
|
console.error(err)
|
2022-10-25 04:33:08 +02:00
|
|
|
})
|
|
|
|
|
2023-10-20 23:39:07 +02:00
|
|
|
newRequest.end()
|
2022-11-30 14:03:38 +01:00
|
|
|
})
|
2022-10-25 04:33:08 +02:00
|
|
|
})
|
|
|
|
|
|
|
|
const imageRequestFilter = { urls: ['https://*/*', 'http://*/*'] }
|
|
|
|
session.defaultSession.webRequest.onBeforeRequest(imageRequestFilter, (details, callback) => {
|
|
|
|
// the requests made by the imagecache:// handler to fetch the image,
|
|
|
|
// are allowed through, as their resourceType is 'other'
|
|
|
|
if (details.resourceType === 'image') {
|
2023-01-03 19:19:41 +01:00
|
|
|
// eslint-disable-next-line n/no-callback-literal
|
2022-10-25 04:33:08 +02:00
|
|
|
callback({
|
|
|
|
redirectURL: `imagecache://${encodeURIComponent(details.url)}`
|
|
|
|
})
|
|
|
|
} else {
|
2023-01-03 19:19:41 +01:00
|
|
|
// eslint-disable-next-line n/no-callback-literal
|
2022-10-25 04:33:08 +02:00
|
|
|
callback({})
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
// --- end of `if experimentsDisableDiskCache` ---
|
|
|
|
}
|
|
|
|
|
2021-06-17 05:16:52 +02:00
|
|
|
await createWindow()
|
2020-10-07 15:57:22 +02:00
|
|
|
|
2022-11-05 15:44:21 +01:00
|
|
|
if (process.env.NODE_ENV === 'development') {
|
2021-06-17 05:16:52 +02:00
|
|
|
installDevTools()
|
|
|
|
}
|
2020-10-07 15:57:22 +02:00
|
|
|
|
2021-06-17 05:16:52 +02:00
|
|
|
if (isDebug) {
|
|
|
|
mainWindow.webContents.openDevTools()
|
|
|
|
}
|
2021-06-07 02:38:06 +02:00
|
|
|
})
|
2020-10-04 22:31:07 +02:00
|
|
|
|
2021-06-07 02:38:06 +02:00
|
|
|
async function installDevTools() {
|
2021-03-07 17:07:09 +01:00
|
|
|
try {
|
|
|
|
/* eslint-disable */
|
|
|
|
require('vue-devtools').install()
|
|
|
|
/* eslint-enable */
|
|
|
|
} catch (err) {
|
2022-09-23 03:04:10 +02:00
|
|
|
console.error(err)
|
2021-03-07 17:07:09 +01:00
|
|
|
}
|
|
|
|
}
|
2020-10-04 22:31:07 +02:00
|
|
|
|
2022-09-29 23:22:28 +02:00
|
|
|
async function createWindow(
|
|
|
|
{
|
|
|
|
replaceMainWindow = true,
|
|
|
|
windowStartupUrl = null,
|
|
|
|
showWindowNow = false,
|
|
|
|
searchQueryText = null
|
|
|
|
} = { }) {
|
2022-05-11 16:30:40 +02:00
|
|
|
// Syncing new window background to theme choice.
|
2023-09-05 07:26:11 +02:00
|
|
|
const windowBackground = await baseHandlers.settings._findTheme().then((setting) => {
|
|
|
|
if (!setting) {
|
|
|
|
return nativeTheme.shouldUseDarkColors ? '#212121' : '#f1f1f1'
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (setting.value) {
|
2022-05-11 16:30:40 +02:00
|
|
|
case 'dark':
|
|
|
|
return '#212121'
|
|
|
|
case 'light':
|
|
|
|
return '#f1f1f1'
|
|
|
|
case 'black':
|
|
|
|
return '#000000'
|
|
|
|
case 'dracula':
|
|
|
|
return '#282a36'
|
2022-07-20 03:44:47 +02:00
|
|
|
case 'catppuccin-mocha':
|
|
|
|
return '#1e1e2e'
|
2023-09-01 15:17:46 +02:00
|
|
|
case 'pastel-pink':
|
|
|
|
return '#ffd1dc'
|
|
|
|
case 'hot-pink':
|
|
|
|
return '#de1c85'
|
2024-02-03 17:25:15 +01:00
|
|
|
case 'nordic':
|
|
|
|
return '#2b2f3a'
|
2022-05-11 16:30:40 +02:00
|
|
|
case 'system':
|
|
|
|
default:
|
|
|
|
return nativeTheme.shouldUseDarkColors ? '#212121' : '#f1f1f1'
|
|
|
|
}
|
|
|
|
}).catch((error) => {
|
2022-09-23 03:04:10 +02:00
|
|
|
console.error(error)
|
2022-05-11 16:30:40 +02:00
|
|
|
// Default to nativeTheme settings if nothing is found.
|
|
|
|
return nativeTheme.shouldUseDarkColors ? '#212121' : '#f1f1f1'
|
|
|
|
})
|
|
|
|
|
2021-03-07 17:07:09 +01:00
|
|
|
/**
|
|
|
|
* Initial window options
|
|
|
|
*/
|
2021-11-10 15:51:21 +01:00
|
|
|
const commonBrowserWindowOptions = {
|
2022-05-11 16:30:40 +02:00
|
|
|
backgroundColor: windowBackground,
|
|
|
|
darkTheme: nativeTheme.shouldUseDarkColors,
|
2022-11-05 15:44:21 +01:00
|
|
|
icon: process.env.NODE_ENV === 'development'
|
2021-03-07 17:07:09 +01:00
|
|
|
? path.join(__dirname, '../../_icons/iconColor.png')
|
2023-01-12 07:55:21 +01:00
|
|
|
/* eslint-disable-next-line n/no-path-concat */
|
2021-03-07 17:07:09 +01:00
|
|
|
: `${__dirname}/_icons/iconColor.png`,
|
|
|
|
autoHideMenuBar: true,
|
|
|
|
// useContentSize: true,
|
|
|
|
webPreferences: {
|
|
|
|
nodeIntegration: true,
|
|
|
|
nodeIntegrationInWorker: false,
|
|
|
|
webSecurity: false,
|
|
|
|
backgroundThrottling: false,
|
|
|
|
contextIsolation: false
|
2021-11-10 15:51:21 +01:00
|
|
|
}
|
|
|
|
}
|
2022-05-11 16:30:40 +02:00
|
|
|
|
2021-11-10 15:51:21 +01:00
|
|
|
const newWindow = new BrowserWindow(
|
|
|
|
Object.assign(
|
|
|
|
{
|
|
|
|
// It will be shown later when ready via `ready-to-show` event
|
2022-02-06 21:07:39 +01:00
|
|
|
show: showWindowNow
|
2021-11-10 15:51:21 +01:00
|
|
|
},
|
|
|
|
commonBrowserWindowOptions
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
// region Ensure child windows use same options since electron 14
|
|
|
|
|
|
|
|
// https://github.com/electron/electron/blob/14-x-y/docs/api/window-open.md#native-window-example
|
2022-02-06 21:07:39 +01:00
|
|
|
newWindow.webContents.setWindowOpenHandler((details) => {
|
|
|
|
createWindow({
|
|
|
|
replaceMainWindow: false,
|
|
|
|
showWindowNow: true,
|
|
|
|
windowStartupUrl: details.url
|
|
|
|
})
|
2021-11-10 15:51:21 +01:00
|
|
|
return {
|
2022-02-06 21:07:39 +01:00
|
|
|
action: 'deny'
|
2021-11-10 15:51:21 +01:00
|
|
|
}
|
2021-03-07 17:07:09 +01:00
|
|
|
})
|
2021-07-03 04:38:41 +02:00
|
|
|
|
2021-11-10 15:51:21 +01:00
|
|
|
// endregion Ensure child windows use same options since electron 14
|
|
|
|
|
2021-04-15 20:28:35 +02:00
|
|
|
if (replaceMainWindow) {
|
|
|
|
mainWindow = newWindow
|
|
|
|
}
|
2021-01-14 19:51:33 +01:00
|
|
|
|
2021-04-15 20:28:35 +02:00
|
|
|
newWindow.setBounds({
|
2021-03-07 17:07:09 +01:00
|
|
|
width: 1200,
|
|
|
|
height: 800
|
|
|
|
})
|
2020-10-04 22:31:07 +02:00
|
|
|
|
Store Revamp / Full database synchronization across windows (#1833)
* History: Refactor history module
* Profiles: Refactor profiles module
* IPC: Move channel ids to their own file and make them constants
* IPC: Replace single sync channel for one channel per sync type
* Everywhere: Replace default profile id magic strings with constant ref
* Profiles: Refactor `activeProfile` property from store
This commit makes it so that `activeProfile`'s getter returns
the entire profile, while the related update function only needs
the profile id (instead of the previously used array index)
to change the currently active profile.
This change was made due to inconsistency regarding the active profile
when creating new profiles.
If a new profile coincidentally landed in the current active profile's
array index after sorting, the app would mistakenly change to it
without any action from the user apart from the profile's creation.
Turning the profile id into the selector instead solves this issue.
* Revert "Store: Implement history synchronization between windows"
This reverts commit 99b61e617873412eb393d8f4dfccd8f8c172021f.
This is necessary for an upcoming improved implementation of the
history synchronization.
* History: Remove unused mutation
* Everywhere: Create abstract database handlers
The project now utilizes abstract handlers to fetch, modify
or otherwise manipulate data from the database.
This facilitates 3 aspects of the app, in addition of
making them future proof:
- Switching database libraries is now trivial
Since most of the app utilizes the abstract handlers, it's incredibly
easily to change to a different DB library.
Hypothetically, all that would need to be done is to simply replace the
the file containing the base handlers, while the rest of the app
would go unchanged.
- Syncing logic between Electron and web is now properly separated
There are now two distinct DB handling APIs: the Electron one and
the web one.
The app doesn't need to manually choose the API, because it's detected
which platform is being utilized on import.
- All Electron windows now share the same database instance
This provides a single source of truth, improving consistency
regarding data manipulation and windows synchronization.
As a sidenote, syncing implementation has been left as is
(web unimplemented; Electron only syncs settings, remaining
datastore syncing will be implemented in the upcoming commits).
* Electron/History: Implement history synchronization
* Profiles: Implement suplementary profile creation logic
* ft-profile-edit: Small fix on profile name missing display
* Electron/Profiles: Implement profile synchronization
* Electron/Playlists: Implement playlist synchronization
2021-12-15 19:42:24 +01:00
|
|
|
const boundsDoc = await baseHandlers.settings._findBounds()
|
2021-06-17 05:16:52 +02:00
|
|
|
if (typeof boundsDoc?.value === 'object') {
|
2022-09-20 14:49:45 +02:00
|
|
|
const { maximized, fullScreen, ...bounds } = boundsDoc.value
|
2023-02-06 02:11:27 +01:00
|
|
|
const windowVisible = screen.getAllDisplays().some(display => {
|
|
|
|
const { x, y, width, height } = display.bounds
|
|
|
|
return !(bounds.x > x + width || bounds.x + bounds.width < x || bounds.y > y + height || bounds.y + bounds.height < y)
|
|
|
|
})
|
2021-03-07 17:07:09 +01:00
|
|
|
|
2023-02-06 02:11:27 +01:00
|
|
|
if (windowVisible) {
|
2021-04-15 20:28:35 +02:00
|
|
|
newWindow.setBounds({
|
2021-03-07 17:07:09 +01:00
|
|
|
x: bounds.x,
|
|
|
|
y: bounds.y,
|
|
|
|
width: bounds.width,
|
|
|
|
height: bounds.height
|
|
|
|
})
|
|
|
|
}
|
2022-05-11 16:30:40 +02:00
|
|
|
|
2021-03-07 17:07:09 +01:00
|
|
|
if (maximized) {
|
2021-04-15 20:28:35 +02:00
|
|
|
newWindow.maximize()
|
2020-10-07 15:57:22 +02:00
|
|
|
}
|
2022-09-20 14:49:45 +02:00
|
|
|
|
|
|
|
if (fullScreen) {
|
|
|
|
newWindow.setFullScreen(true)
|
|
|
|
}
|
2021-06-17 05:16:52 +02:00
|
|
|
}
|
2020-02-16 19:30:00 +01:00
|
|
|
|
2021-04-15 20:28:35 +02:00
|
|
|
// If called multiple times
|
|
|
|
// Duplicate menu items will be added
|
|
|
|
if (replaceMainWindow) {
|
|
|
|
// eslint-disable-next-line
|
|
|
|
setMenu()
|
|
|
|
}
|
2020-02-16 19:30:00 +01:00
|
|
|
|
2021-03-07 17:07:09 +01:00
|
|
|
// load root file/url
|
2022-11-05 15:44:21 +01:00
|
|
|
if (process.env.NODE_ENV === 'development') {
|
2022-02-06 21:07:39 +01:00
|
|
|
let devStartupURL = 'http://localhost:9080'
|
|
|
|
if (windowStartupUrl != null) {
|
|
|
|
devStartupURL = windowStartupUrl
|
|
|
|
}
|
|
|
|
newWindow.loadURL(devStartupURL)
|
2021-03-07 17:07:09 +01:00
|
|
|
} else {
|
2022-02-06 21:07:39 +01:00
|
|
|
if (windowStartupUrl != null) {
|
|
|
|
newWindow.loadURL(windowStartupUrl)
|
|
|
|
} else {
|
2023-01-12 07:55:21 +01:00
|
|
|
/* eslint-disable-next-line n/no-path-concat */
|
2022-02-06 21:07:39 +01:00
|
|
|
newWindow.loadFile(`${__dirname}/index.html`)
|
|
|
|
}
|
2021-03-07 17:07:09 +01:00
|
|
|
}
|
2020-09-20 20:54:23 +02:00
|
|
|
|
2022-09-29 23:22:28 +02:00
|
|
|
if (typeof searchQueryText === 'string' && searchQueryText.length > 0) {
|
|
|
|
ipcMain.once('searchInputHandlingReady', () => {
|
|
|
|
newWindow.webContents.send('updateSearchInputText', searchQueryText)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2021-03-07 17:07:09 +01:00
|
|
|
// Show when loaded
|
2021-07-03 04:44:23 +02:00
|
|
|
newWindow.once('ready-to-show', () => {
|
2022-09-19 15:36:40 +02:00
|
|
|
if (newWindow.isVisible()) {
|
|
|
|
// only open the dev tools if they aren't already open
|
2022-11-05 15:44:21 +01:00
|
|
|
if (process.env.NODE_ENV === 'development' && !newWindow.webContents.isDevToolsOpened()) {
|
2022-09-19 15:36:40 +02:00
|
|
|
newWindow.webContents.openDevTools({ activate: false })
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
2022-02-06 21:07:39 +01:00
|
|
|
|
2021-04-15 20:28:35 +02:00
|
|
|
newWindow.show()
|
|
|
|
newWindow.focus()
|
2022-09-19 15:36:40 +02:00
|
|
|
|
2022-11-05 15:44:21 +01:00
|
|
|
if (process.env.NODE_ENV === 'development') {
|
2022-09-19 15:36:40 +02:00
|
|
|
newWindow.webContents.openDevTools({ activate: false })
|
|
|
|
}
|
2021-01-14 19:51:33 +01:00
|
|
|
})
|
|
|
|
|
2021-07-03 04:43:49 +02:00
|
|
|
newWindow.once('close', async () => {
|
|
|
|
if (BrowserWindow.getAllWindows().length !== 1) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
const value = {
|
|
|
|
...newWindow.getNormalBounds(),
|
2022-09-20 14:49:45 +02:00
|
|
|
maximized: newWindow.isMaximized(),
|
|
|
|
fullScreen: newWindow.isFullScreen()
|
2021-07-03 04:43:49 +02:00
|
|
|
}
|
|
|
|
|
Store Revamp / Full database synchronization across windows (#1833)
* History: Refactor history module
* Profiles: Refactor profiles module
* IPC: Move channel ids to their own file and make them constants
* IPC: Replace single sync channel for one channel per sync type
* Everywhere: Replace default profile id magic strings with constant ref
* Profiles: Refactor `activeProfile` property from store
This commit makes it so that `activeProfile`'s getter returns
the entire profile, while the related update function only needs
the profile id (instead of the previously used array index)
to change the currently active profile.
This change was made due to inconsistency regarding the active profile
when creating new profiles.
If a new profile coincidentally landed in the current active profile's
array index after sorting, the app would mistakenly change to it
without any action from the user apart from the profile's creation.
Turning the profile id into the selector instead solves this issue.
* Revert "Store: Implement history synchronization between windows"
This reverts commit 99b61e617873412eb393d8f4dfccd8f8c172021f.
This is necessary for an upcoming improved implementation of the
history synchronization.
* History: Remove unused mutation
* Everywhere: Create abstract database handlers
The project now utilizes abstract handlers to fetch, modify
or otherwise manipulate data from the database.
This facilitates 3 aspects of the app, in addition of
making them future proof:
- Switching database libraries is now trivial
Since most of the app utilizes the abstract handlers, it's incredibly
easily to change to a different DB library.
Hypothetically, all that would need to be done is to simply replace the
the file containing the base handlers, while the rest of the app
would go unchanged.
- Syncing logic between Electron and web is now properly separated
There are now two distinct DB handling APIs: the Electron one and
the web one.
The app doesn't need to manually choose the API, because it's detected
which platform is being utilized on import.
- All Electron windows now share the same database instance
This provides a single source of truth, improving consistency
regarding data manipulation and windows synchronization.
As a sidenote, syncing implementation has been left as is
(web unimplemented; Electron only syncs settings, remaining
datastore syncing will be implemented in the upcoming commits).
* Electron/History: Implement history synchronization
* Profiles: Implement suplementary profile creation logic
* ft-profile-edit: Small fix on profile name missing display
* Electron/Profiles: Implement profile synchronization
* Electron/Playlists: Implement playlist synchronization
2021-12-15 19:42:24 +01:00
|
|
|
await baseHandlers.settings._updateBounds(value)
|
2021-07-03 04:43:49 +02:00
|
|
|
})
|
|
|
|
|
2021-07-03 04:38:41 +02:00
|
|
|
newWindow.once('closed', () => {
|
|
|
|
const allWindows = BrowserWindow.getAllWindows()
|
|
|
|
if (allWindows.length !== 0 && newWindow === mainWindow) {
|
2021-04-15 20:28:35 +02:00
|
|
|
// Replace mainWindow to avoid accessing `mainWindow.webContents`
|
|
|
|
// Which raises "Object has been destroyed" error
|
2021-07-03 04:38:41 +02:00
|
|
|
mainWindow = allWindows[0]
|
2021-04-15 20:28:35 +02:00
|
|
|
}
|
2021-03-07 17:07:09 +01:00
|
|
|
})
|
2021-04-15 20:28:35 +02:00
|
|
|
}
|
2020-09-20 20:54:23 +02:00
|
|
|
|
2021-07-03 04:44:23 +02:00
|
|
|
ipcMain.once('appReady', () => {
|
2021-04-15 20:28:35 +02:00
|
|
|
if (startupUrl) {
|
|
|
|
mainWindow.webContents.send('openUrl', startupUrl)
|
|
|
|
}
|
|
|
|
})
|
2020-02-16 19:30:00 +01:00
|
|
|
|
2021-07-03 04:44:23 +02:00
|
|
|
ipcMain.once('relaunchRequest', () => {
|
2022-11-05 15:44:21 +01:00
|
|
|
if (process.env.NODE_ENV === 'development') {
|
2021-06-16 06:30:01 +02:00
|
|
|
app.exit(parseInt(process.env.FREETUBE_RELAUNCH_EXIT_CODE))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// The AppImage and Windows portable formats must be accounted for
|
|
|
|
// because `process.execPath` points at the temporarily extracted
|
|
|
|
// executables, not the executables themselves
|
|
|
|
//
|
|
|
|
// It's possible to detect these formats and identify their
|
|
|
|
// executables' paths by checking the environmental variables
|
|
|
|
const { env: { APPIMAGE, PORTABLE_EXECUTABLE_FILE } } = process
|
|
|
|
|
|
|
|
if (!APPIMAGE) {
|
|
|
|
// If it's a Windows portable, PORTABLE_EXECUTABLE_FILE will
|
|
|
|
// hold a value.
|
|
|
|
// Otherwise, `process.execPath` should be used instead.
|
|
|
|
app.relaunch({
|
|
|
|
args: process.argv.slice(1),
|
|
|
|
execPath: PORTABLE_EXECUTABLE_FILE || process.execPath
|
|
|
|
})
|
|
|
|
} else {
|
|
|
|
// If it's an AppImage, things must be done the "hard way"
|
|
|
|
// `app.relaunch` doesn't work because of FUSE limitations
|
|
|
|
// Spawn a new process using the APPIMAGE env variable
|
2021-11-12 02:35:20 +01:00
|
|
|
const subprocess = cp.spawn(APPIMAGE, { detached: true, stdio: 'ignore' })
|
|
|
|
subprocess.unref()
|
2021-06-16 06:30:01 +02:00
|
|
|
}
|
2020-02-16 19:30:00 +01:00
|
|
|
|
2021-06-16 06:30:01 +02:00
|
|
|
app.quit()
|
2021-04-15 20:28:35 +02:00
|
|
|
})
|
2020-02-16 19:30:00 +01:00
|
|
|
|
2022-05-11 16:30:40 +02:00
|
|
|
nativeTheme.on('updated', () => {
|
|
|
|
const allWindows = BrowserWindow.getAllWindows()
|
|
|
|
|
|
|
|
allWindows.forEach((window) => {
|
|
|
|
window.webContents.send(IpcChannels.NATIVE_THEME_UPDATE, nativeTheme.shouldUseDarkColors)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
Store Revamp / Full database synchronization across windows (#1833)
* History: Refactor history module
* Profiles: Refactor profiles module
* IPC: Move channel ids to their own file and make them constants
* IPC: Replace single sync channel for one channel per sync type
* Everywhere: Replace default profile id magic strings with constant ref
* Profiles: Refactor `activeProfile` property from store
This commit makes it so that `activeProfile`'s getter returns
the entire profile, while the related update function only needs
the profile id (instead of the previously used array index)
to change the currently active profile.
This change was made due to inconsistency regarding the active profile
when creating new profiles.
If a new profile coincidentally landed in the current active profile's
array index after sorting, the app would mistakenly change to it
without any action from the user apart from the profile's creation.
Turning the profile id into the selector instead solves this issue.
* Revert "Store: Implement history synchronization between windows"
This reverts commit 99b61e617873412eb393d8f4dfccd8f8c172021f.
This is necessary for an upcoming improved implementation of the
history synchronization.
* History: Remove unused mutation
* Everywhere: Create abstract database handlers
The project now utilizes abstract handlers to fetch, modify
or otherwise manipulate data from the database.
This facilitates 3 aspects of the app, in addition of
making them future proof:
- Switching database libraries is now trivial
Since most of the app utilizes the abstract handlers, it's incredibly
easily to change to a different DB library.
Hypothetically, all that would need to be done is to simply replace the
the file containing the base handlers, while the rest of the app
would go unchanged.
- Syncing logic between Electron and web is now properly separated
There are now two distinct DB handling APIs: the Electron one and
the web one.
The app doesn't need to manually choose the API, because it's detected
which platform is being utilized on import.
- All Electron windows now share the same database instance
This provides a single source of truth, improving consistency
regarding data manipulation and windows synchronization.
As a sidenote, syncing implementation has been left as is
(web unimplemented; Electron only syncs settings, remaining
datastore syncing will be implemented in the upcoming commits).
* Electron/History: Implement history synchronization
* Profiles: Implement suplementary profile creation logic
* ft-profile-edit: Small fix on profile name missing display
* Electron/Profiles: Implement profile synchronization
* Electron/Playlists: Implement playlist synchronization
2021-12-15 19:42:24 +01:00
|
|
|
ipcMain.on(IpcChannels.ENABLE_PROXY, (_, url) => {
|
2021-06-16 05:50:30 +02:00
|
|
|
session.defaultSession.setProxy({
|
2021-04-15 20:28:35 +02:00
|
|
|
proxyRules: url
|
2021-03-07 17:07:09 +01:00
|
|
|
})
|
2023-10-20 17:40:40 +02:00
|
|
|
session.defaultSession.closeAllConnections()
|
2021-04-15 20:28:35 +02:00
|
|
|
})
|
|
|
|
|
Store Revamp / Full database synchronization across windows (#1833)
* History: Refactor history module
* Profiles: Refactor profiles module
* IPC: Move channel ids to their own file and make them constants
* IPC: Replace single sync channel for one channel per sync type
* Everywhere: Replace default profile id magic strings with constant ref
* Profiles: Refactor `activeProfile` property from store
This commit makes it so that `activeProfile`'s getter returns
the entire profile, while the related update function only needs
the profile id (instead of the previously used array index)
to change the currently active profile.
This change was made due to inconsistency regarding the active profile
when creating new profiles.
If a new profile coincidentally landed in the current active profile's
array index after sorting, the app would mistakenly change to it
without any action from the user apart from the profile's creation.
Turning the profile id into the selector instead solves this issue.
* Revert "Store: Implement history synchronization between windows"
This reverts commit 99b61e617873412eb393d8f4dfccd8f8c172021f.
This is necessary for an upcoming improved implementation of the
history synchronization.
* History: Remove unused mutation
* Everywhere: Create abstract database handlers
The project now utilizes abstract handlers to fetch, modify
or otherwise manipulate data from the database.
This facilitates 3 aspects of the app, in addition of
making them future proof:
- Switching database libraries is now trivial
Since most of the app utilizes the abstract handlers, it's incredibly
easily to change to a different DB library.
Hypothetically, all that would need to be done is to simply replace the
the file containing the base handlers, while the rest of the app
would go unchanged.
- Syncing logic between Electron and web is now properly separated
There are now two distinct DB handling APIs: the Electron one and
the web one.
The app doesn't need to manually choose the API, because it's detected
which platform is being utilized on import.
- All Electron windows now share the same database instance
This provides a single source of truth, improving consistency
regarding data manipulation and windows synchronization.
As a sidenote, syncing implementation has been left as is
(web unimplemented; Electron only syncs settings, remaining
datastore syncing will be implemented in the upcoming commits).
* Electron/History: Implement history synchronization
* Profiles: Implement suplementary profile creation logic
* ft-profile-edit: Small fix on profile name missing display
* Electron/Profiles: Implement profile synchronization
* Electron/Playlists: Implement playlist synchronization
2021-12-15 19:42:24 +01:00
|
|
|
ipcMain.on(IpcChannels.DISABLE_PROXY, () => {
|
2021-06-16 05:50:30 +02:00
|
|
|
session.defaultSession.setProxy({})
|
2023-10-20 17:40:40 +02:00
|
|
|
session.defaultSession.closeAllConnections()
|
2021-04-15 20:28:35 +02:00
|
|
|
})
|
|
|
|
|
Store Revamp / Full database synchronization across windows (#1833)
* History: Refactor history module
* Profiles: Refactor profiles module
* IPC: Move channel ids to their own file and make them constants
* IPC: Replace single sync channel for one channel per sync type
* Everywhere: Replace default profile id magic strings with constant ref
* Profiles: Refactor `activeProfile` property from store
This commit makes it so that `activeProfile`'s getter returns
the entire profile, while the related update function only needs
the profile id (instead of the previously used array index)
to change the currently active profile.
This change was made due to inconsistency regarding the active profile
when creating new profiles.
If a new profile coincidentally landed in the current active profile's
array index after sorting, the app would mistakenly change to it
without any action from the user apart from the profile's creation.
Turning the profile id into the selector instead solves this issue.
* Revert "Store: Implement history synchronization between windows"
This reverts commit 99b61e617873412eb393d8f4dfccd8f8c172021f.
This is necessary for an upcoming improved implementation of the
history synchronization.
* History: Remove unused mutation
* Everywhere: Create abstract database handlers
The project now utilizes abstract handlers to fetch, modify
or otherwise manipulate data from the database.
This facilitates 3 aspects of the app, in addition of
making them future proof:
- Switching database libraries is now trivial
Since most of the app utilizes the abstract handlers, it's incredibly
easily to change to a different DB library.
Hypothetically, all that would need to be done is to simply replace the
the file containing the base handlers, while the rest of the app
would go unchanged.
- Syncing logic between Electron and web is now properly separated
There are now two distinct DB handling APIs: the Electron one and
the web one.
The app doesn't need to manually choose the API, because it's detected
which platform is being utilized on import.
- All Electron windows now share the same database instance
This provides a single source of truth, improving consistency
regarding data manipulation and windows synchronization.
As a sidenote, syncing implementation has been left as is
(web unimplemented; Electron only syncs settings, remaining
datastore syncing will be implemented in the upcoming commits).
* Electron/History: Implement history synchronization
* Profiles: Implement suplementary profile creation logic
* ft-profile-edit: Small fix on profile name missing display
* Electron/Profiles: Implement profile synchronization
* Electron/Playlists: Implement playlist synchronization
2021-12-15 19:42:24 +01:00
|
|
|
ipcMain.on(IpcChannels.OPEN_EXTERNAL_LINK, (_, url) => {
|
2021-05-22 01:49:48 +02:00
|
|
|
if (typeof url === 'string') shell.openExternal(url)
|
|
|
|
})
|
|
|
|
|
Store Revamp / Full database synchronization across windows (#1833)
* History: Refactor history module
* Profiles: Refactor profiles module
* IPC: Move channel ids to their own file and make them constants
* IPC: Replace single sync channel for one channel per sync type
* Everywhere: Replace default profile id magic strings with constant ref
* Profiles: Refactor `activeProfile` property from store
This commit makes it so that `activeProfile`'s getter returns
the entire profile, while the related update function only needs
the profile id (instead of the previously used array index)
to change the currently active profile.
This change was made due to inconsistency regarding the active profile
when creating new profiles.
If a new profile coincidentally landed in the current active profile's
array index after sorting, the app would mistakenly change to it
without any action from the user apart from the profile's creation.
Turning the profile id into the selector instead solves this issue.
* Revert "Store: Implement history synchronization between windows"
This reverts commit 99b61e617873412eb393d8f4dfccd8f8c172021f.
This is necessary for an upcoming improved implementation of the
history synchronization.
* History: Remove unused mutation
* Everywhere: Create abstract database handlers
The project now utilizes abstract handlers to fetch, modify
or otherwise manipulate data from the database.
This facilitates 3 aspects of the app, in addition of
making them future proof:
- Switching database libraries is now trivial
Since most of the app utilizes the abstract handlers, it's incredibly
easily to change to a different DB library.
Hypothetically, all that would need to be done is to simply replace the
the file containing the base handlers, while the rest of the app
would go unchanged.
- Syncing logic between Electron and web is now properly separated
There are now two distinct DB handling APIs: the Electron one and
the web one.
The app doesn't need to manually choose the API, because it's detected
which platform is being utilized on import.
- All Electron windows now share the same database instance
This provides a single source of truth, improving consistency
regarding data manipulation and windows synchronization.
As a sidenote, syncing implementation has been left as is
(web unimplemented; Electron only syncs settings, remaining
datastore syncing will be implemented in the upcoming commits).
* Electron/History: Implement history synchronization
* Profiles: Implement suplementary profile creation logic
* ft-profile-edit: Small fix on profile name missing display
* Electron/Profiles: Implement profile synchronization
* Electron/Playlists: Implement playlist synchronization
2021-12-15 19:42:24 +01:00
|
|
|
ipcMain.handle(IpcChannels.GET_SYSTEM_LOCALE, () => {
|
2024-01-19 19:24:57 +01:00
|
|
|
// we should switch to getPreferredSystemLanguages at some point and iterate through until we find a supported locale
|
|
|
|
return app.getSystemLocale()
|
2021-05-22 01:49:48 +02:00
|
|
|
})
|
|
|
|
|
Store Revamp / Full database synchronization across windows (#1833)
* History: Refactor history module
* Profiles: Refactor profiles module
* IPC: Move channel ids to their own file and make them constants
* IPC: Replace single sync channel for one channel per sync type
* Everywhere: Replace default profile id magic strings with constant ref
* Profiles: Refactor `activeProfile` property from store
This commit makes it so that `activeProfile`'s getter returns
the entire profile, while the related update function only needs
the profile id (instead of the previously used array index)
to change the currently active profile.
This change was made due to inconsistency regarding the active profile
when creating new profiles.
If a new profile coincidentally landed in the current active profile's
array index after sorting, the app would mistakenly change to it
without any action from the user apart from the profile's creation.
Turning the profile id into the selector instead solves this issue.
* Revert "Store: Implement history synchronization between windows"
This reverts commit 99b61e617873412eb393d8f4dfccd8f8c172021f.
This is necessary for an upcoming improved implementation of the
history synchronization.
* History: Remove unused mutation
* Everywhere: Create abstract database handlers
The project now utilizes abstract handlers to fetch, modify
or otherwise manipulate data from the database.
This facilitates 3 aspects of the app, in addition of
making them future proof:
- Switching database libraries is now trivial
Since most of the app utilizes the abstract handlers, it's incredibly
easily to change to a different DB library.
Hypothetically, all that would need to be done is to simply replace the
the file containing the base handlers, while the rest of the app
would go unchanged.
- Syncing logic between Electron and web is now properly separated
There are now two distinct DB handling APIs: the Electron one and
the web one.
The app doesn't need to manually choose the API, because it's detected
which platform is being utilized on import.
- All Electron windows now share the same database instance
This provides a single source of truth, improving consistency
regarding data manipulation and windows synchronization.
As a sidenote, syncing implementation has been left as is
(web unimplemented; Electron only syncs settings, remaining
datastore syncing will be implemented in the upcoming commits).
* Electron/History: Implement history synchronization
* Profiles: Implement suplementary profile creation logic
* ft-profile-edit: Small fix on profile name missing display
* Electron/Profiles: Implement profile synchronization
* Electron/Playlists: Implement playlist synchronization
2021-12-15 19:42:24 +01:00
|
|
|
ipcMain.handle(IpcChannels.GET_USER_DATA_PATH, () => {
|
2021-05-22 01:49:48 +02:00
|
|
|
return app.getPath('userData')
|
|
|
|
})
|
|
|
|
|
Store Revamp / Full database synchronization across windows (#1833)
* History: Refactor history module
* Profiles: Refactor profiles module
* IPC: Move channel ids to their own file and make them constants
* IPC: Replace single sync channel for one channel per sync type
* Everywhere: Replace default profile id magic strings with constant ref
* Profiles: Refactor `activeProfile` property from store
This commit makes it so that `activeProfile`'s getter returns
the entire profile, while the related update function only needs
the profile id (instead of the previously used array index)
to change the currently active profile.
This change was made due to inconsistency regarding the active profile
when creating new profiles.
If a new profile coincidentally landed in the current active profile's
array index after sorting, the app would mistakenly change to it
without any action from the user apart from the profile's creation.
Turning the profile id into the selector instead solves this issue.
* Revert "Store: Implement history synchronization between windows"
This reverts commit 99b61e617873412eb393d8f4dfccd8f8c172021f.
This is necessary for an upcoming improved implementation of the
history synchronization.
* History: Remove unused mutation
* Everywhere: Create abstract database handlers
The project now utilizes abstract handlers to fetch, modify
or otherwise manipulate data from the database.
This facilitates 3 aspects of the app, in addition of
making them future proof:
- Switching database libraries is now trivial
Since most of the app utilizes the abstract handlers, it's incredibly
easily to change to a different DB library.
Hypothetically, all that would need to be done is to simply replace the
the file containing the base handlers, while the rest of the app
would go unchanged.
- Syncing logic between Electron and web is now properly separated
There are now two distinct DB handling APIs: the Electron one and
the web one.
The app doesn't need to manually choose the API, because it's detected
which platform is being utilized on import.
- All Electron windows now share the same database instance
This provides a single source of truth, improving consistency
regarding data manipulation and windows synchronization.
As a sidenote, syncing implementation has been left as is
(web unimplemented; Electron only syncs settings, remaining
datastore syncing will be implemented in the upcoming commits).
* Electron/History: Implement history synchronization
* Profiles: Implement suplementary profile creation logic
* ft-profile-edit: Small fix on profile name missing display
* Electron/Profiles: Implement profile synchronization
* Electron/Playlists: Implement playlist synchronization
2021-12-15 19:42:24 +01:00
|
|
|
ipcMain.on(IpcChannels.GET_USER_DATA_PATH_SYNC, (event) => {
|
2021-05-22 01:49:48 +02:00
|
|
|
event.returnValue = app.getPath('userData')
|
|
|
|
})
|
|
|
|
|
2022-05-30 15:24:34 +02:00
|
|
|
ipcMain.handle(IpcChannels.GET_PICTURES_PATH, () => {
|
|
|
|
return app.getPath('pictures')
|
|
|
|
})
|
|
|
|
|
2022-10-14 08:00:23 +02:00
|
|
|
ipcMain.handle(IpcChannels.SHOW_OPEN_DIALOG, async ({ sender }, options) => {
|
|
|
|
const senderWindow = findSenderWindow(sender)
|
|
|
|
if (senderWindow) {
|
|
|
|
return await dialog.showOpenDialog(senderWindow, options)
|
|
|
|
}
|
2021-05-22 01:49:48 +02:00
|
|
|
return await dialog.showOpenDialog(options)
|
|
|
|
})
|
|
|
|
|
2022-10-14 08:00:23 +02:00
|
|
|
ipcMain.handle(IpcChannels.SHOW_SAVE_DIALOG, async ({ sender }, options) => {
|
|
|
|
const senderWindow = findSenderWindow(sender)
|
|
|
|
if (senderWindow) {
|
|
|
|
return await dialog.showSaveDialog(senderWindow, options)
|
2022-05-30 15:24:34 +02:00
|
|
|
}
|
2021-05-22 01:49:48 +02:00
|
|
|
return await dialog.showSaveDialog(options)
|
|
|
|
})
|
|
|
|
|
2022-10-14 08:00:23 +02:00
|
|
|
function findSenderWindow(sender) {
|
|
|
|
return BrowserWindow.getAllWindows().find((window) => {
|
|
|
|
return window.webContents.id === sender.id
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
Store Revamp / Full database synchronization across windows (#1833)
* History: Refactor history module
* Profiles: Refactor profiles module
* IPC: Move channel ids to their own file and make them constants
* IPC: Replace single sync channel for one channel per sync type
* Everywhere: Replace default profile id magic strings with constant ref
* Profiles: Refactor `activeProfile` property from store
This commit makes it so that `activeProfile`'s getter returns
the entire profile, while the related update function only needs
the profile id (instead of the previously used array index)
to change the currently active profile.
This change was made due to inconsistency regarding the active profile
when creating new profiles.
If a new profile coincidentally landed in the current active profile's
array index after sorting, the app would mistakenly change to it
without any action from the user apart from the profile's creation.
Turning the profile id into the selector instead solves this issue.
* Revert "Store: Implement history synchronization between windows"
This reverts commit 99b61e617873412eb393d8f4dfccd8f8c172021f.
This is necessary for an upcoming improved implementation of the
history synchronization.
* History: Remove unused mutation
* Everywhere: Create abstract database handlers
The project now utilizes abstract handlers to fetch, modify
or otherwise manipulate data from the database.
This facilitates 3 aspects of the app, in addition of
making them future proof:
- Switching database libraries is now trivial
Since most of the app utilizes the abstract handlers, it's incredibly
easily to change to a different DB library.
Hypothetically, all that would need to be done is to simply replace the
the file containing the base handlers, while the rest of the app
would go unchanged.
- Syncing logic between Electron and web is now properly separated
There are now two distinct DB handling APIs: the Electron one and
the web one.
The app doesn't need to manually choose the API, because it's detected
which platform is being utilized on import.
- All Electron windows now share the same database instance
This provides a single source of truth, improving consistency
regarding data manipulation and windows synchronization.
As a sidenote, syncing implementation has been left as is
(web unimplemented; Electron only syncs settings, remaining
datastore syncing will be implemented in the upcoming commits).
* Electron/History: Implement history synchronization
* Profiles: Implement suplementary profile creation logic
* ft-profile-edit: Small fix on profile name missing display
* Electron/Profiles: Implement profile synchronization
* Electron/Playlists: Implement playlist synchronization
2021-12-15 19:42:24 +01:00
|
|
|
ipcMain.on(IpcChannels.STOP_POWER_SAVE_BLOCKER, (_, id) => {
|
2021-05-22 01:49:48 +02:00
|
|
|
powerSaveBlocker.stop(id)
|
|
|
|
})
|
|
|
|
|
Store Revamp / Full database synchronization across windows (#1833)
* History: Refactor history module
* Profiles: Refactor profiles module
* IPC: Move channel ids to their own file and make them constants
* IPC: Replace single sync channel for one channel per sync type
* Everywhere: Replace default profile id magic strings with constant ref
* Profiles: Refactor `activeProfile` property from store
This commit makes it so that `activeProfile`'s getter returns
the entire profile, while the related update function only needs
the profile id (instead of the previously used array index)
to change the currently active profile.
This change was made due to inconsistency regarding the active profile
when creating new profiles.
If a new profile coincidentally landed in the current active profile's
array index after sorting, the app would mistakenly change to it
without any action from the user apart from the profile's creation.
Turning the profile id into the selector instead solves this issue.
* Revert "Store: Implement history synchronization between windows"
This reverts commit 99b61e617873412eb393d8f4dfccd8f8c172021f.
This is necessary for an upcoming improved implementation of the
history synchronization.
* History: Remove unused mutation
* Everywhere: Create abstract database handlers
The project now utilizes abstract handlers to fetch, modify
or otherwise manipulate data from the database.
This facilitates 3 aspects of the app, in addition of
making them future proof:
- Switching database libraries is now trivial
Since most of the app utilizes the abstract handlers, it's incredibly
easily to change to a different DB library.
Hypothetically, all that would need to be done is to simply replace the
the file containing the base handlers, while the rest of the app
would go unchanged.
- Syncing logic between Electron and web is now properly separated
There are now two distinct DB handling APIs: the Electron one and
the web one.
The app doesn't need to manually choose the API, because it's detected
which platform is being utilized on import.
- All Electron windows now share the same database instance
This provides a single source of truth, improving consistency
regarding data manipulation and windows synchronization.
As a sidenote, syncing implementation has been left as is
(web unimplemented; Electron only syncs settings, remaining
datastore syncing will be implemented in the upcoming commits).
* Electron/History: Implement history synchronization
* Profiles: Implement suplementary profile creation logic
* ft-profile-edit: Small fix on profile name missing display
* Electron/Profiles: Implement profile synchronization
* Electron/Playlists: Implement playlist synchronization
2021-12-15 19:42:24 +01:00
|
|
|
ipcMain.handle(IpcChannels.START_POWER_SAVE_BLOCKER, (_) => {
|
|
|
|
return powerSaveBlocker.start('prevent-display-sleep')
|
2021-05-22 01:49:48 +02:00
|
|
|
})
|
|
|
|
|
2022-09-29 23:22:28 +02:00
|
|
|
ipcMain.on(IpcChannels.CREATE_NEW_WINDOW, (_e, { windowStartupUrl = null, searchQueryText = null } = { }) => {
|
2022-02-06 21:07:39 +01:00
|
|
|
createWindow({
|
|
|
|
replaceMainWindow: false,
|
2022-05-30 20:32:38 +02:00
|
|
|
showWindowNow: true,
|
2022-09-29 23:22:28 +02:00
|
|
|
windowStartupUrl: windowStartupUrl,
|
|
|
|
searchQueryText: searchQueryText
|
2022-02-06 21:07:39 +01:00
|
|
|
})
|
2021-04-15 20:28:35 +02:00
|
|
|
})
|
2020-09-20 20:54:23 +02:00
|
|
|
|
Store Revamp / Full database synchronization across windows (#1833)
* History: Refactor history module
* Profiles: Refactor profiles module
* IPC: Move channel ids to their own file and make them constants
* IPC: Replace single sync channel for one channel per sync type
* Everywhere: Replace default profile id magic strings with constant ref
* Profiles: Refactor `activeProfile` property from store
This commit makes it so that `activeProfile`'s getter returns
the entire profile, while the related update function only needs
the profile id (instead of the previously used array index)
to change the currently active profile.
This change was made due to inconsistency regarding the active profile
when creating new profiles.
If a new profile coincidentally landed in the current active profile's
array index after sorting, the app would mistakenly change to it
without any action from the user apart from the profile's creation.
Turning the profile id into the selector instead solves this issue.
* Revert "Store: Implement history synchronization between windows"
This reverts commit 99b61e617873412eb393d8f4dfccd8f8c172021f.
This is necessary for an upcoming improved implementation of the
history synchronization.
* History: Remove unused mutation
* Everywhere: Create abstract database handlers
The project now utilizes abstract handlers to fetch, modify
or otherwise manipulate data from the database.
This facilitates 3 aspects of the app, in addition of
making them future proof:
- Switching database libraries is now trivial
Since most of the app utilizes the abstract handlers, it's incredibly
easily to change to a different DB library.
Hypothetically, all that would need to be done is to simply replace the
the file containing the base handlers, while the rest of the app
would go unchanged.
- Syncing logic between Electron and web is now properly separated
There are now two distinct DB handling APIs: the Electron one and
the web one.
The app doesn't need to manually choose the API, because it's detected
which platform is being utilized on import.
- All Electron windows now share the same database instance
This provides a single source of truth, improving consistency
regarding data manipulation and windows synchronization.
As a sidenote, syncing implementation has been left as is
(web unimplemented; Electron only syncs settings, remaining
datastore syncing will be implemented in the upcoming commits).
* Electron/History: Implement history synchronization
* Profiles: Implement suplementary profile creation logic
* ft-profile-edit: Small fix on profile name missing display
* Electron/Profiles: Implement profile synchronization
* Electron/Playlists: Implement playlist synchronization
2021-12-15 19:42:24 +01:00
|
|
|
ipcMain.on(IpcChannels.OPEN_IN_EXTERNAL_PLAYER, (_, payload) => {
|
|
|
|
const child = cp.spawn(payload.executable, payload.args, { detached: true, stdio: 'ignore' })
|
|
|
|
child.unref()
|
|
|
|
})
|
|
|
|
|
|
|
|
// ************************************************* //
|
|
|
|
// DB related IPC calls
|
|
|
|
// *********** //
|
|
|
|
|
|
|
|
// Settings
|
|
|
|
ipcMain.handle(IpcChannels.DB_SETTINGS, async (event, { action, data }) => {
|
|
|
|
try {
|
|
|
|
switch (action) {
|
|
|
|
case DBActions.GENERAL.FIND:
|
|
|
|
return await baseHandlers.settings.find()
|
|
|
|
|
|
|
|
case DBActions.GENERAL.UPSERT:
|
|
|
|
await baseHandlers.settings.upsert(data._id, data.value)
|
|
|
|
syncOtherWindows(
|
|
|
|
IpcChannels.SYNC_SETTINGS,
|
|
|
|
event,
|
|
|
|
{ event: SyncEvents.GENERAL.UPSERT, data }
|
|
|
|
)
|
2022-12-26 22:42:43 +01:00
|
|
|
switch (data._id) {
|
|
|
|
// Update app menu on related setting update
|
|
|
|
case 'hideTrendingVideos':
|
|
|
|
case 'hidePopularVideos':
|
2023-03-22 03:27:27 +01:00
|
|
|
case 'backendFallback':
|
|
|
|
case 'backendPreference':
|
2022-12-26 22:42:43 +01:00
|
|
|
case 'hidePlaylists':
|
|
|
|
await setMenu()
|
|
|
|
break
|
|
|
|
|
|
|
|
default:
|
|
|
|
// Do nothing for unmatched settings
|
|
|
|
}
|
Store Revamp / Full database synchronization across windows (#1833)
* History: Refactor history module
* Profiles: Refactor profiles module
* IPC: Move channel ids to their own file and make them constants
* IPC: Replace single sync channel for one channel per sync type
* Everywhere: Replace default profile id magic strings with constant ref
* Profiles: Refactor `activeProfile` property from store
This commit makes it so that `activeProfile`'s getter returns
the entire profile, while the related update function only needs
the profile id (instead of the previously used array index)
to change the currently active profile.
This change was made due to inconsistency regarding the active profile
when creating new profiles.
If a new profile coincidentally landed in the current active profile's
array index after sorting, the app would mistakenly change to it
without any action from the user apart from the profile's creation.
Turning the profile id into the selector instead solves this issue.
* Revert "Store: Implement history synchronization between windows"
This reverts commit 99b61e617873412eb393d8f4dfccd8f8c172021f.
This is necessary for an upcoming improved implementation of the
history synchronization.
* History: Remove unused mutation
* Everywhere: Create abstract database handlers
The project now utilizes abstract handlers to fetch, modify
or otherwise manipulate data from the database.
This facilitates 3 aspects of the app, in addition of
making them future proof:
- Switching database libraries is now trivial
Since most of the app utilizes the abstract handlers, it's incredibly
easily to change to a different DB library.
Hypothetically, all that would need to be done is to simply replace the
the file containing the base handlers, while the rest of the app
would go unchanged.
- Syncing logic between Electron and web is now properly separated
There are now two distinct DB handling APIs: the Electron one and
the web one.
The app doesn't need to manually choose the API, because it's detected
which platform is being utilized on import.
- All Electron windows now share the same database instance
This provides a single source of truth, improving consistency
regarding data manipulation and windows synchronization.
As a sidenote, syncing implementation has been left as is
(web unimplemented; Electron only syncs settings, remaining
datastore syncing will be implemented in the upcoming commits).
* Electron/History: Implement history synchronization
* Profiles: Implement suplementary profile creation logic
* ft-profile-edit: Small fix on profile name missing display
* Electron/Profiles: Implement profile synchronization
* Electron/Playlists: Implement playlist synchronization
2021-12-15 19:42:24 +01:00
|
|
|
return null
|
|
|
|
|
|
|
|
default:
|
|
|
|
// eslint-disable-next-line no-throw-literal
|
|
|
|
throw 'invalid settings db action'
|
2021-07-03 04:38:41 +02:00
|
|
|
}
|
Store Revamp / Full database synchronization across windows (#1833)
* History: Refactor history module
* Profiles: Refactor profiles module
* IPC: Move channel ids to their own file and make them constants
* IPC: Replace single sync channel for one channel per sync type
* Everywhere: Replace default profile id magic strings with constant ref
* Profiles: Refactor `activeProfile` property from store
This commit makes it so that `activeProfile`'s getter returns
the entire profile, while the related update function only needs
the profile id (instead of the previously used array index)
to change the currently active profile.
This change was made due to inconsistency regarding the active profile
when creating new profiles.
If a new profile coincidentally landed in the current active profile's
array index after sorting, the app would mistakenly change to it
without any action from the user apart from the profile's creation.
Turning the profile id into the selector instead solves this issue.
* Revert "Store: Implement history synchronization between windows"
This reverts commit 99b61e617873412eb393d8f4dfccd8f8c172021f.
This is necessary for an upcoming improved implementation of the
history synchronization.
* History: Remove unused mutation
* Everywhere: Create abstract database handlers
The project now utilizes abstract handlers to fetch, modify
or otherwise manipulate data from the database.
This facilitates 3 aspects of the app, in addition of
making them future proof:
- Switching database libraries is now trivial
Since most of the app utilizes the abstract handlers, it's incredibly
easily to change to a different DB library.
Hypothetically, all that would need to be done is to simply replace the
the file containing the base handlers, while the rest of the app
would go unchanged.
- Syncing logic between Electron and web is now properly separated
There are now two distinct DB handling APIs: the Electron one and
the web one.
The app doesn't need to manually choose the API, because it's detected
which platform is being utilized on import.
- All Electron windows now share the same database instance
This provides a single source of truth, improving consistency
regarding data manipulation and windows synchronization.
As a sidenote, syncing implementation has been left as is
(web unimplemented; Electron only syncs settings, remaining
datastore syncing will be implemented in the upcoming commits).
* Electron/History: Implement history synchronization
* Profiles: Implement suplementary profile creation logic
* ft-profile-edit: Small fix on profile name missing display
* Electron/Profiles: Implement profile synchronization
* Electron/Playlists: Implement playlist synchronization
2021-12-15 19:42:24 +01:00
|
|
|
} catch (err) {
|
|
|
|
if (typeof err === 'string') throw err
|
|
|
|
else throw err.toString()
|
|
|
|
}
|
|
|
|
})
|
2021-06-09 06:57:35 +02:00
|
|
|
|
Store Revamp / Full database synchronization across windows (#1833)
* History: Refactor history module
* Profiles: Refactor profiles module
* IPC: Move channel ids to their own file and make them constants
* IPC: Replace single sync channel for one channel per sync type
* Everywhere: Replace default profile id magic strings with constant ref
* Profiles: Refactor `activeProfile` property from store
This commit makes it so that `activeProfile`'s getter returns
the entire profile, while the related update function only needs
the profile id (instead of the previously used array index)
to change the currently active profile.
This change was made due to inconsistency regarding the active profile
when creating new profiles.
If a new profile coincidentally landed in the current active profile's
array index after sorting, the app would mistakenly change to it
without any action from the user apart from the profile's creation.
Turning the profile id into the selector instead solves this issue.
* Revert "Store: Implement history synchronization between windows"
This reverts commit 99b61e617873412eb393d8f4dfccd8f8c172021f.
This is necessary for an upcoming improved implementation of the
history synchronization.
* History: Remove unused mutation
* Everywhere: Create abstract database handlers
The project now utilizes abstract handlers to fetch, modify
or otherwise manipulate data from the database.
This facilitates 3 aspects of the app, in addition of
making them future proof:
- Switching database libraries is now trivial
Since most of the app utilizes the abstract handlers, it's incredibly
easily to change to a different DB library.
Hypothetically, all that would need to be done is to simply replace the
the file containing the base handlers, while the rest of the app
would go unchanged.
- Syncing logic between Electron and web is now properly separated
There are now two distinct DB handling APIs: the Electron one and
the web one.
The app doesn't need to manually choose the API, because it's detected
which platform is being utilized on import.
- All Electron windows now share the same database instance
This provides a single source of truth, improving consistency
regarding data manipulation and windows synchronization.
As a sidenote, syncing implementation has been left as is
(web unimplemented; Electron only syncs settings, remaining
datastore syncing will be implemented in the upcoming commits).
* Electron/History: Implement history synchronization
* Profiles: Implement suplementary profile creation logic
* ft-profile-edit: Small fix on profile name missing display
* Electron/Profiles: Implement profile synchronization
* Electron/Playlists: Implement playlist synchronization
2021-12-15 19:42:24 +01:00
|
|
|
// *********** //
|
|
|
|
// History
|
|
|
|
ipcMain.handle(IpcChannels.DB_HISTORY, async (event, { action, data }) => {
|
|
|
|
try {
|
|
|
|
switch (action) {
|
|
|
|
case DBActions.GENERAL.FIND:
|
|
|
|
return await baseHandlers.history.find()
|
|
|
|
|
|
|
|
case DBActions.GENERAL.UPSERT:
|
|
|
|
await baseHandlers.history.upsert(data)
|
|
|
|
syncOtherWindows(
|
|
|
|
IpcChannels.SYNC_HISTORY,
|
|
|
|
event,
|
|
|
|
{ event: SyncEvents.GENERAL.UPSERT, data }
|
|
|
|
)
|
|
|
|
return null
|
|
|
|
|
|
|
|
case DBActions.HISTORY.UPDATE_WATCH_PROGRESS:
|
|
|
|
await baseHandlers.history.updateWatchProgress(data.videoId, data.watchProgress)
|
|
|
|
syncOtherWindows(
|
|
|
|
IpcChannels.SYNC_HISTORY,
|
|
|
|
event,
|
|
|
|
{ event: SyncEvents.HISTORY.UPDATE_WATCH_PROGRESS, data }
|
|
|
|
)
|
|
|
|
return null
|
|
|
|
|
2023-01-26 03:18:04 +01:00
|
|
|
case DBActions.HISTORY.UPDATE_PLAYLIST:
|
2024-01-03 19:44:57 +01:00
|
|
|
await baseHandlers.history.updateLastViewedPlaylist(data.videoId, data.lastViewedPlaylistId, data.lastViewedPlaylistType, data.lastViewedPlaylistItemId)
|
2023-01-26 03:18:04 +01:00
|
|
|
syncOtherWindows(
|
|
|
|
IpcChannels.SYNC_HISTORY,
|
|
|
|
event,
|
|
|
|
{ event: SyncEvents.HISTORY.UPDATE_PLAYLIST, data }
|
|
|
|
)
|
|
|
|
return null
|
|
|
|
|
Store Revamp / Full database synchronization across windows (#1833)
* History: Refactor history module
* Profiles: Refactor profiles module
* IPC: Move channel ids to their own file and make them constants
* IPC: Replace single sync channel for one channel per sync type
* Everywhere: Replace default profile id magic strings with constant ref
* Profiles: Refactor `activeProfile` property from store
This commit makes it so that `activeProfile`'s getter returns
the entire profile, while the related update function only needs
the profile id (instead of the previously used array index)
to change the currently active profile.
This change was made due to inconsistency regarding the active profile
when creating new profiles.
If a new profile coincidentally landed in the current active profile's
array index after sorting, the app would mistakenly change to it
without any action from the user apart from the profile's creation.
Turning the profile id into the selector instead solves this issue.
* Revert "Store: Implement history synchronization between windows"
This reverts commit 99b61e617873412eb393d8f4dfccd8f8c172021f.
This is necessary for an upcoming improved implementation of the
history synchronization.
* History: Remove unused mutation
* Everywhere: Create abstract database handlers
The project now utilizes abstract handlers to fetch, modify
or otherwise manipulate data from the database.
This facilitates 3 aspects of the app, in addition of
making them future proof:
- Switching database libraries is now trivial
Since most of the app utilizes the abstract handlers, it's incredibly
easily to change to a different DB library.
Hypothetically, all that would need to be done is to simply replace the
the file containing the base handlers, while the rest of the app
would go unchanged.
- Syncing logic between Electron and web is now properly separated
There are now two distinct DB handling APIs: the Electron one and
the web one.
The app doesn't need to manually choose the API, because it's detected
which platform is being utilized on import.
- All Electron windows now share the same database instance
This provides a single source of truth, improving consistency
regarding data manipulation and windows synchronization.
As a sidenote, syncing implementation has been left as is
(web unimplemented; Electron only syncs settings, remaining
datastore syncing will be implemented in the upcoming commits).
* Electron/History: Implement history synchronization
* Profiles: Implement suplementary profile creation logic
* ft-profile-edit: Small fix on profile name missing display
* Electron/Profiles: Implement profile synchronization
* Electron/Playlists: Implement playlist synchronization
2021-12-15 19:42:24 +01:00
|
|
|
case DBActions.GENERAL.DELETE:
|
|
|
|
await baseHandlers.history.delete(data)
|
|
|
|
syncOtherWindows(
|
|
|
|
IpcChannels.SYNC_HISTORY,
|
|
|
|
event,
|
|
|
|
{ event: SyncEvents.GENERAL.DELETE, data }
|
|
|
|
)
|
|
|
|
return null
|
|
|
|
|
|
|
|
case DBActions.GENERAL.DELETE_ALL:
|
|
|
|
await baseHandlers.history.deleteAll()
|
|
|
|
syncOtherWindows(
|
|
|
|
IpcChannels.SYNC_HISTORY,
|
|
|
|
event,
|
|
|
|
{ event: SyncEvents.GENERAL.DELETE_ALL }
|
|
|
|
)
|
|
|
|
return null
|
|
|
|
|
|
|
|
case DBActions.GENERAL.PERSIST:
|
|
|
|
baseHandlers.history.persist()
|
|
|
|
return null
|
|
|
|
|
|
|
|
default:
|
|
|
|
// eslint-disable-next-line no-throw-literal
|
|
|
|
throw 'invalid history db action'
|
|
|
|
}
|
|
|
|
} catch (err) {
|
|
|
|
if (typeof err === 'string') throw err
|
|
|
|
else throw err.toString()
|
2021-06-09 06:57:35 +02:00
|
|
|
}
|
|
|
|
})
|
|
|
|
|
Store Revamp / Full database synchronization across windows (#1833)
* History: Refactor history module
* Profiles: Refactor profiles module
* IPC: Move channel ids to their own file and make them constants
* IPC: Replace single sync channel for one channel per sync type
* Everywhere: Replace default profile id magic strings with constant ref
* Profiles: Refactor `activeProfile` property from store
This commit makes it so that `activeProfile`'s getter returns
the entire profile, while the related update function only needs
the profile id (instead of the previously used array index)
to change the currently active profile.
This change was made due to inconsistency regarding the active profile
when creating new profiles.
If a new profile coincidentally landed in the current active profile's
array index after sorting, the app would mistakenly change to it
without any action from the user apart from the profile's creation.
Turning the profile id into the selector instead solves this issue.
* Revert "Store: Implement history synchronization between windows"
This reverts commit 99b61e617873412eb393d8f4dfccd8f8c172021f.
This is necessary for an upcoming improved implementation of the
history synchronization.
* History: Remove unused mutation
* Everywhere: Create abstract database handlers
The project now utilizes abstract handlers to fetch, modify
or otherwise manipulate data from the database.
This facilitates 3 aspects of the app, in addition of
making them future proof:
- Switching database libraries is now trivial
Since most of the app utilizes the abstract handlers, it's incredibly
easily to change to a different DB library.
Hypothetically, all that would need to be done is to simply replace the
the file containing the base handlers, while the rest of the app
would go unchanged.
- Syncing logic between Electron and web is now properly separated
There are now two distinct DB handling APIs: the Electron one and
the web one.
The app doesn't need to manually choose the API, because it's detected
which platform is being utilized on import.
- All Electron windows now share the same database instance
This provides a single source of truth, improving consistency
regarding data manipulation and windows synchronization.
As a sidenote, syncing implementation has been left as is
(web unimplemented; Electron only syncs settings, remaining
datastore syncing will be implemented in the upcoming commits).
* Electron/History: Implement history synchronization
* Profiles: Implement suplementary profile creation logic
* ft-profile-edit: Small fix on profile name missing display
* Electron/Profiles: Implement profile synchronization
* Electron/Playlists: Implement playlist synchronization
2021-12-15 19:42:24 +01:00
|
|
|
// *********** //
|
|
|
|
// Profiles
|
|
|
|
ipcMain.handle(IpcChannels.DB_PROFILES, async (event, { action, data }) => {
|
|
|
|
try {
|
|
|
|
switch (action) {
|
|
|
|
case DBActions.GENERAL.CREATE: {
|
|
|
|
const newProfile = await baseHandlers.profiles.create(data)
|
|
|
|
syncOtherWindows(
|
|
|
|
IpcChannels.SYNC_PROFILES,
|
|
|
|
event,
|
|
|
|
{ event: SyncEvents.GENERAL.CREATE, data: newProfile }
|
|
|
|
)
|
|
|
|
return newProfile
|
|
|
|
}
|
|
|
|
|
|
|
|
case DBActions.GENERAL.FIND:
|
|
|
|
return await baseHandlers.profiles.find()
|
|
|
|
|
|
|
|
case DBActions.GENERAL.UPSERT:
|
|
|
|
await baseHandlers.profiles.upsert(data)
|
|
|
|
syncOtherWindows(
|
|
|
|
IpcChannels.SYNC_PROFILES,
|
|
|
|
event,
|
|
|
|
{ event: SyncEvents.GENERAL.UPSERT, data }
|
|
|
|
)
|
|
|
|
return null
|
|
|
|
|
|
|
|
case DBActions.GENERAL.DELETE:
|
|
|
|
await baseHandlers.profiles.delete(data)
|
|
|
|
syncOtherWindows(
|
|
|
|
IpcChannels.SYNC_PROFILES,
|
|
|
|
event,
|
|
|
|
{ event: SyncEvents.GENERAL.DELETE, data }
|
|
|
|
)
|
|
|
|
return null
|
|
|
|
|
|
|
|
case DBActions.GENERAL.PERSIST:
|
|
|
|
baseHandlers.profiles.persist()
|
|
|
|
return null
|
|
|
|
|
|
|
|
default:
|
|
|
|
// eslint-disable-next-line no-throw-literal
|
|
|
|
throw 'invalid profile db action'
|
|
|
|
}
|
|
|
|
} catch (err) {
|
|
|
|
if (typeof err === 'string') throw err
|
|
|
|
else throw err.toString()
|
|
|
|
}
|
2021-06-13 17:31:43 +02:00
|
|
|
})
|
|
|
|
|
Store Revamp / Full database synchronization across windows (#1833)
* History: Refactor history module
* Profiles: Refactor profiles module
* IPC: Move channel ids to their own file and make them constants
* IPC: Replace single sync channel for one channel per sync type
* Everywhere: Replace default profile id magic strings with constant ref
* Profiles: Refactor `activeProfile` property from store
This commit makes it so that `activeProfile`'s getter returns
the entire profile, while the related update function only needs
the profile id (instead of the previously used array index)
to change the currently active profile.
This change was made due to inconsistency regarding the active profile
when creating new profiles.
If a new profile coincidentally landed in the current active profile's
array index after sorting, the app would mistakenly change to it
without any action from the user apart from the profile's creation.
Turning the profile id into the selector instead solves this issue.
* Revert "Store: Implement history synchronization between windows"
This reverts commit 99b61e617873412eb393d8f4dfccd8f8c172021f.
This is necessary for an upcoming improved implementation of the
history synchronization.
* History: Remove unused mutation
* Everywhere: Create abstract database handlers
The project now utilizes abstract handlers to fetch, modify
or otherwise manipulate data from the database.
This facilitates 3 aspects of the app, in addition of
making them future proof:
- Switching database libraries is now trivial
Since most of the app utilizes the abstract handlers, it's incredibly
easily to change to a different DB library.
Hypothetically, all that would need to be done is to simply replace the
the file containing the base handlers, while the rest of the app
would go unchanged.
- Syncing logic between Electron and web is now properly separated
There are now two distinct DB handling APIs: the Electron one and
the web one.
The app doesn't need to manually choose the API, because it's detected
which platform is being utilized on import.
- All Electron windows now share the same database instance
This provides a single source of truth, improving consistency
regarding data manipulation and windows synchronization.
As a sidenote, syncing implementation has been left as is
(web unimplemented; Electron only syncs settings, remaining
datastore syncing will be implemented in the upcoming commits).
* Electron/History: Implement history synchronization
* Profiles: Implement suplementary profile creation logic
* ft-profile-edit: Small fix on profile name missing display
* Electron/Profiles: Implement profile synchronization
* Electron/Playlists: Implement playlist synchronization
2021-12-15 19:42:24 +01:00
|
|
|
// *********** //
|
|
|
|
// Playlists
|
|
|
|
// ! NOTE: A lot of these actions are currently not used for anything
|
|
|
|
// As such, only the currently used actions have synchronization implemented
|
|
|
|
// The remaining should have it implemented only when playlists
|
|
|
|
// get fully implemented into the app
|
|
|
|
ipcMain.handle(IpcChannels.DB_PLAYLISTS, async (event, { action, data }) => {
|
|
|
|
try {
|
|
|
|
switch (action) {
|
|
|
|
case DBActions.GENERAL.CREATE:
|
|
|
|
await baseHandlers.playlists.create(data)
|
2024-01-03 19:44:57 +01:00
|
|
|
syncOtherWindows(
|
|
|
|
IpcChannels.SYNC_PLAYLISTS,
|
|
|
|
event,
|
|
|
|
{ event: SyncEvents.GENERAL.CREATE, data }
|
|
|
|
)
|
Store Revamp / Full database synchronization across windows (#1833)
* History: Refactor history module
* Profiles: Refactor profiles module
* IPC: Move channel ids to their own file and make them constants
* IPC: Replace single sync channel for one channel per sync type
* Everywhere: Replace default profile id magic strings with constant ref
* Profiles: Refactor `activeProfile` property from store
This commit makes it so that `activeProfile`'s getter returns
the entire profile, while the related update function only needs
the profile id (instead of the previously used array index)
to change the currently active profile.
This change was made due to inconsistency regarding the active profile
when creating new profiles.
If a new profile coincidentally landed in the current active profile's
array index after sorting, the app would mistakenly change to it
without any action from the user apart from the profile's creation.
Turning the profile id into the selector instead solves this issue.
* Revert "Store: Implement history synchronization between windows"
This reverts commit 99b61e617873412eb393d8f4dfccd8f8c172021f.
This is necessary for an upcoming improved implementation of the
history synchronization.
* History: Remove unused mutation
* Everywhere: Create abstract database handlers
The project now utilizes abstract handlers to fetch, modify
or otherwise manipulate data from the database.
This facilitates 3 aspects of the app, in addition of
making them future proof:
- Switching database libraries is now trivial
Since most of the app utilizes the abstract handlers, it's incredibly
easily to change to a different DB library.
Hypothetically, all that would need to be done is to simply replace the
the file containing the base handlers, while the rest of the app
would go unchanged.
- Syncing logic between Electron and web is now properly separated
There are now two distinct DB handling APIs: the Electron one and
the web one.
The app doesn't need to manually choose the API, because it's detected
which platform is being utilized on import.
- All Electron windows now share the same database instance
This provides a single source of truth, improving consistency
regarding data manipulation and windows synchronization.
As a sidenote, syncing implementation has been left as is
(web unimplemented; Electron only syncs settings, remaining
datastore syncing will be implemented in the upcoming commits).
* Electron/History: Implement history synchronization
* Profiles: Implement suplementary profile creation logic
* ft-profile-edit: Small fix on profile name missing display
* Electron/Profiles: Implement profile synchronization
* Electron/Playlists: Implement playlist synchronization
2021-12-15 19:42:24 +01:00
|
|
|
return null
|
|
|
|
|
|
|
|
case DBActions.GENERAL.FIND:
|
|
|
|
return await baseHandlers.playlists.find()
|
|
|
|
|
2024-01-03 19:44:57 +01:00
|
|
|
case DBActions.GENERAL.UPSERT:
|
|
|
|
await baseHandlers.playlists.upsert(data)
|
|
|
|
syncOtherWindows(
|
|
|
|
IpcChannels.SYNC_PLAYLISTS,
|
|
|
|
event,
|
|
|
|
{ event: SyncEvents.GENERAL.UPSERT, data }
|
|
|
|
)
|
|
|
|
return null
|
|
|
|
|
Store Revamp / Full database synchronization across windows (#1833)
* History: Refactor history module
* Profiles: Refactor profiles module
* IPC: Move channel ids to their own file and make them constants
* IPC: Replace single sync channel for one channel per sync type
* Everywhere: Replace default profile id magic strings with constant ref
* Profiles: Refactor `activeProfile` property from store
This commit makes it so that `activeProfile`'s getter returns
the entire profile, while the related update function only needs
the profile id (instead of the previously used array index)
to change the currently active profile.
This change was made due to inconsistency regarding the active profile
when creating new profiles.
If a new profile coincidentally landed in the current active profile's
array index after sorting, the app would mistakenly change to it
without any action from the user apart from the profile's creation.
Turning the profile id into the selector instead solves this issue.
* Revert "Store: Implement history synchronization between windows"
This reverts commit 99b61e617873412eb393d8f4dfccd8f8c172021f.
This is necessary for an upcoming improved implementation of the
history synchronization.
* History: Remove unused mutation
* Everywhere: Create abstract database handlers
The project now utilizes abstract handlers to fetch, modify
or otherwise manipulate data from the database.
This facilitates 3 aspects of the app, in addition of
making them future proof:
- Switching database libraries is now trivial
Since most of the app utilizes the abstract handlers, it's incredibly
easily to change to a different DB library.
Hypothetically, all that would need to be done is to simply replace the
the file containing the base handlers, while the rest of the app
would go unchanged.
- Syncing logic between Electron and web is now properly separated
There are now two distinct DB handling APIs: the Electron one and
the web one.
The app doesn't need to manually choose the API, because it's detected
which platform is being utilized on import.
- All Electron windows now share the same database instance
This provides a single source of truth, improving consistency
regarding data manipulation and windows synchronization.
As a sidenote, syncing implementation has been left as is
(web unimplemented; Electron only syncs settings, remaining
datastore syncing will be implemented in the upcoming commits).
* Electron/History: Implement history synchronization
* Profiles: Implement suplementary profile creation logic
* ft-profile-edit: Small fix on profile name missing display
* Electron/Profiles: Implement profile synchronization
* Electron/Playlists: Implement playlist synchronization
2021-12-15 19:42:24 +01:00
|
|
|
case DBActions.PLAYLISTS.UPSERT_VIDEO:
|
2024-01-03 19:44:57 +01:00
|
|
|
await baseHandlers.playlists.upsertVideoByPlaylistId(data._id, data.videoData)
|
Store Revamp / Full database synchronization across windows (#1833)
* History: Refactor history module
* Profiles: Refactor profiles module
* IPC: Move channel ids to their own file and make them constants
* IPC: Replace single sync channel for one channel per sync type
* Everywhere: Replace default profile id magic strings with constant ref
* Profiles: Refactor `activeProfile` property from store
This commit makes it so that `activeProfile`'s getter returns
the entire profile, while the related update function only needs
the profile id (instead of the previously used array index)
to change the currently active profile.
This change was made due to inconsistency regarding the active profile
when creating new profiles.
If a new profile coincidentally landed in the current active profile's
array index after sorting, the app would mistakenly change to it
without any action from the user apart from the profile's creation.
Turning the profile id into the selector instead solves this issue.
* Revert "Store: Implement history synchronization between windows"
This reverts commit 99b61e617873412eb393d8f4dfccd8f8c172021f.
This is necessary for an upcoming improved implementation of the
history synchronization.
* History: Remove unused mutation
* Everywhere: Create abstract database handlers
The project now utilizes abstract handlers to fetch, modify
or otherwise manipulate data from the database.
This facilitates 3 aspects of the app, in addition of
making them future proof:
- Switching database libraries is now trivial
Since most of the app utilizes the abstract handlers, it's incredibly
easily to change to a different DB library.
Hypothetically, all that would need to be done is to simply replace the
the file containing the base handlers, while the rest of the app
would go unchanged.
- Syncing logic between Electron and web is now properly separated
There are now two distinct DB handling APIs: the Electron one and
the web one.
The app doesn't need to manually choose the API, because it's detected
which platform is being utilized on import.
- All Electron windows now share the same database instance
This provides a single source of truth, improving consistency
regarding data manipulation and windows synchronization.
As a sidenote, syncing implementation has been left as is
(web unimplemented; Electron only syncs settings, remaining
datastore syncing will be implemented in the upcoming commits).
* Electron/History: Implement history synchronization
* Profiles: Implement suplementary profile creation logic
* ft-profile-edit: Small fix on profile name missing display
* Electron/Profiles: Implement profile synchronization
* Electron/Playlists: Implement playlist synchronization
2021-12-15 19:42:24 +01:00
|
|
|
syncOtherWindows(
|
|
|
|
IpcChannels.SYNC_PLAYLISTS,
|
|
|
|
event,
|
|
|
|
{ event: SyncEvents.PLAYLISTS.UPSERT_VIDEO, data }
|
|
|
|
)
|
|
|
|
return null
|
|
|
|
|
2024-01-03 19:44:57 +01:00
|
|
|
case DBActions.PLAYLISTS.UPSERT_VIDEOS:
|
|
|
|
await baseHandlers.playlists.upsertVideosByPlaylistId(data._id, data.videos)
|
|
|
|
syncOtherWindows(
|
|
|
|
IpcChannels.SYNC_PLAYLISTS,
|
|
|
|
event,
|
|
|
|
{ event: SyncEvents.PLAYLISTS.UPSERT_VIDEOS, data }
|
|
|
|
)
|
Store Revamp / Full database synchronization across windows (#1833)
* History: Refactor history module
* Profiles: Refactor profiles module
* IPC: Move channel ids to their own file and make them constants
* IPC: Replace single sync channel for one channel per sync type
* Everywhere: Replace default profile id magic strings with constant ref
* Profiles: Refactor `activeProfile` property from store
This commit makes it so that `activeProfile`'s getter returns
the entire profile, while the related update function only needs
the profile id (instead of the previously used array index)
to change the currently active profile.
This change was made due to inconsistency regarding the active profile
when creating new profiles.
If a new profile coincidentally landed in the current active profile's
array index after sorting, the app would mistakenly change to it
without any action from the user apart from the profile's creation.
Turning the profile id into the selector instead solves this issue.
* Revert "Store: Implement history synchronization between windows"
This reverts commit 99b61e617873412eb393d8f4dfccd8f8c172021f.
This is necessary for an upcoming improved implementation of the
history synchronization.
* History: Remove unused mutation
* Everywhere: Create abstract database handlers
The project now utilizes abstract handlers to fetch, modify
or otherwise manipulate data from the database.
This facilitates 3 aspects of the app, in addition of
making them future proof:
- Switching database libraries is now trivial
Since most of the app utilizes the abstract handlers, it's incredibly
easily to change to a different DB library.
Hypothetically, all that would need to be done is to simply replace the
the file containing the base handlers, while the rest of the app
would go unchanged.
- Syncing logic between Electron and web is now properly separated
There are now two distinct DB handling APIs: the Electron one and
the web one.
The app doesn't need to manually choose the API, because it's detected
which platform is being utilized on import.
- All Electron windows now share the same database instance
This provides a single source of truth, improving consistency
regarding data manipulation and windows synchronization.
As a sidenote, syncing implementation has been left as is
(web unimplemented; Electron only syncs settings, remaining
datastore syncing will be implemented in the upcoming commits).
* Electron/History: Implement history synchronization
* Profiles: Implement suplementary profile creation logic
* ft-profile-edit: Small fix on profile name missing display
* Electron/Profiles: Implement profile synchronization
* Electron/Playlists: Implement playlist synchronization
2021-12-15 19:42:24 +01:00
|
|
|
return null
|
|
|
|
|
|
|
|
case DBActions.GENERAL.DELETE:
|
|
|
|
await baseHandlers.playlists.delete(data)
|
2024-01-03 19:44:57 +01:00
|
|
|
syncOtherWindows(
|
|
|
|
IpcChannels.SYNC_PLAYLISTS,
|
|
|
|
event,
|
|
|
|
{ event: SyncEvents.GENERAL.DELETE, data }
|
|
|
|
)
|
Store Revamp / Full database synchronization across windows (#1833)
* History: Refactor history module
* Profiles: Refactor profiles module
* IPC: Move channel ids to their own file and make them constants
* IPC: Replace single sync channel for one channel per sync type
* Everywhere: Replace default profile id magic strings with constant ref
* Profiles: Refactor `activeProfile` property from store
This commit makes it so that `activeProfile`'s getter returns
the entire profile, while the related update function only needs
the profile id (instead of the previously used array index)
to change the currently active profile.
This change was made due to inconsistency regarding the active profile
when creating new profiles.
If a new profile coincidentally landed in the current active profile's
array index after sorting, the app would mistakenly change to it
without any action from the user apart from the profile's creation.
Turning the profile id into the selector instead solves this issue.
* Revert "Store: Implement history synchronization between windows"
This reverts commit 99b61e617873412eb393d8f4dfccd8f8c172021f.
This is necessary for an upcoming improved implementation of the
history synchronization.
* History: Remove unused mutation
* Everywhere: Create abstract database handlers
The project now utilizes abstract handlers to fetch, modify
or otherwise manipulate data from the database.
This facilitates 3 aspects of the app, in addition of
making them future proof:
- Switching database libraries is now trivial
Since most of the app utilizes the abstract handlers, it's incredibly
easily to change to a different DB library.
Hypothetically, all that would need to be done is to simply replace the
the file containing the base handlers, while the rest of the app
would go unchanged.
- Syncing logic between Electron and web is now properly separated
There are now two distinct DB handling APIs: the Electron one and
the web one.
The app doesn't need to manually choose the API, because it's detected
which platform is being utilized on import.
- All Electron windows now share the same database instance
This provides a single source of truth, improving consistency
regarding data manipulation and windows synchronization.
As a sidenote, syncing implementation has been left as is
(web unimplemented; Electron only syncs settings, remaining
datastore syncing will be implemented in the upcoming commits).
* Electron/History: Implement history synchronization
* Profiles: Implement suplementary profile creation logic
* ft-profile-edit: Small fix on profile name missing display
* Electron/Profiles: Implement profile synchronization
* Electron/Playlists: Implement playlist synchronization
2021-12-15 19:42:24 +01:00
|
|
|
return null
|
|
|
|
|
|
|
|
case DBActions.PLAYLISTS.DELETE_VIDEO_ID:
|
2024-01-18 04:52:42 +01:00
|
|
|
await baseHandlers.playlists.deleteVideoIdByPlaylistId({
|
|
|
|
_id: data._id,
|
|
|
|
videoId: data.videoId,
|
|
|
|
playlistItemId: data.playlistItemId,
|
|
|
|
})
|
Store Revamp / Full database synchronization across windows (#1833)
* History: Refactor history module
* Profiles: Refactor profiles module
* IPC: Move channel ids to their own file and make them constants
* IPC: Replace single sync channel for one channel per sync type
* Everywhere: Replace default profile id magic strings with constant ref
* Profiles: Refactor `activeProfile` property from store
This commit makes it so that `activeProfile`'s getter returns
the entire profile, while the related update function only needs
the profile id (instead of the previously used array index)
to change the currently active profile.
This change was made due to inconsistency regarding the active profile
when creating new profiles.
If a new profile coincidentally landed in the current active profile's
array index after sorting, the app would mistakenly change to it
without any action from the user apart from the profile's creation.
Turning the profile id into the selector instead solves this issue.
* Revert "Store: Implement history synchronization between windows"
This reverts commit 99b61e617873412eb393d8f4dfccd8f8c172021f.
This is necessary for an upcoming improved implementation of the
history synchronization.
* History: Remove unused mutation
* Everywhere: Create abstract database handlers
The project now utilizes abstract handlers to fetch, modify
or otherwise manipulate data from the database.
This facilitates 3 aspects of the app, in addition of
making them future proof:
- Switching database libraries is now trivial
Since most of the app utilizes the abstract handlers, it's incredibly
easily to change to a different DB library.
Hypothetically, all that would need to be done is to simply replace the
the file containing the base handlers, while the rest of the app
would go unchanged.
- Syncing logic between Electron and web is now properly separated
There are now two distinct DB handling APIs: the Electron one and
the web one.
The app doesn't need to manually choose the API, because it's detected
which platform is being utilized on import.
- All Electron windows now share the same database instance
This provides a single source of truth, improving consistency
regarding data manipulation and windows synchronization.
As a sidenote, syncing implementation has been left as is
(web unimplemented; Electron only syncs settings, remaining
datastore syncing will be implemented in the upcoming commits).
* Electron/History: Implement history synchronization
* Profiles: Implement suplementary profile creation logic
* ft-profile-edit: Small fix on profile name missing display
* Electron/Profiles: Implement profile synchronization
* Electron/Playlists: Implement playlist synchronization
2021-12-15 19:42:24 +01:00
|
|
|
syncOtherWindows(
|
|
|
|
IpcChannels.SYNC_PLAYLISTS,
|
|
|
|
event,
|
|
|
|
{ event: SyncEvents.PLAYLISTS.DELETE_VIDEO, data }
|
|
|
|
)
|
|
|
|
return null
|
|
|
|
|
|
|
|
case DBActions.PLAYLISTS.DELETE_VIDEO_IDS:
|
2024-01-03 19:44:57 +01:00
|
|
|
await baseHandlers.playlists.deleteVideoIdsByPlaylistId(data._id, data.videoIds)
|
Store Revamp / Full database synchronization across windows (#1833)
* History: Refactor history module
* Profiles: Refactor profiles module
* IPC: Move channel ids to their own file and make them constants
* IPC: Replace single sync channel for one channel per sync type
* Everywhere: Replace default profile id magic strings with constant ref
* Profiles: Refactor `activeProfile` property from store
This commit makes it so that `activeProfile`'s getter returns
the entire profile, while the related update function only needs
the profile id (instead of the previously used array index)
to change the currently active profile.
This change was made due to inconsistency regarding the active profile
when creating new profiles.
If a new profile coincidentally landed in the current active profile's
array index after sorting, the app would mistakenly change to it
without any action from the user apart from the profile's creation.
Turning the profile id into the selector instead solves this issue.
* Revert "Store: Implement history synchronization between windows"
This reverts commit 99b61e617873412eb393d8f4dfccd8f8c172021f.
This is necessary for an upcoming improved implementation of the
history synchronization.
* History: Remove unused mutation
* Everywhere: Create abstract database handlers
The project now utilizes abstract handlers to fetch, modify
or otherwise manipulate data from the database.
This facilitates 3 aspects of the app, in addition of
making them future proof:
- Switching database libraries is now trivial
Since most of the app utilizes the abstract handlers, it's incredibly
easily to change to a different DB library.
Hypothetically, all that would need to be done is to simply replace the
the file containing the base handlers, while the rest of the app
would go unchanged.
- Syncing logic between Electron and web is now properly separated
There are now two distinct DB handling APIs: the Electron one and
the web one.
The app doesn't need to manually choose the API, because it's detected
which platform is being utilized on import.
- All Electron windows now share the same database instance
This provides a single source of truth, improving consistency
regarding data manipulation and windows synchronization.
As a sidenote, syncing implementation has been left as is
(web unimplemented; Electron only syncs settings, remaining
datastore syncing will be implemented in the upcoming commits).
* Electron/History: Implement history synchronization
* Profiles: Implement suplementary profile creation logic
* ft-profile-edit: Small fix on profile name missing display
* Electron/Profiles: Implement profile synchronization
* Electron/Playlists: Implement playlist synchronization
2021-12-15 19:42:24 +01:00
|
|
|
// TODO: Syncing (implement only when it starts being used)
|
|
|
|
// syncOtherWindows(IpcChannels.SYNC_PLAYLISTS, event, { event: '_', data })
|
|
|
|
return null
|
|
|
|
|
|
|
|
case DBActions.PLAYLISTS.DELETE_ALL_VIDEOS:
|
2024-01-03 19:44:57 +01:00
|
|
|
await baseHandlers.playlists.deleteAllVideosByPlaylistId(data)
|
Store Revamp / Full database synchronization across windows (#1833)
* History: Refactor history module
* Profiles: Refactor profiles module
* IPC: Move channel ids to their own file and make them constants
* IPC: Replace single sync channel for one channel per sync type
* Everywhere: Replace default profile id magic strings with constant ref
* Profiles: Refactor `activeProfile` property from store
This commit makes it so that `activeProfile`'s getter returns
the entire profile, while the related update function only needs
the profile id (instead of the previously used array index)
to change the currently active profile.
This change was made due to inconsistency regarding the active profile
when creating new profiles.
If a new profile coincidentally landed in the current active profile's
array index after sorting, the app would mistakenly change to it
without any action from the user apart from the profile's creation.
Turning the profile id into the selector instead solves this issue.
* Revert "Store: Implement history synchronization between windows"
This reverts commit 99b61e617873412eb393d8f4dfccd8f8c172021f.
This is necessary for an upcoming improved implementation of the
history synchronization.
* History: Remove unused mutation
* Everywhere: Create abstract database handlers
The project now utilizes abstract handlers to fetch, modify
or otherwise manipulate data from the database.
This facilitates 3 aspects of the app, in addition of
making them future proof:
- Switching database libraries is now trivial
Since most of the app utilizes the abstract handlers, it's incredibly
easily to change to a different DB library.
Hypothetically, all that would need to be done is to simply replace the
the file containing the base handlers, while the rest of the app
would go unchanged.
- Syncing logic between Electron and web is now properly separated
There are now two distinct DB handling APIs: the Electron one and
the web one.
The app doesn't need to manually choose the API, because it's detected
which platform is being utilized on import.
- All Electron windows now share the same database instance
This provides a single source of truth, improving consistency
regarding data manipulation and windows synchronization.
As a sidenote, syncing implementation has been left as is
(web unimplemented; Electron only syncs settings, remaining
datastore syncing will be implemented in the upcoming commits).
* Electron/History: Implement history synchronization
* Profiles: Implement suplementary profile creation logic
* ft-profile-edit: Small fix on profile name missing display
* Electron/Profiles: Implement profile synchronization
* Electron/Playlists: Implement playlist synchronization
2021-12-15 19:42:24 +01:00
|
|
|
// TODO: Syncing (implement only when it starts being used)
|
|
|
|
// syncOtherWindows(IpcChannels.SYNC_PLAYLISTS, event, { event: '_', data })
|
|
|
|
return null
|
|
|
|
|
|
|
|
case DBActions.GENERAL.DELETE_MULTIPLE:
|
|
|
|
await baseHandlers.playlists.deleteMultiple(data)
|
|
|
|
// TODO: Syncing (implement only when it starts being used)
|
|
|
|
// syncOtherWindows(IpcChannels.SYNC_PLAYLISTS, event, { event: '_', data })
|
|
|
|
return null
|
|
|
|
|
|
|
|
case DBActions.GENERAL.DELETE_ALL:
|
|
|
|
await baseHandlers.playlists.deleteAll()
|
|
|
|
// TODO: Syncing (implement only when it starts being used)
|
|
|
|
// syncOtherWindows(IpcChannels.SYNC_PLAYLISTS, event, { event: '_', data })
|
|
|
|
return null
|
|
|
|
|
|
|
|
default:
|
|
|
|
// eslint-disable-next-line no-throw-literal
|
|
|
|
throw 'invalid playlist db action'
|
|
|
|
}
|
|
|
|
} catch (err) {
|
|
|
|
if (typeof err === 'string') throw err
|
|
|
|
else throw err.toString()
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
// *********** //
|
|
|
|
|
|
|
|
function syncOtherWindows(channel, event, payload) {
|
|
|
|
const otherWindows = BrowserWindow.getAllWindows().filter((window) => {
|
|
|
|
return window.webContents.id !== event.sender.id
|
|
|
|
})
|
|
|
|
|
|
|
|
for (const window of otherWindows) {
|
|
|
|
window.webContents.send(channel, payload)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// ************************************************* //
|
|
|
|
|
2023-10-08 15:40:58 +02:00
|
|
|
let resourcesCleanUpDone = false
|
|
|
|
|
2023-05-12 01:34:20 +02:00
|
|
|
app.on('window-all-closed', () => {
|
2023-08-10 22:38:40 +02:00
|
|
|
// Clean up resources (datastores' compaction + Electron cache and storage data clearing)
|
|
|
|
cleanUpResources().finally(() => {
|
|
|
|
if (process.platform !== 'darwin') {
|
|
|
|
app.quit()
|
|
|
|
}
|
2021-06-16 06:08:48 +02:00
|
|
|
})
|
2020-09-20 20:54:23 +02:00
|
|
|
})
|
2020-02-16 19:30:00 +01:00
|
|
|
|
2023-10-08 15:40:58 +02:00
|
|
|
if (process.platform === 'darwin') {
|
|
|
|
// `window-all-closed` doesn't fire for Cmd+Q
|
|
|
|
// https://www.electronjs.org/docs/latest/api/app#event-window-all-closed
|
|
|
|
// This is also fired when `app.quit` called
|
|
|
|
// Not using `before-quit` since that one is fired before windows are closed
|
|
|
|
app.on('will-quit', e => {
|
|
|
|
// Let app quit when the cleanup is finished
|
|
|
|
|
|
|
|
if (resourcesCleanUpDone) { return }
|
|
|
|
|
|
|
|
e.preventDefault()
|
|
|
|
cleanUpResources().finally(() => {
|
|
|
|
// Quit AFTER the resources cleanup is finished
|
|
|
|
// Which calls the listener again, which is why we have the variable
|
|
|
|
|
|
|
|
app.quit()
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
async function cleanUpResources() {
|
|
|
|
if (resourcesCleanUpDone) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
await Promise.allSettled([
|
2023-08-10 22:38:40 +02:00
|
|
|
baseHandlers.compactAllDatastores(),
|
|
|
|
session.defaultSession.clearCache(),
|
|
|
|
session.defaultSession.clearStorageData({
|
|
|
|
storages: [
|
|
|
|
'appcache',
|
|
|
|
'cookies',
|
|
|
|
'filesystem',
|
|
|
|
'indexdb',
|
|
|
|
'shadercache',
|
|
|
|
'websql',
|
|
|
|
'serviceworkers',
|
|
|
|
'cachestorage'
|
|
|
|
]
|
|
|
|
})
|
|
|
|
])
|
2023-10-08 15:40:58 +02:00
|
|
|
|
|
|
|
resourcesCleanUpDone = true
|
2023-08-10 22:38:40 +02:00
|
|
|
}
|
|
|
|
|
2023-05-12 01:34:20 +02:00
|
|
|
// MacOS event
|
|
|
|
// https://www.electronjs.org/docs/latest/api/app#event-activate-macos
|
2021-03-07 17:07:09 +01:00
|
|
|
app.on('activate', () => {
|
2021-07-03 04:44:23 +02:00
|
|
|
if (BrowserWindow.getAllWindows().length === 0) {
|
2021-03-07 17:07:09 +01:00
|
|
|
createWindow()
|
2020-10-04 22:31:07 +02:00
|
|
|
}
|
|
|
|
})
|
2020-10-07 15:57:22 +02:00
|
|
|
|
2021-03-07 17:07:09 +01:00
|
|
|
/*
|
|
|
|
* Callback when processing a freetube:// link (macOS)
|
|
|
|
*/
|
|
|
|
app.on('open-url', (event, url) => {
|
|
|
|
event.preventDefault()
|
2021-01-14 19:51:33 +01:00
|
|
|
|
2021-03-07 17:07:09 +01:00
|
|
|
if (mainWindow && mainWindow.webContents) {
|
|
|
|
mainWindow.webContents.send('openUrl', baseUrl(url))
|
|
|
|
} else {
|
|
|
|
startupUrl = baseUrl(url)
|
|
|
|
}
|
2021-01-14 19:51:33 +01:00
|
|
|
})
|
2020-02-16 19:30:00 +01:00
|
|
|
|
2021-03-07 17:07:09 +01:00
|
|
|
/*
|
|
|
|
* Check if an argument was passed and send it over to the GUI (Linux / Windows).
|
|
|
|
* Remove freetube:// protocol if present
|
|
|
|
*/
|
|
|
|
const url = getLinkUrl(process.argv)
|
|
|
|
if (url) {
|
|
|
|
startupUrl = url
|
2020-02-16 19:30:00 +01:00
|
|
|
}
|
2020-08-21 03:20:22 +02:00
|
|
|
|
2021-03-07 17:07:09 +01:00
|
|
|
function baseUrl(arg) {
|
2023-01-27 19:50:02 +01:00
|
|
|
let newArg = arg.replace('freetube://', '')
|
|
|
|
// add support for authority free url
|
|
|
|
.replace('freetube:', '')
|
|
|
|
|
|
|
|
// fix for Qt URL, like `freetube://https//www.youtube.com/watch?v=...`
|
|
|
|
// For details see https://github.com/FreeTubeApp/FreeTube/pull/3119
|
|
|
|
if (newArg.startsWith('https') && newArg.charAt(5) !== ':') {
|
|
|
|
newArg = 'https:' + newArg.substring(5)
|
|
|
|
}
|
|
|
|
return newArg
|
2020-02-16 19:30:00 +01:00
|
|
|
}
|
2020-10-15 15:33:25 +02:00
|
|
|
|
2021-03-07 17:07:09 +01:00
|
|
|
function getLinkUrl(argv) {
|
|
|
|
if (argv.length > 1) {
|
|
|
|
return baseUrl(argv[argv.length - 1])
|
|
|
|
} else {
|
|
|
|
return null
|
|
|
|
}
|
2020-10-15 15:33:25 +02:00
|
|
|
}
|
|
|
|
|
2022-12-31 11:08:04 +01:00
|
|
|
/*
|
2021-03-07 17:07:09 +01:00
|
|
|
* Auto Updater
|
|
|
|
*
|
|
|
|
* Uncomment the following code below and install `electron-updater` to
|
|
|
|
* support auto updating. Code Signing with a valid certificate is required.
|
|
|
|
* https://simulatedgreg.gitbooks.io/electron-vue/content/en/using-electron-builder.html#auto-updating
|
|
|
|
*/
|
2020-10-15 15:33:25 +02:00
|
|
|
|
2021-03-07 17:07:09 +01:00
|
|
|
/*
|
|
|
|
import { autoUpdater } from 'electron-updater'
|
|
|
|
autoUpdater.on('update-downloaded', () => {
|
|
|
|
autoUpdater.quitAndInstall()
|
|
|
|
})
|
2020-10-15 15:33:25 +02:00
|
|
|
|
2021-03-07 17:07:09 +01:00
|
|
|
app.on('ready', () => {
|
|
|
|
if (process.env.NODE_ENV === 'production') autoUpdater.checkForUpdates()
|
|
|
|
})
|
|
|
|
*/
|
2020-02-16 19:30:00 +01:00
|
|
|
|
2022-12-31 11:08:04 +01:00
|
|
|
function navigateTo(path, browserWindow) {
|
|
|
|
if (browserWindow == null) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
browserWindow.webContents.send(
|
|
|
|
'change-view',
|
|
|
|
{ route: path }
|
|
|
|
)
|
2020-02-16 19:30:00 +01:00
|
|
|
}
|
2021-03-07 17:07:09 +01:00
|
|
|
|
2022-12-26 22:42:43 +01:00
|
|
|
async function setMenu() {
|
|
|
|
const sidenavSettings = baseHandlers.settings._findSidenavSettings()
|
|
|
|
const hideTrendingVideos = (await sidenavSettings.hideTrendingVideos)?.value
|
|
|
|
const hidePopularVideos = (await sidenavSettings.hidePopularVideos)?.value
|
2023-03-22 03:27:27 +01:00
|
|
|
const backendFallback = (await sidenavSettings.backendFallback)?.value
|
|
|
|
const backendPreference = (await sidenavSettings.backendPreference)?.value
|
2022-12-26 22:42:43 +01:00
|
|
|
const hidePlaylists = (await sidenavSettings.hidePlaylists)?.value
|
|
|
|
|
2021-06-07 02:38:06 +02:00
|
|
|
const template = [
|
|
|
|
{
|
|
|
|
label: 'File',
|
2022-06-21 04:31:47 +02:00
|
|
|
submenu: [
|
|
|
|
{
|
|
|
|
label: 'New Window',
|
|
|
|
accelerator: 'CmdOrCtrl+N',
|
|
|
|
click: (_menuItem, _browserWindow, _event) => {
|
|
|
|
createWindow({
|
|
|
|
replaceMainWindow: false,
|
|
|
|
showWindowNow: true
|
|
|
|
})
|
|
|
|
},
|
|
|
|
type: 'normal'
|
|
|
|
},
|
|
|
|
{ type: 'separator' },
|
2022-10-29 19:08:03 +02:00
|
|
|
{
|
|
|
|
label: 'Preferences',
|
|
|
|
accelerator: 'CmdOrCtrl+,',
|
|
|
|
click: (_menuItem, browserWindow, _event) => {
|
2022-12-31 11:08:04 +01:00
|
|
|
navigateTo('/settings', browserWindow)
|
2022-10-29 19:08:03 +02:00
|
|
|
},
|
|
|
|
type: 'normal'
|
|
|
|
},
|
|
|
|
{ type: 'separator' },
|
2022-06-21 04:31:47 +02:00
|
|
|
{ role: 'quit' }
|
|
|
|
]
|
2021-06-07 02:38:06 +02:00
|
|
|
},
|
2021-03-07 17:07:09 +01:00
|
|
|
{
|
2021-06-07 02:38:06 +02:00
|
|
|
label: 'Edit',
|
|
|
|
submenu: [
|
|
|
|
{ role: 'cut' },
|
|
|
|
{
|
|
|
|
role: 'copy',
|
|
|
|
accelerator: 'CmdOrCtrl+C',
|
|
|
|
selector: 'copy:'
|
|
|
|
},
|
|
|
|
{
|
|
|
|
role: 'paste',
|
|
|
|
accelerator: 'CmdOrCtrl+V',
|
|
|
|
selector: 'paste:'
|
|
|
|
},
|
|
|
|
{ role: 'pasteandmatchstyle' },
|
|
|
|
{ role: 'delete' },
|
|
|
|
{ role: 'selectall' }
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
label: 'View',
|
|
|
|
submenu: [
|
|
|
|
{ role: 'reload' },
|
|
|
|
{
|
|
|
|
role: 'forcereload',
|
|
|
|
accelerator: 'CmdOrCtrl+Shift+R'
|
|
|
|
},
|
|
|
|
{ role: 'toggledevtools' },
|
2022-09-19 15:36:40 +02:00
|
|
|
{ role: 'toggledevtools', accelerator: 'f12', visible: false },
|
|
|
|
{
|
|
|
|
label: 'Enter Inspect Element Mode',
|
|
|
|
accelerator: 'CmdOrCtrl+Shift+C',
|
|
|
|
click: (_, window) => {
|
|
|
|
if (window.webContents.isDevToolsOpened()) {
|
|
|
|
window.devToolsWebContents.executeJavaScript('DevToolsAPI.enterInspectElementMode()')
|
|
|
|
} else {
|
|
|
|
window.webContents.once('devtools-opened', () => {
|
|
|
|
window.devToolsWebContents.executeJavaScript('DevToolsAPI.enterInspectElementMode()')
|
|
|
|
})
|
|
|
|
window.webContents.openDevTools()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
2021-06-07 02:38:06 +02:00
|
|
|
{ type: 'separator' },
|
|
|
|
{ role: 'resetzoom' },
|
2022-06-20 13:57:25 +02:00
|
|
|
{ role: 'resetzoom', accelerator: 'CmdOrCtrl+num0', visible: false },
|
|
|
|
{ role: 'zoomin', accelerator: 'CmdOrCtrl+Plus' },
|
|
|
|
{ role: 'zoomin', accelerator: 'CmdOrCtrl+=', visible: false },
|
|
|
|
{ role: 'zoomin', accelerator: 'CmdOrCtrl+numadd', visible: false },
|
2021-06-07 02:38:06 +02:00
|
|
|
{ role: 'zoomout' },
|
2022-06-20 13:57:25 +02:00
|
|
|
{ role: 'zoomout', accelerator: 'CmdOrCtrl+numsub', visible: false },
|
2021-06-07 02:38:06 +02:00
|
|
|
{ type: 'separator' },
|
2022-11-24 18:47:44 +01:00
|
|
|
{ role: 'togglefullscreen' },
|
|
|
|
{ type: 'separator' },
|
2022-12-11 08:41:03 +01:00
|
|
|
{
|
|
|
|
label: 'Back',
|
|
|
|
accelerator: 'Alt+Left',
|
|
|
|
click: (_menuItem, browserWindow, _event) => {
|
|
|
|
if (browserWindow == null) { return }
|
|
|
|
|
|
|
|
browserWindow.webContents.send(
|
|
|
|
'history-back',
|
|
|
|
)
|
|
|
|
},
|
|
|
|
type: 'normal',
|
|
|
|
},
|
|
|
|
{
|
|
|
|
label: 'Forward',
|
|
|
|
accelerator: 'Alt+Right',
|
|
|
|
click: (_menuItem, browserWindow, _event) => {
|
|
|
|
if (browserWindow == null) { return }
|
|
|
|
|
|
|
|
browserWindow.webContents.send(
|
|
|
|
'history-forward',
|
|
|
|
)
|
|
|
|
},
|
|
|
|
type: 'normal',
|
|
|
|
},
|
2021-06-07 02:38:06 +02:00
|
|
|
]
|
|
|
|
},
|
2022-12-26 22:42:43 +01:00
|
|
|
{
|
|
|
|
label: 'Navigate',
|
|
|
|
submenu: [
|
|
|
|
{
|
|
|
|
label: 'Subscriptions',
|
|
|
|
click: (_menuItem, browserWindow, _event) => {
|
2022-12-31 11:08:04 +01:00
|
|
|
navigateTo('/subscriptions', browserWindow)
|
2022-12-26 22:42:43 +01:00
|
|
|
},
|
|
|
|
type: 'normal'
|
|
|
|
},
|
|
|
|
{
|
|
|
|
label: 'Channels',
|
|
|
|
click: (_menuItem, browserWindow, _event) => {
|
2022-12-31 11:08:04 +01:00
|
|
|
navigateTo('/subscribedchannels', browserWindow)
|
2022-12-26 22:42:43 +01:00
|
|
|
},
|
|
|
|
type: 'normal'
|
|
|
|
},
|
|
|
|
!hideTrendingVideos && {
|
|
|
|
label: 'Trending',
|
|
|
|
click: (_menuItem, browserWindow, _event) => {
|
2022-12-31 11:08:04 +01:00
|
|
|
navigateTo('/trending', browserWindow)
|
2022-12-26 22:42:43 +01:00
|
|
|
},
|
|
|
|
type: 'normal'
|
|
|
|
},
|
2023-03-22 03:27:27 +01:00
|
|
|
(!hidePopularVideos && (backendFallback || backendPreference === 'invidious')) && {
|
2022-12-26 22:42:43 +01:00
|
|
|
label: 'Most Popular',
|
|
|
|
click: (_menuItem, browserWindow, _event) => {
|
2022-12-31 11:08:04 +01:00
|
|
|
navigateTo('/popular', browserWindow)
|
2022-12-26 22:42:43 +01:00
|
|
|
},
|
|
|
|
type: 'normal'
|
|
|
|
},
|
|
|
|
!hidePlaylists && {
|
|
|
|
label: 'Playlists',
|
|
|
|
click: (_menuItem, browserWindow, _event) => {
|
2022-12-31 11:08:04 +01:00
|
|
|
navigateTo('/userplaylists', browserWindow)
|
2022-12-26 22:42:43 +01:00
|
|
|
},
|
|
|
|
type: 'normal'
|
|
|
|
},
|
|
|
|
{
|
|
|
|
label: 'History',
|
|
|
|
// MacOS: Command + Y
|
|
|
|
// Other OS: Ctrl + H
|
|
|
|
accelerator: process.platform === 'darwin' ? 'Cmd+Y' : 'Ctrl+H',
|
|
|
|
click: (_menuItem, browserWindow, _event) => {
|
2022-12-31 11:08:04 +01:00
|
|
|
navigateTo('/history', browserWindow)
|
2022-12-26 22:42:43 +01:00
|
|
|
},
|
|
|
|
type: 'normal'
|
|
|
|
},
|
2023-11-26 00:37:32 +01:00
|
|
|
{
|
|
|
|
label: 'Profile Manager',
|
|
|
|
click: (_menuItem, browserWindow, _event) => {
|
|
|
|
navigateTo('/settings/profile/', browserWindow)
|
|
|
|
},
|
|
|
|
type: 'normal'
|
|
|
|
},
|
2022-12-26 22:42:43 +01:00
|
|
|
].filter((v) => v !== false),
|
|
|
|
},
|
2021-06-07 02:38:06 +02:00
|
|
|
{
|
|
|
|
role: 'window',
|
|
|
|
submenu: [
|
|
|
|
{ role: 'minimize' },
|
|
|
|
{ role: 'close' }
|
|
|
|
]
|
2021-03-07 17:07:09 +01:00
|
|
|
}
|
|
|
|
]
|
2020-02-16 19:30:00 +01:00
|
|
|
|
2021-03-07 17:07:09 +01:00
|
|
|
if (process.platform === 'darwin') {
|
|
|
|
template.unshift({
|
|
|
|
label: app.getName(),
|
|
|
|
submenu: [
|
|
|
|
{ role: 'about' },
|
|
|
|
{ type: 'separator' },
|
|
|
|
{ role: 'services' },
|
|
|
|
{ type: 'separator' },
|
|
|
|
{ role: 'hide' },
|
|
|
|
{ role: 'hideothers' },
|
|
|
|
{ role: 'unhide' },
|
|
|
|
{ type: 'separator' },
|
|
|
|
{ role: 'quit' }
|
|
|
|
]
|
|
|
|
})
|
2020-02-16 19:30:00 +01:00
|
|
|
|
2021-06-07 02:38:06 +02:00
|
|
|
template.push(
|
|
|
|
{ role: 'window' },
|
|
|
|
{ role: 'help' },
|
|
|
|
{ role: 'services' }
|
|
|
|
)
|
2021-03-07 17:07:09 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
const menu = Menu.buildFromTemplate(template)
|
|
|
|
Menu.setApplicationMenu(menu)
|
|
|
|
}
|
2020-02-16 19:30:00 +01:00
|
|
|
}
|