Skip to content

Commit

Permalink
Merge branch 'development' into custom-builds/tmp
Browse files Browse the repository at this point in the history
* development: (35 commits)
  Shrink mime-db even further (FreeTubeApp#6659)
  * Update play next recommended video setting to be "by default" (FreeTubeApp#6400)
  Miscellaneous performance improvements (FreeTubeApp#6658)
  Bump stylelint in the stylelint group across 1 directory (FreeTubeApp#6660)
  Bump the stylelint group across 1 directory with 4 updates (FreeTubeApp#6605)
  Fixes FreeTubeApp#5476: Adjusted z-index for tooltips to avoid overlapping with bars (FreeTubeApp#6656)
  Bump shaka-player from 4.12.8 to 4.13.0 (FreeTubeApp#6649)
  Migrate ProfileSettings, FtProfileBubble and FtProfileEdit to the composition API (FreeTubeApp#6639)
  Translated using Weblate (Arabic)
  Bump the eslint group with 4 updates (FreeTubeApp#6645)
  Bump bgutils-js from 3.1.2 to 3.1.3 (FreeTubeApp#6650)
  Translated using Weblate (Arabic)
  Translated using Weblate (Arabic)
  Bump electron from 34.0.0 to 34.0.1 (FreeTubeApp#6648)
  Bump lefthook from 1.10.9 to 1.10.10 (FreeTubeApp#6647)
  Bump the babel group with 2 updates (FreeTubeApp#6644)
  Translated using Weblate (Arabic)
  Avoid logging an error when a player cache entry does not exist (FreeTubeApp#6640)
  Move saving screenshots to the default folder to an IPC call (FreeTubeApp#6636)
  Replace rimraf dev dependency with clean script (FreeTubeApp#6638)
  ...
  • Loading branch information
PikachuEXE committed Jan 29, 2025
2 parents 5112a82 + fb098b3 commit 54c3c02
Show file tree
Hide file tree
Showing 60 changed files with 2,168 additions and 1,530 deletions.
10 changes: 10 additions & 0 deletions _scripts/clean.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { rm } from 'fs/promises'
import { join } from 'path'

const BUILD_PATH = join(import.meta.dirname, '..', 'build')
const DIST_PATH = join(import.meta.dirname, '..', 'dist')

await Promise.all([
rm(BUILD_PATH, { recursive: true, force: true }),
rm(DIST_PATH, { recursive: true, force: true })
])
23 changes: 10 additions & 13 deletions _scripts/mime-db-shrinking-loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,15 @@
module.exports = function (source) {
const original = JSON.parse(source)

const reduced = {}
// Only the extensions field is needed, see: https://github.com/kevva/ext-list/blob/v2.2.2/index.js

for (const mimeType of Object.keys(original)) {
if (mimeType.startsWith('image/') && original[mimeType].extensions &&
(!mimeType.startsWith('image/x-') || mimeType === 'image/x-icon' || mimeType === 'image/x-ms-bmp') &&
(!mimeType.startsWith('image/vnd.') || mimeType === 'image/vnd.microsoft.icon')) {
// Only the extensions field is needed, see: https://github.com/kevva/ext-list/blob/v2.2.2/index.js
reduced[mimeType] = {
extensions: original[mimeType].extensions
}
}
}

return JSON.stringify(reduced)
return JSON.stringify({
'image/apng': { extensions: original['image/apng'].extensions },
'image/avif': { extensions: original['image/avif'].extensions },
'image/gif': { extensions: original['image/gif'].extensions },
'image/jpeg': { extensions: original['image/jpeg'].extensions },
'image/png': { extensions: original['image/png'].extensions },
'image/svg+xml': { extensions: original['image/svg+xml'].extensions },
'image/webp': { extensions: original['image/webp'].extensions }
})
}
32 changes: 15 additions & 17 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"build-release": "node _scripts/build.js",
"build-release:arm64": "node _scripts/build.js arm64",
"build-release:arm32": "node _scripts/build.js arm32",
"clean": "rimraf build/ dist/",
"clean": "node _scripts/clean.mjs",
"debug": "run-s rebuild:electron patch-shaka debug-runner",
"debug-runner": "node _scripts/dev-runner.js --remote-debug",
"dev": "run-s rebuild:electron patch-shaka dev-runner",
Expand All @@ -49,7 +49,6 @@
"pack:web": "webpack --mode=production --node-env=production --config _scripts/webpack.web.config.js",
"pack:botGuardScript": "webpack --config _scripts/webpack.botGuardScript.config.js",
"postinstall": "run-s --silent rebuild:electron patch-shaka",
"prettier": "prettier --write \"{src,_scripts}/**/*.{js,vue}\"",
"rebuild:electron": "electron-builder install-app-deps",
"release": "run-s test build",
"ci": "yarn install --silent --frozen-lockfile"
Expand All @@ -62,13 +61,13 @@
"@fortawesome/vue-fontawesome": "^2.0.10",
"@seald-io/nedb": "^4.0.4",
"autolinker": "^4.1.0",
"bgutils-js": "^3.1.2",
"bgutils-js": "^3.1.3",
"electron-context-menu": "^4.0.4",
"marked": "^15.0.6",
"path-browserify": "^1.0.1",
"portal-vue": "^2.1.7",
"process": "^0.11.10",
"shaka-player": "^4.12.8",
"shaka-player": "^4.13.0",
"swiper": "^11.2.1",
"vue": "^2.7.16",
"vue-i18n": "^8.28.2",
Expand All @@ -78,21 +77,21 @@
"youtubei.js": "^13.0.0"
},
"devDependencies": {
"@babel/core": "^7.26.0",
"@babel/core": "^7.26.7",
"@babel/plugin-transform-class-properties": "^7.25.9",
"@babel/preset-env": "^7.26.0",
"@double-great/stylelint-a11y": "^3.0.2",
"@eslint/js": "^9.18.0",
"@babel/preset-env": "^7.26.7",
"@double-great/stylelint-a11y": "^3.0.3",
"@eslint/js": "^9.19.0",
"@intlify/eslint-plugin-vue-i18n": "^3.2.0",
"babel-loader": "^9.2.1",
"copy-webpack-plugin": "^12.0.2",
"css-loader": "^7.1.2",
"css-minimizer-webpack-plugin": "^7.0.0",
"electron": "^34.0.0",
"electron": "^34.0.1",
"electron-builder": "^25.1.8",
"eslint": "^9.18.0",
"eslint-plugin-jsdoc": "^50.6.2",
"eslint-plugin-jsonc": "^2.18.2",
"eslint": "^9.19.0",
"eslint-plugin-jsdoc": "^50.6.3",
"eslint-plugin-jsonc": "^2.19.1",
"eslint-plugin-unicorn": "^56.0.1",
"eslint-plugin-vue": "^9.32.0",
"eslint-plugin-vuejs-accessibility": "^2.4.1",
Expand All @@ -101,18 +100,17 @@
"html-webpack-plugin": "^5.6.3",
"js-yaml": "^4.1.0",
"json-minimizer-webpack-plugin": "^5.0.0",
"lefthook": "^1.10.9",
"lefthook": "^1.10.10",
"mini-css-extract-plugin": "^2.9.2",
"neostandard": "^0.12.0",
"npm-run-all2": "^7.0.2",
"postcss": "^8.4.49",
"postcss": "^8.5.1",
"postcss-scss": "^4.0.9",
"rimraf": "^6.0.1",
"sass": "^1.83.4",
"sass-loader": "^16.0.4",
"stylelint": "^16.12.0",
"stylelint": "^16.14.1",
"stylelint-config-sass-guidelines": "^12.1.0",
"stylelint-config-standard": "^36.0.1",
"stylelint-config-standard": "^37.0.0",
"stylelint-high-performance-animation": "^1.10.0",
"stylelint-use-logical-spec": "^5.0.1",
"tree-kill": "1.2.2",
Expand Down
2 changes: 2 additions & 0 deletions src/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ const IpcChannels = {
SET_INVIDIOUS_AUTHORIZATION: 'set-invidious-authorization',

GENERATE_PO_TOKEN: 'generate-po-token',

WRITE_SCREENSHOT: 'write-screenshot',
}

const DBActions = {
Expand Down
4 changes: 4 additions & 0 deletions src/datastores/handlers/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ class Settings {
}
}

static _findScreenshotFolderPath() {
return db.settings.findOneAsync({ _id: 'screenshotFolderPath' })
}

static _updateBounds(value) {
return db.settings.updateAsync({ _id: 'bounds' }, { _id: 'bounds', value }, { upsert: true })
}
Expand Down
41 changes: 40 additions & 1 deletion src/main/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -1010,6 +1010,40 @@ function runApp() {
})
}

ipcMain.handle(IpcChannels.WRITE_SCREENSHOT, async (event, filename, arrayBuffer) => {
if (!isFreeTubeUrl(event.senderFrame.url) || typeof filename !== 'string' || !(arrayBuffer instanceof ArrayBuffer)) {
return
}

const screenshotFolderPath = await baseHandlers.settings._findScreenshotFolderPath()

let directory
if (screenshotFolderPath && screenshotFolderPath.value.length > 0) {
directory = screenshotFolderPath.value
} else {
directory = path.join(app.getPath('pictures'), 'FreeTube')
}

directory = path.normalize(directory)

const filePath = path.resolve(directory, filename)

// Ensure that we are only writing inside of the expected directory
if (path.dirname(filePath) !== directory) {
throw new Error('Invalid save location')
}

try {
await asyncFs.mkdir(directory, { recursive: true })

await asyncFs.writeFile(filePath, new DataView(arrayBuffer))
} catch (error) {
console.error('WRITE_SCREENSHOT failed', error)
// throw a new error so that we don't expose the real error to the renderer
throw new Error('Failed to save')
}
})

ipcMain.on(IpcChannels.STOP_POWER_SAVE_BLOCKER, (_, id) => {
powerSaveBlocker.stop(id)
})
Expand Down Expand Up @@ -1092,7 +1126,12 @@ function runApp() {

return contents.buffer
} catch (e) {
console.error(e)
// Don't log the error if the file doesn't exist as we'll just fetch it from YouTube
// this usually happens when YouTube updates their player JavaScript
if (e.code !== 'ENOENT') {
console.error(e)
}

return undefined
}
})
Expand Down
2 changes: 1 addition & 1 deletion src/renderer/components/CommentSection/CommentSection.css
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@
font-size: 14px;
margin-block-start: -10px;
margin-inline-start: 70px;
word-break: break-word;
word-wrap: break-word;
}

.commentPinned {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,14 @@
</div>
</template>

<div
v-if="primarySections"
class="primarySections"
>
<div class="primarySections">
<div
v-for="(primarySection, index) of primarySections"
:key="index"
class="primarySection"
>
<div
v-for="secondarySection in primarySection.secondarySections"
v-for="secondarySection in primarySection"
:key="secondarySection.title"
class="secondarySection"
>
Expand Down Expand Up @@ -85,30 +82,26 @@ const situationalAppShortcuts = computed(() =>
)
const primarySections = computed(() => [
{
secondarySections: [
{
title: t('KeyboardShortcutPrompt.Sections.Video.Playback'),
shortcutDictionary: playbackPlayerShortcuts.value
},
{
title: t('KeyboardShortcutPrompt.Sections.Video.General'),
shortcutDictionary: generalPlayerShortcuts.value
},
]
},
{
secondarySections: [
{
title: t('KeyboardShortcutPrompt.Sections.App.General'),
shortcutDictionary: generalAppShortcuts.value
},
{
title: t('KeyboardShortcutPrompt.Sections.App.Situational'),
shortcutDictionary: situationalAppShortcuts.value
}
]
}
[
{
title: t('KeyboardShortcutPrompt.Sections.Video.Playback'),
shortcutDictionary: playbackPlayerShortcuts.value
},
{
title: t('KeyboardShortcutPrompt.Sections.Video.General'),
shortcutDictionary: generalPlayerShortcuts.value
},
],
[
{
title: t('KeyboardShortcutPrompt.Sections.App.General'),
shortcutDictionary: generalAppShortcuts.value
},
{
title: t('KeyboardShortcutPrompt.Sections.App.Situational'),
shortcutDictionary: situationalAppShortcuts.value
}
]
])
const isMac = process.platform === 'darwin'
Expand Down
74 changes: 74 additions & 0 deletions src/renderer/components/FtProfileBubble/FtProfileBubble.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<template>
<div
class="bubblePadding"
tabindex="0"
role="button"
:aria-labelledby="id"
@click="click"
@keydown.space.enter.prevent="click"
>
<div
class="bubble"
:style="{ background: backgroundColor, color: textColor }"
>
<div class="initial">
{{ profileInitial }}
</div>
</div>
<div
:id="id"
class="profileName"
>
{{ translatedProfileName }}
</div>
</div>
</template>

<script setup>
import { computed } from 'vue'
import { useId } from '../../composables/use-id-polyfill'
import { useI18n } from '../../composables/use-i18n-polyfill'
import { getFirstCharacter } from '../../helpers/strings'
const props = defineProps({
profileName: {
type: String,
required: true
},
isMainProfile: {
type: Boolean,
required: true
},
backgroundColor: {
type: String,
required: true
},
textColor: {
type: String,
required: true
}
})
const { locale, t } = useI18n()
const id = useId()
const translatedProfileName = computed(() => {
return props.isMainProfile ? t('Profile.All Channels') : props.profileName
})
const profileInitial = computed(() => {
return props.profileName
? getFirstCharacter(translatedProfileName.value, locale.value).toUpperCase()
: ''
})
const emit = defineEmits(['click'])
function click() {
emit('click')
}
</script>

<style scoped src="./FtProfileBubble.css" />
Loading

0 comments on commit 54c3c02

Please sign in to comment.