Skip to content

Commit

Permalink
Merge branch 'development' into feature/subscription-cache
Browse files Browse the repository at this point in the history
* development: (49 commits)
  Translated using Weblate (Serbian)
  Translated using Weblate (Turkish)
  Translated using Weblate (English (United Kingdom))
  Translated using Weblate (Italian)
  Translated using Weblate (Chinese (Simplified Han script))
  Translated using Weblate (Italian)
  Translated using Weblate (Italian)
  Translated using Weblate (Italian)
  Translated using Weblate (Italian)
  Translated using Weblate (French)
  Translated using Weblate (German)
  Bump swiper from 11.1.10 to 11.1.12 (FreeTubeApp#5635)
  Translated using Weblate (Spanish)
  Bump the stylelint group with 2 updates (FreeTubeApp#5633)
  Migrate video player from video.js to shaka-player (FreeTubeApp#4978)
  Bump lefthook from 1.7.14 to 1.7.15 (FreeTubeApp#5634)
  Bump electron-context-menu from 4.0.2 to 4.0.4 (FreeTubeApp#5636)
  Bump youtubei.js from 10.3.0 to 10.4.0 (FreeTubeApp#5637)
  Cleanup the Hide Profile Pictures in Comments code (FreeTubeApp#5625)
  Switch to non-deprecated Electron navigation history APIs (FreeTubeApp#5626)
  ...

# Conflicts:
#	src/renderer/store/modules/index.js
  • Loading branch information
PikachuEXE committed Sep 3, 2024
2 parents ad0a93e + f60ca8b commit 1b9c1fd
Show file tree
Hide file tree
Showing 128 changed files with 6,366 additions and 7,977 deletions.
2 changes: 1 addition & 1 deletion .stylelintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"selector-pseudo-class-no-unknown": [
true,
{
"ignorePseudoClasses": ["deep"]
"ignorePseudoClasses": ["deep", "global"]
}
],
"a11y/no-outline-none": true,
Expand Down
5 changes: 0 additions & 5 deletions _scripts/_domParser.js

This file was deleted.

34 changes: 24 additions & 10 deletions _scripts/dev-runner.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,14 @@ const web = process.argv.indexOf('--web') !== -1
let mainConfig
let rendererConfig
let webConfig
let SHAKA_LOCALES_TO_BE_BUNDLED

if (!web) {
mainConfig = require('./webpack.main.config')
rendererConfig = require('./webpack.renderer.config')

SHAKA_LOCALES_TO_BE_BUNDLED = rendererConfig.SHAKA_LOCALES_TO_BE_BUNDLED
delete rendererConfig.SHAKA_LOCALES_TO_BE_BUNDLED
} else {
webConfig = require('./webpack.web.config')
}
Expand Down Expand Up @@ -128,17 +132,27 @@ function startRenderer(callback) {
})

const server = new WebpackDevServer({
static: {
directory: path.resolve(__dirname, '..', 'static'),
watch: {
ignored: [
/(dashFiles|storyboards)\/*/,
'/**/.DS_Store',
'**/static/locales/*'
]
static: [
{
directory: path.resolve(__dirname, '..', 'static'),
watch: {
ignored: [
/(dashFiles|storyboards)\/*/,
'/**/.DS_Store',
'**/static/locales/*'
]
},
publicPath: '/static'
},
publicPath: '/static'
},
{
directory: path.resolve(__dirname, '..', 'node_modules', 'shaka-player', 'ui', 'locales'),
publicPath: '/static/shaka-player-locales',
watch: {
// Ignore everything that isn't one of the locales that we would bundle in production mode
ignored: `**/!(${SHAKA_LOCALES_TO_BE_BUNDLED.join('|')}).json`
}
}
],
port
}, compiler)

Expand Down
114 changes: 114 additions & 0 deletions _scripts/getShakaLocales.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
const { readFileSync, readdirSync } = require('fs')

function getPreloadedLocales() {
const localesFile = readFileSync(`${__dirname}/../node_modules/shaka-player/dist/locales.js`, 'utf-8')

const localesLine = localesFile.match(/^\/\/ LOCALES: ([\w, -]+)$/m)

if (!localesLine) {
throw new Error("Failed to parse shaka-player's preloaded locales")
}

return localesLine[1].split(',').map(locale => locale.trim())
}

function getAllLocales() {
const filenames = readdirSync(`${__dirname}/../node_modules/shaka-player/ui/locales`)

return new Set(filenames
.filter(filename => filename !== 'source.json' && filename.endsWith('.json'))
.map(filename => filename.replace('.json', '')))
}

/**
* Maps the shaka locales to FreeTube's active ones
* This allows us to know which locale files are actually needed
* and which shaka locale needs to be activated for a given FreeTube one.
* @param {Set<string>} shakaLocales
* @param {string[]} freeTubeLocales
*/
function getMappings(shakaLocales, freeTubeLocales) {
/**
* @type {[string, string][]}
* Using this structure as it gets passed to `new Map()` in the player component
* The first element is the FreeTube locale, the second one is the shaka-player one
**/
const mappings = []

for (const locale of freeTubeLocales) {
if (shakaLocales.has(locale)) {
mappings.push([
locale,
locale
])
} else if (shakaLocales.has(locale.replace('_', '-'))) {
mappings.push([
locale,
locale.replace('_', '-')
])
} else if (shakaLocales.has(locale.split(/[-_]/)[0])) {
mappings.push([
locale,
locale.split(/[-_]/)[0]
])
}
}

// special cases

mappings.push(
// according to https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
// "no" is the macro language for "nb" and "nn"
[
'nb_NO',
'no'
],
[
'nn',
'no'
],

// according to https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
// "iw" is the old/original code for Hebrew, these days it's "he"
[
'he',
'iw'
],

// not sure why we have pt, pt-PT and pt-BR in the FreeTube locales
// as pt and pt-PT are the same thing, but we should handle it here anyway
[
'pt',
'pt-PT'
]
)

return mappings
}

function getShakaLocales() {
const shakaLocales = getAllLocales()

/** @type {string[]} */
const freeTubeLocales = JSON.parse(readFileSync(`${__dirname}/../static/locales/activeLocales.json`, 'utf-8'))

const mappings = getMappings(shakaLocales, freeTubeLocales)

const preloaded = getPreloadedLocales()

const shakaMappings = mappings.map(mapping => mapping[1])

// use a set to deduplicate the list
// we don't need to bundle any locale files that are already embedded in shaka-player/preloaded

/** @type {string[]} */
const toBeBundled = [...new Set(shakaMappings.filter(locale => !preloaded.includes(locale)))]

return {
SHAKA_LOCALE_MAPPINGS: mappings,
SHAKA_LOCALES_PREBUNDLED: preloaded,
SHAKA_LOCALES_TO_BE_BUNDLED: toBeBundled
}
}

module.exports = getShakaLocales()
135 changes: 135 additions & 0 deletions _scripts/patchShaka.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
// This script fixes shaka not exporting its type definitions and referencing remote google fonts in its CSS
// by adding an export line to the type definitions and downloading the fonts and updating the CSS to point to the local files
// this script only makes changes if they are needed, so running it multiple times doesn't cause any problems

import { appendFileSync, closeSync, ftruncateSync, openSync, readFileSync, writeFileSync, writeSync } from 'fs'
import { resolve } from 'path'

const SHAKA_DIST_DIR = resolve(import.meta.dirname, '../node_modules/shaka-player/dist')

function fixTypes() {
let fixedTypes = false

let fileHandleNormal
try {
fileHandleNormal = openSync(`${SHAKA_DIST_DIR}/shaka-player.ui.d.ts`, 'a+')

const contents = readFileSync(fileHandleNormal, 'utf-8')

// This script is run after every `yarn install`, even if shaka-player wasn't updated
// So we want to check first, if we actually need to make any changes
// or if the ones from the previous run are still intact
if (!contents.includes('export default shaka')) {
appendFileSync(fileHandleNormal, 'export default shaka;\n')

fixedTypes = true
}
} finally {
if (typeof fileHandleNormal !== 'undefined') {
closeSync(fileHandleNormal)
}
}

let fileHandleDebug
try {
fileHandleDebug = openSync(`${SHAKA_DIST_DIR}/shaka-player.ui.debug.d.ts`, 'a+')

const contents = readFileSync(fileHandleDebug, 'utf-8')

// This script is run after every `yarn install`, even if shaka-player wasn't updated
// So we want to check first, if we actually need to make any changes
// or if the ones from the previous run are still intact
if (!contents.includes('export default shaka')) {
appendFileSync(fileHandleDebug, 'export default shaka;\n')

fixedTypes = true
}
} finally {
if (typeof fileHandleDebug !== 'undefined') {
closeSync(fileHandleDebug)
}
}

if (fixedTypes) {
console.log('Fixed shaka-player types')
}
}

async function removeRobotoFont() {
let cssFileHandle
try {
cssFileHandle = openSync(`${SHAKA_DIST_DIR}/controls.css`, 'r+')

let cssContents = readFileSync(cssFileHandle, 'utf-8')

const beforeReplacement = cssContents.length
cssContents = cssContents.replace(/@font-face\{font-family:Roboto;[^}]+\}/, '')

if (cssContents.length !== beforeReplacement) {
ftruncateSync(cssFileHandle)
writeSync(cssFileHandle, cssContents, 0, 'utf-8')

console.log('Removed shaka-player Roboto font, so it uses ours')
}
} finally {
if (typeof cssFileHandle !== 'undefined') {
closeSync(cssFileHandle)
}
}
}

async function replaceAndDownloadMaterialIconsFont() {
let cssFileHandle
try {
cssFileHandle = openSync(`${SHAKA_DIST_DIR}/controls.css`, 'r+')

let cssContents = readFileSync(cssFileHandle, 'utf-8')

const fontFaceRegex = /@font-face{font-family:'Material Icons Round'[^}]+format\('opentype'\)}/

if (fontFaceRegex.test(cssContents)) {
const cssResponse = await fetch('https://fonts.googleapis.com/icon?family=Material+Icons+Round', {
headers: {
// Without the user-agent it returns the otf file instead of the woff2 one
'user-agent': 'Firefox/125.0'
}
})

const text = await cssResponse.text()

let newFontCSS = text.match(/(@font-face\s*{[^}]+})/)[1].replaceAll('\n', '')


const urlMatch = newFontCSS.match(/https:\/\/fonts\.gstatic\.com\/s\/materialiconsround\/(?<version>[^\/]+)\/[^.]+\.(?<extension>[\w]+)/)

const url = urlMatch[0]
const { version, extension } = urlMatch.groups

const fontResponse = await fetch(url)
const fontContent = new Uint8Array(await fontResponse.arrayBuffer())

const filename = `shaka-materialiconsround-${version}.${extension}`
writeFileSync(`${SHAKA_DIST_DIR}/${filename}`, fontContent)

newFontCSS = newFontCSS.replace(url, `./${filename}`)

cssContents = cssContents.replace(fontFaceRegex, newFontCSS)

ftruncateSync(cssFileHandle)
writeSync(cssFileHandle, cssContents, 0, 'utf-8')

console.log('Changed shaka-player Material Icons Rounded font to use the smaller woff2 format instead of otf')
console.log('Downloaded shaka-player Material Icons Rounded font')
}
} catch (e) {
console.error(e)
} finally {
if (typeof cssFileHandle !== 'undefined') {
closeSync(cssFileHandle)
}
}
}

fixTypes()
await removeRobotoFont()
await replaceAndDownloadMaterialIconsFont()
37 changes: 31 additions & 6 deletions _scripts/webpack.renderer.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin')
const ProcessLocalesPlugin = require('./ProcessLocalesPlugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const {
SHAKA_LOCALE_MAPPINGS,
SHAKA_LOCALES_PREBUNDLED,
SHAKA_LOCALES_TO_BE_BUNDLED
} = require('./getShakaLocales')

const isDevMode = process.env.NODE_ENV === 'development'

Expand Down Expand Up @@ -122,7 +127,9 @@ const config = {
'process.env.SUPPORTS_LOCAL_API': true,
'process.env.LOCALE_NAMES': JSON.stringify(processLocalesPlugin.localeNames),
'process.env.GEOLOCATION_NAMES': JSON.stringify(readdirSync(path.join(__dirname, '..', 'static', 'geolocations')).map(filename => filename.replace('.json', ''))),
'process.env.SWIPER_VERSION': `'${swiperVersion}'`
'process.env.SWIPER_VERSION': `'${swiperVersion}'`,
'process.env.SHAKA_LOCALE_MAPPINGS': JSON.stringify(SHAKA_LOCALE_MAPPINGS),
'process.env.SHAKA_LOCALES_PREBUNDLED': JSON.stringify(SHAKA_LOCALES_PREBUNDLED)
}),
new HtmlWebpackPlugin({
excludeChunks: ['processTaskWorker'],
Expand All @@ -143,7 +150,21 @@ const config = {
transformAll: (assets) => {
return Buffer.concat(assets.map(asset => asset.data))
}
}
},
// Don't need to copy them in dev mode,
// as we configure WebpackDevServer to serve them
...(isDevMode ? [] : [
{
from: path.join(__dirname, '../node_modules/shaka-player/ui/locales', `{${SHAKA_LOCALES_TO_BE_BUNDLED.join(',')}}.json`).replaceAll('\\', '/'),
to: path.join(__dirname, '../dist/static/shaka-player-locales'),
context: path.join(__dirname, '../node_modules/shaka-player/ui/locales'),
transform: {
transformer: (input) => {
return JSON.stringify(JSON.parse(input.toString('utf-8')))
}
}
}
])
]
})
],
Expand All @@ -156,14 +177,18 @@ const config = {

'youtubei.js$': 'youtubei.js/web',

// video.js's mpd-parser uses @xmldom/xmldom so that it can support both node and web browsers
// as FreeTube only runs in electron and web browsers we can use the native DOMParser class, instead of the "polyfill"
// https://caniuse.com/mdn-api_domparser
'@xmldom/xmldom$': path.resolve(__dirname, '_domParser.js')
// change to "shaka-player.ui.debug.js" to get debug logs (update jsconfig to get updated types)
'shaka-player$': 'shaka-player/dist/shaka-player.ui.js',
},
extensions: ['.js', '.vue']
},
target: 'electron-renderer',
}

if (isDevMode) {
// hack to pass it through to the dev-runner.js script
// gets removed there before the config object is passed to webpack
config.SHAKA_LOCALES_TO_BE_BUNDLED = SHAKA_LOCALES_TO_BE_BUNDLED
}

module.exports = config
Loading

0 comments on commit 1b9c1fd

Please sign in to comment.