Skip to content

Commit 680ff0a

Browse files
committed
Merge branch 'development' into feature/subscription-cache
* development: (24 commits) Add ability to see comment replies of community posts through invidious (FreeTubeApp#5589) Bump electron-builder from 24.13.3 to 25.0.5 (FreeTubeApp#5674) Change Sponsorblock Default Category Colors (FreeTubeApp#5686) Proxy live streams when "Proxy Videos Through Invidious" is enabled (FreeTubeApp#5649) Translated using Weblate (Belarusian) Translated using Weblate (Hebrew) Fix saving Invidious thumbnail URLs for subscriptions (FreeTubeApp#5662) Bump peter-evans/create-pull-request from 6 to 7 (FreeTubeApp#5676) Bump webpack-dev-server from 5.0.4 to 5.1.0 (FreeTubeApp#5672) Use auto-generated playlists for the videos tab on artist topic channels (FreeTubeApp#5661) Rewrite locale file updating to be more Vue 3 friendly (FreeTubeApp#5660) Bump sass from 1.77.8 to 1.78.0 (FreeTubeApp#5673) Bump electron from 32.0.1 to 32.0.2 (FreeTubeApp#5671) Bump marked from 14.1.0 to 14.1.2 (FreeTubeApp#5670) Bump postcss from 8.4.44 to 8.4.45 in the stylelint group (FreeTubeApp#5669) Bump the eslint group with 2 updates (FreeTubeApp#5668) Cleanup a few vue-i18n usages (FreeTubeApp#5663) Use nextTick instead of setTimeout to wait until Vue has rendered changes (FreeTubeApp#5664) Translated using Weblate (Estonian) Translated using Weblate (Belarusian) ... # Conflicts: # src/renderer/components/ft-community-post/ft-community-post.js # src/renderer/helpers/api/local.js
2 parents 26e2328 + 21ff6fe commit 680ff0a

File tree

45 files changed

+2069
-519
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+2069
-519
lines changed

.github/workflows/calibreapp-image-actions.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ jobs:
2020
compressOnly: true
2121
- name: Create New Pull Request If Needed
2222
if: steps.calibre.outputs.markdown != ''
23-
uses: peter-evans/create-pull-request@v6
23+
uses: peter-evans/create-pull-request@v7
2424
with:
2525
title: Compressed Images Nightly
2626
branch-suffix: timestamp

_scripts/ProcessLocalesPlugin.js

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -40,17 +40,17 @@ class ProcessLocalesPlugin {
4040
/** @type {(updatedLocales: [string, string][]) => void|null} */
4141
this.notifyLocaleChange = null
4242

43-
if (this.hotReload) {
44-
this.hotReloadScript = readFileSync(`${__dirname}/_hotReloadLocalesScript.js`, 'utf-8')
45-
}
46-
4743
this.loadLocales()
4844
}
4945

5046
/** @param {import('webpack').Compiler} compiler */
5147
apply(compiler) {
5248
const { CachedSource, RawSource } = compiler.webpack.sources;
53-
const { Compilation } = compiler.webpack
49+
const { Compilation, DefinePlugin } = compiler.webpack
50+
51+
new DefinePlugin({
52+
'process.env.HOT_RELOAD_LOCALES': this.hotReload
53+
}).apply(compiler)
5454

5555
compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => {
5656
const IS_DEV_SERVER = !!compiler.watching
@@ -136,19 +136,6 @@ class ProcessLocalesPlugin {
136136
compilation.fileDependencies.addAll(this.filePaths)
137137
}
138138
})
139-
140-
compiler.hooks.emit.tap(PLUGIN_NAME, (compilation) => {
141-
if (this.hotReload) {
142-
// Find generated JavaScript output file (e.g. renderer.js or web.js)
143-
// and inject the code snippet that listens for locale updates and replaces vue-i18n's locales
144-
145-
/** @type {string} */
146-
const filename = [...[...compilation.chunks][0].files]
147-
.find(file => file.endsWith('.js'))
148-
149-
compilation.assets[filename]._source._children.push(`\n${this.hotReloadScript}`)
150-
}
151-
})
152139
}
153140

154141
loadLocales() {

_scripts/_hotReloadLocalesScript.js

Lines changed: 0 additions & 18 deletions
This file was deleted.

package.json

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363
"autolinker": "^4.0.0",
6464
"electron-context-menu": "^4.0.4",
6565
"lodash.debounce": "^4.0.8",
66-
"marked": "^14.1.0",
66+
"marked": "^14.1.2",
6767
"path-browserify": "^1.0.1",
6868
"portal-vue": "^2.1.7",
6969
"process": "^0.11.10",
@@ -87,18 +87,18 @@
8787
"copy-webpack-plugin": "^12.0.2",
8888
"css-loader": "^7.1.2",
8989
"css-minimizer-webpack-plugin": "^7.0.0",
90-
"electron": "^32.0.1",
91-
"electron-builder": "^24.13.3",
90+
"electron": "^32.0.2",
91+
"electron-builder": "^25.0.5",
9292
"eslint": "^8.57.0",
9393
"eslint-config-prettier": "^9.1.0",
9494
"eslint-config-standard": "^17.1.0",
95-
"eslint-plugin-import": "^2.29.1",
95+
"eslint-plugin-import": "^2.30.0",
9696
"eslint-plugin-jsonc": "^2.16.0",
9797
"eslint-plugin-n": "^17.10.2",
9898
"eslint-plugin-prettier": "^5.2.1",
9999
"eslint-plugin-promise": "^7.1.0",
100100
"eslint-plugin-unicorn": "^55.0.0",
101-
"eslint-plugin-vue": "^9.27.0",
101+
"eslint-plugin-vue": "^9.28.0",
102102
"eslint-plugin-vuejs-accessibility": "^2.4.1",
103103
"eslint-plugin-yml": "^1.14.0",
104104
"html-webpack-plugin": "^5.6.0",
@@ -107,11 +107,11 @@
107107
"lefthook": "^1.7.15",
108108
"mini-css-extract-plugin": "^2.9.1",
109109
"npm-run-all2": "^6.2.2",
110-
"postcss": "^8.4.44",
110+
"postcss": "^8.4.45",
111111
"postcss-scss": "^4.0.9",
112112
"prettier": "^2.8.8",
113113
"rimraf": "^6.0.1",
114-
"sass": "^1.77.8",
114+
"sass": "^1.78.0",
115115
"sass-loader": "^16.0.1",
116116
"stylelint": "^16.9.0",
117117
"stylelint-config-sass-guidelines": "^12.0.0",
@@ -124,7 +124,7 @@
124124
"vue-loader": "^15.10.0",
125125
"webpack": "^5.94.0",
126126
"webpack-cli": "^5.1.4",
127-
"webpack-dev-server": "^5.0.4",
127+
"webpack-dev-server": "^5.1.0",
128128
"yaml-eslint-parser": "^1.2.3"
129129
}
130130
}

src/renderer/App.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,17 @@ export default defineComponent({
454454
break
455455
}
456456

457+
case 'post': {
458+
const { postId, query } = result
459+
460+
openInternalPath({
461+
path: `/post/${postId}`,
462+
query,
463+
doCreateNewWindow
464+
})
465+
break
466+
}
467+
457468
case 'channel': {
458469
const { channelId, subPath, url } = result
459470

src/renderer/components/ft-community-post/ft-community-post.js

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { A11y, Navigation, Pagination } from 'swiper/modules'
1010
import {
1111
createWebURL,
1212
deepCopy,
13+
formatNumber,
1314
getRelativeTimeFromDate,
1415
toLocalePublicationString,
1516
} from '../../helpers/utils'
@@ -34,17 +35,23 @@ export default defineComponent({
3435
hideForbiddenTitles: {
3536
type: Boolean,
3637
default: true
37-
}
38+
},
39+
singlePost: {
40+
type: Boolean,
41+
default: false
42+
},
3843
},
3944
data: function () {
4045
return {
4146
postText: '',
4247
postId: '',
4348
authorThumbnails: null,
4449
publishedText: '',
45-
voteCount: '',
50+
voteCount: 0,
51+
formattedVoteCount: '',
4652
postContent: '',
47-
commentCount: '',
53+
commentCount: null,
54+
formattedCommentCount: '',
4855
author: '',
4956
authorId: '',
5057
}
@@ -61,6 +68,16 @@ export default defineComponent({
6168

6269
hideVideo() {
6370
return this.forbiddenTitles.some((text) => this.data.postContent.content.title?.toLowerCase().includes(text.toLowerCase()))
71+
},
72+
73+
backendPreference: function () {
74+
return this.$store.getters.getBackendPreference
75+
},
76+
backendFallback: function () {
77+
return this.$store.getters.getBackendFallback
78+
},
79+
isInvidiousAllowed: function() {
80+
return this.backendPreference === 'invidious' || this.backendFallback
6481
}
6582
},
6683
created: function () {
@@ -132,7 +149,9 @@ export default defineComponent({
132149
isRSS: this.data.isRSS
133150
})
134151
this.voteCount = this.data.voteCount
152+
this.formattedVoteCount = formatNumber(this.voteCount)
135153
this.commentCount = this.data.commentCount
154+
this.formattedCommentCount = formatNumber(this.commentCount)
136155
this.type = (this.data.postContent !== null && this.data.postContent !== undefined) ? this.data.postContent.type : 'text'
137156
this.author = this.data.author
138157
this.authorId = this.data.authorId

src/renderer/components/ft-community-post/ft-community-post.scss

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,12 @@
5959
white-space: pre-wrap;
6060
}
6161

62+
.commentsLink {
63+
color: var(--primary-text-color);
64+
text-decoration: none;
65+
font-weight: bold;
66+
}
67+
6268
.bottomSection {
6369
color: var(--tertiary-text-color);
6470
display: block;

src/renderer/components/ft-community-post/ft-community-post.vue

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -115,11 +115,42 @@
115115
<div
116116
class="bottomSection"
117117
>
118-
<span class="likeCount"><font-awesome-icon
119-
class="thumbs-up-icon"
120-
:icon="['fas', 'thumbs-up']"
121-
/> {{ voteCount }}</span>
122-
<span class="commentCount">
118+
<span
119+
class="likeCount"
120+
:title="$tc('Global.Counts.Like Count', voteCount, {count: formattedVoteCount})"
121+
:aria-label="$tc('Global.Counts.Like Count', voteCount, {count: formattedVoteCount})"
122+
>
123+
<font-awesome-icon
124+
class="thumbs-up-icon"
125+
:icon="['fas', 'thumbs-up']"
126+
aria-hidden="true"
127+
/> {{ formattedVoteCount }}</span>
128+
<router-link
129+
v-if="isInvidiousAllowed && !singlePost"
130+
:to="{
131+
path: `/post/${postId}`,
132+
query: authorId ? { authorId } : undefined
133+
}"
134+
class="commentsLink"
135+
:aria-label="$t('Channel.Community.View Full Post')"
136+
>
137+
<span
138+
class="commentCount"
139+
:title="$tc('Global.Counts.Comment Count', commentCount, {count: formattedCommentCount})"
140+
:aria-label="$tc('Global.Counts.Comment Count', commentCount, {count: formattedCommentCount})"
141+
>
142+
<font-awesome-icon
143+
class="comment-count-icon"
144+
:icon="['fas', 'comment']"
145+
aria-hidden="true"
146+
/> {{ formattedCommentCount }}</span>
147+
</router-link>
148+
<span
149+
v-else-if="commentCount != null"
150+
class="commentCount"
151+
:title="$tc('Global.Counts.Comment Count', commentCount, {count: formattedCommentCount})"
152+
:aria-label="$tc('Global.Counts.Comment Count', commentCount, {count: formattedCommentCount})"
153+
>
123154
<font-awesome-icon
124155
class="comment-count-icon"
125156
:icon="['fas', 'comment']"

src/renderer/components/ft-icon-button/ft-icon-button.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { defineComponent } from 'vue'
1+
import { defineComponent, nextTick } from 'vue'
22
import FtPrompt from '../ft-prompt/ft-prompt.vue'
33
import { sanitizeForHtmlId } from '../../helpers/accessibility'
44

@@ -102,7 +102,7 @@ export default defineComponent({
102102
if (this.dropdownShown && !this.useModal) {
103103
// wait until the dropdown is visible
104104
// then focus it so we can hide it automatically when it loses focus
105-
setTimeout(() => {
105+
nextTick(() => {
106106
this.$refs.dropdown?.focus()
107107
})
108108
}

src/renderer/components/ft-input/ft-input.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ export default defineComponent({
207207
case 'search':
208208
case 'channel':
209209
case 'hashtag':
210+
case 'post':
210211
isYoutubeLink = true
211212
break
212213

src/renderer/components/ft-profile-selector/ft-profile-selector.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { defineComponent } from 'vue'
1+
import { defineComponent, nextTick } from 'vue'
22
import { mapActions } from 'vuex'
33

44
import FtCard from '../../components/ft-card/ft-card.vue'
@@ -53,7 +53,7 @@ export default defineComponent({
5353
if (this.profileListShown) {
5454
// wait until the profile list is visible
5555
// then focus it so we can hide it automatically when it loses focus
56-
setTimeout(() => {
56+
nextTick(() => {
5757
this.$refs.profileList?.$el?.focus()
5858
})
5959
}

src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ const HTTP_IN_HEX = 0x68747470
3838
const USE_OVERFLOW_MENU_WIDTH_THRESHOLD = 600
3939

4040
const RequestType = shaka.net.NetworkingEngine.RequestType
41+
const AdvancedRequestType = shaka.net.NetworkingEngine.AdvancedRequestType
4142
const TrackLabelFormat = shaka.ui.Overlay.TrackLabelFormat
4243

4344
/** @type {Map<string, string>} */
@@ -1232,7 +1233,47 @@ export default defineComponent({
12321233
response.data = new TextEncoder().encode(cleaned).buffer
12331234
}
12341235
}
1236+
} else if (type === RequestType.MANIFEST && context.type === AdvancedRequestType.MEDIA_PLAYLIST) {
1237+
const url = new URL(response.uri)
1238+
1239+
// Fixes proxied HLS manifests, as Invidious replaces the path parameters with query parameters,
1240+
// so shaka-player isn't able to infer the mime type from the `/file/seg.ts` part like it does for non-proxied HLS manifests.
1241+
// Shaka-player does attempt to detect it with HEAD request but the `Content-Type` header is `application/octet-stream`,
1242+
// which still doesn't tell shaka-player how to handle the stream because that's the equivalent of saying "binary data".
1243+
if (url.searchParams.has('local')) {
1244+
const stringBody = new TextDecoder().decode(response.data)
1245+
const fixed = stringBody.replaceAll(/https?:\/\/.+$/gm, hlsProxiedUrlReplacer)
1246+
1247+
response.data = new TextEncoder().encode(fixed).buffer
1248+
}
1249+
}
1250+
}
1251+
1252+
/**
1253+
* @param {string} match
1254+
*/
1255+
function hlsProxiedUrlReplacer(match) {
1256+
const url = new URL(match)
1257+
1258+
let fileValue
1259+
for (const [key, value] of url.searchParams) {
1260+
if (key === 'file') {
1261+
fileValue = value
1262+
continue
1263+
} else if (key === 'hls_chunk_host') {
1264+
// Add the host parameter so some Invidious instances stop complaining about the missing host parameter
1265+
// Replace .c.youtube.com with .googlevideo.com as the built-in Invidious video proxy only accepts host parameters with googlevideo.com
1266+
url.pathname += `/host/${encodeURIComponent(value.replace('.c.youtube.com', '.googlevideo.com'))}`
1267+
}
1268+
1269+
url.pathname += `/${key}/${encodeURIComponent(value)}`
12351270
}
1271+
1272+
// This has to be right at the end so that shaka-player can read the file extension
1273+
url.pathname += `/file/${encodeURIComponent(fileValue)}`
1274+
1275+
url.search = ''
1276+
return url.toString()
12361277
}
12371278

12381279
// #endregion request/response filters

src/renderer/components/ft-toast/ft-toast.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { defineComponent } from 'vue'
1+
import { defineComponent, nextTick } from 'vue'
22
import FtToastEvents from './ft-toast-events.js'
33

44
let id = 0
@@ -38,7 +38,7 @@ export default defineComponent({
3838
id: id++
3939
}
4040
toast.timeout = setTimeout(this.close, time || 3000, toast)
41-
setTimeout(() => { toast.isOpen = true })
41+
nextTick(() => { toast.isOpen = true })
4242
if (this.toasts.length > 4) {
4343
this.remove(0)
4444
}

src/renderer/components/subscriptions-community/subscriptions-community.js

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -173,12 +173,8 @@ export default defineComponent({
173173
let thumbnailUrl = post.authorThumbnails?.[0]?.url
174174

175175
if (name || thumbnailUrl) {
176-
if (thumbnailUrl) {
177-
if (thumbnailUrl.startsWith('//')) {
178-
thumbnailUrl = 'https:' + thumbnailUrl
179-
} else if (thumbnailUrl.startsWith(`${this.currentInvidiousInstanceUrl}/ggpht`)) {
180-
thumbnailUrl = thumbnailUrl.replace(`${this.currentInvidiousInstanceUrl}/ggpht`, 'https://yt3.googleusercontent.com')
181-
}
176+
if (thumbnailUrl?.startsWith('//')) {
177+
thumbnailUrl = 'https:' + thumbnailUrl
182178
}
183179

184180
subscriptionUpdates.push({

0 commit comments

Comments
 (0)