mirror of https://github.com/FreeTubeApp/FreeTube
Merge branch 'development' into add-command-line-arg-to-search
This commit is contained in:
commit
40c1c01b4b
|
@ -1 +1,17 @@
|
|||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Discussions
|
||||
url: https://github.com/FreeTubeApp/FreeTube/discussions/categories/general
|
||||
about: View discussions or start one yourself
|
||||
- name: Questions
|
||||
url: https://github.com/FreeTubeApp/FreeTube/discussions/categories/q-a
|
||||
about: Ask and answer questions
|
||||
- name: Matrix Community
|
||||
url: https://matrix.to/#/+freetube:matrix.org
|
||||
about: Join our Matrix chatroom - "Note: Bugs and Feature requests should be made on GitHub and not in the Matrix room"
|
||||
- name: Translate FreeTube
|
||||
url: https://hosted.weblate.org/engage/free-tube/
|
||||
about: Help translate FreeTube on Weblate
|
||||
- name: FreeTube Documentation
|
||||
url: https://docs.freetubeapp.io/
|
||||
about: View the Documentation to find all relevant information about FreeTube
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
process.env.NODE_ENV = 'development'
|
||||
|
||||
const open = require('open')
|
||||
const electron = require('electron')
|
||||
const webpack = require('webpack')
|
||||
const WebpackDevServer = require('webpack-dev-server')
|
||||
|
@ -161,7 +160,8 @@ function startWeb (callback) {
|
|||
if (!web) {
|
||||
startRenderer(startMain)
|
||||
} else {
|
||||
startWeb(({ port }) => {
|
||||
startWeb(async ({ port }) => {
|
||||
const open = (await import('open')).default
|
||||
open(`http://localhost:${port}`)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -11,6 +11,8 @@ const CopyWebpackPlugin = require('copy-webpack-plugin')
|
|||
|
||||
const isDevMode = process.env.NODE_ENV === 'development'
|
||||
|
||||
const { version: swiperVersion } = JSON.parse(readFileSync(path.join(__dirname, '../node_modules/swiper/package.json')))
|
||||
|
||||
const processLocalesPlugin = new ProcessLocalesPlugin({
|
||||
compress: !isDevMode,
|
||||
inputDir: path.join(__dirname, '../static/locales'),
|
||||
|
@ -118,7 +120,8 @@ const config = {
|
|||
'process.env.IS_ELECTRON': true,
|
||||
'process.env.IS_ELECTRON_MAIN': false,
|
||||
'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.GEOLOCATION_NAMES': JSON.stringify(readdirSync(path.join(__dirname, '..', 'static', 'geolocations')).map(filename => filename.replace('.json', ''))),
|
||||
'process.env.SWIPER_VERSION': `'${swiperVersion}'`
|
||||
}),
|
||||
new HtmlWebpackPlugin({
|
||||
excludeChunks: ['processTaskWorker'],
|
||||
|
@ -137,7 +140,7 @@ const config = {
|
|||
patterns: [
|
||||
{
|
||||
from: path.join(__dirname, '../node_modules/swiper/modules/{a11y,navigation,pagination}-element.css').replaceAll('\\', '/'),
|
||||
to: 'swiper.css',
|
||||
to: `swiper-${swiperVersion}.css`,
|
||||
context: path.join(__dirname, '../node_modules/swiper/modules'),
|
||||
transformAll: (assets) => {
|
||||
return Buffer.concat(assets.map(asset => asset.data))
|
||||
|
|
|
@ -11,6 +11,8 @@ const ProcessLocalesPlugin = require('./ProcessLocalesPlugin')
|
|||
|
||||
const isDevMode = process.env.NODE_ENV === 'development'
|
||||
|
||||
const { version: swiperVersion } = JSON.parse(fs.readFileSync(path.join(__dirname, '../node_modules/swiper/package.json')))
|
||||
|
||||
const config = {
|
||||
name: 'web',
|
||||
mode: process.env.NODE_ENV,
|
||||
|
@ -114,6 +116,7 @@ const config = {
|
|||
new webpack.DefinePlugin({
|
||||
'process.env.IS_ELECTRON': false,
|
||||
'process.env.IS_ELECTRON_MAIN': false,
|
||||
'process.env.SWIPER_VERSION': `'${swiperVersion}'`,
|
||||
|
||||
// video.js' vhs-utils supports both atob() in web browsers and Buffer in node
|
||||
// As the FreeTube web build only runs in web browsers, we can override their check for atob() here: https://github.com/videojs/vhs-utils/blob/main/src/decode-b64-to-uint8-array.js#L3
|
||||
|
@ -145,7 +148,7 @@ const config = {
|
|||
patterns: [
|
||||
{
|
||||
from: path.join(__dirname, '../node_modules/swiper/modules/{a11y,navigation,pagination}-element.css').replaceAll('\\', '/'),
|
||||
to: 'swiper.css',
|
||||
to: `swiper-${swiperVersion}.css`,
|
||||
context: path.join(__dirname, '../node_modules/swiper/modules'),
|
||||
transformAll: (assets) => {
|
||||
return Buffer.concat(assets.map(asset => asset.data))
|
||||
|
|
32
package.json
32
package.json
|
@ -62,10 +62,10 @@
|
|||
"autolinker": "^4.0.0",
|
||||
"electron-context-menu": "^3.6.1",
|
||||
"lodash.debounce": "^4.0.8",
|
||||
"marked": "^11.2.0",
|
||||
"marked": "^12.0.0",
|
||||
"path-browserify": "^1.0.1",
|
||||
"process": "^0.11.10",
|
||||
"swiper": "^11.0.6",
|
||||
"swiper": "^11.0.7",
|
||||
"video.js": "7.21.5",
|
||||
"videojs-contrib-quality-levels": "^3.0.0",
|
||||
"videojs-http-source-selector": "^1.1.6",
|
||||
|
@ -77,21 +77,21 @@
|
|||
"vue-observe-visibility": "^1.0.0",
|
||||
"vue-router": "^3.6.5",
|
||||
"vuex": "^3.6.2",
|
||||
"youtubei.js": "^9.0.2"
|
||||
"youtubei.js": "^9.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.23.9",
|
||||
"@babel/core": "^7.24.0",
|
||||
"@babel/eslint-parser": "^7.23.10",
|
||||
"@babel/plugin-proposal-class-properties": "^7.18.6",
|
||||
"@babel/preset-env": "^7.23.9",
|
||||
"@double-great/stylelint-a11y": "^3.0.1",
|
||||
"@babel/preset-env": "^7.24.0",
|
||||
"@double-great/stylelint-a11y": "^3.0.2",
|
||||
"babel-loader": "^9.1.3",
|
||||
"copy-webpack-plugin": "^12.0.2",
|
||||
"css-loader": "^6.10.0",
|
||||
"css-minimizer-webpack-plugin": "^6.0.0",
|
||||
"electron": "^28.2.2",
|
||||
"electron-builder": "^24.9.1",
|
||||
"eslint": "^8.56.0",
|
||||
"electron": "^29.1.0",
|
||||
"electron-builder": "^24.13.3",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-config-standard": "^17.1.0",
|
||||
"eslint-plugin-import": "^2.29.1",
|
||||
|
@ -100,21 +100,21 @@
|
|||
"eslint-plugin-prettier": "^5.1.3",
|
||||
"eslint-plugin-promise": "^6.1.1",
|
||||
"eslint-plugin-unicorn": "^51.0.1",
|
||||
"eslint-plugin-vue": "^9.21.1",
|
||||
"eslint-plugin-vue": "^9.22.0",
|
||||
"eslint-plugin-vuejs-accessibility": "^2.2.1",
|
||||
"eslint-plugin-yml": "^1.12.2",
|
||||
"html-webpack-plugin": "^5.6.0",
|
||||
"js-yaml": "^4.1.0",
|
||||
"json-minimizer-webpack-plugin": "^5.0.0",
|
||||
"lefthook": "^1.6.1",
|
||||
"mini-css-extract-plugin": "^2.8.0",
|
||||
"lefthook": "^1.6.4",
|
||||
"mini-css-extract-plugin": "^2.8.1",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"postcss": "^8.4.35",
|
||||
"postcss-scss": "^4.0.9",
|
||||
"prettier": "^2.8.8",
|
||||
"rimraf": "^5.0.5",
|
||||
"sass": "^1.70.0",
|
||||
"sass-loader": "^14.1.0",
|
||||
"sass": "^1.71.1",
|
||||
"sass-loader": "^14.1.1",
|
||||
"stylelint": "^16.2.1",
|
||||
"stylelint-config-sass-guidelines": "^11.0.0",
|
||||
"stylelint-config-standard": "^36.0.0",
|
||||
|
@ -124,9 +124,9 @@
|
|||
"vue-devtools": "^5.1.4",
|
||||
"vue-eslint-parser": "^9.4.2",
|
||||
"vue-loader": "^15.10.0",
|
||||
"webpack": "^5.90.1",
|
||||
"webpack": "^5.90.3",
|
||||
"webpack-cli": "^5.1.4",
|
||||
"webpack-dev-server": "^4.15.1",
|
||||
"webpack-dev-server": "^5.0.2",
|
||||
"webpack-watch-external-files-plugin": "^3.0.0",
|
||||
"yaml-eslint-parser": "^1.2.2"
|
||||
}
|
||||
|
|
|
@ -64,7 +64,9 @@ function runApp() {
|
|||
const path = urlParts[1]
|
||||
|
||||
if (path) {
|
||||
visible = ['/playlist', '/channel', '/watch'].some(p => path.startsWith(p))
|
||||
visible = ['/channel', '/watch'].some(p => path.startsWith(p)) ||
|
||||
// Only show copy link entry for non user playlists
|
||||
(path.startsWith('/playlist') && !/playlistType=user/.test(path))
|
||||
}
|
||||
} else {
|
||||
visible = true
|
||||
|
@ -103,17 +105,17 @@ function runApp() {
|
|||
let url
|
||||
|
||||
if (toYouTube) {
|
||||
url = `https://youtu.be/${id}`
|
||||
url = new URL(`https://youtu.be/${id}`)
|
||||
} else {
|
||||
url = `https://redirect.invidious.io/watch?v=${id}`
|
||||
url = new URL(`https://redirect.invidious.io/watch?v=${id}`)
|
||||
}
|
||||
|
||||
if (query) {
|
||||
const params = new URLSearchParams(query)
|
||||
const newParams = new URLSearchParams()
|
||||
const newParams = new URLSearchParams(url.search)
|
||||
let hasParams = false
|
||||
|
||||
if (params.has('playlistId')) {
|
||||
if (params.has('playlistId') && params.get('playlistType') !== 'user') {
|
||||
newParams.set('list', params.get('playlistId'))
|
||||
hasParams = true
|
||||
}
|
||||
|
@ -124,11 +126,11 @@ function runApp() {
|
|||
}
|
||||
|
||||
if (hasParams) {
|
||||
url += '?' + newParams.toString()
|
||||
url.search = newParams.toString()
|
||||
}
|
||||
}
|
||||
|
||||
return url
|
||||
return url.toString()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -882,7 +882,23 @@ export default defineComponent({
|
|||
showToast(`${message}: ${err}`)
|
||||
return
|
||||
}
|
||||
const playlists = JSON.parse(data)
|
||||
let playlists = null
|
||||
|
||||
// for the sake of backwards compatibility,
|
||||
// check if this is the old JSON array export (used until version 0.19.1),
|
||||
// that didn't match the actual database format
|
||||
const trimmedData = data.trim()
|
||||
|
||||
if (trimmedData[0] === '[' && trimmedData[trimmedData.length - 1] === ']') {
|
||||
playlists = JSON.parse(trimmedData)
|
||||
} else {
|
||||
// otherwise assume this is the correct database format,
|
||||
// which is also what we export now (used in 0.20.0 and later versions)
|
||||
data = data.split('\n')
|
||||
data.pop()
|
||||
|
||||
playlists = data.map(playlistJson => JSON.parse(playlistJson))
|
||||
}
|
||||
|
||||
const requiredKeys = [
|
||||
'playlistName',
|
||||
|
@ -1015,7 +1031,11 @@ export default defineComponent({
|
|||
]
|
||||
}
|
||||
|
||||
await this.promptAndWriteToFile(options, JSON.stringify(this.allPlaylists), 'All playlists has been successfully exported')
|
||||
const playlistsDb = this.allPlaylists.map(playlist => {
|
||||
return JSON.stringify(playlist)
|
||||
}).join('\n') + '\n'// a trailing line is expected
|
||||
|
||||
await this.promptAndWriteToFile(options, playlistsDb, 'All playlists has been successfully exported')
|
||||
},
|
||||
|
||||
exportPlaylistsForOlderVersionsSometimes: function () {
|
||||
|
@ -1133,7 +1153,7 @@ export default defineComponent({
|
|||
})
|
||||
|
||||
if (process.env.IS_ELECTRON && this.backendFallback && this.backendPreference === 'invidious') {
|
||||
showToast(this.$t('Falling back to the local API'))
|
||||
showToast(this.$t('Falling back to Local API'))
|
||||
resolve(this.getChannelInfoLocal(channelId))
|
||||
} else {
|
||||
resolve([])
|
||||
|
|
|
@ -3,10 +3,14 @@ import { defineComponent } from 'vue'
|
|||
export default defineComponent({
|
||||
name: 'FtAgeRestricted',
|
||||
props: {
|
||||
contentTypeString: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
isChannel: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
isVideo: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
emoji: function () {
|
||||
|
@ -15,8 +19,11 @@ export default defineComponent({
|
|||
},
|
||||
|
||||
restrictedMessage: function () {
|
||||
const contentType = this.$t('Age Restricted.Type.' + this.contentTypeString)
|
||||
return this.$t('Age Restricted.This {videoOrPlaylist} is age restricted', { videoOrPlaylist: contentType })
|
||||
if (this.isChannel) {
|
||||
return this.$t('Age Restricted.This channel is age restricted')
|
||||
}
|
||||
|
||||
return this.$t('Age Restricted.This video is age restricted:')
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
@ -40,7 +40,6 @@ export default defineComponent({
|
|||
voteCount: '',
|
||||
postContent: '',
|
||||
commentCount: '',
|
||||
isLoading: true,
|
||||
author: '',
|
||||
authorId: '',
|
||||
}
|
||||
|
@ -73,7 +72,7 @@ export default defineComponent({
|
|||
injectStylesUrls: [
|
||||
// This file is created with the copy webpack plugin in the web and renderer webpack configs.
|
||||
// If you add more modules, please remember to add their CSS files to the list in webpack config files.
|
||||
createWebURL('/swiper.css')
|
||||
createWebURL(`/swiper-${process.env.SWIPER_VERSION}.css`)
|
||||
],
|
||||
|
||||
a11y: true,
|
||||
|
@ -132,7 +131,6 @@ export default defineComponent({
|
|||
this.type = (this.data.postContent !== null && this.data.postContent !== undefined) ? this.data.postContent.type : 'text'
|
||||
this.author = this.data.author
|
||||
this.authorId = this.data.authorId
|
||||
this.isLoading = false
|
||||
},
|
||||
|
||||
getBestQualityImage(imageArray) {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
<template>
|
||||
<div
|
||||
v-if="!isLoading"
|
||||
class="ft-list-post ft-list-item outside"
|
||||
:appearance="appearance"
|
||||
:class="{ list: listType === 'list', grid: listType === 'grid' }"
|
||||
|
|
|
@ -128,6 +128,11 @@ export default defineComponent({
|
|||
|
||||
handleResize: function () {
|
||||
this.useModal = window.innerWidth <= 900
|
||||
}
|
||||
},
|
||||
|
||||
focus() {
|
||||
// To be called by parent components
|
||||
this.$refs.iconButton.focus()
|
||||
},
|
||||
}
|
||||
})
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<template>
|
||||
<div class="ftIconButton">
|
||||
<font-awesome-icon
|
||||
ref="iconButton"
|
||||
class="iconButton"
|
||||
:title="title"
|
||||
:icon="icon"
|
||||
|
|
|
@ -3,3 +3,8 @@
|
|||
.thumbnailLink:hover {
|
||||
outline: 3px solid var(--side-nav-hover-color);
|
||||
}
|
||||
|
||||
.thumbnailImage {
|
||||
// Makes img element sized correctly before image loading starts
|
||||
aspect-ratio: 16/9 auto;
|
||||
}
|
||||
|
|
|
@ -152,7 +152,7 @@
|
|||
<ft-icon-button
|
||||
class="optionsButton"
|
||||
:icon="['fas', 'ellipsis-v']"
|
||||
title="More Options"
|
||||
:title="$t('Video.More Options')"
|
||||
theme="base-no-default"
|
||||
:size="16"
|
||||
:use-shadow="false"
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
>
|
||||
<ft-playlist-selector
|
||||
tabindex="0"
|
||||
:data="playlist"
|
||||
:playlist="playlist"
|
||||
:index="index"
|
||||
:selected="selectedPlaylistIdList.includes(playlist._id)"
|
||||
@selected="countSelected(playlist._id)"
|
||||
|
|
|
@ -8,7 +8,7 @@ export default defineComponent({
|
|||
'ft-icon-button': FtIconButton
|
||||
},
|
||||
props: {
|
||||
data: {
|
||||
playlist: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
|
@ -30,6 +30,8 @@ export default defineComponent({
|
|||
title: '',
|
||||
thumbnail: require('../../assets/img/thumbnail_placeholder.svg'),
|
||||
videoCount: 0,
|
||||
|
||||
videoPresenceCountInPlaylistTextShouldBeVisible: false,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
@ -39,6 +41,9 @@ export default defineComponent({
|
|||
currentInvidiousInstance: function () {
|
||||
return this.$store.getters.getCurrentInvidiousInstance
|
||||
},
|
||||
toBeAddedToPlaylistVideoList: function () {
|
||||
return this.$store.getters.getToBeAddedToPlaylistVideoList
|
||||
},
|
||||
|
||||
titleForDisplay: function () {
|
||||
if (typeof this.title !== 'string') { return '' }
|
||||
|
@ -46,28 +51,63 @@ export default defineComponent({
|
|||
|
||||
return `${this.title.substring(0, 255)}...`
|
||||
},
|
||||
|
||||
loneToBeAddedToPlaylistVideo: function () {
|
||||
if (this.toBeAddedToPlaylistVideoList.length !== 1) { return null }
|
||||
|
||||
return this.toBeAddedToPlaylistVideoList[0]
|
||||
},
|
||||
loneVideoPresenceCountInPlaylist() {
|
||||
if (this.loneToBeAddedToPlaylistVideo == null) { return null }
|
||||
|
||||
const v = this.playlist.videos.reduce((accumulator, video) => {
|
||||
return video.videoId === this.loneToBeAddedToPlaylistVideo.videoId
|
||||
? accumulator + 1
|
||||
: accumulator
|
||||
}, 0)
|
||||
// Don't display zero value
|
||||
return v === 0 ? null : v
|
||||
},
|
||||
loneVideoPresenceCountInPlaylistText() {
|
||||
if (this.loneVideoPresenceCountInPlaylist == null) { return null }
|
||||
|
||||
return this.$tc('User Playlists.AddVideoPrompt.Added {count} Times', this.loneVideoPresenceCountInPlaylist, {
|
||||
count: this.loneVideoPresenceCountInPlaylist,
|
||||
})
|
||||
},
|
||||
videoPresenceCountInPlaylistTextVisible() {
|
||||
if (!this.videoPresenceCountInPlaylistTextShouldBeVisible) { return false }
|
||||
|
||||
return this.loneVideoPresenceCountInPlaylistText != null
|
||||
},
|
||||
},
|
||||
created: function () {
|
||||
this.parseUserData()
|
||||
},
|
||||
methods: {
|
||||
parseUserData: function () {
|
||||
this.title = this.data.playlistName
|
||||
if (this.data.videos.length > 0) {
|
||||
const thumbnailURL = `https://i.ytimg.com/vi/${this.data.videos[0].videoId}/mqdefault.jpg`
|
||||
this.title = this.playlist.playlistName
|
||||
if (this.playlist.videos.length > 0) {
|
||||
const thumbnailURL = `https://i.ytimg.com/vi/${this.playlist.videos[0].videoId}/mqdefault.jpg`
|
||||
if (this.backendPreference === 'invidious') {
|
||||
this.thumbnail = thumbnailURL.replace('https://i.ytimg.com', this.currentInvidiousInstance)
|
||||
} else {
|
||||
this.thumbnail = thumbnailURL
|
||||
}
|
||||
}
|
||||
this.videoCount = this.data.videos.length
|
||||
this.videoCount = this.playlist.videos.length
|
||||
},
|
||||
|
||||
toggleSelection: function () {
|
||||
this.$emit('selected', this.index)
|
||||
},
|
||||
|
||||
onVisibilityChanged(visible) {
|
||||
if (!visible) { return }
|
||||
|
||||
this.videoPresenceCountInPlaylistTextShouldBeVisible = true
|
||||
},
|
||||
|
||||
...mapActions([
|
||||
'openInExternalPlayer'
|
||||
])
|
||||
|
|
|
@ -54,6 +54,10 @@
|
|||
word-wrap: break-word;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.videoPresenceCount {
|
||||
margin-block-start: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
&.grid {
|
||||
|
|
|
@ -29,12 +29,24 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="info">
|
||||
<span
|
||||
<div
|
||||
v-observe-visibility="{
|
||||
callback: onVisibilityChanged,
|
||||
once: true,
|
||||
}"
|
||||
class="info"
|
||||
>
|
||||
<div
|
||||
class="title"
|
||||
>
|
||||
{{ titleForDisplay }}
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
v-if="videoPresenceCountInPlaylistTextVisible"
|
||||
class="videoPresenceCount"
|
||||
>
|
||||
{{ loneVideoPresenceCountInPlaylistText }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -9,18 +9,29 @@ export default defineComponent({
|
|||
}
|
||||
},
|
||||
methods: {
|
||||
catchTimestampClick: function(event) {
|
||||
const match = event.detail.match(/(\d+):(\d+):?(\d+)?/)
|
||||
if (match[3] !== undefined) { // HH:MM:SS
|
||||
const seconds = 3600 * Number(match[1]) + 60 * Number(match[2]) + Number(match[3])
|
||||
this.$emit('timestamp-event', seconds)
|
||||
} else { // MM:SS
|
||||
const seconds = 60 * Number(match[1]) + Number(match[2])
|
||||
this.$emit('timestamp-event', seconds)
|
||||
}
|
||||
catchTimestampClick: function (event) {
|
||||
this.$emit('timestamp-event', event.detail)
|
||||
},
|
||||
detectTimestamps: function (input) {
|
||||
return input.replaceAll(/(\d+(:\d+)+)/g, '<a href="#" onclick="this.dispatchEvent(new CustomEvent(\'timestamp-clicked\',{bubbles:true, detail:\'$1\'}))">$1</a>')
|
||||
const videoId = this.$route.params.id
|
||||
|
||||
return input.replaceAll(/(?:(\d+):)?(\d+):(\d+)/g, (timestamp, hours, minutes, seconds) => {
|
||||
let time = 60 * Number(minutes) + Number(seconds)
|
||||
|
||||
if (hours) {
|
||||
time += 3600 * Number(hours)
|
||||
}
|
||||
|
||||
const url = this.$router.resolve({
|
||||
path: `/watch/${videoId}`,
|
||||
query: {
|
||||
timestamp: time
|
||||
}
|
||||
}).href
|
||||
|
||||
// Adding the URL lets the user open the video in a new window at this timestamp
|
||||
return `<a href="${url}" onclick="event.preventDefault();this.dispatchEvent(new CustomEvent('timestamp-clicked',{bubbles:true,detail:${time}}));window.scrollTo(0,0)">${timestamp}</a>`
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import { defineComponent } from 'vue'
|
||||
import FtToastEvents from './ft-toast-events.js'
|
||||
|
||||
let id = 0
|
||||
|
||||
export default defineComponent({
|
||||
name: 'FtToast',
|
||||
data: function () {
|
||||
|
@ -15,7 +17,9 @@ export default defineComponent({
|
|||
FtToastEvents.removeEventListener('toast-open', this.open)
|
||||
},
|
||||
methods: {
|
||||
performAction: function (index) {
|
||||
performAction: function (id) {
|
||||
const index = this.toasts.findIndex(toast => id === toast.id)
|
||||
|
||||
this.toasts[index].action()
|
||||
this.remove(index)
|
||||
},
|
||||
|
@ -26,7 +30,13 @@ export default defineComponent({
|
|||
toast.isOpen = false
|
||||
},
|
||||
open: function ({ detail: { message, time, action } }) {
|
||||
const toast = { message: message, action: action || (() => { }), isOpen: false, timeout: null }
|
||||
const toast = {
|
||||
message: message,
|
||||
action: action || (() => { }),
|
||||
isOpen: false,
|
||||
timeout: null,
|
||||
id: id++
|
||||
}
|
||||
toast.timeout = setTimeout(this.close, time || 3000, toast)
|
||||
setTimeout(() => { toast.isOpen = true })
|
||||
if (this.toasts.length > 4) {
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
<template>
|
||||
<div class="toast-holder">
|
||||
<div
|
||||
v-for="(toast, index) in toasts"
|
||||
:key="'toast-' + index"
|
||||
v-for="toast in toasts"
|
||||
:key="toast.id"
|
||||
class="toast"
|
||||
:class="{ closed: !toast.isOpen, open: toast.isOpen }"
|
||||
tabindex="0"
|
||||
role="status"
|
||||
@click="performAction(index)"
|
||||
@keydown.enter.prevent="performAction(index)"
|
||||
@keydown.space.prevent="performAction(index)"
|
||||
@click="performAction(toast.id)"
|
||||
@keydown.enter.prevent="performAction(toast.id)"
|
||||
@keydown.space.prevent="performAction(toast.id)"
|
||||
>
|
||||
<p class="message">
|
||||
{{ toast.message }}
|
||||
|
|
|
@ -5,10 +5,12 @@ import FtFlexBox from '../ft-flex-box/ft-flex-box.vue'
|
|||
import FtIconButton from '../ft-icon-button/ft-icon-button.vue'
|
||||
import FtInput from '../ft-input/ft-input.vue'
|
||||
import FtPrompt from '../ft-prompt/ft-prompt.vue'
|
||||
import FtButton from '../ft-button/ft-button.vue'
|
||||
import {
|
||||
formatNumber,
|
||||
showToast,
|
||||
} from '../../helpers/utils'
|
||||
import debounce from 'lodash.debounce'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'PlaylistInfo',
|
||||
|
@ -18,6 +20,7 @@ export default defineComponent({
|
|||
'ft-icon-button': FtIconButton,
|
||||
'ft-input': FtInput,
|
||||
'ft-prompt': FtPrompt,
|
||||
'ft-button': FtButton,
|
||||
},
|
||||
props: {
|
||||
id: {
|
||||
|
@ -83,6 +86,9 @@ export default defineComponent({
|
|||
},
|
||||
data: function () {
|
||||
return {
|
||||
searchVideoMode: false,
|
||||
query: '',
|
||||
updateQueryDebounce: function() {},
|
||||
editMode: false,
|
||||
showDeletePlaylistPrompt: false,
|
||||
showRemoveVideosOnWatchPrompt: false,
|
||||
|
@ -232,6 +238,8 @@ export default defineComponent({
|
|||
created: function () {
|
||||
this.newTitle = this.title
|
||||
this.newDescription = this.description
|
||||
|
||||
this.updateQueryDebounce = debounce(this.updateQuery, 500)
|
||||
},
|
||||
methods: {
|
||||
toggleCopyVideosPrompt: function (force = false) {
|
||||
|
@ -373,6 +381,30 @@ export default defineComponent({
|
|||
showToast(this.$t('User Playlists.SinglePlaylistView.Toast.Quick bookmark disabled'))
|
||||
},
|
||||
|
||||
updateQuery(query) {
|
||||
this.query = query
|
||||
this.$emit('search-video-query-change', query)
|
||||
},
|
||||
enableVideoSearchMode() {
|
||||
this.searchVideoMode = true
|
||||
this.$emit('search-video-mode-on')
|
||||
|
||||
nextTick(() => {
|
||||
// Some elements only present after rendering update
|
||||
this.$refs.searchInput.focus()
|
||||
})
|
||||
},
|
||||
disableVideoSearchMode() {
|
||||
this.searchVideoMode = false
|
||||
this.updateQuery('')
|
||||
this.$emit('search-video-mode-off')
|
||||
|
||||
nextTick(() => {
|
||||
// Some elements only present after rendering update
|
||||
this.$refs.enableSearchModeButton?.focus()
|
||||
})
|
||||
},
|
||||
|
||||
...mapActions([
|
||||
'showAddToPlaylistPromptForManyVideos',
|
||||
'updatePlaylist',
|
||||
|
|
|
@ -72,3 +72,20 @@
|
|||
column-gap: 8px;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.searchInputsRow {
|
||||
margin-block-start: 8px;
|
||||
|
||||
display: grid;
|
||||
|
||||
/* 2 columns */
|
||||
grid-template-columns: 1fr auto;
|
||||
column-gap: 8px;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 1250px) {
|
||||
:deep(.sharePlaylistIcon .iconDropdown) {
|
||||
inset-inline-start: auto;
|
||||
inset-inline-end: auto;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -76,6 +76,7 @@
|
|||
<hr>
|
||||
|
||||
<div
|
||||
v-if="!searchVideoMode"
|
||||
class="channelShareWrapper"
|
||||
>
|
||||
<router-link
|
||||
|
@ -106,6 +107,14 @@
|
|||
</div>
|
||||
|
||||
<div class="playlistOptions">
|
||||
<ft-icon-button
|
||||
v-if="isUserPlaylist && videoCount > 0 && !editMode"
|
||||
ref="enableSearchModeButton"
|
||||
:title="$t('User Playlists.SinglePlaylistView.Search for Videos')"
|
||||
:icon="['fas', 'search']"
|
||||
theme="secondary"
|
||||
@click="enableVideoSearchMode"
|
||||
/>
|
||||
<ft-icon-button
|
||||
v-if="editMode"
|
||||
:title="$t('User Playlists.Save Changes')"
|
||||
|
@ -166,6 +175,7 @@
|
|||
<ft-share-button
|
||||
v-if="sharePlaylistButtonVisible"
|
||||
:id="id"
|
||||
class="sharePlaylistIcon"
|
||||
:dropdown-position-y="description ? 'top' : 'bottom'"
|
||||
share-target-type="Playlist"
|
||||
/>
|
||||
|
@ -186,6 +196,28 @@
|
|||
@click="handleRemoveVideosOnWatchPromptAnswer"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="isUserPlaylist && searchVideoMode"
|
||||
class="searchInputsRow"
|
||||
>
|
||||
<ft-input
|
||||
ref="searchInput"
|
||||
class="searchInput"
|
||||
:placeholder="$t('User Playlists.SinglePlaylistView.Search for Videos')"
|
||||
:show-clear-text-button="true"
|
||||
:show-action-button="false"
|
||||
@input="(input) => updateQueryDebounce(input)"
|
||||
@clear="updateQueryDebounce('')"
|
||||
/>
|
||||
<ft-icon-button
|
||||
v-if="isUserPlaylist && searchVideoMode"
|
||||
:title="$t('User Playlists.Cancel')"
|
||||
:icon="['fas', 'times']"
|
||||
theme="secondary"
|
||||
@click="disableVideoSearchMode"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
/>
|
||||
</div>
|
||||
<p
|
||||
v-if="!hideLabelsSideBar"
|
||||
id="channelLabel"
|
||||
class="navLabel"
|
||||
>
|
||||
|
|
|
@ -121,6 +121,8 @@ export default defineComponent({
|
|||
this.attemptedFetch = true
|
||||
|
||||
this.errorChannels = []
|
||||
const subscriptionUpdates = []
|
||||
|
||||
const postListFromRemote = (await Promise.all(channelsToLoadFromRemote.map(async (channel) => {
|
||||
let posts = []
|
||||
if (!process.env.IS_ELECTRON || this.backendPreference === 'invidious') {
|
||||
|
@ -137,6 +139,32 @@ export default defineComponent({
|
|||
channelId: channel.id,
|
||||
posts: posts,
|
||||
})
|
||||
|
||||
if (posts.length > 0) {
|
||||
const post = posts.find(post => post.authorId === channel.id)
|
||||
|
||||
if (post) {
|
||||
const name = post.author
|
||||
let thumbnailUrl = post.authorThumbnails?.[0]?.url
|
||||
|
||||
if (name || thumbnailUrl) {
|
||||
if (thumbnailUrl) {
|
||||
if (thumbnailUrl.startsWith('//')) {
|
||||
thumbnailUrl = 'https:' + thumbnailUrl
|
||||
} else if (thumbnailUrl.startsWith(`${this.currentInvidiousInstance}/ggpht`)) {
|
||||
thumbnailUrl = thumbnailUrl.replace(`${this.currentInvidiousInstance}/ggpht`, 'https://yt3.googleusercontent.com')
|
||||
}
|
||||
}
|
||||
|
||||
subscriptionUpdates.push({
|
||||
channelId: channel.id,
|
||||
channelName: name,
|
||||
channelThumbnailUrl: thumbnailUrl
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return posts
|
||||
}))).flatMap((o) => o)
|
||||
postList.push(...postListFromRemote)
|
||||
|
@ -147,6 +175,8 @@ export default defineComponent({
|
|||
this.postList = postList
|
||||
this.isLoading = false
|
||||
this.updateShowProgressBar(false)
|
||||
|
||||
this.batchUpdateSubscriptionDetails(subscriptionUpdates)
|
||||
},
|
||||
|
||||
maybeLoadPostsForSubscriptionsFromRemote: async function () {
|
||||
|
@ -200,7 +230,7 @@ export default defineComponent({
|
|||
copyToClipboard(err)
|
||||
})
|
||||
if (process.env.IS_ELECTRON && this.backendPreference === 'invidious' && this.backendFallback) {
|
||||
showToast(this.$t('Falling back to the local API'))
|
||||
showToast(this.$t('Falling back to Local API'))
|
||||
resolve(this.getChannelPostsLocal(channel))
|
||||
} else {
|
||||
resolve([])
|
||||
|
@ -211,6 +241,7 @@ export default defineComponent({
|
|||
|
||||
...mapActions([
|
||||
'updateShowProgressBar',
|
||||
'batchUpdateSubscriptionDetails',
|
||||
'updateSubscriptionPostsCacheByChannel',
|
||||
]),
|
||||
|
||||
|
|
|
@ -129,19 +129,23 @@ export default defineComponent({
|
|||
this.attemptedFetch = true
|
||||
|
||||
this.errorChannels = []
|
||||
const subscriptionUpdates = []
|
||||
|
||||
const videoListFromRemote = (await Promise.all(channelsToLoadFromRemote.map(async (channel) => {
|
||||
let videos = []
|
||||
let name, thumbnailUrl
|
||||
|
||||
if (!process.env.IS_ELECTRON || this.backendPreference === 'invidious') {
|
||||
if (useRss) {
|
||||
videos = await this.getChannelLiveInvidiousRSS(channel)
|
||||
({ videos, name, thumbnailUrl } = await this.getChannelLiveInvidiousRSS(channel))
|
||||
} else {
|
||||
videos = await this.getChannelLiveInvidious(channel)
|
||||
({ videos, name, thumbnailUrl } = await this.getChannelLiveInvidious(channel))
|
||||
}
|
||||
} else {
|
||||
if (useRss) {
|
||||
videos = await this.getChannelLiveLocalRSS(channel)
|
||||
({ videos, name, thumbnailUrl } = await this.getChannelLiveLocalRSS(channel))
|
||||
} else {
|
||||
videos = await this.getChannelLiveLocal(channel)
|
||||
({ videos, name, thumbnailUrl } = await this.getChannelLiveLocal(channel))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -152,6 +156,15 @@ export default defineComponent({
|
|||
channelId: channel.id,
|
||||
videos: videos,
|
||||
})
|
||||
|
||||
if (name || thumbnailUrl) {
|
||||
subscriptionUpdates.push({
|
||||
channelId: channel.id,
|
||||
channelName: name,
|
||||
channelThumbnailUrl: thumbnailUrl
|
||||
})
|
||||
}
|
||||
|
||||
return videos
|
||||
}))).flatMap((o) => o)
|
||||
videoList.push(...videoListFromRemote)
|
||||
|
@ -159,6 +172,8 @@ export default defineComponent({
|
|||
this.videoList = updateVideoListAfterProcessing(videoList)
|
||||
this.isLoading = false
|
||||
this.updateShowProgressBar(false)
|
||||
|
||||
this.batchUpdateSubscriptionDetails(subscriptionUpdates)
|
||||
},
|
||||
|
||||
maybeLoadVideosForSubscriptionsFromRemote: async function () {
|
||||
|
@ -174,16 +189,18 @@ export default defineComponent({
|
|||
|
||||
getChannelLiveLocal: async function (channel, failedAttempts = 0) {
|
||||
try {
|
||||
const entries = await getLocalChannelLiveStreams(channel.id)
|
||||
const result = await getLocalChannelLiveStreams(channel.id)
|
||||
|
||||
if (entries === null) {
|
||||
if (result === null) {
|
||||
this.errorChannels.push(channel)
|
||||
return []
|
||||
return {
|
||||
videos: []
|
||||
}
|
||||
}
|
||||
|
||||
addPublishedDatesLocal(entries)
|
||||
addPublishedDatesLocal(result.videos)
|
||||
|
||||
return entries
|
||||
return result
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
const errorMessage = this.$t('Local API Error (Click to copy)')
|
||||
|
@ -198,12 +215,16 @@ export default defineComponent({
|
|||
showToast(this.$t('Falling back to Invidious API'))
|
||||
return await this.getChannelLiveInvidious(channel, failedAttempts + 1)
|
||||
} else {
|
||||
return []
|
||||
return {
|
||||
videos: []
|
||||
}
|
||||
}
|
||||
case 2:
|
||||
return await this.getChannelLiveLocalRSS(channel, failedAttempts + 1)
|
||||
default:
|
||||
return []
|
||||
return {
|
||||
videos: []
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -227,7 +248,9 @@ export default defineComponent({
|
|||
this.errorChannels.push(channel)
|
||||
}
|
||||
|
||||
return []
|
||||
return {
|
||||
videos: []
|
||||
}
|
||||
}
|
||||
|
||||
return await parseYouTubeRSSFeed(await response.text(), channel.id)
|
||||
|
@ -245,12 +268,16 @@ export default defineComponent({
|
|||
showToast(this.$t('Falling back to Invidious API'))
|
||||
return this.getChannelLiveInvidiousRSS(channel, failedAttempts + 1)
|
||||
} else {
|
||||
return []
|
||||
return {
|
||||
videos: []
|
||||
}
|
||||
}
|
||||
case 2:
|
||||
return this.getChannelLiveLocal(channel, failedAttempts + 1)
|
||||
default:
|
||||
return []
|
||||
return {
|
||||
videos: []
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -269,7 +296,16 @@ export default defineComponent({
|
|||
|
||||
addPublishedDatesInvidious(videos)
|
||||
|
||||
resolve(videos)
|
||||
let name
|
||||
|
||||
if (videos.length > 0) {
|
||||
name = videos.find(video => video.author).author
|
||||
}
|
||||
|
||||
resolve({
|
||||
name,
|
||||
videos
|
||||
})
|
||||
}).catch((err) => {
|
||||
console.error(err)
|
||||
const errorMessage = this.$t('Invidious API Error (Click to copy)')
|
||||
|
@ -282,17 +318,21 @@ export default defineComponent({
|
|||
break
|
||||
case 1:
|
||||
if (process.env.IS_ELECTRON && this.backendFallback) {
|
||||
showToast(this.$t('Falling back to the local API'))
|
||||
showToast(this.$t('Falling back to Local API'))
|
||||
resolve(this.getChannelLiveLocal(channel, failedAttempts + 1))
|
||||
} else {
|
||||
resolve([])
|
||||
resolve({
|
||||
videos: []
|
||||
})
|
||||
}
|
||||
break
|
||||
case 2:
|
||||
resolve(this.getChannelLiveInvidiousRSS(channel, failedAttempts + 1))
|
||||
break
|
||||
default:
|
||||
resolve([])
|
||||
resolve({
|
||||
videos: []
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
|
@ -306,7 +346,9 @@ export default defineComponent({
|
|||
const response = await fetch(feedUrl)
|
||||
|
||||
if (response.status === 500 || response.status === 404) {
|
||||
return []
|
||||
return {
|
||||
videos: []
|
||||
}
|
||||
}
|
||||
|
||||
return await parseYouTubeRSSFeed(await response.text(), channel.id)
|
||||
|
@ -321,20 +363,25 @@ export default defineComponent({
|
|||
return this.getChannelLiveInvidious(channel, failedAttempts + 1)
|
||||
case 1:
|
||||
if (process.env.IS_ELECTRON && this.backendFallback) {
|
||||
showToast(this.$t('Falling back to the local API'))
|
||||
showToast(this.$t('Falling back to Local API'))
|
||||
return this.getChannelLiveLocalRSS(channel, failedAttempts + 1)
|
||||
} else {
|
||||
return []
|
||||
return {
|
||||
videos: []
|
||||
}
|
||||
}
|
||||
case 2:
|
||||
return this.getChannelLiveInvidious(channel, failedAttempts + 1)
|
||||
default:
|
||||
return []
|
||||
return {
|
||||
videos: []
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
...mapActions([
|
||||
'batchUpdateSubscriptionDetails',
|
||||
'updateShowProgressBar',
|
||||
'updateSubscriptionLiveCacheByChannel',
|
||||
]),
|
||||
|
|
|
@ -114,12 +114,16 @@ export default defineComponent({
|
|||
this.attemptedFetch = true
|
||||
|
||||
this.errorChannels = []
|
||||
const subscriptionUpdates = []
|
||||
|
||||
const videoListFromRemote = (await Promise.all(channelsToLoadFromRemote.map(async (channel) => {
|
||||
let videos = []
|
||||
let name
|
||||
|
||||
if (!process.env.IS_ELECTRON || this.backendPreference === 'invidious') {
|
||||
videos = await this.getChannelShortsInvidious(channel)
|
||||
({ videos, name } = await this.getChannelShortsInvidious(channel))
|
||||
} else {
|
||||
videos = await this.getChannelShortsLocal(channel)
|
||||
({ videos, name } = await this.getChannelShortsLocal(channel))
|
||||
}
|
||||
|
||||
channelCount++
|
||||
|
@ -129,6 +133,14 @@ export default defineComponent({
|
|||
channelId: channel.id,
|
||||
videos: videos,
|
||||
})
|
||||
|
||||
if (name) {
|
||||
subscriptionUpdates.push({
|
||||
channelId: channel.id,
|
||||
channelName: name
|
||||
})
|
||||
}
|
||||
|
||||
return videos
|
||||
}))).flatMap((o) => o)
|
||||
videoList.push(...videoListFromRemote)
|
||||
|
@ -136,6 +148,8 @@ export default defineComponent({
|
|||
this.videoList = updateVideoListAfterProcessing(videoList)
|
||||
this.isLoading = false
|
||||
this.updateShowProgressBar(false)
|
||||
|
||||
this.batchUpdateSubscriptionDetails(subscriptionUpdates)
|
||||
},
|
||||
|
||||
maybeLoadVideosForSubscriptionsFromRemote: async function () {
|
||||
|
@ -168,7 +182,9 @@ export default defineComponent({
|
|||
this.errorChannels.push(channel)
|
||||
}
|
||||
|
||||
return []
|
||||
return {
|
||||
videos: []
|
||||
}
|
||||
}
|
||||
|
||||
return await parseYouTubeRSSFeed(await response.text(), channel.id)
|
||||
|
@ -184,10 +200,14 @@ export default defineComponent({
|
|||
showToast(this.$t('Falling back to Invidious API'))
|
||||
return this.getChannelShortsInvidious(channel, failedAttempts + 1)
|
||||
} else {
|
||||
return []
|
||||
return {
|
||||
videos: []
|
||||
}
|
||||
}
|
||||
default:
|
||||
return []
|
||||
return {
|
||||
videos: []
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -200,7 +220,9 @@ export default defineComponent({
|
|||
const response = await fetch(feedUrl)
|
||||
|
||||
if (response.status === 500 || response.status === 404) {
|
||||
return []
|
||||
return {
|
||||
videos: []
|
||||
}
|
||||
}
|
||||
|
||||
return await parseYouTubeRSSFeed(await response.text(), channel.id)
|
||||
|
@ -213,18 +235,23 @@ export default defineComponent({
|
|||
switch (failedAttempts) {
|
||||
case 0:
|
||||
if (process.env.IS_ELECTRON && this.backendFallback) {
|
||||
showToast(this.$t('Falling back to the local API'))
|
||||
showToast(this.$t('Falling back to Local API'))
|
||||
return this.getChannelShortsLocal(channel, failedAttempts + 1)
|
||||
} else {
|
||||
return []
|
||||
return {
|
||||
videos: []
|
||||
}
|
||||
}
|
||||
default:
|
||||
return []
|
||||
return {
|
||||
videos: []
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
...mapActions([
|
||||
'batchUpdateSubscriptionDetails',
|
||||
'updateShowProgressBar',
|
||||
'updateSubscriptionShortsCacheByChannel',
|
||||
]),
|
||||
|
|
|
@ -129,19 +129,23 @@ export default defineComponent({
|
|||
this.attemptedFetch = true
|
||||
|
||||
this.errorChannels = []
|
||||
const subscriptionUpdates = []
|
||||
|
||||
const videoListFromRemote = (await Promise.all(channelsToLoadFromRemote.map(async (channel) => {
|
||||
let videos = []
|
||||
let name, thumbnailUrl
|
||||
|
||||
if (!process.env.IS_ELECTRON || this.backendPreference === 'invidious') {
|
||||
if (useRss) {
|
||||
videos = await this.getChannelVideosInvidiousRSS(channel)
|
||||
({ videos, name, thumbnailUrl } = await this.getChannelVideosInvidiousRSS(channel))
|
||||
} else {
|
||||
videos = await this.getChannelVideosInvidiousScraper(channel)
|
||||
({ videos, name, thumbnailUrl } = await this.getChannelVideosInvidiousScraper(channel))
|
||||
}
|
||||
} else {
|
||||
if (useRss) {
|
||||
videos = await this.getChannelVideosLocalRSS(channel)
|
||||
({ videos, name, thumbnailUrl } = await this.getChannelVideosLocalRSS(channel))
|
||||
} else {
|
||||
videos = await this.getChannelVideosLocalScraper(channel)
|
||||
({ videos, name, thumbnailUrl } = await this.getChannelVideosLocalScraper(channel))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -152,6 +156,15 @@ export default defineComponent({
|
|||
channelId: channel.id,
|
||||
videos: videos,
|
||||
})
|
||||
|
||||
if (name || thumbnailUrl) {
|
||||
subscriptionUpdates.push({
|
||||
channelId: channel.id,
|
||||
channelName: name,
|
||||
channelThumbnailUrl: thumbnailUrl
|
||||
})
|
||||
}
|
||||
|
||||
return videos
|
||||
}))).flatMap((o) => o)
|
||||
videoList.push(...videoListFromRemote)
|
||||
|
@ -159,6 +172,8 @@ export default defineComponent({
|
|||
this.videoList = updateVideoListAfterProcessing(videoList)
|
||||
this.isLoading = false
|
||||
this.updateShowProgressBar(false)
|
||||
|
||||
this.batchUpdateSubscriptionDetails(subscriptionUpdates)
|
||||
},
|
||||
|
||||
maybeLoadVideosForSubscriptionsFromRemote: async function () {
|
||||
|
@ -174,16 +189,18 @@ export default defineComponent({
|
|||
|
||||
getChannelVideosLocalScraper: async function (channel, failedAttempts = 0) {
|
||||
try {
|
||||
const videos = await getLocalChannelVideos(channel.id)
|
||||
const result = await getLocalChannelVideos(channel.id)
|
||||
|
||||
if (videos === null) {
|
||||
if (result === null) {
|
||||
this.errorChannels.push(channel)
|
||||
return []
|
||||
return {
|
||||
videos: []
|
||||
}
|
||||
}
|
||||
|
||||
addPublishedDatesLocal(videos)
|
||||
addPublishedDatesLocal(result.videos)
|
||||
|
||||
return videos
|
||||
return result
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
const errorMessage = this.$t('Local API Error (Click to copy)')
|
||||
|
@ -198,12 +215,16 @@ export default defineComponent({
|
|||
showToast(this.$t('Falling back to Invidious API'))
|
||||
return await this.getChannelVideosInvidiousScraper(channel, failedAttempts + 1)
|
||||
} else {
|
||||
return []
|
||||
return {
|
||||
videos: []
|
||||
}
|
||||
}
|
||||
case 2:
|
||||
return await this.getChannelVideosLocalRSS(channel, failedAttempts + 1)
|
||||
default:
|
||||
return []
|
||||
return {
|
||||
videos: []
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -227,7 +248,9 @@ export default defineComponent({
|
|||
this.errorChannels.push(channel)
|
||||
}
|
||||
|
||||
return []
|
||||
return {
|
||||
videos: []
|
||||
}
|
||||
}
|
||||
|
||||
return await parseYouTubeRSSFeed(await response.text(), channel.id)
|
||||
|
@ -245,12 +268,16 @@ export default defineComponent({
|
|||
showToast(this.$t('Falling back to Invidious API'))
|
||||
return this.getChannelVideosInvidiousRSS(channel, failedAttempts + 1)
|
||||
} else {
|
||||
return []
|
||||
return {
|
||||
videos: []
|
||||
}
|
||||
}
|
||||
case 2:
|
||||
return this.getChannelVideosLocalScraper(channel, failedAttempts + 1)
|
||||
default:
|
||||
return []
|
||||
return {
|
||||
videos: []
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -266,7 +293,16 @@ export default defineComponent({
|
|||
invidiousAPICall(subscriptionsPayload).then((result) => {
|
||||
addPublishedDatesInvidious(result.videos)
|
||||
|
||||
resolve(result.videos)
|
||||
let name
|
||||
|
||||
if (result.videos.length > 0) {
|
||||
name = result.videos.find(video => video.type === 'video' && video.author).author
|
||||
}
|
||||
|
||||
resolve({
|
||||
name,
|
||||
videos: result.videos
|
||||
})
|
||||
}).catch((err) => {
|
||||
console.error(err)
|
||||
const errorMessage = this.$t('Invidious API Error (Click to copy)')
|
||||
|
@ -279,17 +315,21 @@ export default defineComponent({
|
|||
break
|
||||
case 1:
|
||||
if (process.env.IS_ELECTRON && this.backendFallback) {
|
||||
showToast(this.$t('Falling back to the local API'))
|
||||
showToast(this.$t('Falling back to Local API'))
|
||||
resolve(this.getChannelVideosLocalScraper(channel, failedAttempts + 1))
|
||||
} else {
|
||||
resolve([])
|
||||
resolve({
|
||||
videos: []
|
||||
})
|
||||
}
|
||||
break
|
||||
case 2:
|
||||
resolve(this.getChannelVideosInvidiousRSS(channel, failedAttempts + 1))
|
||||
break
|
||||
default:
|
||||
resolve([])
|
||||
resolve({
|
||||
videos: []
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
|
@ -304,7 +344,9 @@ export default defineComponent({
|
|||
|
||||
if (response.status === 500 || response.status === 404) {
|
||||
this.errorChannels.push(channel)
|
||||
return []
|
||||
return {
|
||||
videos: []
|
||||
}
|
||||
}
|
||||
|
||||
return await parseYouTubeRSSFeed(await response.text(), channel.id)
|
||||
|
@ -319,20 +361,25 @@ export default defineComponent({
|
|||
return this.getChannelVideosInvidiousScraper(channel, failedAttempts + 1)
|
||||
case 1:
|
||||
if (process.env.IS_ELECTRON && this.backendFallback) {
|
||||
showToast(this.$t('Falling back to the local API'))
|
||||
showToast(this.$t('Falling back to Local API'))
|
||||
return this.getChannelVideosLocalRSS(channel, failedAttempts + 1)
|
||||
} else {
|
||||
return []
|
||||
return {
|
||||
videos: []
|
||||
}
|
||||
}
|
||||
case 2:
|
||||
return this.getChannelVideosInvidiousScraper(channel, failedAttempts + 1)
|
||||
default:
|
||||
return []
|
||||
return {
|
||||
videos: []
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
...mapActions([
|
||||
'batchUpdateSubscriptionDetails',
|
||||
'updateShowProgressBar',
|
||||
'updateSubscriptionVideosCacheByChannel',
|
||||
]),
|
||||
|
|
|
@ -54,7 +54,6 @@
|
|||
.chapterThumbnail {
|
||||
grid-area: thumbnail;
|
||||
inline-size: 130px;
|
||||
block-size: auto;
|
||||
margin: 3px;
|
||||
}
|
||||
|
||||
|
|
|
@ -49,6 +49,7 @@ export default defineComponent({
|
|||
changeChapter: function(index) {
|
||||
this.currentIndex = index
|
||||
this.$emit('timestamp-event', this.chapters[index].startSeconds)
|
||||
window.scrollTo(0, 0)
|
||||
},
|
||||
|
||||
navigateChapters(direction) {
|
||||
|
|
|
@ -46,13 +46,15 @@
|
|||
@keydown.space.stop.prevent="changeChapter(index)"
|
||||
@keydown.enter.stop.prevent="changeChapter(index)"
|
||||
>
|
||||
<!-- Setting the aspect ratio avoids layout shifts when the images load -->
|
||||
<img
|
||||
v-if="!compact"
|
||||
alt=""
|
||||
aria-hidden="true"
|
||||
class="chapterThumbnail"
|
||||
loading="lazy"
|
||||
:src="chapter.thumbnail"
|
||||
:src="chapter.thumbnail.url"
|
||||
:style="{ aspectRatio: chapter.thumbnail.width / chapter.thumbnail.height }"
|
||||
>
|
||||
<div class="chapterTimestamp">
|
||||
{{ chapter.timestamp }}
|
||||
|
|
|
@ -293,7 +293,7 @@ export default defineComponent({
|
|||
copyToClipboard(err)
|
||||
})
|
||||
if (process.env.IS_ELECTRON && this.backendFallback && this.backendPreference === 'invidious') {
|
||||
showToast(this.$t('Falling back to local API'))
|
||||
showToast(this.$t('Falling back to Local API'))
|
||||
this.getCommentDataLocal()
|
||||
} else {
|
||||
this.isLoading = false
|
||||
|
|
|
@ -268,7 +268,7 @@
|
|||
v-else-if="showComments && !isLoading"
|
||||
>
|
||||
<h3 class="noCommentMsg">
|
||||
{{ $t("There are no comments available for this video") }}
|
||||
{{ $t("Comments.There are no comments available for this video") }}
|
||||
</h3>
|
||||
</div>
|
||||
<h4
|
||||
|
|
|
@ -64,6 +64,19 @@
|
|||
inset-inline-end: calc(50% - 20px);
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 460px) {
|
||||
flex-wrap: nowrap;
|
||||
:deep(.iconDropdown) {
|
||||
inset-inline-start: auto;
|
||||
inset-inline-end: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
@media screen and (max-width: 460px) {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
margin-block-start: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -72,29 +85,43 @@
|
|||
color: var(--tertiary-text-color);
|
||||
|
||||
.likeSection {
|
||||
color: var(--tertiary-text-color);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-inline-start: auto;
|
||||
margin-block-start: 4px;
|
||||
max-inline-size: 210px;
|
||||
text-align: end;
|
||||
|
||||
@media screen and (max-width: 680px) {
|
||||
margin-inline-start: 0;
|
||||
text-align: start;
|
||||
}
|
||||
|
||||
.likeBar {
|
||||
border-radius: 4px;
|
||||
block-size: 8px;
|
||||
margin-block-end: 4px;
|
||||
}
|
||||
|
||||
.likeCount {
|
||||
margin-inline-end: 0;
|
||||
color: var(--tertiary-text-color);
|
||||
display: flex;
|
||||
gap: 3px;
|
||||
flex-direction: column;
|
||||
margin-inline-start: auto;
|
||||
margin-block-start: 4px;
|
||||
max-inline-size: 210px;
|
||||
text-align: end;
|
||||
|
||||
@media screen and (max-width: 680px) {
|
||||
margin-inline-start: 0;
|
||||
text-align: start;
|
||||
}
|
||||
|
||||
.likeBar {
|
||||
border-radius: 4px;
|
||||
block-size: 8px;
|
||||
margin-block-end: 4px;
|
||||
}
|
||||
|
||||
.likeCount {
|
||||
margin-inline-end: 0;
|
||||
display: flex;
|
||||
gap: 3px;
|
||||
}
|
||||
}
|
||||
.datePublishedAndViewCount {
|
||||
@media only screen and (max-width: 460px) {
|
||||
display: flex;
|
||||
justify-content: left;
|
||||
flex-direction: column;
|
||||
|
||||
.seperator {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
.videoViews {
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,12 @@
|
|||
</div>
|
||||
<div class="videoMetrics">
|
||||
<div class="datePublishedAndViewCount">
|
||||
{{ publishedString }} {{ dateString }} • {{ parsedViewCount }}
|
||||
{{ publishedString }} {{ dateString }}
|
||||
<template
|
||||
v-if="!hideVideoViews"
|
||||
>
|
||||
<span class="seperator">• </span><span class="videoViews">{{ parsedViewCount }}</span>
|
||||
</template>
|
||||
</div>
|
||||
<div
|
||||
v-if="!hideVideoLikesAndDislikes"
|
||||
|
|
|
@ -367,7 +367,7 @@ export async function generateInvidiousDashManifestLocally(formats) {
|
|||
|
||||
return await FormatUtils.toDash({
|
||||
adaptive_formats: formats
|
||||
}, urlTransformer, undefined, undefined, player)
|
||||
}, false, urlTransformer, undefined, undefined, player)
|
||||
}
|
||||
|
||||
export function convertInvidiousToLocalFormat(format) {
|
||||
|
|
|
@ -35,23 +35,23 @@ const TRACKING_PARAM_NAMES = [
|
|||
* @param {boolean} options.generateSessionLocally generate the session locally or let YouTube generate it (local is faster, remote is more accurate)
|
||||
* @returns the Innertube instance
|
||||
*/
|
||||
async function createInnertube(options = { withPlayer: false, location: undefined, safetyMode: false, clientType: undefined, generateSessionLocally: true }) {
|
||||
async function createInnertube({ withPlayer = false, location = undefined, safetyMode = false, clientType = undefined, generateSessionLocally = true } = {}) {
|
||||
let cache
|
||||
if (options.withPlayer) {
|
||||
if (withPlayer) {
|
||||
const userData = await getUserDataPath()
|
||||
cache = new PlayerCache(join(userData, 'player_cache'))
|
||||
}
|
||||
|
||||
return await Innertube.create({
|
||||
retrieve_player: !!options.withPlayer,
|
||||
location: options.location,
|
||||
enable_safety_mode: !!options.safetyMode,
|
||||
client_type: options.clientType,
|
||||
retrieve_player: !!withPlayer,
|
||||
location: location,
|
||||
enable_safety_mode: !!safetyMode,
|
||||
client_type: clientType,
|
||||
|
||||
// use browser fetch
|
||||
fetch: (input, init) => fetch(input, init),
|
||||
cache,
|
||||
generate_session_locally: !!options.generateSessionLocally
|
||||
generate_session_locally: !!generateSessionLocally
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -274,6 +274,9 @@ export async function getLocalChannel(id) {
|
|||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} id
|
||||
*/
|
||||
export async function getLocalChannelVideos(id) {
|
||||
const innertube = await createInnertube()
|
||||
|
||||
|
@ -286,15 +289,22 @@ export async function getLocalChannelVideos(id) {
|
|||
}))
|
||||
|
||||
const videosTab = new YT.Channel(null, response)
|
||||
const { id: channelId = id, name, thumbnailUrl } = parseLocalChannelHeader(videosTab)
|
||||
|
||||
let videos
|
||||
|
||||
// if the channel doesn't have a videos tab, YouTube returns the home tab instead
|
||||
// so we need to check that we got the right tab
|
||||
if (videosTab.current_tab?.endpoint.metadata.url?.endsWith('/videos')) {
|
||||
const { id: channelId = id, name } = parseLocalChannelHeader(videosTab)
|
||||
|
||||
return parseLocalChannelVideos(videosTab.videos, channelId, name)
|
||||
videos = parseLocalChannelVideos(videosTab.videos, channelId, name)
|
||||
} else {
|
||||
return []
|
||||
videos = []
|
||||
}
|
||||
|
||||
return {
|
||||
name,
|
||||
thumbnailUrl,
|
||||
videos
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
|
@ -306,6 +316,9 @@ export async function getLocalChannelVideos(id) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} id
|
||||
*/
|
||||
export async function getLocalChannelLiveStreams(id) {
|
||||
const innertube = await createInnertube()
|
||||
|
||||
|
@ -318,15 +331,22 @@ export async function getLocalChannelLiveStreams(id) {
|
|||
}))
|
||||
|
||||
const liveStreamsTab = new YT.Channel(null, response)
|
||||
const { id: channelId = id, name, thumbnailUrl } = parseLocalChannelHeader(liveStreamsTab)
|
||||
|
||||
let videos
|
||||
|
||||
// if the channel doesn't have a live tab, YouTube returns the home tab instead
|
||||
// so we need to check that we got the right tab
|
||||
if (liveStreamsTab.current_tab?.endpoint.metadata.url?.endsWith('/streams')) {
|
||||
const { id: channelId = id, name } = parseLocalChannelHeader(liveStreamsTab)
|
||||
|
||||
return parseLocalChannelVideos(liveStreamsTab.videos, channelId, name)
|
||||
videos = parseLocalChannelVideos(liveStreamsTab.videos, channelId, name)
|
||||
} else {
|
||||
return []
|
||||
videos = []
|
||||
}
|
||||
|
||||
return {
|
||||
name,
|
||||
thumbnailUrl,
|
||||
videos
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
|
@ -539,7 +559,7 @@ export function parseLocalChannelShorts(shorts, channelId, channelName) {
|
|||
title: short.title.text,
|
||||
author: channelName,
|
||||
authorId: channelId,
|
||||
viewCount: parseLocalSubscriberCount(short.views.text),
|
||||
viewCount: short.views.isEmpty() ? null : parseLocalSubscriberCount(short.views.text),
|
||||
lengthSeconds: ''
|
||||
}
|
||||
})
|
||||
|
|
|
@ -80,9 +80,14 @@ export async function parseYouTubeRSSFeed(rssString, channelId) {
|
|||
promises.push(parseRSSEntry(entry, channelId, channelName))
|
||||
}
|
||||
|
||||
return await Promise.all(promises)
|
||||
return {
|
||||
name: channelName,
|
||||
videos: await Promise.all(promises)
|
||||
}
|
||||
} catch (e) {
|
||||
return []
|
||||
return {
|
||||
videos: []
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -616,9 +616,10 @@ export function getVideoParamsFromUrl(url) {
|
|||
|
||||
/**
|
||||
* This will match sequences of upper case characters and convert them into title cased words.
|
||||
* This will also match excessive strings of punctionation and convert them to one representative character
|
||||
* @param {string} title the title to process
|
||||
* @param {number} minUpperCase the minimum number of consecutive upper case characters to match
|
||||
* @returns {string} the title with upper case characters removed
|
||||
* @returns {string} the title with upper case characters removed and punctuation normalized
|
||||
*/
|
||||
export function toDistractionFreeTitle(title, minUpperCase = 3) {
|
||||
const firstValidCharIndex = (word) => {
|
||||
|
@ -634,7 +635,10 @@ export function toDistractionFreeTitle(title, minUpperCase = 3) {
|
|||
}
|
||||
|
||||
const reg = RegExp(`[\\p{Lu}|']{${minUpperCase},}`, 'ug')
|
||||
return title.replace(reg, x => capitalizedWord(x.toLowerCase()))
|
||||
return title
|
||||
.replaceAll(/!{2,}/g, '!')
|
||||
.replaceAll(/[!?]{2,}/g, '?')
|
||||
.replace(reg, x => capitalizedWord(x.toLowerCase()))
|
||||
}
|
||||
|
||||
export function formatNumber(number, options = undefined) {
|
||||
|
|
|
@ -39,6 +39,7 @@ const actions = {
|
|||
console.error(err)
|
||||
}
|
||||
}
|
||||
|
||||
// If the invidious instance fetch isn't returning anything interpretable
|
||||
if (instances.length === 0) {
|
||||
// Fallback: read from static file
|
||||
|
@ -46,15 +47,13 @@ const actions = {
|
|||
/* eslint-disable-next-line n/no-path-concat */
|
||||
const fileLocation = process.env.NODE_ENV === 'development' ? './static/' : `${__dirname}/static/`
|
||||
const filePath = `${fileLocation}${fileName}`
|
||||
if (!process.env.IS_ELECTRON) {
|
||||
console.warn('reading static file for invidious instances')
|
||||
const fileData = process.env.IS_ELECTRON ? await fs.readFile(filePath, 'utf8') : await (await fetch(createWebURL(filePath))).text()
|
||||
instances = JSON.parse(fileData).filter(e => {
|
||||
return process.env.IS_ELECTRON || e.cors
|
||||
}).map(e => {
|
||||
return e.url
|
||||
})
|
||||
}
|
||||
console.warn('reading static file for invidious instances')
|
||||
const fileData = process.env.IS_ELECTRON ? await fs.readFile(filePath, 'utf8') : await (await fetch(createWebURL(filePath))).text()
|
||||
instances = JSON.parse(fileData).filter(e => {
|
||||
return process.env.IS_ELECTRON || e.cors
|
||||
}).map(e => {
|
||||
return e.url
|
||||
})
|
||||
}
|
||||
commit('setInvidiousInstancesList', instances)
|
||||
},
|
||||
|
|
|
@ -91,6 +91,43 @@ const actions = {
|
|||
commit('setProfileList', profiles)
|
||||
},
|
||||
|
||||
async batchUpdateSubscriptionDetails({ getters, dispatch }, channels) {
|
||||
if (channels.length === 0) { return }
|
||||
|
||||
const profileList = getters.getProfileList
|
||||
|
||||
for (const profile of profileList) {
|
||||
const currentProfileCopy = deepCopy(profile)
|
||||
let profileUpdated = false
|
||||
|
||||
for (const { channelThumbnailUrl, channelName, channelId } of channels) {
|
||||
const channel = currentProfileCopy.subscriptions.find((channel) => {
|
||||
return channel.id === channelId
|
||||
}) ?? null
|
||||
|
||||
if (channel === null) { continue }
|
||||
|
||||
if (channel.name !== channelName && channelName != null) {
|
||||
channel.name = channelName
|
||||
profileUpdated = true
|
||||
}
|
||||
|
||||
if (channelThumbnailUrl) {
|
||||
const thumbnail = channelThumbnailUrl.replace(/=s\d*/, '=s176') // change thumbnail size if different
|
||||
|
||||
if (channel.thumbnail !== thumbnail) {
|
||||
channel.thumbnail = thumbnail
|
||||
profileUpdated = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (profileUpdated) {
|
||||
await dispatch('updateProfile', currentProfileCopy)
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
async updateSubscriptionDetails({ getters, dispatch }, { channelThumbnailUrl, channelName, channelId }) {
|
||||
const thumbnail = channelThumbnailUrl?.replace(/=s\d*/, '=s176') ?? null // change thumbnail size if different
|
||||
const profileList = getters.getProfileList
|
||||
|
|
|
@ -289,7 +289,7 @@ const state = {
|
|||
videoPlaybackRateInterval: 0.25,
|
||||
downloadAskPath: true,
|
||||
downloadFolderPath: '',
|
||||
downloadBehavior: 'download',
|
||||
downloadBehavior: 'open',
|
||||
enableScreenshot: false,
|
||||
screenshotFormat: 'png',
|
||||
screenshotQuality: 95,
|
||||
|
|
|
@ -54,6 +54,10 @@ const actions = {
|
|||
commit('updateShortsCacheByChannel', payload)
|
||||
},
|
||||
|
||||
updateSubscriptionShortsCacheWithChannelPageShorts: ({ commit }, payload) => {
|
||||
commit('updateShortsCacheWithChannelPageShorts', payload)
|
||||
},
|
||||
|
||||
updateSubscriptionLiveCacheByChannel: ({ commit }, payload) => {
|
||||
commit('updateLiveCacheByChannel', payload)
|
||||
},
|
||||
|
@ -86,6 +90,31 @@ const mutations = {
|
|||
if (videos != null) { newObject.videos = videos }
|
||||
state.shortsCache[channelId] = newObject
|
||||
},
|
||||
updateShortsCacheWithChannelPageShorts(state, { channelId, videos }) {
|
||||
const cachedObject = state.shortsCache[channelId]
|
||||
|
||||
if (cachedObject && cachedObject.videos.length > 0) {
|
||||
cachedObject.videos.forEach(cachedVideo => {
|
||||
const channelVideo = videos.find(short => cachedVideo.videoId === short.videoId)
|
||||
|
||||
if (channelVideo) {
|
||||
// authorId probably never changes, so we don't need to update that
|
||||
|
||||
cachedVideo.title = channelVideo.title
|
||||
cachedVideo.author = channelVideo.author
|
||||
|
||||
// as the channel shorts page only has compact view counts for numbers above 1000 e.g. 12k
|
||||
// and the RSS feeds include an exact value, we only want to overwrite it when the number is larger than the cached value
|
||||
// 12345 vs 12000 => 12345
|
||||
// 12345 vs 15000 => 15000
|
||||
|
||||
if (channelVideo.viewCount > cachedVideo.viewCount) {
|
||||
cachedVideo.viewCount = channelVideo.viewCount
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
clearShortsCache(state) {
|
||||
state.shortsCache = {}
|
||||
},
|
||||
|
|
|
@ -33,6 +33,10 @@ import {
|
|||
parseLocalListVideo,
|
||||
parseLocalSubscriberCount
|
||||
} from '../../helpers/api/local'
|
||||
import {
|
||||
addPublishedDatesInvidious,
|
||||
addPublishedDatesLocal
|
||||
} from '../../helpers/subscriptions'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'Channel',
|
||||
|
@ -171,6 +175,13 @@ export default defineComponent({
|
|||
return this.subscriptionInfo !== null
|
||||
},
|
||||
|
||||
isSubscribedInAnyProfile: function () {
|
||||
const profileList = this.$store.getters.getProfileList
|
||||
|
||||
// check the all channels profile
|
||||
return profileList[0].subscriptions.some((channel) => channel.id === this.id)
|
||||
},
|
||||
|
||||
videoLiveSelectNames: function () {
|
||||
return [
|
||||
this.$t('Channel.Videos.Sort Types.Newest'),
|
||||
|
@ -767,6 +778,17 @@ export default defineComponent({
|
|||
this.latestVideos = parseLocalChannelVideos(videosTab.videos, this.id, this.channelName)
|
||||
this.videoContinuationData = videosTab.has_continuation ? videosTab : null
|
||||
this.isElementListLoading = false
|
||||
|
||||
if (this.isSubscribedInAnyProfile && this.latestVideos.length > 0 && this.videoSortBy === 'newest') {
|
||||
addPublishedDatesLocal(this.latestVideos)
|
||||
this.updateSubscriptionVideosCacheByChannel({
|
||||
channelId: this.id,
|
||||
// create a copy so that we only cache the first page
|
||||
// if we use the same array, the store will get angry at us for modifying it outside of the store,
|
||||
// when the user clicks load more
|
||||
videos: [...this.latestVideos]
|
||||
})
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
const errorMessage = this.$t('Local API Error (Click to copy)')
|
||||
|
@ -825,6 +847,16 @@ export default defineComponent({
|
|||
this.latestShorts = parseLocalChannelShorts(shortsTab.videos, this.id, this.channelName)
|
||||
this.shortContinuationData = shortsTab.has_continuation ? shortsTab : null
|
||||
this.isElementListLoading = false
|
||||
|
||||
if (this.isSubscribedInAnyProfile && this.latestShorts.length > 0 && this.shortSortBy === 'newest') {
|
||||
// As the shorts tab API response doesn't include the published dates,
|
||||
// we can't just write the results to the subscriptions cache like we do with videos and live (can't sort chronologically without the date).
|
||||
// However we can still update the metadata in the cache such as the view count and title that might have changed since it was cached
|
||||
this.updateSubscriptionShortsCacheWithChannelPageShorts({
|
||||
channelId: this.id,
|
||||
videos: this.latestShorts
|
||||
})
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
const errorMessage = this.$t('Local API Error (Click to copy)')
|
||||
|
@ -883,6 +915,17 @@ export default defineComponent({
|
|||
this.latestLive = parseLocalChannelVideos(liveTab.videos, this.id, this.channelName)
|
||||
this.liveContinuationData = liveTab.has_continuation ? liveTab : null
|
||||
this.isElementListLoading = false
|
||||
|
||||
if (this.isSubscribedInAnyProfile && this.latestLive.length > 0 && this.liveSortBy === 'newest') {
|
||||
addPublishedDatesLocal(this.latestLive)
|
||||
this.updateSubscriptionLiveCacheByChannel({
|
||||
channelId: this.id,
|
||||
// create a copy so that we only cache the first page
|
||||
// if we use the same array, the store will get angry at us for modifying it outside of the store,
|
||||
// when the user clicks load more
|
||||
videos: [...this.latestLive]
|
||||
})
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
const errorMessage = this.$t('Local API Error (Click to copy)')
|
||||
|
@ -1052,6 +1095,16 @@ export default defineComponent({
|
|||
}
|
||||
this.videoContinuationData = response.continuation || null
|
||||
this.isElementListLoading = false
|
||||
|
||||
if (this.isSubscribedInAnyProfile && !more && this.latestVideos.length > 0 && this.videoSortBy === 'newest') {
|
||||
addPublishedDatesInvidious(this.latestVideos)
|
||||
this.updateSubscriptionVideosCacheByChannel({
|
||||
channelId: this.id,
|
||||
// create a copy so that we only cache the first page
|
||||
// if we use the same array, it will also contain all the next pages
|
||||
videos: [...this.latestVideos]
|
||||
})
|
||||
}
|
||||
}).catch((err) => {
|
||||
console.error(err)
|
||||
const errorMessage = this.$t('Invidious API Error (Click to copy)')
|
||||
|
@ -1101,6 +1154,17 @@ export default defineComponent({
|
|||
}
|
||||
this.shortContinuationData = response.continuation || null
|
||||
this.isElementListLoading = false
|
||||
|
||||
if (this.isSubscribedInAnyProfile && !more && this.latestShorts.length > 0 && this.shortSortBy === 'newest') {
|
||||
// As the shorts tab API response doesn't include the published dates,
|
||||
// we can't just write the results to the subscriptions cache like we do with videos and live (can't sort chronologically without the date).
|
||||
// However we can still update the metadata in the cache e.g. adding the duration, as that isn't included in the RSS feeds
|
||||
// and updating the view count and title that might have changed since it was cached
|
||||
this.updateSubscriptionShortsCacheWithChannelPageShorts({
|
||||
channelId: this.id,
|
||||
videos: this.latestShorts
|
||||
})
|
||||
}
|
||||
}).catch((err) => {
|
||||
console.error(err)
|
||||
const errorMessage = this.$t('Invidious API Error (Click to copy)')
|
||||
|
@ -1142,6 +1206,17 @@ export default defineComponent({
|
|||
}
|
||||
this.liveContinuationData = response.continuation || null
|
||||
this.isElementListLoading = false
|
||||
|
||||
if (this.isSubscribedInAnyProfile && !more && this.latestLive.length > 0 && this.liveSortBy === 'newest') {
|
||||
addPublishedDatesInvidious(this.latestLive)
|
||||
this.updateSubscriptionLiveCacheByChannel({
|
||||
channelId: this.id,
|
||||
// create a copy so that we only cache the first page
|
||||
// if we use the same array, the store will get angry at us for modifying it outside of the store,
|
||||
// when the user clicks load more
|
||||
videos: [...this.latestLive]
|
||||
})
|
||||
}
|
||||
}).catch((err) => {
|
||||
console.error(err)
|
||||
const errorMessage = this.$t('Invidious API Error (Click to copy)')
|
||||
|
@ -1444,7 +1519,7 @@ export default defineComponent({
|
|||
})
|
||||
if (this.backendPreference === 'local' && this.backendFallback) {
|
||||
showToast(this.$t('Falling back to Invidious API'))
|
||||
this.getChannelPodcastsInvidious()
|
||||
this.channelInvidiousPodcasts()
|
||||
} else {
|
||||
this.isLoading = false
|
||||
}
|
||||
|
@ -1559,6 +1634,19 @@ export default defineComponent({
|
|||
|
||||
this.latestCommunityPosts = parseLocalCommunityPosts(posts)
|
||||
this.communityContinuationData = communityTab.has_continuation ? communityTab : null
|
||||
|
||||
if (this.latestCommunityPosts.length > 0) {
|
||||
this.latestCommunityPosts.forEach(post => {
|
||||
post.authorId = this.id
|
||||
})
|
||||
this.updateSubscriptionPostsCacheByChannel({
|
||||
channelId: this.id,
|
||||
// create a copy so that we only cache the first page
|
||||
// if we use the same array, the store will get angry at us for modifying it outside of the store,
|
||||
// when the user clicks load more
|
||||
posts: [...this.latestCommunityPosts]
|
||||
})
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
const errorMessage = this.$t('Local API Error (Click to copy)')
|
||||
|
@ -1610,6 +1698,19 @@ export default defineComponent({
|
|||
this.latestCommunityPosts = posts
|
||||
}
|
||||
this.communityContinuationData = continuation
|
||||
|
||||
if (this.isSubscribedInAnyProfile && !more && this.latestCommunityPosts.length > 0) {
|
||||
this.latestCommunityPosts.forEach(post => {
|
||||
post.authorId = this.id
|
||||
})
|
||||
this.updateSubscriptionPostsCacheByChannel({
|
||||
channelId: this.id,
|
||||
// create a copy so that we only cache the first page
|
||||
// if we use the same array, the store will get angry at us for modifying it outside of the store,
|
||||
// when the user clicks load more
|
||||
posts: [...this.latestCommunityPosts]
|
||||
})
|
||||
}
|
||||
}).catch(async (err) => {
|
||||
console.error(err)
|
||||
const errorMessage = this.$t('Invidious API Error (Click to copy)')
|
||||
|
@ -1849,7 +1950,11 @@ export default defineComponent({
|
|||
|
||||
...mapActions([
|
||||
'showOutlines',
|
||||
'updateSubscriptionDetails'
|
||||
'updateSubscriptionDetails',
|
||||
'updateSubscriptionVideosCacheByChannel',
|
||||
'updateSubscriptionLiveCacheByChannel',
|
||||
'updateSubscriptionShortsCacheWithChannelPageShorts',
|
||||
'updateSubscriptionPostsCacheByChannel'
|
||||
])
|
||||
}
|
||||
})
|
||||
|
|
|
@ -417,7 +417,7 @@
|
|||
<ft-age-restricted
|
||||
v-else-if="!isLoading && (!isFamilyFriendly && showFamilyFriendlyOnly)"
|
||||
class="ageRestricted"
|
||||
:content-type-string="'Channel'"
|
||||
:is-channel="true"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -60,6 +60,9 @@ export default defineComponent({
|
|||
getPlaylistInfoDebounce: function() {},
|
||||
playlistInEditMode: false,
|
||||
|
||||
playlistInVideoSearchMode: false,
|
||||
videoSearchQuery: '',
|
||||
|
||||
promptOpen: false,
|
||||
}
|
||||
},
|
||||
|
@ -104,7 +107,7 @@ export default defineComponent({
|
|||
|
||||
moreVideoDataAvailable() {
|
||||
if (this.isUserPlaylistRequested) {
|
||||
return this.userPlaylistVisibleLimit < this.videoCount
|
||||
return this.userPlaylistVisibleLimit < this.sometimesFilteredUserPlaylistItems.length
|
||||
} else {
|
||||
return this.continuationData !== null
|
||||
}
|
||||
|
@ -123,17 +126,29 @@ export default defineComponent({
|
|||
return this.selectedUserPlaylist?._id !== this.quickBookmarkPlaylistId
|
||||
},
|
||||
|
||||
sometimesFilteredUserPlaylistItems() {
|
||||
if (!this.isUserPlaylistRequested) { return this.playlistItems }
|
||||
if (this.processedVideoSearchQuery === '') { return this.playlistItems }
|
||||
|
||||
return this.playlistItems.filter((v) => {
|
||||
return v.title.toLowerCase().includes(this.processedVideoSearchQuery)
|
||||
})
|
||||
},
|
||||
visiblePlaylistItems: function () {
|
||||
if (!this.isUserPlaylistRequested) {
|
||||
// No filtering for non user playlists yet
|
||||
return this.playlistItems
|
||||
}
|
||||
|
||||
if (this.userPlaylistVisibleLimit < this.videoCount) {
|
||||
return this.playlistItems.slice(0, this.userPlaylistVisibleLimit)
|
||||
if (this.userPlaylistVisibleLimit < this.sometimesFilteredUserPlaylistItems.length) {
|
||||
return this.sometimesFilteredUserPlaylistItems.slice(0, this.userPlaylistVisibleLimit)
|
||||
} else {
|
||||
return this.playlistItems
|
||||
return this.sometimesFilteredUserPlaylistItems
|
||||
}
|
||||
}
|
||||
},
|
||||
processedVideoSearchQuery() {
|
||||
return this.videoSearchQuery.trim().toLowerCase()
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
$route () {
|
||||
|
@ -269,7 +284,7 @@ export default defineComponent({
|
|||
const dateString = new Date(result.updated * 1000)
|
||||
this.lastUpdated = dateString.toLocaleDateString(this.currentLocale, { year: 'numeric', month: 'short', day: 'numeric' })
|
||||
|
||||
this.allPlaylistItems = result.videos
|
||||
this.playlistItems = result.videos
|
||||
|
||||
this.isLoading = false
|
||||
}).catch((err) => {
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
box-sizing: border-box;
|
||||
block-size: calc(100vh - 132px);
|
||||
margin-inline-end: 1em;
|
||||
overflow-y: auto;
|
||||
padding: 10px;
|
||||
position: sticky;
|
||||
inset-block-start: 96px;
|
||||
|
|
|
@ -28,6 +28,9 @@
|
|||
}"
|
||||
@enter-edit-mode="playlistInEditMode = true"
|
||||
@exit-edit-mode="playlistInEditMode = false"
|
||||
@search-video-mode-on="playlistInVideoSearchMode = true"
|
||||
@search-video-mode-off="playlistInVideoSearchMode = false"
|
||||
@search-video-query-change="(v) => videoSearchQuery = v"
|
||||
@prompt-open="promptOpen = true"
|
||||
@prompt-close="promptOpen = false"
|
||||
/>
|
||||
|
@ -39,48 +42,59 @@
|
|||
<template
|
||||
v-if="playlistItems.length > 0"
|
||||
>
|
||||
<transition-group
|
||||
name="playlistItem"
|
||||
tag="span"
|
||||
<template
|
||||
v-if="visiblePlaylistItems.length > 0"
|
||||
>
|
||||
<ft-list-video-numbered
|
||||
v-for="(item, index) in visiblePlaylistItems"
|
||||
:key="`${item.videoId}-${item.playlistItemId || index}`"
|
||||
class="playlistItem"
|
||||
:data="item"
|
||||
:playlist-id="playlistId"
|
||||
:playlist-type="infoSource"
|
||||
:playlist-index="index"
|
||||
:playlist-item-id="item.playlistItemId"
|
||||
appearance="result"
|
||||
:always-show-add-to-playlist-button="true"
|
||||
:quick-bookmark-button-enabled="quickBookmarkButtonEnabled"
|
||||
:can-move-video-up="index > 0"
|
||||
:can-move-video-down="index < visiblePlaylistItems.length - 1"
|
||||
:can-remove-from-playlist="true"
|
||||
:video-index="index"
|
||||
:initial-visible-state="index < 10"
|
||||
@move-video-up="moveVideoUp(item.videoId, item.playlistItemId)"
|
||||
@move-video-down="moveVideoDown(item.videoId, item.playlistItemId)"
|
||||
@remove-from-playlist="removeVideoFromPlaylist(item.videoId, item.playlistItemId)"
|
||||
/>
|
||||
</transition-group>
|
||||
<transition-group
|
||||
name="playlistItem"
|
||||
tag="span"
|
||||
>
|
||||
<ft-list-video-numbered
|
||||
v-for="(item, index) in visiblePlaylistItems"
|
||||
:key="`${item.videoId}-${item.playlistItemId || index}`"
|
||||
class="playlistItem"
|
||||
:data="item"
|
||||
:playlist-id="playlistId"
|
||||
:playlist-type="infoSource"
|
||||
:playlist-index="playlistInVideoSearchMode ? playlistItems.findIndex(i => i === item) : index"
|
||||
:playlist-item-id="item.playlistItemId"
|
||||
appearance="result"
|
||||
:always-show-add-to-playlist-button="true"
|
||||
:quick-bookmark-button-enabled="quickBookmarkButtonEnabled"
|
||||
:can-move-video-up="index > 0 && !playlistInVideoSearchMode"
|
||||
:can-move-video-down="index < playlistItems.length - 1 && !playlistInVideoSearchMode"
|
||||
:can-remove-from-playlist="true"
|
||||
:video-index="playlistInVideoSearchMode ? playlistItems.findIndex(i => i === item) : index"
|
||||
:initial-visible-state="index < 10"
|
||||
@move-video-up="moveVideoUp(item.videoId, item.playlistItemId)"
|
||||
@move-video-down="moveVideoDown(item.videoId, item.playlistItemId)"
|
||||
@remove-from-playlist="removeVideoFromPlaylist(item.videoId, item.playlistItemId)"
|
||||
/>
|
||||
</transition-group>
|
||||
<ft-flex-box
|
||||
v-if="moreVideoDataAvailable && !isLoadingMore"
|
||||
>
|
||||
<ft-button
|
||||
:label="$t('Subscriptions.Load More Videos')"
|
||||
background-color="var(--primary-color)"
|
||||
text-color="var(--text-with-main-color)"
|
||||
@click="getNextPage"
|
||||
/>
|
||||
</ft-flex-box>
|
||||
<div
|
||||
v-if="isLoadingMore"
|
||||
class="loadNextPageWrapper"
|
||||
>
|
||||
<ft-loader />
|
||||
</div>
|
||||
</template>
|
||||
<ft-flex-box
|
||||
v-if="moreVideoDataAvailable && !isLoadingMore"
|
||||
v-else
|
||||
>
|
||||
<ft-button
|
||||
:label="$t('Subscriptions.Load More Videos')"
|
||||
background-color="var(--primary-color)"
|
||||
text-color="var(--text-with-main-color)"
|
||||
@click="getNextPage"
|
||||
/>
|
||||
<p class="message">
|
||||
{{ $t("User Playlists['Empty Search Message']") }}
|
||||
</p>
|
||||
</ft-flex-box>
|
||||
<div
|
||||
v-if="isLoadingMore"
|
||||
class="loadNextPageWrapper"
|
||||
>
|
||||
<ft-loader />
|
||||
</div>
|
||||
</template>
|
||||
<ft-flex-box
|
||||
v-else
|
||||
|
|
|
@ -450,7 +450,7 @@ export default defineComponent({
|
|||
timestamp: formatDurationAsTimestamp(start),
|
||||
startSeconds: start,
|
||||
endSeconds: 0,
|
||||
thumbnail: chapter.thumbnail[0].url
|
||||
thumbnail: chapter.thumbnail[0]
|
||||
})
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -87,7 +87,7 @@
|
|||
<ft-age-restricted
|
||||
v-if="(!isLoading && !isFamilyFriendly && showFamilyFriendlyOnly)"
|
||||
class="ageRestricted"
|
||||
:content-type-string="'Video'"
|
||||
:is-video="true"
|
||||
/>
|
||||
<div
|
||||
v-if="(isFamilyFriendly || !showFamilyFriendlyOnly)"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Put the name of your locale in the same language
|
||||
Locale Name: 'الإنجليزية (الولايات المتحدة)'
|
||||
Locale Name: 'العربية'
|
||||
FreeTube: 'فري تيوب'
|
||||
# Currently on Subscriptions, Playlists, and History
|
||||
'This part of the app is not ready yet. Come back later when progress has been made.': >-
|
||||
|
@ -173,6 +173,7 @@ User Playlists:
|
|||
Reverted to use {oldPlaylistName} for quick bookmark: تمت العودة لاستخدام {oldPlaylistName}
|
||||
للإشارة المرجعية السريعة
|
||||
Quick bookmark disabled: تم تعطيل الإشارة المرجعية السريعة
|
||||
Search for Videos: البحث عن مقاطع الفيديو
|
||||
AddVideoPrompt:
|
||||
Select a playlist to add your N videos to: حدد قائمة تشغيل لإضافة الفيديو الخاص
|
||||
بك إلى | حدد قائمة تشغيل لإضافة مقاطع الفيديو {videoCount} إليها
|
||||
|
@ -186,6 +187,7 @@ User Playlists:
|
|||
Save: حفظ
|
||||
Search in Playlists: البحث في قوائم التشغيل
|
||||
N playlists selected: تم تحديد {playlistCount}
|
||||
Added {count} Times: تمت إضافة {count} الوقت | تمت إضافة {count} مرة
|
||||
CreatePlaylistPrompt:
|
||||
Toast:
|
||||
There is already a playlist with this name. Please pick a different name.: توجد
|
||||
|
@ -518,8 +520,8 @@ Settings:
|
|||
Hide Upcoming Premieres: إخفاء العروض الأولى القادمة
|
||||
Hide Channels: إخفاء مقاطع الفيديو من القنوات
|
||||
Hide Channels Placeholder: معرف القناة
|
||||
Display Titles Without Excessive Capitalisation: عرض العناوين بدون احرف كبيرة
|
||||
بشكل مفرط
|
||||
Display Titles Without Excessive Capitalisation: عرض العناوين بدون استخدام الأحرف
|
||||
الكبيرة وعلامات الترقيم بشكل مفرط
|
||||
Hide Featured Channels: إخفاء القنوات المميزة
|
||||
Hide Channel Playlists: إخفاء قوائم تشغيل القناة
|
||||
Hide Channel Community: إخفاء مجتمع القناة
|
||||
|
@ -931,6 +933,7 @@ Video:
|
|||
Pause on Current Video: توقف مؤقتًا على الفيديو الحالي
|
||||
Unhide Channel: عرض القناة
|
||||
Hide Channel: إخفاء القناة
|
||||
More Options: المزيد من الخيارات
|
||||
Videos:
|
||||
#& Sort By
|
||||
Sort By:
|
||||
|
@ -1007,7 +1010,7 @@ Up Next: 'التالي'
|
|||
Local API Error (Click to copy): 'خطأ API المحلي (انقر للنسخ)'
|
||||
Invidious API Error (Click to copy): 'خطأ Invidious API ( انقر للنسخ)'
|
||||
Falling back to Invidious API: 'التراجع إلى Invidious API'
|
||||
Falling back to the local API: 'التراجع إلى API المحلي'
|
||||
Falling back to Local API: 'التراجع إلى API المحلي'
|
||||
Subscriptions have not yet been implemented: 'لم يتم تنفيذ الاشتراكات بعد'
|
||||
Loop is now disabled: 'تم تعطيل التكرار'
|
||||
Loop is now enabled: 'تم تمكين التكرار'
|
||||
|
@ -1131,11 +1134,6 @@ Starting download: بدء تنزيل "{videoTitle}"
|
|||
Screenshot Success: تم حفظ لقطة الشاشة كا"{filePath}"
|
||||
Screenshot Error: فشل أخذ لقطة للشاشة. {error}
|
||||
New Window: نافذة جديدة
|
||||
Age Restricted:
|
||||
Type:
|
||||
Channel: القناة
|
||||
Video: فيديو
|
||||
This {videoOrPlaylist} is age restricted: 'هذا {videoOrPlaylist} مقيد بالعمر'
|
||||
Channels:
|
||||
Count: تم العثور على قناة (قنوات) {number}.
|
||||
Unsubscribed: 'تمت إزالة {channelName} من اشتراكاتك'
|
||||
|
@ -1172,3 +1170,7 @@ Trimmed input must be at least N characters long: يجب أن يكون طول ا
|
|||
حرفًا واحدًا على الأقل | يجب أن يبلغ طول الإدخال المقتطع {length} من الأحرف على
|
||||
الأقل
|
||||
Tag already exists: العلامة "{tagName}" موجودة بالفعل
|
||||
Age Restricted:
|
||||
This channel is age restricted: هذه القناة مقيدة بالعمر
|
||||
This video is age restricted: هذا الفيديو مقيد بالفئة العمرية
|
||||
Close Banner: إغلاق الشعار
|
||||
|
|
|
@ -813,7 +813,7 @@ Tooltips:
|
|||
Local API Error (Click to copy): ''
|
||||
Invidious API Error (Click to copy): ''
|
||||
Falling back to Invidious API: ''
|
||||
Falling back to the local API: ''
|
||||
Falling back to Local API: ''
|
||||
This video is unavailable because of missing formats. This can happen due to country unavailability.: ''
|
||||
Subscriptions have not yet been implemented: ''
|
||||
Unknown YouTube url type, cannot be opened in app: ''
|
||||
|
@ -833,11 +833,6 @@ Canceled next video autoplay: ''
|
|||
Default Invidious instance has been set to {instance}: ''
|
||||
Default Invidious instance has been cleared: ''
|
||||
'The playlist has ended. Enable loop to continue playing': ''
|
||||
Age Restricted:
|
||||
This {videoOrPlaylist} is age restricted: ''
|
||||
Type:
|
||||
Channel: ''
|
||||
Video: ''
|
||||
External link opening has been disabled in the general settings: ''
|
||||
Downloading has completed: ''
|
||||
Starting download: ''
|
||||
|
|
|
@ -1023,7 +1023,7 @@ Up Next: 'Следващ'
|
|||
Local API Error (Click to copy): 'Грешка в локалния интерфейс (щракнете за копиране)'
|
||||
Invidious API Error (Click to copy): 'Грешка в Invidious интерфейса (щракнете за копиране)'
|
||||
Falling back to Invidious API: 'Връщане към Invidious интерфейса'
|
||||
Falling back to the local API: 'Връщане към локалния интерфейс'
|
||||
Falling back to Local API: 'Връщане към локалния интерфейс'
|
||||
This video is unavailable because of missing formats. This can happen due to country unavailability.: 'Видеото
|
||||
не е достъпно поради липсващи формати. Това може да се дължи на ограничен достъп
|
||||
за страната.'
|
||||
|
@ -1148,12 +1148,6 @@ Downloading failed: Имаше проблем при изтеглянето на
|
|||
Screenshot Error: Снимката на екрана е неуспешна. {error}
|
||||
Screenshot Success: Запазена снимка на екрана като "{filePath}"
|
||||
New Window: Нов прозорец
|
||||
Age Restricted:
|
||||
This {videoOrPlaylist} is age restricted: Този {videoOrPlaylist} е с възрастово
|
||||
ограничение
|
||||
Type:
|
||||
Channel: Канал
|
||||
Video: Видео
|
||||
Channels:
|
||||
Count: Намерени са {number} канала.
|
||||
Unsubscribe: Отписване
|
||||
|
|
|
@ -135,10 +135,6 @@ External link opening has been disabled in the general settings: সাধার
|
|||
বহিঃসংযোগ খোলা নিষ্ক্রিয় রাখা হয়েছে
|
||||
Are you sure you want to open this link?: তুমি কি এই সংযোগটি খোলার ব্যাপারে নিশ্চিত?
|
||||
Preferences: পছন্দসমূহ
|
||||
Age Restricted:
|
||||
Type:
|
||||
Channel: চ্যানেল
|
||||
Video: ভিডিও
|
||||
Most Popular: অতিপরিচিত
|
||||
Channels:
|
||||
Search bar placeholder: চ্যানেল খুঁজুন
|
||||
|
|
|
@ -829,7 +829,7 @@ Tooltips:
|
|||
Local API Error (Click to copy): ''
|
||||
Invidious API Error (Click to copy): ''
|
||||
Falling back to Invidious API: ''
|
||||
Falling back to the local API: ''
|
||||
Falling back to Local API: ''
|
||||
This video is unavailable because of missing formats. This can happen due to country unavailability.: ''
|
||||
Subscriptions have not yet been implemented: ''
|
||||
Unknown YouTube url type, cannot be opened in app: ''
|
||||
|
@ -849,11 +849,6 @@ Canceled next video autoplay: ''
|
|||
Default Invidious instance has been set to {instance}: ''
|
||||
Default Invidious instance has been cleared: ''
|
||||
'The playlist has ended. Enable loop to continue playing': ''
|
||||
Age Restricted:
|
||||
This {videoOrPlaylist} is age restricted: ''
|
||||
Type:
|
||||
Channel: 'کەناڵ'
|
||||
Video: 'ڤیدیۆ'
|
||||
External link opening has been disabled in the general settings: ''
|
||||
Downloading has completed: ''
|
||||
Starting download: ''
|
||||
|
|
|
@ -146,6 +146,7 @@ User Playlists:
|
|||
Select a playlist to add your N videos to: Vyberte playlist, do kterého přidat
|
||||
vaše video | Vyberte playlist, do kterého přidat vašich {videoCount} videí
|
||||
N playlists selected: Vybráno {playlistCount}
|
||||
Added {count} Times: Přidáno {count}krát | Přidáno {count}krát
|
||||
SinglePlaylistView:
|
||||
Toast:
|
||||
There were no videos to remove.: Nejsou zde žádná videa k odstranění.
|
||||
|
@ -175,6 +176,7 @@ User Playlists:
|
|||
This playlist is now used for quick bookmark: Tento playlist bude nyní použit
|
||||
pro rychlé uložení
|
||||
Quick bookmark disabled: Rychlé uložení vypnuto
|
||||
Search for Videos: Hledat videa
|
||||
Are you sure you want to delete this playlist? This cannot be undone: Opravdu chcete
|
||||
odstranit tento playlist? Tato akce je nevratná.
|
||||
Sort By:
|
||||
|
@ -234,7 +236,7 @@ Settings:
|
|||
General Settings:
|
||||
General Settings: 'Obecné nastavení'
|
||||
Check for Updates: 'Kontrolovat aktualizace'
|
||||
Check for Latest Blog Posts: 'Kontrolovat nejnovější příspěvky blogů'
|
||||
Check for Latest Blog Posts: 'Kontrolovat nejnovější příspěvky na blogu'
|
||||
Fallback to Non-Preferred Backend on Failure: 'Při chybě přepnout na nepreferovaný
|
||||
backend'
|
||||
Enable Search Suggestions: 'Zapnout návrhy vyhledávání'
|
||||
|
@ -444,7 +446,7 @@ Settings:
|
|||
Hide Channels: Skrýt videa z kanálů
|
||||
Hide Channels Placeholder: ID kanálu
|
||||
Display Titles Without Excessive Capitalisation: Zobrazit názvy bez nadměrného
|
||||
použití velkých písmen
|
||||
použití velkých písmen a interpunkce
|
||||
Hide Featured Channels: Skrýt doporučené kanály
|
||||
Hide Channel Playlists: Skrýt playlisty kanálu
|
||||
Hide Channel Community: Skrýt komunitu kanálu
|
||||
|
@ -926,6 +928,7 @@ Video:
|
|||
Pause on Current Video: Pozastavit na současném videu
|
||||
Unhide Channel: Zobrazit kanál
|
||||
Hide Channel: Skrýt kanál
|
||||
More Options: Další možnosti
|
||||
Videos:
|
||||
#& Sort By
|
||||
Sort By:
|
||||
|
@ -1025,10 +1028,10 @@ Tooltips:
|
|||
otevřít ve FreeTube.\nVe výchozím nastavení otevře FreeTube odkaz ve vašem výchozím
|
||||
prohlížeči.\n"
|
||||
Player Settings:
|
||||
Force Local Backend for Legacy Formats: 'Funguje pouze v případě, že je výchozím
|
||||
nastavením API Invidious. Je-li povoleno, spustí se místní API a použije starší
|
||||
Force Local Backend for Legacy Formats: 'Funguje pouze v případě, že je jako výchozí
|
||||
nastaveno API Invidious. Je-li povoleno, spustí se místní API a použije starší
|
||||
formáty místo těch, které vrátí Invidious. Může pomoci, pokud videa z Invidious
|
||||
nemohou být přehrána kvůli regionálnímu omezení.'
|
||||
nemohou být přehrána z důvodu regionálních omezení.'
|
||||
Proxy Videos Through Invidious: 'Připojí se k Invidious, aby poskytoval videa
|
||||
namísto přímého připojení k YouTube. Toto přepíše předvolby API.'
|
||||
Default Video Format: 'Nastavte formáty použité při přehrávání videa. Formáty
|
||||
|
@ -1090,7 +1093,7 @@ Tooltips:
|
|||
Local API Error (Click to copy): 'Chyba lokálního API (kliknutím zkopírujete)'
|
||||
Invidious API Error (Click to copy): 'Chyba Invidious API (kliknutím zkopírujete)'
|
||||
Falling back to Invidious API: 'Přepínám na Invidious API'
|
||||
Falling back to the local API: 'Přepínám na lokální API'
|
||||
Falling back to Local API: 'Přepínám na lokální API'
|
||||
This video is unavailable because of missing formats. This can happen due to country unavailability.: 'Toto
|
||||
video není k dispozici z důvodu chybějících formátů. K tomu může dojít z důvodu
|
||||
nedostupnosti země.'
|
||||
|
@ -1129,11 +1132,6 @@ Downloading has completed: Bylo dokončeno stahování "{videoTitle}"
|
|||
Downloading failed: Došlo k problému při stahování "{videoTitle}"
|
||||
Starting download: Zahájení stahování "{videoTitle}"
|
||||
New Window: Nové okno
|
||||
Age Restricted:
|
||||
This {videoOrPlaylist} is age restricted: Toto {videoOrPlaylist} je omezeno věkem
|
||||
Type:
|
||||
Channel: kanál
|
||||
Video: Video
|
||||
Channels:
|
||||
Channels: Kanály
|
||||
Title: Seznam kanálů
|
||||
|
@ -1170,3 +1168,7 @@ Channel Unhidden: Kanál {channel} odebrán z filtrů kanálů
|
|||
Trimmed input must be at least N characters long: Oříznutý vstup musí být dlouhý alespoň
|
||||
1 znak | Oříznutý vstup musí být dlouhý alespoň {length} znaků
|
||||
Tag already exists: Štítek „{tagName}“ již existuje
|
||||
Close Banner: Zavřít panel
|
||||
Age Restricted:
|
||||
This channel is age restricted: Tento kanál je omezen věkem
|
||||
This video is age restricted: Toto video je omezeno věkem
|
||||
|
|
|
@ -831,7 +831,7 @@ Tooltips:
|
|||
Local API Error (Click to copy): ''
|
||||
Invidious API Error (Click to copy): ''
|
||||
Falling back to Invidious API: ''
|
||||
Falling back to the local API: ''
|
||||
Falling back to Local API: ''
|
||||
This video is unavailable because of missing formats. This can happen due to country unavailability.: ''
|
||||
Subscriptions have not yet been implemented: ''
|
||||
Unknown YouTube url type, cannot be opened in app: ''
|
||||
|
@ -851,11 +851,6 @@ Canceled next video autoplay: ''
|
|||
Default Invidious instance has been set to {instance}: ''
|
||||
Default Invidious instance has been cleared: ''
|
||||
'The playlist has ended. Enable loop to continue playing': ''
|
||||
Age Restricted:
|
||||
This {videoOrPlaylist} is age restricted: ''
|
||||
Type:
|
||||
Channel: 'Sianel'
|
||||
Video: 'Fideo'
|
||||
External link opening has been disabled in the general settings: ''
|
||||
Downloading has completed: ''
|
||||
Starting download: ''
|
||||
|
|
|
@ -769,7 +769,7 @@ Up Next: 'Næste'
|
|||
Local API Error (Click to copy): 'Lokal API-Fejl (Klik for at kopiere)'
|
||||
Invidious API Error (Click to copy): 'Invidious-API-Fejl (Klik for at kopiere)'
|
||||
Falling back to Invidious API: 'Falder tilbage til Invidious-API'
|
||||
Falling back to the local API: 'Falder tilbage til den lokale API'
|
||||
Falling back to Local API: 'Falder tilbage til den lokale API'
|
||||
Subscriptions have not yet been implemented: 'Abonnementer er endnu ikke blevet implementerede'
|
||||
Loop is now disabled: 'Gentagelse er nu deaktiveret'
|
||||
Loop is now enabled: 'Gentagelse er nu aktiveret'
|
||||
|
@ -858,11 +858,6 @@ Default Invidious instance has been cleared: Standard Invidious-instans er bleve
|
|||
Are you sure you want to open this link?: Er du sikker på at du vil åbne dette link?
|
||||
Search Bar:
|
||||
Clear Input: Ryd Input
|
||||
Age Restricted:
|
||||
Type:
|
||||
Video: Video
|
||||
Channel: Kanal
|
||||
This {videoOrPlaylist} is age restricted: Denne {videoOrPlaylist} er aldersbegrænset
|
||||
Downloading failed: Der var et problem med at downloade "{videoTitle}"
|
||||
Unknown YouTube url type, cannot be opened in app: Ukendt YouTube URL-type, kan ikke
|
||||
åbnes i appen
|
||||
|
|
|
@ -1014,7 +1014,7 @@ Up Next: Nächster Titel
|
|||
Local API Error (Click to copy): Lokaler API-Fehler (Zum Kopieren anklicken)
|
||||
Invidious API Error (Click to copy): Invidious-API-Fehler (Zum Kopieren anklicken)
|
||||
Falling back to Invidious API: Rückgriff auf Invidious-API
|
||||
Falling back to the local API: Rückgriff auf lokale API
|
||||
Falling back to Local API: Rückgriff auf lokale API
|
||||
This video is unavailable because of missing formats. This can happen due to country unavailability.: Dieses
|
||||
Video ist aufgrund fehlender Formate nicht verfügbar. Zugriffsbeschränkungen im
|
||||
Land kann dafür der Grund sein.
|
||||
|
@ -1204,11 +1204,6 @@ Downloading failed: Beim Herunterladen von „{videoTitle}“ gab es ein Problem
|
|||
Screenshot Success: Bildschirmfoto als „{filePath}“ gespeichert
|
||||
Screenshot Error: Bildschirmfoto fehlgeschlagen. {error}
|
||||
New Window: Neues Fenster
|
||||
Age Restricted:
|
||||
Type:
|
||||
Video: Video
|
||||
Channel: Kanal
|
||||
This {videoOrPlaylist} is age restricted: Dieses {videoOrPlaylist} ist altersbeschränkt
|
||||
Channels:
|
||||
Channels: Kanäle
|
||||
Title: Kanalliste
|
||||
|
|
|
@ -945,7 +945,7 @@ Local API Error (Click to copy): 'Τοπικό σφάλμα Διεπαφής π
|
|||
Invidious API Error (Click to copy): 'Σφάλμα Διεπαφής προγραμματισμού εφαρμογής Invidious(*API)
|
||||
(Κάντε κλικ για αντιγραφή)'
|
||||
Falling back to Invidious API: 'Επιστροφή στο Invidious API'
|
||||
Falling back to the local API: 'Επιστροφή στη τοπική Διεπαφή προγραμματισμού εφαρμογής
|
||||
Falling back to Local API: 'Επιστροφή στη τοπική Διεπαφή προγραμματισμού εφαρμογής
|
||||
(API)'
|
||||
Subscriptions have not yet been implemented: 'Οι συνδρομές δεν έχουν ακόμη υλοποιηθεί'
|
||||
Loop is now disabled: 'Η επανάληψη είναι πλέον απενεργοποιημένη'
|
||||
|
@ -1097,12 +1097,6 @@ Chapters:
|
|||
Chapters: Κεφάλαια
|
||||
'Chapters list visible, current chapter: {chapterName}': 'Ορατή λίστα κεφαλαίων,
|
||||
τρέχον κεφάλαιο: {chapterName}'
|
||||
Age Restricted:
|
||||
This {videoOrPlaylist} is age restricted: Αυτό το {videoOrPlaylist} έχει περιορισμό
|
||||
ηλικίας
|
||||
Type:
|
||||
Channel: Κανάλι
|
||||
Video: Βίντεο
|
||||
Ok: Εντάξει
|
||||
Preferences: Προτιμήσεις
|
||||
Screenshot Success: Αποθηκευμένο στιγμιότυπο οθόνης ως "{filePath}"
|
||||
|
|
|
@ -32,6 +32,7 @@ Back: Back
|
|||
Forward: Forward
|
||||
Open New Window: Open New Window
|
||||
Go to page: Go to {page}
|
||||
Close Banner: Close Banner
|
||||
|
||||
Version {versionNumber} is now available! Click for more details: Version {versionNumber} is now available! Click
|
||||
for more details
|
||||
|
@ -186,6 +187,8 @@ User Playlists:
|
|||
EarliestPlayedFirst: 'Earliest Played'
|
||||
|
||||
SinglePlaylistView:
|
||||
Search for Videos: Search for Videos
|
||||
|
||||
Toast:
|
||||
This video cannot be moved up.: This video cannot be moved up.
|
||||
This video cannot be moved down.: This video cannot be moved down.
|
||||
|
@ -213,6 +216,8 @@ User Playlists:
|
|||
Search in Playlists: Search in Playlists
|
||||
Save: Save
|
||||
|
||||
Added {count} Times: 'Added {count} Time | Added {count} Times'
|
||||
|
||||
Toast:
|
||||
You haven't selected any playlist yet.: You haven't selected any playlist yet.
|
||||
"{videoCount} video(s) added to 1 playlist": "1 video added to 1 playlist | {videoCount} videos added to 1 playlist"
|
||||
|
@ -451,7 +456,7 @@ Settings:
|
|||
Hide Video Description: Hide Video Description
|
||||
Hide Comments: Hide Comments
|
||||
Hide Profile Pictures in Comments: Hide Profile Pictures in Comments
|
||||
Display Titles Without Excessive Capitalisation: Display Titles Without Excessive Capitalisation
|
||||
Display Titles Without Excessive Capitalisation: Display Titles Without Excessive Capitalisation And Punctuation
|
||||
Hide Live Streams: Hide Live Streams
|
||||
Hide Upcoming Premieres: Hide Upcoming Premieres
|
||||
Hide Sharing Actions: Hide Sharing Actions
|
||||
|
@ -722,6 +727,7 @@ Channel:
|
|||
Hide Answers: Hide Answers
|
||||
Video hidden by FreeTube: Video hidden by FreeTube
|
||||
Video:
|
||||
More Options: More Options
|
||||
Mark As Watched: Mark As Watched
|
||||
Remove From History: Remove From History
|
||||
Video has been marked as watched: Video has been marked as watched
|
||||
|
@ -955,7 +961,7 @@ Tooltips:
|
|||
By default FreeTube will open the clicked link in your default browser.
|
||||
Player Settings:
|
||||
Force Local Backend for Legacy Formats: Only works when the Invidious API is your
|
||||
default. When enabled, the local API will run and use the legacy formats returned
|
||||
default. When enabled, the Local API will run and use the legacy formats returned
|
||||
by that instead of the ones returned by Invidious. Helps when the videos returned
|
||||
by Invidious don't play due to country restrictions.
|
||||
Proxy Videos Through Invidious: Will connect to Invidious to serve videos instead
|
||||
|
@ -1009,7 +1015,7 @@ Tooltips:
|
|||
Local API Error (Click to copy): Local API Error (Click to copy)
|
||||
Invidious API Error (Click to copy): Invidious API Error (Click to copy)
|
||||
Falling back to Invidious API: Falling back to Invidious API
|
||||
Falling back to the local API: Falling back to the local API
|
||||
Falling back to Local API: Falling back to Local API
|
||||
This video is unavailable because of missing formats. This can happen due to country unavailability.: This
|
||||
video is unavailable because of missing formats. This can happen due to country
|
||||
unavailability.
|
||||
|
@ -1033,10 +1039,8 @@ Default Invidious instance has been cleared: Default Invidious instance has been
|
|||
'The playlist has ended. Enable loop to continue playing': 'The playlist has ended. Enable
|
||||
loop to continue playing'
|
||||
Age Restricted:
|
||||
This {videoOrPlaylist} is age restricted: This {videoOrPlaylist} is age restricted
|
||||
Type:
|
||||
Channel: Channel
|
||||
Video: Video
|
||||
This channel is age restricted: This channel is age restricted
|
||||
This video is age restricted: This video is age restricted
|
||||
External link opening has been disabled in the general settings: 'External link opening has been disabled in the general settings'
|
||||
Downloading has completed: '"{videoTitle}" has finished downloading'
|
||||
Starting download: 'Starting download of "{videoTitle}"'
|
||||
|
|
|
@ -121,14 +121,14 @@ Playlists: 'Playlists'
|
|||
User Playlists:
|
||||
Your Playlists: 'Your playlists'
|
||||
Playlist Message: This page is not reflective of fully working playlists. It only
|
||||
lists videos that you have saved or favourited. When the work has finished, all
|
||||
videos currently here will be migrated to a ‘Favourites’ playlist.
|
||||
lists videos that you have saved or made a Favourite. When the work has finished,
|
||||
all videos currently here will be migrated to a ‘Favourites’ playlist.
|
||||
Your saved videos are empty. Click on the save button on the corner of a video to have it listed here: Your
|
||||
saved videos are empty. Click on the save button on the corner of a video to have
|
||||
it listed here
|
||||
Search bar placeholder: Search in playlist
|
||||
Empty Search Message: There are no videos in this playlist that match your search
|
||||
Create New Playlist: Create new playlist
|
||||
Create New Playlist: Create new Playlist
|
||||
Add to Playlist: Add to playlist
|
||||
This playlist currently has no videos.: This playlist currently has no videos.
|
||||
Move Video Down: Move video down
|
||||
|
@ -185,11 +185,21 @@ User Playlists:
|
|||
"{videoCount} video(s) added to 1 playlist": 1 video added to 1 playlist | {videoCount}
|
||||
videos added to 1 playlist
|
||||
You haven't selected any playlist yet.: You haven't selected any playlist yet.
|
||||
"{videoCount} video(s) added to {playlistCount} playlists": 1 video added to
|
||||
{playlistCount} playlists | {videoCount} videos added to {playlistCount}
|
||||
playlists
|
||||
Select a playlist to add your N videos to: Select a playlist to add your video
|
||||
to | Select a playlist to add your {videoCount} videos to
|
||||
CreatePlaylistPrompt:
|
||||
New Playlist Name: New playlist name
|
||||
New Playlist Name: New Playlist name
|
||||
Create: Create
|
||||
Toast:
|
||||
Playlist {playlistName} has been successfully created.: Playlist {playlistName}
|
||||
has been successfully created.
|
||||
There was an issue with creating the playlist.: There was an problem when creating
|
||||
the playlist.
|
||||
There is already a playlist with this name. Please pick a different name.: There
|
||||
is already a Playlist with this name. Please pick a different name.
|
||||
You have no playlists. Click on the create new playlist button to create a new one.: You
|
||||
have no playlists. Click on the create new playlist button to create a new one.
|
||||
Move Video Up: Move video up
|
||||
|
@ -252,7 +262,7 @@ Settings:
|
|||
Clear Default Instance: Clear default instance
|
||||
Set Current Instance as Default: Set current instance as default
|
||||
Current instance will be randomized on startup: Current instance will be randomised
|
||||
on startup
|
||||
on Startup
|
||||
No default instance has been set: No default instance has been set
|
||||
The currently set default instance is {instance}: The currently set default instance
|
||||
is {instance}
|
||||
|
@ -966,7 +976,7 @@ Up Next: 'Up Next'
|
|||
Local API Error (Click to copy): 'Local API Error (Click to copy)'
|
||||
Invidious API Error (Click to copy): 'Invidious API Error (Click to copy)'
|
||||
Falling back to Invidious API: 'Falling back to Invidious API'
|
||||
Falling back to the local API: 'Falling back to the local API'
|
||||
Falling back to Local API: 'Falling back to Local API'
|
||||
Subscriptions have not yet been implemented: 'Subscriptions have not yet been implemented'
|
||||
Loop is now disabled: 'Loop is now disabled'
|
||||
Loop is now enabled: 'Loop is now enabled'
|
||||
|
@ -998,7 +1008,7 @@ Tooltips:
|
|||
Proxy Videos Through Invidious: Will connect to Invidious to serve videos instead
|
||||
of making a direct connection to YouTube. Overrides API preference.
|
||||
Force Local Backend for Legacy Formats: Only works when the Invidious API is your
|
||||
default. When enabled, the local API will run and use the legacy formats returned
|
||||
default. When enabled, the Local API will run and use the legacy formats returned
|
||||
by that instead of the ones returned by Invidious. Helps when the videos returned
|
||||
by Invidious don’t play due to country restrictions.
|
||||
Scroll Playback Rate Over Video Player: While the cursor is over the video, press
|
||||
|
@ -1082,17 +1092,15 @@ New Window: New window
|
|||
Channels:
|
||||
Empty: Your channel list is currently empty.
|
||||
Unsubscribe: Unsubscribe
|
||||
Unsubscribed: '{channelName} has been removed from your subscriptions'
|
||||
Unsubscribe Prompt: Are you sure you want to unsubscribe from ‘{channelName}’?
|
||||
Unsubscribed: '{channelName} has been removed from your Subscriptions'
|
||||
Unsubscribe Prompt: Are you sure you want to Unsubscribe from ‘{channelName}’?
|
||||
Title: Channel list
|
||||
Search bar placeholder: Search channels
|
||||
Channels: Channels
|
||||
Count: '{number} channel(s) found.'
|
||||
Age Restricted:
|
||||
This {videoOrPlaylist} is age restricted: This {videoOrPlaylist} is age restricted
|
||||
Type:
|
||||
Video: Video
|
||||
Channel: Channel
|
||||
This channel is age restricted: This channel is age restricted
|
||||
This video is age restricted: This video is age restricted
|
||||
Chapters:
|
||||
'Chapters list visible, current chapter: {chapterName}': 'Chapters list visible,
|
||||
current chapter: {chapterName}'
|
||||
|
@ -1115,3 +1123,4 @@ Playlist will not pause when current video is finished: Playlist will not pause
|
|||
current video is finished
|
||||
Go to page: Go to {page}
|
||||
Tag already exists: ‘{tagName}’ tag already exists
|
||||
Close Banner: Close Banner
|
||||
|
|
|
@ -678,7 +678,7 @@ Local API Error (Click to copy): 'Error de la API local (Presione para copiar)'
|
|||
Invidious API Error (Click to copy): 'Error de la API de Invidious (Presione para
|
||||
copiar)'
|
||||
Falling back to Invidious API: 'Recurriendo a la API de Invidious'
|
||||
Falling back to the local API: 'Recurriendo a la API local'
|
||||
Falling back to Local API: 'Recurriendo a la API local'
|
||||
Subscriptions have not yet been implemented: 'Las suscripciones aún no se han implementado'
|
||||
Loop is now disabled: 'El bucle esta desactivado'
|
||||
Loop is now enabled: 'El bucle esta activado'
|
||||
|
|
|
@ -142,6 +142,7 @@ User Playlists:
|
|||
a la que añadir su vídeo | Seleccione una lista de reproducción a la que añadir
|
||||
sus {videoCount} vídeos
|
||||
N playlists selected: '{playlistCount} seleccionada'
|
||||
Added {count} Times: Añadido {count} vez | Añadido {count} veces
|
||||
SinglePlaylistView:
|
||||
Toast:
|
||||
There were no videos to remove.: No había vídeos que eliminar.
|
||||
|
@ -532,8 +533,8 @@ Settings:
|
|||
Hide Upcoming Premieres: Ocultar los próximos estrenos
|
||||
Hide Channels: Ocultar vídeos de los canales
|
||||
Hide Channels Placeholder: ID del canal
|
||||
Display Titles Without Excessive Capitalisation: Mostrar títulos sin demasiadas
|
||||
mayúsculas
|
||||
Display Titles Without Excessive Capitalisation: Mostrar títulos sin mayúsculas
|
||||
ni signos de puntuación excesivos
|
||||
Hide Featured Channels: Ocultar canales recomendados
|
||||
Hide Channel Playlists: Ocultar las listas de reproducción de los canales
|
||||
Hide Channel Community: Ocultar canales de la comunidad
|
||||
|
@ -955,6 +956,7 @@ Video:
|
|||
Pause on Current Video: Pausa en el vídeo actual
|
||||
Unhide Channel: Mostrar el canal
|
||||
Hide Channel: Ocultar el canal
|
||||
More Options: Más opciones
|
||||
Videos:
|
||||
#& Sort By
|
||||
Sort By:
|
||||
|
@ -1038,7 +1040,7 @@ Local API Error (Click to copy): 'Error de la API local (Clic para copiar el có
|
|||
Invidious API Error (Click to copy): 'Error de la API de Invidious (Clic para copiar
|
||||
el código)'
|
||||
Falling back to Invidious API: 'Recurriendo a la API de Invidious'
|
||||
Falling back to the local API: 'Recurriendo a la API local'
|
||||
Falling back to Local API: 'Recurriendo a la API local'
|
||||
Subscriptions have not yet been implemented: 'Todavía no se han implementado las suscripciones'
|
||||
Loop is now disabled: 'Reproducción en bucle desactivada'
|
||||
Loop is now enabled: 'Reproducción en bucle activada'
|
||||
|
@ -1077,10 +1079,11 @@ Tooltips:
|
|||
Proxy Videos Through Invidious: Se conectará a Invidious para obtener vídeos en
|
||||
lugar de conectar directamente con YouTube. Sobreescribirá la preferencia de
|
||||
API.
|
||||
Force Local Backend for Legacy Formats: Solo funciona cuando la API de Invidious
|
||||
es la predeterminada. la API local se ejecutará y usará los formatos heredados
|
||||
en lugar de Invidious. Esto ayudará cuando Invidious no pueda reproducir un
|
||||
vídeo por culpa de las restricciones regionales.
|
||||
Force Local Backend for Legacy Formats: Sólo funciona cuando la API de Invidious
|
||||
es la predeterminada. Si está activada, la API local se ejecutará y utilizará
|
||||
los formatos heredados devueltos por ella en lugar de los devueltos por Invidious.
|
||||
Es útil cuando los vídeos devueltos por Invidious no se reproducen debido a
|
||||
restricciones nacionales.
|
||||
Scroll Playback Rate Over Video Player: Cuando el cursor esté sobre el vídeo,
|
||||
presiona y mantén la tecla Control (Comando en Mac) y desplaza la rueda del
|
||||
ratón hacia arriba o abajo para cambiar la velocidad de reproducción. Presiona
|
||||
|
@ -1184,12 +1187,6 @@ Channels:
|
|||
Unsubscribe: Cancelar la suscripción
|
||||
Unsubscribed: '{channelName} ha sido eliminado de tus suscripciones'
|
||||
Unsubscribe Prompt: ¿Está seguro/segura de querer desuscribirse de «{channelName}»?
|
||||
Age Restricted:
|
||||
Type:
|
||||
Channel: Canal
|
||||
Video: Vídeo
|
||||
This {videoOrPlaylist} is age restricted: Este {videoOrPlaylist} tiene restricción
|
||||
de edad
|
||||
Clipboard:
|
||||
Copy failed: Error al copiar al portapapeles
|
||||
Cannot access clipboard without a secure connection: No se puede acceder al portapapeles
|
||||
|
@ -1216,3 +1213,7 @@ Channel Unhidden: '{channel} eliminado del filtro de canales'
|
|||
Tag already exists: La etiqueta "{tagName}" ya existe
|
||||
Trimmed input must be at least N characters long: La entrada recortada debe tener
|
||||
al menos 1 carácter | La entrada recortada debe tener al menos {length} caracteres
|
||||
Close Banner: Cerrar el banner
|
||||
Age Restricted:
|
||||
This channel is age restricted: Este canal está restringido por edad
|
||||
This video is age restricted: Este vídeo está restringido por edad
|
||||
|
|
|
@ -161,6 +161,7 @@ User Playlists:
|
|||
Select a playlist to add your N videos to: Vali esitusloend, kuhu soovid oma video
|
||||
lisada | Vali esitusloend, kuhu soovid oma {videoCount} videot lisada
|
||||
N playlists selected: '{playlistCount} valitud'
|
||||
Added {count} Times: Lisatud {count} kord | Lisatud {count} korda
|
||||
SinglePlaylistView:
|
||||
Toast:
|
||||
There were no videos to remove.: Ei leidnud ühtegi videot, mida saaks eemaldada.
|
||||
|
@ -497,7 +498,7 @@ Settings:
|
|||
Hide Channels: Peida kanalites leiduvad videod
|
||||
Hide Channels Placeholder: Kanali tunnus
|
||||
Display Titles Without Excessive Capitalisation: Näita pealkirju ilma liigsete
|
||||
suurtähtedeta
|
||||
suurtähtede ja kirjavahemärkideta
|
||||
Sections:
|
||||
General: Üldist
|
||||
Side Bar: Külgpaan
|
||||
|
@ -884,6 +885,7 @@ Video:
|
|||
Pause on Current Video: Peata hetkel esitatav video
|
||||
Unhide Channel: Näita kanalit
|
||||
Hide Channel: Peida kanal
|
||||
More Options: Veel valikuid
|
||||
Videos:
|
||||
#& Sort By
|
||||
Sort By:
|
||||
|
@ -964,7 +966,7 @@ Up Next: 'Järgmisena'
|
|||
Local API Error (Click to copy): 'Kohaliku API viga (kopeerimiseks klõpsi)'
|
||||
Invidious API Error (Click to copy): 'Invidious''e API viga (kopeerimiseks klõpsi)'
|
||||
Falling back to Invidious API: 'Varuvariandina kasutan Invidious''e API''t'
|
||||
Falling back to the local API: 'Varuvariandina kasutan kohalikku API''t'
|
||||
Falling back to Local API: 'Varuvariandina kasutan kohalikku API''t'
|
||||
This video is unavailable because of missing formats. This can happen due to country unavailability.: 'Kuna
|
||||
vajalikke vorminguid ei leidu, siis see video pole saadaval. Niisugune viga võib
|
||||
juhtuda ka maapiirangute tõttu.'
|
||||
|
@ -1093,11 +1095,6 @@ Channels:
|
|||
Unsubscribe: Loobu tellimusest
|
||||
Unsubscribed: '{channelName} on sinu tellimustest eemaldatud'
|
||||
Unsubscribe Prompt: Kas oled kindel, et soovid „{channelName}“ tellimusest loobuda?
|
||||
Age Restricted:
|
||||
This {videoOrPlaylist} is age restricted: See {videoOrPlaylist} on vanusepiiranguga
|
||||
Type:
|
||||
Channel: Kanal
|
||||
Video: Video
|
||||
Screenshot Success: Kuvatõmmis on salvestatud faili „{filePath}“
|
||||
Clipboard:
|
||||
Copy failed: Lõikelauale kopeerimine ei õnnestunud
|
||||
|
@ -1125,3 +1122,7 @@ Channel Unhidden: '{channel} on eemaldatud kanalite filtrist'
|
|||
Tag already exists: Silt „{tagName}“ on juba olemas
|
||||
Trimmed input must be at least N characters long: Kärbitud sisend peab olema vähemalt
|
||||
1 tähemärgi pikkune | Kärbitud sisend peab olema vähemalt {length} tähemärgi pikkune
|
||||
Age Restricted:
|
||||
This channel is age restricted: Kanali vaatamisel on vanusepiirang
|
||||
This video is age restricted: Video vaatamisel on vanusepiirang
|
||||
Close Banner: Sulge rekaampilt
|
||||
|
|
|
@ -34,6 +34,17 @@ Forward: 'Aurrera'
|
|||
Global:
|
||||
Videos: 'Bideoak'
|
||||
|
||||
Counts:
|
||||
Subscriber Count: 1.harpideduna| {count} harpidedun
|
||||
Watching Count: 1. ikuslea | {count} ikusle
|
||||
Channel Count: 1. kanala ! {count} kanal
|
||||
Video Count: 1. bideoa | {count} bideo
|
||||
View Count: 1. ikustaldia | {count} ikustaldi
|
||||
Live: Zuzenekoa
|
||||
Shorts: Laburrak
|
||||
Input Tags:
|
||||
Length Requirement: Etiketak {zenbaki} karaktere izan behar ditu gutxienez
|
||||
Community: Komunitatea
|
||||
Version {versionNumber} is now available! Click for more details: '{versionNumber}
|
||||
bertsioa erabilgarri! Klikatu azalpen gehiagorako'
|
||||
Download From Site: 'Webgunetik jaitsi'
|
||||
|
@ -90,6 +101,14 @@ Subscriptions:
|
|||
Refresh Subscriptions: 'Harpidetzak freskatu'
|
||||
Load More Videos: 'Bideo gehiago kargatu'
|
||||
Error Channels: Akatsak dituzten kateak
|
||||
Disabled Automatic Fetching: Harpidetza-bilaketa automatikoa desgaitu duzu. Freskatu
|
||||
harpidetzak hemen ikusteko.
|
||||
Empty Channels: Harpidetutako kanalek ez dute bideorik.
|
||||
Empty Posts: Harpidetutako kanalek ez dute argitalpenik.
|
||||
Load More Posts: Kargatu mezu gehiago
|
||||
Subscriptions Tabs: Harpidetzen fitxak
|
||||
All Subscription Tabs Hidden: Harpidetza fitxa guztiak ezkutatuta daude. Hemen edukia
|
||||
ikusteko, erakutsi fitxa batzuk "{azpisection}" ataleko "{settingsSection}"-ean.
|
||||
More: 'Gehiago'
|
||||
Trending:
|
||||
Trending: 'Joerak'
|
||||
|
@ -111,6 +130,100 @@ User Playlists:
|
|||
Search bar placeholder: Bilatu Erreprodukzio-zerrendan
|
||||
Empty Search Message: Erreprodukzio-zerrenda honetan ez dago zure bilaketarekin
|
||||
bat datorren bideorik
|
||||
Remove Watched Videos: Kendu ikusitako bideoak
|
||||
You have no playlists. Click on the create new playlist button to create a new one.: Ez
|
||||
duzu erreprodukzio-zerrendarik. Egin klik sortu erreprodukzio-zerrenda berria
|
||||
botoian berri bat sortzeko.
|
||||
This playlist currently has no videos.: Erreprodukzio-zerrenda honek ez du bideorik.
|
||||
Create New Playlist: Sortu erreprodukzio zerrenda berria
|
||||
Add to Playlist: Gehitu erreprodukzio zerrendara
|
||||
Add to Favorites: Gehitu {playlistName}-ra
|
||||
Remove from Favorites: Kendu {playlistName}tik
|
||||
Move Video Up: Mugitu bideoa gora
|
||||
Move Video Down: Mugitu bideoa behera
|
||||
Remove from Playlist: Kendu erreprodukzio zerrendatik
|
||||
Playlist Name: Erreprodukzio zerrendaren izena
|
||||
Playlist Description: Erreprodukzio-zerrendaren deskribapena
|
||||
Save Changes: Gorde aldaketak
|
||||
Cancel: Utzi
|
||||
Edit Playlist Info: Editatu erreprodukzio zerrendaren informazioa
|
||||
Copy Playlist: Kopiatu Erreprodukzio zerrenda
|
||||
CreatePlaylistPrompt:
|
||||
New Playlist Name: Erreprodukzio-zerrendaren izen berria
|
||||
Toast:
|
||||
Playlist {playlistName} has been successfully created.: '{playlistName} erreprodukzio-zerrenda
|
||||
behar bezala sortu da.'
|
||||
There was an issue with creating the playlist.: Arazo bat izan da erreprodukzio-zerrenda
|
||||
sortzearekin.
|
||||
There is already a playlist with this name. Please pick a different name.: Badago
|
||||
dagoeneko izen honekin erreprodukzio-zerrenda bat. Mesedez, aukeratu beste
|
||||
izen bat.
|
||||
Create: Sortu
|
||||
Enable Quick Bookmark With This Playlist: Gaitu laster-marka azkarra erreprodukzio-zerrenda
|
||||
honekin
|
||||
Disable Quick Bookmark: Desgaitu laster-marka azkarra
|
||||
Sort By:
|
||||
NameDescending: Z-A
|
||||
LatestCreatedFirst: Sortu berria
|
||||
EarliestCreatedFirst: Lehenen sortuak
|
||||
LatestPlayedFirst: Duela gutxi erreproduzitua
|
||||
EarliestPlayedFirst: Lehenen erreproduzitua
|
||||
Sort By: Ordenatu honen arabera
|
||||
NameAscending: A-Z
|
||||
EarliestUpdatedFirst: Lehenen eguneratuak
|
||||
LatestUpdatedFirst: Eguneratu berriak
|
||||
Delete Playlist: Ezabatu erreprodukzio zerrenda
|
||||
Are you sure you want to delete this playlist? This cannot be undone: Ziur erreprodukzio-zerrenda
|
||||
ezabatu nahi duzula? Hau ezin da desegin.
|
||||
SinglePlaylistView:
|
||||
Toast:
|
||||
Playlist has been updated.: Erreprodukzio-zerrenda eguneratu da.
|
||||
"{videoCount} video(s) have been removed": bideo 1 kendu da | {videoCount} bideo
|
||||
kendu dira
|
||||
This video cannot be moved up.: Bideo hau ezin da gora eraman.
|
||||
This video cannot be moved down.: Bideoa ezin da behera eraman.
|
||||
Video has been removed: Bideoa kendu da
|
||||
There was a problem with removing this video: Arazo bat izan da bideoa kentzean
|
||||
This playlist is now used for quick bookmark: Erreprodukzio-zerrenda hau laster-markak
|
||||
egiteko erabiltzen da orain
|
||||
Quick bookmark disabled: Laster-marka azkarra desgaituta dago
|
||||
This playlist is now used for quick bookmark instead of {oldPlaylistName}. Click here to undo: Erreprodukzio-zerrenda
|
||||
hau laster-marketarako erabiltzen da orain {oldPlaylistName}-ren ordez. Egin
|
||||
klik hemen desegiteko
|
||||
Reverted to use {oldPlaylistName} for quick bookmark: '{oldPlaylistName} erabili
|
||||
da berriro azkar markatzeko'
|
||||
Some videos in the playlist are not loaded yet. Click here to copy anyway.: Erreprodukzio-zerrendako
|
||||
bideo batzuk oraindik ez dira kargatu. Egin klik hemen kopiatzeko hala ere.
|
||||
Playlist name cannot be empty. Please input a name.: Erreprodukzio zerrendaren
|
||||
izena ezin da hutsik egon. Mesedez, idatzi izena.
|
||||
There was an issue with updating this playlist.: Arazo bat izan da erreprodukzio-zerrenda
|
||||
eguneratzean.
|
||||
There were no videos to remove.: Ez zegoen kentzeko bideorik.
|
||||
This playlist is protected and cannot be removed.: Erreprodukzio-zerrenda hau
|
||||
babestuta dago eta ezin da kendu.
|
||||
Playlist {playlistName} has been deleted.: '{playlistName} erreprodukzio-zerrenda
|
||||
ezabatu da.'
|
||||
This playlist does not exist: Erreprodukzio-zerrenda hau ez da existitzen
|
||||
Search for Videos: Bilatu bideoak
|
||||
AddVideoPrompt:
|
||||
Added {count} Times: Gehitu da {count} Time | {count} aldiz gehitu da
|
||||
Toast:
|
||||
"{videoCount} video(s) added to 1 playlist": Bideo 1 gehitu da erreprodukzio-zerrenda
|
||||
batera | {videoCount} bideo gehitu dira erreprodukzio-zerrenda batera
|
||||
You haven't selected any playlist yet.: Oraindik ez duzu erreprodukzio zerrendarik
|
||||
hautatu.
|
||||
"{videoCount} video(s) added to {playlistCount} playlists": Bideo 1 gehitu da
|
||||
{playlistCount} erreprodukzio zerrendetan | {videoCount} bideo gehitu dira
|
||||
{playlistCount} erreprodukzio-zerrendetan
|
||||
Select a playlist to add your N videos to: Hautatu erreprodukzio-zerrenda zure
|
||||
bideoa -ra gehitzeko | Hautatu erreprodukzio-zerrenda zure {videoCount} bideoak
|
||||
gehitzeko
|
||||
N playlists selected: '{playlistCount} hautatuta'
|
||||
Search in Playlists: Bilatu erreprodukzio-zerrendetan
|
||||
Save: Gorde
|
||||
Are you sure you want to remove all watched videos from this playlist? This cannot be undone: Ziur
|
||||
ikusitako bideo guztiak erreprodukzio-zerrenda honetatik kendu nahi dituzula?
|
||||
Hau ezin da desegin.
|
||||
History:
|
||||
# On History Page
|
||||
History: 'Historikoa'
|
||||
|
@ -147,6 +260,8 @@ Settings:
|
|||
Beginning: 'Hasiera'
|
||||
Middle: 'Erdian'
|
||||
End: 'Bukaera'
|
||||
Hidden: Ezkutatuta
|
||||
Blur: Lausotzea
|
||||
View all Invidious instance information: 'Invidious instantzia guztien informazioa
|
||||
ikusi'
|
||||
Region for Trending: 'Joeren eskualdea'
|
||||
|
@ -179,6 +294,9 @@ Settings:
|
|||
Dracula: Drakula
|
||||
System Default: Sistemak lehenetsia
|
||||
Catppuccin Mocha: Catppuccin Motxa
|
||||
Nordic: nordikoa
|
||||
Pastel Pink: Pastel arrosa
|
||||
Hot Pink: Arrosa beroa
|
||||
Main Color Theme:
|
||||
Main Color Theme: 'Oinarrizko koloreen gaia'
|
||||
Red: 'Gorria'
|
||||
|
@ -221,6 +339,7 @@ Settings:
|
|||
Secondary Color Theme: 'Gaiaren bigarren mailako kolorea'
|
||||
#* Main Color Theme
|
||||
Hide Side Bar Labels: Ezkutatu alboko barraren etiketak
|
||||
Hide FreeTube Header Logo: Ezkutatu FreeTube goiburuko logotipoa
|
||||
Player Settings:
|
||||
Player Settings: 'Erreprodukzioaren ezarpenak'
|
||||
Force Local Backend for Legacy Formats: 'Behartu backend lokala Legacy formatuentzat'
|
||||
|
@ -272,6 +391,11 @@ Settings:
|
|||
Display Play Button In Video Player: Bistaratu Erreproduzitzeko botoia bideo erreproduzitzailean
|
||||
Max Video Playback Rate: Gehienezko bideoen erreprodukzio-tasa
|
||||
Video Playback Rate Interval: Bideo Erreprodukzio-tasa tartea
|
||||
Comment Auto Load:
|
||||
Comment Auto Load: Iruzkin karga automatikoa
|
||||
Skip by Scrolling Over Video Player: Saltatu bideo-erreproduzitzailean korrituz
|
||||
Enter Fullscreen on Display Rotate: Sartu pantaila osoko pantaila biratu pantailan
|
||||
Allow DASH AV1 formats: Baimendu DASH AV1 formatuak
|
||||
Privacy Settings:
|
||||
Privacy Settings: 'Pribatutasunari buruzko ezarpenak'
|
||||
Remember History: 'Historikoa oroitu'
|
||||
|
@ -289,11 +413,20 @@ Settings:
|
|||
Are you sure you want to remove all subscriptions and profiles? This cannot be undone.: 'Ziur
|
||||
al zaude zure profil eta harpidetza guztiak ezabatu nahi dituzula? Ezingo duzu
|
||||
atzera egin.'
|
||||
All playlists have been removed: Erreprodukzio-zerrenda guztiak kendu dira
|
||||
Save Watched Videos With Last Viewed Playlist: Gorde ikusitako bideoak ikusitako
|
||||
azken erreprodukzio-zerrendarekin
|
||||
Remove All Playlists: Kendu erreprodukzio-zerrenda guztiak
|
||||
Are you sure you want to remove all your playlists?: Ziur erreprodukzio-zerrenda
|
||||
guztiak kendu nahi dituzula?
|
||||
Subscription Settings:
|
||||
Subscription Settings: 'Harpidetzen ezarpenak'
|
||||
Hide Videos on Watch: 'Ikusten ari zaren bideoa ezkutatu'
|
||||
Fetch Feeds from RSS: 'RSS jarioak eskuratu'
|
||||
Manage Subscriptions: 'Harpidetzak kudeatu'
|
||||
Fetch Automatically: Eskuratu jarioa automatikoki
|
||||
Only Show Latest Video for Each Channel: Erakutsi soilik kanal bakoitzeko azken
|
||||
bideoa
|
||||
Distraction Free Settings:
|
||||
Distraction Free Settings: 'Oharkabetasunak ekiditeko ezarpenak'
|
||||
Hide Video Views: 'Bideoen ikustaldi kopurua ezkutatu'
|
||||
|
@ -310,6 +443,38 @@ Settings:
|
|||
Hide Video Description: Bideoaren deskribapena ezkutatu
|
||||
Hide Comments: Iruzkinak ezkutatu
|
||||
Hide Live Streams: Zuzeneko emanaldiak ezkutatu
|
||||
Sections:
|
||||
Side Bar: Alboko Barra
|
||||
Subscriptions Page: Harpidetzak Orria
|
||||
Channel Page: Kanalaren Orria
|
||||
General: Orokorra
|
||||
Watch Page: Ikusi Orria
|
||||
Hide Profile Pictures in Comments: Ezkutatu profileko argazkiak iruzkinetan
|
||||
Display Titles Without Excessive Capitalisation: Bistaratu izenburuak gehiegizko
|
||||
letra larriz eta puntuaziorik gabe
|
||||
Hide Channels Placeholder: Kanalaren IDa
|
||||
Hide Channel Playlists: Ezkutatu kanaleko erreprodukzio-zerrendak
|
||||
Hide Channel Community: Ezkutatu kanalaren komunitatea
|
||||
Hide Channel Podcasts: Ezkutatu kanaleko podcastak
|
||||
Hide Videos and Playlists Containing Text: Ezkutatu testua duten bideoak eta erreprodukzio-zerrendak
|
||||
Hide Channels: Ezkutatu bideoak kanaletatik
|
||||
Hide Upcoming Premieres: Ezkutatu datozen estreinaldiak
|
||||
Hide Subscriptions Videos: Ezkutatu harpidetza-bideoak
|
||||
Hide Subscriptions Shorts: Ezkutatu bideo laburren harpidetzak
|
||||
Hide Channel Releases: Ezkutatu kanalen kaleratzeak
|
||||
Hide Chapters: Ezkutatu kapituluak
|
||||
Hide Channels Invalid: Emandako kanalaren IDa baliogabea da
|
||||
Hide Channels API Error: Errore bat gertatu da emandako IDa duen erabiltzailea
|
||||
berreskuratzean. Mesedez, egiaztatu berriro IDa zuzena den.
|
||||
Hide Channels Already Exists: Kanalaren IDa badago jada
|
||||
Hide Channel Shorts: Ezkutatu kanalaren bideo laburrak
|
||||
Hide Videos and Playlists Containing Text Placeholder: Hitza, Hitzaren zatia edo
|
||||
esaldia
|
||||
Hide Subscriptions Live: Ezkutatu zuzenekoen harpidetzak
|
||||
Hide Subscriptions Community: Ezkutatu harpidetzen komunitateak
|
||||
Hide Featured Channels: Ezkutatu nabarmendutako kanalak
|
||||
Hide Channels Disabled Message: Kanal batzuk IDa erabiliz blokeatu dira eta ez
|
||||
dira prozesatu. Eginbidea blokeatuta dago ID horiek eguneratzen ari diren bitartean
|
||||
Data Settings:
|
||||
Data Settings: 'Datuen ezarpenak'
|
||||
Select Import Type: 'Hautatu Inportazio mota'
|
||||
|
@ -357,6 +522,18 @@ Settings:
|
|||
esportatu dira
|
||||
Playlist insufficient data: Ez da datu nahikorik "{playlist}" erreprodukzio zerrendarentzat,
|
||||
elementutik ateratzen
|
||||
History File: Historikoaren fitxategia
|
||||
Playlist File: Erreprodukzio-zerrendaren fitxategia
|
||||
Export Playlists For Older FreeTube Versions:
|
||||
Label: Esportatu erreprodukzio zerrendak FreeTube bertsio zaharretarako
|
||||
Tooltip: "Aukera honek erreprodukzio-zerrenda guztietako bideoak \"Gogokoak\"\
|
||||
\ izeneko erreprodukzio-zerrenda batera esportatzen ditu.\nNola esportatu
|
||||
eta inportatu bideoak erreprodukzio-zerrendetan FreeTube-ren bertsio zaharrago
|
||||
baterako:\n 1. Esportatu zure erreprodukzio zerrendak aukera hau gaituta.\n
|
||||
2. Ezabatu lehendik dituzun erreprodukzio-zerrenda guztiak Pribatutasun-ezarpenetan
|
||||
dagoen Kendu zerrenda guztiak aukera erabiliz.\n 3. Abiarazi FreeTube-ren
|
||||
bertsio zaharra eta inportatu esportatutako erreprodukzio-zerrendak.\""
|
||||
Subscription File: Harpidetza Fitxategia
|
||||
Proxy Settings:
|
||||
Proxy Settings: 'Proxy-aren ezarpenak'
|
||||
Enable Tor / Proxy: 'Tor / Proxy ahalbidetu'
|
||||
|
@ -381,6 +558,10 @@ Settings:
|
|||
External Player: Kanpoko erreproduzitzailea
|
||||
Custom External Player Executable: Lehenetsitako kanpo erreproduzitzailea exekutagarria
|
||||
Custom External Player Arguments: Lehenetsitako kanpo erreproduzitzailea argudioak
|
||||
Ignore Default Arguments: Ez ikusi lehenetsitako argudioak
|
||||
Players:
|
||||
None:
|
||||
Name: Bat ere ez
|
||||
Download Settings:
|
||||
Download Settings: Deskargen ezarpenak
|
||||
Ask Download Path: Deskargaren ibilbidea galdetu
|
||||
|
@ -402,11 +583,31 @@ Settings:
|
|||
'SponsorBlock API Url (Default is https://sponsor.ajay.app)': Babesleak blokeatzeko
|
||||
API Url (lehenetsia https://sponsor.ajay.app da)
|
||||
SponsorBlock Settings: Babesleak blokeatzeko ezarpenak
|
||||
UseDeArrowTitles: Erabili DeArrow bideo-izenburuak
|
||||
UseDeArrowThumbnails: Erabili DeArrow irudi txikietarako
|
||||
'DeArrow Thumbnail Generator API Url (Default is https://dearrow-thumb.ajay.app)': DeArrow
|
||||
Thumbnail Generator API URLa (lehenetsia https://dearrow-thumb.ajay.app da)
|
||||
Parental Control Settings:
|
||||
Show Family Friendly Only: Erakutsi familientzat aproposa dena bakarrik
|
||||
Hide Unsubscribe Button: Harpidetza kendu botoia ezkutatu
|
||||
Parental Control Settings: Gurasoen kontrolaren ezarpenak
|
||||
Hide Search Bar: Bilaketa barra ezkutatu
|
||||
Password Dialog:
|
||||
Password: Pasahitza
|
||||
Password Incorrect: Pasahitza okerra
|
||||
Unlock: Desblokeatu
|
||||
Enter Password To Unlock: Sartu pasahitza ezarpenak desblokeatzeko
|
||||
Experimental Settings:
|
||||
Replace HTTP Cache: Ordeztu HTTP cachea
|
||||
Experimental Settings: Ezarpen esperimentalak
|
||||
Warning: Ezarpen hauek esperimentalak dira, aktibatuta dauden bitartean hutsegiteak
|
||||
eragin ditzakete. Oso gomendagarria da babeskopiak egitea. Erabili zure ardurapean!
|
||||
Password Settings:
|
||||
Password Settings: Pasahitz ezarpenak
|
||||
Set Password To Prevent Access: Ezarri pasahitz bat ezarpenetara sarbidea galarazteko
|
||||
Remove Password: Pasahitza ezabatu
|
||||
Set Password: Ezarri pasahitza
|
||||
Expand All Settings Sections: Zabaldu ezarpen guztien atalak
|
||||
About:
|
||||
#On About page
|
||||
About: 'Honi buruz'
|
||||
|
@ -436,6 +637,7 @@ About:
|
|||
these people and projects: 'Hurrengo pertsonak eta proiektuak'
|
||||
Donate: 'Donazioa egin'
|
||||
|
||||
Discussions: Eztabaidak
|
||||
Profile:
|
||||
Profile Select: 'Hautatu profila'
|
||||
Profile Filter: 'Profilaren iragazkiak'
|
||||
|
@ -480,6 +682,12 @@ Profile:
|
|||
batetik ezabatuko.'
|
||||
#On Channel Page
|
||||
Profile Settings: Profilaren ezarpenak
|
||||
Close Profile Dropdown: Itxi goitibeherako profila
|
||||
Open Profile Dropdown: Ireki goitibeherako profila
|
||||
Toggle Profile List: Aldatu profilen zerrenda
|
||||
Edit Profile Name: Editatu profilaren izena
|
||||
Create Profile Name: Sortu profilaren izena
|
||||
Profile Name: Profilaren izena
|
||||
Channel:
|
||||
Subscribe: 'Harpidetu'
|
||||
Unsubscribe: 'Harpidetza kendu'
|
||||
|
@ -510,6 +718,39 @@ Channel:
|
|||
About: 'Honi buruz'
|
||||
Channel Description: 'Kanalaren deskribapena'
|
||||
Featured Channels: 'Nabarmendutako kanalak'
|
||||
Joined: Bat eginda
|
||||
Location: Kokapena
|
||||
Tags:
|
||||
Tags: Etiketak
|
||||
Search for: Bilatu "{tag}"
|
||||
Details: Xehetasunak
|
||||
This channel does not exist: Kanal hau ez da existitzen
|
||||
This channel is age-restricted and currently cannot be viewed in FreeTube.: Kanal
|
||||
hau adin mugatuta dago eta une honetan ezin da ikusi FreeTube-n.
|
||||
Shorts:
|
||||
This channel does not currently have any shorts: Une honetan kanal honek ez du
|
||||
bideo laburrik
|
||||
Releases:
|
||||
This channel does not currently have any releases: Une honetan kanal honek ez
|
||||
du argitalpenik
|
||||
Releases: Argitalpenak
|
||||
Community:
|
||||
Hide Answers: Erantzunak ezkutatu
|
||||
votes: '{votes} bozka'
|
||||
This channel currently does not have any posts: Une honetan kanal honek ez du
|
||||
argitalpenik
|
||||
Reveal Answers: Erantzunak agerian utzi
|
||||
Video hidden by FreeTube: FreeTube-k ezkutatutako bideoa
|
||||
Channel Tabs: Kanalaren fitxak
|
||||
This channel does not allow searching: Kanal honek ez du bilaketarik onartzen
|
||||
Live:
|
||||
Live: Zuzenekoak
|
||||
This channel does not currently have any live streams: Kanal honek ez du zuzeneko
|
||||
erreprodukziorik
|
||||
Podcasts:
|
||||
Podcasts: Podcastak
|
||||
This channel does not currently have any podcasts: Une honetan kanal honek ez
|
||||
du podcastik
|
||||
Video:
|
||||
Mark As Watched: 'Ikusitako gisa jarri'
|
||||
Remove From History: 'Historikotik ezabatu'
|
||||
|
@ -592,6 +833,7 @@ Video:
|
|||
Years: 'Urteak'
|
||||
Ago: 'Duela'
|
||||
Upcoming: 'Estreinaldiak'
|
||||
In less than a minute: Minutu bat baino gutxiagoan
|
||||
Published on: 'Noiz argitaratua'
|
||||
Streamed on: 'Noiz zuzenean emana'
|
||||
Started streaming on: 'Noiz hasi zen zuzenekoa'
|
||||
|
@ -636,6 +878,16 @@ Video:
|
|||
intro: Sarrera
|
||||
Skipped segment: Saltatu egin da segmentua
|
||||
Premieres on: Estreinaldiak
|
||||
Hide Channel: Kanala ezkutatu
|
||||
Unhide Channel: Kanala erakutsi
|
||||
Premieres: Estreinaldiak
|
||||
'Live Chat is unavailable for this stream. It may have been disabled by the uploader.': Zuzeneko
|
||||
txata ez dago erabilgarri zuzeneko honentzat. Baliteke igo duenak desgaitu izana.
|
||||
Show Super Chat Comment: Erakutsi Super txat iruzkina
|
||||
Pause on Current Video: Gelditu uneko bideoa
|
||||
More Options: Aukera gehiago
|
||||
Upcoming: Datozenak
|
||||
Scroll to Bottom: Joan Beherantz
|
||||
Videos:
|
||||
#& Sort By
|
||||
Sort By:
|
||||
|
@ -685,6 +937,7 @@ Share:
|
|||
YouTube Channel URL copied to clipboard: 'Youtube-ko kanalaren URL-a arbelean itsatsi
|
||||
da'
|
||||
|
||||
Share Channel: Kanala partekatu
|
||||
Mini Player: 'Erreproduzitzaile txikia'
|
||||
Comments:
|
||||
Comments: 'Iruzkinak'
|
||||
|
@ -710,6 +963,10 @@ Comments:
|
|||
Show More Replies: Erantzun gehiago erakutsi
|
||||
And others: eta bestelakoak
|
||||
Pinned by: Honengatik ainguratuta
|
||||
Hearted: Bihotzez
|
||||
From {channelName}: '{channelName}-tik'
|
||||
View {replyCount} replies: Ikusi {replyCount} erantzunak
|
||||
Subscribed: Harpidetuta
|
||||
Up Next: 'Hurrengoa'
|
||||
|
||||
#Tooltips
|
||||
|
@ -749,11 +1006,19 @@ Tooltips:
|
|||
eta mantendu (Komando tekla MAC-etan) eta ondoren saguaren ezkerreko botoia
|
||||
sakatu, lehenetsitako erreprodukzio tasara itzultzeko (1x baldin eta ezarpenetan
|
||||
aldaketarik egin ez bada).
|
||||
Skip by Scrolling Over Video Player: Erabili korritze-gurpila bideoa saltatzeko,
|
||||
MPV estiloa.
|
||||
Allow DASH AV1 formats: DASH AV1 formatuak DASH H.264 formatuak baino itxura hobea
|
||||
izan dezake. DASH AV1 formatuek potentzia gehiago behar dute erreproduzitzeko!
|
||||
Ez daude bideo guztietan eskuragarri, kasu horietan erreproduzitzaileak DASH
|
||||
H.264 formatuak erabiliko ditu ordez.
|
||||
Subscription Settings:
|
||||
Fetch Feeds from RSS: 'Posible denean, Freetube-k bere lehenetsitako metodoa erabili
|
||||
beharrean RSS-ak baliatuko ditu zure harpidetzen jariora konektatzeko. RSS arinagoa
|
||||
izateaz gain, IP-en blokeoak saihesten ditu. Aldiz, zuzenekoaren egoeraren edo
|
||||
bideoaren iraupenaren informaziorik ez du ematen, besteak beste'
|
||||
Fetch Automatically: Gaituta dagoenean, FreeTubek automatikoki eskuratuko du zure
|
||||
harpidetza-jarioa leiho berri bat irekitzen denean eta profila aldatzean.
|
||||
Privacy Settings:
|
||||
Remove Video Meta Files: 'Gaituta dagoenean, FreeTube-k automatikoki ezabatzen
|
||||
ditu bideoen erreprodukzioan sortutako metafitxategiak, bistaratze orria ixten
|
||||
|
@ -772,11 +1037,34 @@ Tooltips:
|
|||
Individious-en ezarpenek ez dituzte kanpo erreproduzitzaileak trabatzen.
|
||||
Custom External Player Arguments: Komando-lerroko argumentu pertsonalizatuak,
|
||||
puntu eta komaz bereizita (';'), kanpoko erreproduzitzailera pasatzea nahi duzu.
|
||||
Ignore Default Arguments: Ez bidali argumentu lehenetsirik kanpoko erreproduzitzaileari
|
||||
bideoaren URLaz gain (adibidez, erreprodukzio-tasa, erreprodukzio-zerrendaren
|
||||
URLa, etab.). Argumentu pertsonalizatuak transmitituko dira oraindik.
|
||||
Distraction Free Settings:
|
||||
Hide Channels: Sartu kanalaren ID bat bideo, erreprodukzio-zerrenda eta kanala
|
||||
bera bilaketetan, joeran, ezagunenetan eta gomendagarrienetan ager ez dadin
|
||||
ezkutatzeko. Sartutako kanalaren IDak guztiz bat etorri behar du eta maiuskulak
|
||||
eta minuskulak bereizten ditu.
|
||||
Hide Videos and Playlists Containing Text: Idatzi hitz bat, hitz-zati bat edo
|
||||
esaldi bat (maiuskulak eta minuskulak bereizten ez diren) jatorrizko izenburuak
|
||||
FreeTube osoan duten bideo eta erreprodukzio-zerrenda guztiak ezkutatzeko, historia,
|
||||
zure erreprodukzio-zerrendak eta erreprodukzio-zerrenden barneko bideoak soilik
|
||||
kenduta.
|
||||
Hide Subscriptions Live: Ezarpen hau aplikazio osorako "{appWideSetting}" ezarpenak
|
||||
ordezkatzen du, "{settingsSection}" ataleko "{azpisekzioa}" atalean
|
||||
Experimental Settings:
|
||||
Replace HTTP Cache: Electron-en diskoan oinarritutako HTTP cachea desgaitzen du
|
||||
eta memoriako irudien cache pertsonalizatua gaitu. RAM erabilera handitzea ekarriko
|
||||
du.
|
||||
SponsorBlock Settings:
|
||||
UseDeArrowThumbnails: Ordeztu bideoaren miniaturak DeArrow-en miniaturaz.
|
||||
UseDeArrowTitles: Ordeztu bideoen izenburuak DeArrow-en erabiltzaileek bidalitako
|
||||
tituluekin.
|
||||
Local API Error (Click to copy): 'Tokiko API-ak huts egin du (klikatu kopiatzeko)'
|
||||
Invidious API Error (Click to copy): 'Individious-eko APIak huts egin du (klikatu
|
||||
kopiatzeko)'
|
||||
Falling back to Invidious API: 'Individious-eko APIra itzultzen'
|
||||
Falling back to the local API: 'Tokiko APIra itzultzen'
|
||||
Falling back to Local API: 'Tokiko APIra itzultzen'
|
||||
This video is unavailable because of missing formats. This can happen due to country unavailability.: 'Bideo
|
||||
hau ez dago erabilgarri, zenbait formatu eskas baitira. Honakoa zure herrialdean
|
||||
erabilgarri ez dagoelako gerta daiteke.'
|
||||
|
@ -827,9 +1115,34 @@ Channels:
|
|||
Unsubscribe Prompt: Ziur al zaude "{channelName}"-ren harpidetza kendu nahi duzula?
|
||||
Count: '{number} kanal aurkitu dira.'
|
||||
Empty: Zure kanalen zerrenda hutsik da.
|
||||
Age Restricted:
|
||||
This {videoOrPlaylist} is age restricted: Honako {videoOrPlaylist} adin muga du
|
||||
Type:
|
||||
Channel: Kanala
|
||||
Video: Bideoa
|
||||
Preferences: Hobespenak
|
||||
Go to page: Joan {page}-ra
|
||||
Close Banner: Itxi iragarkia
|
||||
Age Restricted:
|
||||
This channel is age restricted: Kanal hau adin mugatuta dago
|
||||
This video is age restricted: Bideo hau adin mugatuta dago
|
||||
Playlist will not pause when current video is finished: Erreprodukzio-zerrenda ez
|
||||
da etengo uneko bideoa amaitzen denean
|
||||
Playlist will pause when current video is finished: Erreprodukzio-zerrenda pausatu
|
||||
egingo da uneko bideoa amaitzen denean
|
||||
Channel Unhidden: '{channel} kanalaren iragazkitik kendu da'
|
||||
Clipboard:
|
||||
Cannot access clipboard without a secure connection: Ezin da arbelera sartu konexio
|
||||
segururik gabe
|
||||
Copy failed: Ezin izan da kopiatu arbelean
|
||||
Tag already exists: '"{tagName}" etiketa badago jada'
|
||||
Trimmed input must be at least N characters long: Moztutako sarrerak karaktere bat
|
||||
izan behar du gutxienez | Moztutako sarrerak gutxienez {length} karaktere izan behar
|
||||
ditu
|
||||
Chapters:
|
||||
'Chapters list hidden, current chapter: {chapterName}': 'Kapituluen zerrenda ezkutatuta
|
||||
dago, uneko kapitulua: {chapterName}'
|
||||
Chapters: Kapituluak
|
||||
'Chapters list visible, current chapter: {chapterName}': 'Kapituluen zerrenda ikusgai,
|
||||
uneko kapitulua: {chapterName}'
|
||||
Hashtag:
|
||||
Hashtag: Traola
|
||||
This hashtag does not currently have any videos: Traola honek ez du bideorik une
|
||||
honetan
|
||||
Ok: Ados
|
||||
Channel Hidden: '{channel} gehitu da kanalaren iragazkian'
|
||||
|
|
|
@ -900,12 +900,6 @@ Screenshot Success: اسکرین شات به عنوان «{filePath}» ذخیر
|
|||
Ok: تایید
|
||||
Downloading has completed: دانلود '{videoTitle}' به پایان رسید
|
||||
Loop is now enabled: حلقه اکنون فعال است
|
||||
Age Restricted:
|
||||
Type:
|
||||
Video: ویدیو
|
||||
Channel: کانال
|
||||
This {videoOrPlaylist} is age restricted: این {videoOrPlaylist} دارای محدودیت سنی
|
||||
است
|
||||
Shuffle is now enabled: Shuffle اکنون فعال است
|
||||
Falling back to Invidious API: بازگشت به Invidious API
|
||||
Local API Error (Click to copy): خطای Local API (برای کپی کلیک کنید)
|
||||
|
@ -913,7 +907,7 @@ Shuffle is now disabled: Shuffle اکنون غیرفعال است
|
|||
Canceled next video autoplay: پخش خودکار ویدیوی بعدی لغو شد
|
||||
Unknown YouTube url type, cannot be opened in app: نوع URL ناشناخته YouTube، در برنامه
|
||||
باز نمی شود
|
||||
Falling back to the local API: بازگشت به API محلی
|
||||
Falling back to Local API: بازگشت به API محلی
|
||||
This video is unavailable because of missing formats. This can happen due to country unavailability.: این
|
||||
ویدیو به دلیل عدم وجود قالب در دسترس نیست. این ممکن است به دلیل در دسترس نبودن کشور
|
||||
اتفاق بیفتد.
|
||||
|
|
|
@ -904,7 +904,7 @@ Up Next: 'Seuraavaksi'
|
|||
Local API Error (Click to copy): 'Paikallinen API-virhe (Kopioi napsauttamalla)'
|
||||
Invidious API Error (Click to copy): 'Invidious API-virhe (Kopioi napsauttamalla)'
|
||||
Falling back to Invidious API: 'Palaa takaisin Invidious-sovellusliittymään'
|
||||
Falling back to the local API: 'Palaa takaisin paikalliseen sovellusliittymään'
|
||||
Falling back to Local API: 'Palaa takaisin paikalliseen sovellusliittymään'
|
||||
Subscriptions have not yet been implemented: 'Tilauksia ei ole vielä jalkautettu'
|
||||
Loop is now disabled: 'Silmukka on poistettu käytöstä'
|
||||
Loop is now enabled: 'Silmukka on nyt käytössä'
|
||||
|
@ -1064,11 +1064,6 @@ Downloading has completed: Videon "{videoTitle}" lataus on valmis
|
|||
Starting download: Aloitetaan lataamaan "{videoTitle}"
|
||||
Screenshot Success: Kuvakaappaus tallennettu nimellä ”{filePath}”
|
||||
New Window: Uusi Ikkuna
|
||||
Age Restricted:
|
||||
This {videoOrPlaylist} is age restricted: Tämä {videoOrPlaylist} on ikärajoitettu
|
||||
Type:
|
||||
Video: Video
|
||||
Channel: Kanava
|
||||
Screenshot Error: Ruutukaappaus epäonnistui. {error}
|
||||
Channels:
|
||||
Channels: Kanavat
|
||||
|
|
|
@ -148,6 +148,7 @@ User Playlists:
|
|||
à {playlistCount} listes de lecture | {videoCount} vidéos ajoutées à {playlistCount}
|
||||
listes de lecture
|
||||
N playlists selected: '{playlistCount} Sélectionnée(s)'
|
||||
Added {count} Times: Ajouté {count} Fois | Ajouté {count} Fois
|
||||
SinglePlaylistView:
|
||||
Toast:
|
||||
There were no videos to remove.: Il n'y avait aucune vidéo à supprimer.
|
||||
|
@ -557,7 +558,7 @@ Settings:
|
|||
Hide Channels: Masquer les vidéos des chaînes
|
||||
Hide Channels Placeholder: Identifiant de la chaîne
|
||||
Display Titles Without Excessive Capitalisation: Afficher les titres sans majuscules
|
||||
excessives
|
||||
ni ponctuation excessives
|
||||
Hide Channel Playlists: Masquer les listes de lecture des chaînes
|
||||
Hide Featured Channels: Masquer les chaînes en vedette
|
||||
Hide Channel Community: Masquer la communauté de la chaîne
|
||||
|
@ -946,6 +947,7 @@ Video:
|
|||
Pause on Current Video: Pause sur la vidéo en cours
|
||||
Hide Channel: Cacher la chaîne
|
||||
Unhide Channel: Rétablir la chaîne
|
||||
More Options: Plus d'options
|
||||
Videos:
|
||||
#& Sort By
|
||||
Sort By:
|
||||
|
@ -1030,7 +1032,7 @@ Up Next: 'À suivre'
|
|||
Local API Error (Click to copy): 'Erreur d''API locale (Cliquez pour copier)'
|
||||
Invidious API Error (Click to copy): 'Erreur d''API Invidious (Cliquez pour copier)'
|
||||
Falling back to Invidious API: 'Revenir à l''API Invidious'
|
||||
Falling back to the local API: 'Revenir à l''API locale'
|
||||
Falling back to Local API: 'Revenir à l''API locale'
|
||||
Subscriptions have not yet been implemented: 'Les abonnements n''ont pas encore été
|
||||
implémentés'
|
||||
Loop is now disabled: 'La boucle est maintenant désactivée'
|
||||
|
@ -1226,12 +1228,6 @@ Download folder does not exist: 'Le répertoire "$" de téléchargement n''exist
|
|||
Screenshot Success: Capture d'écran enregistrée sous « {filePath} »
|
||||
Screenshot Error: La capture d'écran a échoué. {error}
|
||||
New Window: Nouvelle fenêtre
|
||||
Age Restricted:
|
||||
Type:
|
||||
Video: Vidéo
|
||||
Channel: Chaîne
|
||||
This {videoOrPlaylist} is age restricted: Ce {videoOrPlaylist} est soumis à une
|
||||
limite d'âge
|
||||
Channels:
|
||||
Channels: Chaînes
|
||||
Title: Liste des chaînes
|
||||
|
@ -1267,3 +1263,7 @@ Channel Unhidden: '{channel} retiré du filtre de chaîne'
|
|||
Trimmed input must be at least N characters long: L'entrée tronquée doit comporter
|
||||
au moins 1 caractère | L'entrée tronquée doit comporter au moins {length} caractères
|
||||
Tag already exists: L'étiquette « {tagName} » existe déjà
|
||||
Age Restricted:
|
||||
This channel is age restricted: Cette chaîne est soumise à des restrictions d'âge
|
||||
This video is age restricted: Cette vidéo est soumise à des restrictions d'âge
|
||||
Close Banner: Fermer la bannière
|
||||
|
|
|
@ -911,7 +911,7 @@ Tooltips:
|
|||
Local API Error (Click to copy): 'Erro de API local (Preme para copiar)'
|
||||
Invidious API Error (Click to copy): 'Erro de API Invidious (Preme para copiar)'
|
||||
Falling back to Invidious API: 'Recorrendo á API Invidious'
|
||||
Falling back to the local API: 'Recorrendo á API local'
|
||||
Falling back to Local API: 'Recorrendo á API local'
|
||||
This video is unavailable because of missing formats. This can happen due to country unavailability.: 'Este
|
||||
vídeo non está dispoñible porque faltan formatos. Isto pode ocorrer debido á non
|
||||
dispoñibilidade do país.'
|
||||
|
@ -958,12 +958,6 @@ Downloading has completed: '"{videoTitle}" rematou de descargarse'
|
|||
External link opening has been disabled in the general settings: A apertura das ligazóns
|
||||
externas desactivouse na configuración xeral
|
||||
Starting download: Comenzando a descarga de "{videoTitle}"
|
||||
Age Restricted:
|
||||
Type:
|
||||
Channel: Canle
|
||||
Video: Vídeo
|
||||
This {videoOrPlaylist} is age restricted: Esta {videoOrPlaylist} ten restricións
|
||||
de idade
|
||||
Default Invidious instance has been cleared: Borrouse a instancia predeterminada de
|
||||
Invidious
|
||||
Screenshot Error: Produciuse un erro na captura de pantalla. {error}
|
||||
|
|
|
@ -49,4 +49,3 @@ Settings:
|
|||
SponsorBlock Settings: {}
|
||||
Channel: {}
|
||||
Tooltips: {}
|
||||
Age Restricted: {}
|
||||
|
|
|
@ -874,7 +874,7 @@ Up Next: 'הסרטון הבא'
|
|||
Local API Error (Click to copy): 'בעיה ב־API המקומי (יש ללחוץ להעתקה)'
|
||||
Invidious API Error (Click to copy): 'בעיה ב־API של Invidious (יש ללחוץ להעתקה)'
|
||||
Falling back to Invidious API: 'מתבצעת נסיגה ל־API של Invidious'
|
||||
Falling back to the local API: 'מתבצעת נסיגה ל־API המקומי'
|
||||
Falling back to Local API: 'מתבצעת נסיגה ל־API המקומי'
|
||||
This video is unavailable because of missing formats. This can happen due to country unavailability.: 'חסרות
|
||||
תצורות לסרטון הזה. הדבר יכול להיגרם בגלל חוסר זמינות למדינה.'
|
||||
Subscriptions have not yet been implemented: 'מנגנון המינויים עדיין לא מוכן'
|
||||
|
@ -980,11 +980,6 @@ Playing Next Video Interval: הסרטון הבא יתחיל מייד. לחיצה
|
|||
Screenshot Success: צילום המסך נשמר בתור „{filePath}”
|
||||
Screenshot Error: צילום המסך נכשל. {error}
|
||||
New Window: חלון חדש
|
||||
Age Restricted:
|
||||
Type:
|
||||
Channel: ערוץ
|
||||
Video: סרטון
|
||||
This {videoOrPlaylist} is age restricted: '{videoOrPlaylist} זה מוגבל בגיל'
|
||||
Channels:
|
||||
Search bar placeholder: חיפוש ערוצים
|
||||
Empty: רשימת הערוצים שלך ריקה כרגע.
|
||||
|
|
|
@ -195,6 +195,7 @@ User Playlists:
|
|||
videa dodana u 1 zbirku
|
||||
Select a playlist to add your N videos to: Odaberi zbirku za dodavanje tvog videa
|
||||
| Odaberi zbirku za dodavanje tvojih {videoCount} videa
|
||||
Added {count} Times: Dodano {count} puta | Dodano {count} puta
|
||||
CreatePlaylistPrompt:
|
||||
Create: Stvori
|
||||
Toast:
|
||||
|
@ -272,11 +273,12 @@ Settings:
|
|||
Black: 'Crna'
|
||||
Dark: 'Tamna'
|
||||
Light: 'Svijetla'
|
||||
Dracula: 'Drakula'
|
||||
Dracula: 'Dracula'
|
||||
System Default: Standard sustava
|
||||
Catppuccin Mocha: Catppuccin Mocha
|
||||
Pastel Pink: Pastelno ružičasta
|
||||
Hot Pink: Vruća ružičasta
|
||||
Nordic: Nordic
|
||||
Main Color Theme:
|
||||
Main Color Theme: 'Glavna boja teme'
|
||||
Red: 'Crvena'
|
||||
|
@ -521,7 +523,7 @@ Settings:
|
|||
Hide Channels: Sakrij videa iz kanala
|
||||
Hide Channels Placeholder: ID kanala
|
||||
Display Titles Without Excessive Capitalisation: Prikaži naslove bez pretjeranog
|
||||
korištenja velikih slova
|
||||
korištenja velikih slova i interpunkcije
|
||||
Hide Featured Channels: Sakrij istaknute kanale
|
||||
Hide Channel Playlists: Sakrij kanal zbirki
|
||||
Hide Channel Community: Sakrij kanal zajednice
|
||||
|
@ -927,7 +929,7 @@ Video:
|
|||
Resolution: Razlučivost
|
||||
Player Dimensions: Dimenzije playera
|
||||
Bitrate: Brzina prijenosa
|
||||
Volume: Glasnoća
|
||||
Volume: Direktorij
|
||||
Bandwidth: Propusnost
|
||||
Buffered: Učitano u memoriju
|
||||
Mimetype: Mimetype
|
||||
|
@ -942,6 +944,7 @@ Video:
|
|||
Pause on Current Video: Zaustavi trenutačni video
|
||||
Unhide Channel: Prikaži kanal
|
||||
Hide Channel: Sakrij kanal
|
||||
More Options: Više opcija
|
||||
Videos:
|
||||
#& Sort By
|
||||
Sort By:
|
||||
|
@ -1022,7 +1025,7 @@ Up Next: 'Sljedeći'
|
|||
Local API Error (Click to copy): 'Greška lokalnog sučelja (pritisni za kopiranje)'
|
||||
Invidious API Error (Click to copy): 'Greška Invidious sučelja (pritisni za kopiranje)'
|
||||
Falling back to Invidious API: 'Koristit će se Invidious sučelje'
|
||||
Falling back to the local API: 'Koristit će se lokalno sučelje'
|
||||
Falling back to Local API: 'Koristit će se lokalno sučelje'
|
||||
Subscriptions have not yet been implemented: 'Pretplate još nisu implementirane'
|
||||
Loop is now disabled: 'Ponavljanje je sada deaktivirano'
|
||||
Loop is now enabled: 'Ponavljanje je sada aktivirano'
|
||||
|
@ -1053,7 +1056,7 @@ Tooltips:
|
|||
Proxy Videos Through Invidious: Za reprodukciju videa povezat će se s Invidiousom
|
||||
umjesto izravnog povezivanja s YouTubeom. Zanemaruje postavke sučelja.
|
||||
Force Local Backend for Legacy Formats: Radi samo, kad se Invidious postavi kao
|
||||
standardno sučelje. Kada je aktivirano, lokalno sučelje će pokretati i koristiti
|
||||
standardno sučelje. Kada je aktivirano, lokalno API sučelje će pokretati i koristiti
|
||||
stare formate umjesto onih koje dostavlja Invidious. Pomaže u slučajevima, kad
|
||||
je reprodukcija videa koje dostavlja Invidious u zemlji zabranjena/ograničena.
|
||||
Scroll Playback Rate Over Video Player: Dok se pokazivač nalazi na videu, pritisni
|
||||
|
@ -1148,11 +1151,6 @@ Starting download: Početak preuzimanja „{videoTitle}”
|
|||
Screenshot Success: Snimka ekrana je spremljena pod „{filePath}”
|
||||
Screenshot Error: Neuspjela snimka ekrana. {error}
|
||||
New Window: Novi prozor
|
||||
Age Restricted:
|
||||
This {videoOrPlaylist} is age restricted: Ovaj {videoOrPlaylist} je dobno ograničen
|
||||
Type:
|
||||
Channel: Kanal
|
||||
Video: Video
|
||||
Channels:
|
||||
Channels: Kanali
|
||||
Title: Popis kanala
|
||||
|
@ -1187,3 +1185,7 @@ Channel Unhidden: '{channel} je uklonjen iz filtra kanala'
|
|||
Trimmed input must be at least N characters long: Skraćeni unos mora imati barem 1
|
||||
znak | Skraćeni unos mora imati barem {length} znaka
|
||||
Tag already exists: Oznaka „{tagName}” već postoji
|
||||
Age Restricted:
|
||||
This channel is age restricted: Ovaj je dobno ograničeni kanal
|
||||
This video is age restricted: Ovaj je dobno ograničeni video
|
||||
Close Banner: Zatvori natpis
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Put the name of your locale in the same language
|
||||
Locale Name: 'English (US)'
|
||||
Locale Name: 'Magyar'
|
||||
FreeTube: 'FreeTube'
|
||||
# Currently on Subscriptions, Playlists, and History
|
||||
'This part of the app is not ready yet. Come back later when progress has been made.': >-
|
||||
|
@ -147,12 +147,13 @@ User Playlists:
|
|||
lejátszási listákhoz
|
||||
"{videoCount} video(s) added to 1 playlist": 1 videó hozzáadva 1 lejátszási
|
||||
listához | {videoCount} videó hozzáadása 1 lejátszási listához
|
||||
You haven't selected any playlist yet.: Még nem választott ki lejátszási listát
|
||||
sem.
|
||||
You haven't selected any playlist yet.: Még nem választott ki egyetlen lejátszási
|
||||
listát sem.
|
||||
Select a playlist to add your N videos to: Válasszon ki egy lejátszási listát
|
||||
a videó hozzáadásához | Válasszon ki egy lejátszási listát a {videoCount} videó
|
||||
hozzáadásához
|
||||
N playlists selected: '{playlistCount} Kiválasztott'
|
||||
Added {count} Times: Hozzáadva {count} Alkalommal | Hozzáadva {count} Alkalommal
|
||||
SinglePlaylistView:
|
||||
Toast:
|
||||
There were no videos to remove.: Nem voltak eltávolítható videók.
|
||||
|
@ -183,6 +184,7 @@ User Playlists:
|
|||
Kattints ide a visszavonáshoz
|
||||
Reverted to use {oldPlaylistName} for quick bookmark: Visszaállítva a(z) {oldPlaylistName}
|
||||
használatára a gyors könyvjelzőhöz
|
||||
Search for Videos: Videók keresése
|
||||
Are you sure you want to delete this playlist? This cannot be undone: Biztos, hogy
|
||||
törölni szeretné ezt a lejátszási listát? Ezt nem lehet visszacsinálni.
|
||||
Sort By:
|
||||
|
@ -534,14 +536,14 @@ Settings:
|
|||
Hide Playlists: Lejátszási listák elrejtése
|
||||
Hide Video Description: Videó leírásának elrejtése
|
||||
Hide Comments: Megjegyzések elrejtése
|
||||
Hide Live Streams: Élő adatfolyamok elrejtése
|
||||
Hide Live Streams: Élő közvetítések elrejtése
|
||||
Hide Sharing Actions: Megosztási műveletek elrejtése
|
||||
Hide Chapters: Fejezetek elrejtése
|
||||
Hide Upcoming Premieres: Közelgő első előadások elrejtése
|
||||
Hide Channels: Videók elrejtése a csatornákból
|
||||
Hide Channels Placeholder: Csatornaazonosító
|
||||
Display Titles Without Excessive Capitalisation: Címek megjelenítése túlzott nagybetűk
|
||||
nélkül
|
||||
Display Titles Without Excessive Capitalisation: Jelenítse meg a címeket túlzott
|
||||
nagybetűs írás és írásjelek nélkül
|
||||
Hide Featured Channels: Kiemelt csatornák elrejtése
|
||||
Hide Channel Playlists: Csatorna lejátszási listák elrejtése
|
||||
Hide Channel Community: Csatornaközösség elrejtése
|
||||
|
@ -953,6 +955,7 @@ Video:
|
|||
Pause on Current Video: Jelenlegi videó szüneteltetése
|
||||
Unhide Channel: Csatorna megjelenítése
|
||||
Hide Channel: Csatorna elrejtése
|
||||
More Options: További beállítások
|
||||
Videos:
|
||||
#& Sort By
|
||||
Sort By:
|
||||
|
@ -1037,7 +1040,7 @@ Up Next: 'Következő'
|
|||
Local API Error (Click to copy): 'Helyi-API hiba (kattintson a másoláshoz)'
|
||||
Invidious API Error (Click to copy): 'Invidious-API hiba (Kattintson a másoláshoz)'
|
||||
Falling back to Invidious API: 'Invidious-API visszatérve'
|
||||
Falling back to the local API: 'Helyi-API visszatérve'
|
||||
Falling back to Local API: 'Helyi-API visszatérve'
|
||||
This video is unavailable because of missing formats. This can happen due to country unavailability.: 'Ez
|
||||
a videó hiányzó formátumok miatt nem érhető el. Ez az ország nem elérhetősége miatt
|
||||
következhet be.'
|
||||
|
@ -1089,10 +1092,10 @@ Tooltips:
|
|||
videókat szolgáltasson, ahelyett, hogy közvetlen kapcsolatot létesítene a YouTube
|
||||
szolgáltatással. Felülbírálja az API beállítást.
|
||||
Force Local Backend for Legacy Formats: Csak akkor működik, ha az Invidious API
|
||||
az alapértelmezett. Ha engedélyezve van, a helyi API futni fog, és az általa
|
||||
visszaadott örökölt formátumokat fogja használni az Invidious által visszaadottak
|
||||
helyett. Segít, ha az Invidious által visszaküldött videókat nem lehet lejátszani
|
||||
az ország korlátozása miatt.
|
||||
az alapértelmezett. Ha engedélyezve van, a helyi API fut, és az általa visszaadott
|
||||
régi formátumokat használja az Invidious által visszaadottak helyett. Segít,
|
||||
ha az Invidious által visszaküldött videók nem játszódnak le az országos korlátozások
|
||||
miatt.
|
||||
Scroll Playback Rate Over Video Player: Amíg a kurzor a videó felett van, nyomja
|
||||
meg és tartsa lenyomva a Control billentyűt (Mac gépen a Command billentyű),
|
||||
és görgesse az egér görgőjét előre vagy hátra a lejátszási sebesség szabályozásához.
|
||||
|
@ -1171,11 +1174,6 @@ Channels:
|
|||
Unsubscribe: Leiratkozás
|
||||
Unsubscribed: '{channelName} eltávolítva az feliratkozásáiból'
|
||||
Unsubscribe Prompt: Biztosan le szeretne iratkozni a(z) „{channelName}” csatornáról?
|
||||
Age Restricted:
|
||||
Type:
|
||||
Video: Videó
|
||||
Channel: Csatorna
|
||||
This {videoOrPlaylist} is age restricted: A(z) {videoOrPlaylist} korhatáros
|
||||
Downloading failed: Hiba történt a(z) „{videoTitle}” letöltése során
|
||||
Starting download: „{videoTitle}” letöltésének indítása
|
||||
Downloading has completed: A(z) „{videoTitle}” letöltése befejeződött
|
||||
|
@ -1208,3 +1206,7 @@ Trimmed input must be at least N characters long: A vágott bemenetnek legalább
|
|||
hosszúnak kell lennie | A vágott bemenetnek legalább {length} karakter hosszúnak
|
||||
kell lennie
|
||||
Tag already exists: '„{tagName}” címke már létezik'
|
||||
Close Banner: Banner bezárása
|
||||
Age Restricted:
|
||||
This channel is age restricted: Ez a csatorna korhatáros
|
||||
This video is age restricted: Ez a videó korhatáros
|
||||
|
|
|
@ -753,7 +753,7 @@ Up Next: 'Akan Datang'
|
|||
Local API Error (Click to copy): 'API Lokal Galat (Klik untuk menyalin)'
|
||||
Invidious API Error (Click to copy): 'API Invidious Galat (Klik untuk menyalin)'
|
||||
Falling back to Invidious API: 'Kembali ke API Invidious'
|
||||
Falling back to the local API: 'Kembali ke API lokal'
|
||||
Falling back to Local API: 'Kembali ke API lokal'
|
||||
Subscriptions have not yet been implemented: 'Langganan masih belum diterapkan'
|
||||
Loop is now disabled: 'Putar-Ulang sekarang dimatikan'
|
||||
Loop is now enabled: 'Putar-Ulang sekarang diaktifkan'
|
||||
|
|
|
@ -44,6 +44,8 @@ Global:
|
|||
Subscriber Count: 1 áskrifandi | {count} áskrifendur
|
||||
View Count: 1 áhorf | {count} áhorf
|
||||
Watching Count: 1 að horfa | {count} að horfa
|
||||
Input Tags:
|
||||
Length Requirement: Merki þarf að vera a.m.k. {number} stafa langt
|
||||
Version {versionNumber} is now available! Click for more details: 'Útgáfa {versionNumber}
|
||||
er tiltæk! Smelltu til að skoða nánar'
|
||||
Download From Site: 'Sækja af vefsvæði'
|
||||
|
@ -174,6 +176,14 @@ User Playlists:
|
|||
Some videos in the playlist are not loaded yet. Click here to copy anyway.: Sum
|
||||
myndskeið í spilunarlistanum hafa ekki enn hlaðist inn. Smelltu hér til að
|
||||
afrita samt.
|
||||
This playlist is now used for quick bookmark: Þessi spilunarlisti er núna notaður
|
||||
undir flýtibókamerki
|
||||
Quick bookmark disabled: Flýtibókamerki óvirk
|
||||
This playlist is now used for quick bookmark instead of {oldPlaylistName}. Click here to undo: Þessi
|
||||
spilunarlisti er núna notaður undir flýtibókamerki í stað {oldPlaylistName}.
|
||||
Smelltu hér til að afturkalla
|
||||
Reverted to use {oldPlaylistName} for quick bookmark: Snéri aftur í að nota
|
||||
{oldPlaylistName} undir flýtibókamerki
|
||||
AddVideoPrompt:
|
||||
N playlists selected: '{playlistCount} valin'
|
||||
Search in Playlists: Leita í spilunarlistum
|
||||
|
@ -187,6 +197,7 @@ User Playlists:
|
|||
| {videoCount} myndskeiðum bætt við 1 spilunarlista
|
||||
Select a playlist to add your N videos to: Veldu spilunarlista til að bæta myndskeiðinu
|
||||
þínu á | Veldu spilunarlista til að bæta {videoCount}̣ myndskeiðunum þínum á
|
||||
Added {count} Times: Bætt við {count} sinni | Bætt við {count} sinnum
|
||||
CreatePlaylistPrompt:
|
||||
Create: Búa til
|
||||
New Playlist Name: Heiti á nýjum spilunarlista
|
||||
|
@ -209,6 +220,10 @@ User Playlists:
|
|||
Delete Playlist: Eyða spilunarlista
|
||||
Are you sure you want to delete this playlist? This cannot be undone: Ertu viss
|
||||
um að þú viljir eyða þessum spilunarlista? Aðgerðin er ekki afturkallanleg.
|
||||
Add to Favorites: Bæta á {playlistName}
|
||||
Remove from Favorites: Fjarlægja af {playlistName}
|
||||
Enable Quick Bookmark With This Playlist: Virkja flýtibókamerki með þessum spilunarlista
|
||||
Disable Quick Bookmark: Eyða flýtibókamerki
|
||||
History:
|
||||
# On History Page
|
||||
History: 'Áhorf'
|
||||
|
@ -283,6 +298,7 @@ Settings:
|
|||
Catppuccin Mocha: Catppuccin Mocha
|
||||
Pastel Pink: Pastelbleikt
|
||||
Hot Pink: Dimmbleikt
|
||||
Nordic: Norrænt
|
||||
Main Color Theme:
|
||||
Main Color Theme: 'Aðallitur þema'
|
||||
Red: 'Rautt'
|
||||
|
@ -436,6 +452,7 @@ Settings:
|
|||
Hide Channels: Fela myndskeið úr rásum
|
||||
Hide Channels Placeholder: Auðkenni rásar
|
||||
Display Titles Without Excessive Capitalisation: Birta titla án umfram-hástafa
|
||||
og greinarmerkja
|
||||
Sections:
|
||||
Side Bar: Hliðarspjald
|
||||
Channel Page: Rásasíða
|
||||
|
@ -461,6 +478,9 @@ Settings:
|
|||
Hide Channels Already Exists: Auðkenni rásar er þegar til
|
||||
Hide Channels API Error: Villa við að ná í notanda með uppgefið auðkenni. Athugaðu
|
||||
aftur hvort auðkennið ré rétt.
|
||||
Hide Videos and Playlists Containing Text: Fela myndskeið og spilunarlista sem
|
||||
innihalda texta
|
||||
Hide Videos and Playlists Containing Text Placeholder: Orð, orðhluti eða setning
|
||||
Data Settings:
|
||||
Data Settings: 'Stillingar gagna'
|
||||
Select Import Type: 'Veldu tegund innflutnings'
|
||||
|
@ -721,6 +741,7 @@ Channel:
|
|||
Reveal Answers: Birta svör
|
||||
Hide Answers: Fela svör
|
||||
votes: '{votes} atkvæði'
|
||||
Video hidden by FreeTube: Myndskeið falið af FreeTube
|
||||
Shorts:
|
||||
This channel does not currently have any shorts: Þessi rás er í augnablikinu ekki
|
||||
með neinar stuttmyndir
|
||||
|
@ -878,6 +899,7 @@ Video:
|
|||
Pause on Current Video: Setja núverandi myndskeið í bið
|
||||
Unhide Channel: Birta rás
|
||||
Hide Channel: Fela rás
|
||||
More Options: Fleiri valkostir
|
||||
Videos:
|
||||
#& Sort By
|
||||
Sort By:
|
||||
|
@ -1043,7 +1065,7 @@ Local API Error (Click to copy): 'Villa í staðværu API-kerfisviðmóti (smell
|
|||
Invidious API Error (Click to copy): 'Villa í Invidious API-kerfisviðmóti (smella
|
||||
til að afrita)'
|
||||
Falling back to Invidious API: 'Nota til vara Invidious API-kerfisviðmót'
|
||||
Falling back to the local API: 'Nota til vara staðvært API-kerfisviðmót'
|
||||
Falling back to Local API: 'Nota til vara staðvært API-kerfisviðmót'
|
||||
This video is unavailable because of missing formats. This can happen due to country unavailability.: 'Þetta
|
||||
myndskeiðer ekki tiltækt vegna þess að það vantar skráasnið. Þetta getur gest ef
|
||||
þau eru ekki tiltæk í viðkomandi landi.'
|
||||
|
@ -1084,11 +1106,6 @@ Starting download: Byrja að sækja "{videoTitle}"
|
|||
Downloading failed: Vandamál kom upp við að sækja "{videoTitle}"
|
||||
Screenshot Error: Skjámyndataka mistókst. {error}
|
||||
Screenshot Success: Vistaði skjámynd sem "{filePath}"
|
||||
Age Restricted:
|
||||
Type:
|
||||
Channel: Rás
|
||||
Video: Myndskeið
|
||||
This {videoOrPlaylist} is age restricted: Þetta {videoOrPlaylist} er með aldurstakmörkunum
|
||||
New Window: Nýr gluggi
|
||||
Channels:
|
||||
Search bar placeholder: Leita í rásum
|
||||
|
@ -1122,3 +1139,8 @@ Playlist will not pause when current video is finished: Spilunarlisti mun ekki f
|
|||
Go to page: Fara á {page}
|
||||
Channel Hidden: '{channel} bætt við rásasíu'
|
||||
Channel Unhidden: '{channel} fjarlægt úr rásasíu'
|
||||
Close Banner: Loka borða
|
||||
Age Restricted:
|
||||
This video is age restricted: Þetta myndskeið er með aldurstakmörkunum
|
||||
This channel is age restricted: Þessi rás er með aldurstakmörkunum
|
||||
Tag already exists: '"{tagName}" merkið er þegar til staðar'
|
||||
|
|
|
@ -143,6 +143,7 @@ User Playlists:
|
|||
Select a playlist to add your N videos to: Seleziona una playlist a cui aggiungere
|
||||
il tuo video | Seleziona una playlist a cui aggiungere i tuoi {videoCount} video
|
||||
N playlists selected: '{playlistCount} selezionate'
|
||||
Added {count} Times: Aggiunto {count} volta | Aggiunti {count} volte
|
||||
SinglePlaylistView:
|
||||
Toast:
|
||||
There were no videos to remove.: Non c'erano video da rimuovere.
|
||||
|
@ -175,6 +176,7 @@ User Playlists:
|
|||
This playlist is now used for quick bookmark instead of {oldPlaylistName}. Click here to undo: Questa
|
||||
playlist è ora usata per i segnalibri rapidi al posto di {oldPlaylistName}.
|
||||
Fai clic qui per annullare
|
||||
Search for Videos: Cerca video
|
||||
Are you sure you want to delete this playlist? This cannot be undone: Sei sicuro
|
||||
di voler eliminare questa playlist? Questa operazione non può essere annullata.
|
||||
Sort By:
|
||||
|
@ -537,8 +539,8 @@ Settings:
|
|||
Hide Upcoming Premieres: Nascondi le prossime Première
|
||||
Hide Channels: Nascondi i video dai canali
|
||||
Hide Channels Placeholder: ID del canale
|
||||
Display Titles Without Excessive Capitalisation: Visualizza i titoli senza un
|
||||
uso eccessivo di maiuscole
|
||||
Display Titles Without Excessive Capitalisation: Visualizza i titoli senza maiuscole
|
||||
e punteggiatura eccessive
|
||||
Hide Featured Channels: Nascondi i canali in evidenza
|
||||
Hide Channel Playlists: Nascondi le playlist del canale
|
||||
Hide Channel Community: Nascondi la comunità del canale
|
||||
|
@ -914,6 +916,7 @@ Video:
|
|||
Pause on Current Video: Pausa sul video attuale
|
||||
Unhide Channel: Mostra canale
|
||||
Hide Channel: Nascondi canale
|
||||
More Options: Più opzioni
|
||||
Videos:
|
||||
#& Sort By
|
||||
Sort By:
|
||||
|
@ -997,7 +1000,7 @@ Up Next: 'Prossimi video'
|
|||
Local API Error (Click to copy): 'Errore API Locale (Clicca per copiare)'
|
||||
Invidious API Error (Click to copy): 'Errore API Invidious (Clicca per copiare)'
|
||||
Falling back to Invidious API: 'Torno alle API Invidious'
|
||||
Falling back to the local API: 'Torno alle API locali'
|
||||
Falling back to Local API: 'Torno alle API locali'
|
||||
Subscriptions have not yet been implemented: 'Le Iscrizioni non sono ancora state
|
||||
implementate'
|
||||
Loop is now disabled: 'Il loop è ora disabilitato'
|
||||
|
@ -1178,13 +1181,6 @@ Starting download: Avvio del download di "{videoTitle}"
|
|||
Downloading failed: Si è verificato un problema durante il download di "{videoTitle}"
|
||||
Screenshot Success: Screenshot salvato come "{filePath}"
|
||||
Screenshot Error: Screenshot non riuscito. {error}
|
||||
Age Restricted:
|
||||
The currently set default instance is {instance}: Questo {instance} è limitato dall'età
|
||||
Type:
|
||||
Channel: Canale
|
||||
Video: Video
|
||||
This {videoOrPlaylist} is age restricted: Questo {videoOrPlaylist} ha limiti di
|
||||
età
|
||||
New Window: Nuova finestra
|
||||
Channels:
|
||||
Unsubscribed: '{channelName} è stato rimosso dalle tue iscrizioni'
|
||||
|
@ -1221,3 +1217,7 @@ Channel Unhidden: '{channel} rimosso dal filtro canali'
|
|||
Tag already exists: Il tag "{tagName}" esiste già
|
||||
Trimmed input must be at least N characters long: L'input troncato deve essere lungo
|
||||
almeno 1 carattere | L'input troncato deve essere lungo almeno {length} caratteri
|
||||
Age Restricted:
|
||||
This video is age restricted: Questo video è soggetto a limiti di età
|
||||
This channel is age restricted: Questo canale è soggetto a limiti di età
|
||||
Close Banner: Chiudi banner
|
||||
|
|
|
@ -114,6 +114,10 @@ User Playlists:
|
|||
このページは、完全に動作する動画リストではありません。保存またはお気に入りと設定した動画のみが表示されます。操作が完了すると、現在ここにあるすべての動画は「お気に入り」の動画リストに移動します。
|
||||
Search bar placeholder: 動画リスト内の検索
|
||||
Empty Search Message: この再生リストに、検索に一致する動画はありません
|
||||
This playlist currently has no videos.: 存在、この再生リストには動画があっていません。
|
||||
Create New Playlist: 新規再生リストを作られる
|
||||
Sort By:
|
||||
NameAscending: A-Z
|
||||
History:
|
||||
# On History Page
|
||||
History: '履歴'
|
||||
|
@ -276,7 +280,7 @@ Settings:
|
|||
Folder Button: フォルダーの選択
|
||||
Enter Fullscreen on Display Rotate: 横画面時にフルスクリーンにする
|
||||
Skip by Scrolling Over Video Player: 動画プレーヤーでスクロールしてスキップ可能にする
|
||||
Allow DASH AV1 formats: DASH AV1形式を許可する
|
||||
Allow DASH AV1 formats: DASH AV1形式を許可
|
||||
Comment Auto Load:
|
||||
Comment Auto Load: コメント自動読み込み
|
||||
Subscription Settings:
|
||||
|
@ -794,7 +798,7 @@ Up Next: '次の動画'
|
|||
Local API Error (Click to copy): '内部 API エラー(クリックするとコピー)'
|
||||
Invidious API Error (Click to copy): 'Invidious API エラー(クリックするとコピー)'
|
||||
Falling back to Invidious API: '代替の Invidious API に切替'
|
||||
Falling back to the local API: '代替の内部 API に切替'
|
||||
Falling back to Local API: '代替の内部 API に切替'
|
||||
Subscriptions have not yet been implemented: '登録チャンネルは未実装です'
|
||||
Loop is now disabled: 'ループ再生を無効にしました'
|
||||
Loop is now enabled: 'ループ再生を有効にしました'
|
||||
|
@ -850,7 +854,7 @@ The playlist has been reversed: 再生リストを逆順にしました
|
|||
A new blog is now available, {blogTitle}. Click to view more: '新着ブログ公開、{blogTitle}。クリックしてブログを読む'
|
||||
Download From Site: サイトからダウンロード
|
||||
Version {versionNumber} is now available! Click for more details: 最新バージョン {versionNumber}
|
||||
配信中! 詳細はクリックして確認してください
|
||||
配信中!詳細はクリックして確認してください
|
||||
This video is unavailable because of missing formats. This can happen due to country unavailability.: この動画は、動画形式の情報が利用できないため再生できません。再生が許可されていない国で発生します。
|
||||
Tooltips:
|
||||
Subscription Settings:
|
||||
|
@ -866,8 +870,8 @@ Tooltips:
|
|||
Scroll Playback Rate Over Video Player: カーソルが動画上にあるとき、Ctrl キー(Mac では Command キー)を押したまま、マウスホイールを前後にスクロールして再生速度を調整します。Control
|
||||
キー(Mac では Command キー)を押したままマウスを左クリックすると、すぐにデフォルトの再生速度(設定を変更していない場合は 1 x)に戻ります。
|
||||
Skip by Scrolling Over Video Player: スクロール ホイールを使用して、ビデオ、MPV スタイルをスキップします。
|
||||
Allow DASH AV1 formats: DASH H.264形式よりDASH AV1形式の方がきれいに見える可能性があるけど、再生には必要な電力がより多い。全ての動画でDASH
|
||||
AV1を利用できないため、プレイヤーはDASH H.264形式に自動変更する場合があります。
|
||||
Allow DASH AV1 formats: DASH H.264形式よりもDASH AV1形式の方がきれいに見える可能性がありますが、再生にはより多くの処理能力が必要となります。DASH
|
||||
AV1形式を使用できない場合、プレイヤーはDASH H.264形式を自動で使用します。
|
||||
General Settings:
|
||||
Invidious Instance: FreeTube が使用する Invidious API の接続先サーバーです。
|
||||
Preferred API Backend: FreeTube が youtube からデータを取得する方法を選択します。「内部 API」とはアプリから取得する方法です。「Invidious
|
||||
|
@ -913,12 +917,6 @@ Are you sure you want to open this link?: このリンクを開きますか?
|
|||
Starting download: '"{videoTitle}" のダウンロードを開始します'
|
||||
Downloading has completed: '"{videoTitle}" のダウンロードが終了しました'
|
||||
Downloading failed: '"{videoTitle}" のダウンロード中に問題が発生しました'
|
||||
Age Restricted:
|
||||
The currently set default instance is {instance}: '{instance} は 18 歳以上の視聴者向け動画です'
|
||||
Type:
|
||||
Channel: チャンネル
|
||||
Video: 動画
|
||||
This {videoOrPlaylist} is age restricted: この {videoOrPlaylist} は年齢制限があります
|
||||
Channels:
|
||||
Channels: チャンネル
|
||||
Unsubscribe: 登録解除
|
||||
|
@ -947,3 +945,5 @@ Hashtag:
|
|||
This hashtag does not currently have any videos: このハッシュタグには現在動画がありません
|
||||
Playlist will pause when current video is finished: 現在のビデオが終了すると、プレイリストは停止します
|
||||
Playlist will not pause when current video is finished: 現在のビデオが終了しても、プレイリストは停止しません
|
||||
Close Banner: バナーを閉じる
|
||||
Go to page: '{page}に行く'
|
||||
|
|
|
@ -761,7 +761,7 @@ Tooltips:
|
|||
Local API Error (Click to copy): '로컬 API 오류(복사하려면 클릭)'
|
||||
Invidious API Error (Click to copy): 'Invidious API 오류(복사하려면 클릭)'
|
||||
Falling back to Invidious API: 'Invidious API로 대체'
|
||||
Falling back to the local API: '로컬 API로 대체'
|
||||
Falling back to Local API: '로컬 API로 대체'
|
||||
This video is unavailable because of missing formats. This can happen due to country unavailability.: '이
|
||||
동영상은 형식이 누락되어 사용할 수 없습니다. 이는 국가를 사용할 수 없기 때문에 발생할 수 있습니다.'
|
||||
Subscriptions have not yet been implemented: '구독이 아직 구현되지 않았습니다'
|
||||
|
@ -804,11 +804,6 @@ Channels:
|
|||
Unsubscribe Prompt: '"{channelName}"에서 구독을 취소하시겠습니까?'
|
||||
Count: '{number} 채널이 발견되었습니다.'
|
||||
Unsubscribed: '{channelName} 구독에서 제거되었습니다'
|
||||
Age Restricted:
|
||||
Type:
|
||||
Video: 비디오
|
||||
Channel: 채널
|
||||
The currently set default instance is {instance}: 이 {instance}는 연령 제한입니다
|
||||
Downloading has completed: '"{videoTitle}" 다운로드가 완료되었습니다'
|
||||
Starting download: '"{videoTitle}" 다운로드를 시작하는 중'
|
||||
Downloading failed: '"{videoTitle}"를 다운로드하는 동안 문제가 발생했습니다'
|
||||
|
|
|
@ -41,6 +41,9 @@ Global:
|
|||
Counts:
|
||||
Subscriber Count: 1 prenumeruoti | {count} prenumeratorių
|
||||
Channel Count: 1 kanalas | {count} kanalai
|
||||
Video Count: 1 vaizdo įrašas | {count} vaizdo įrašai
|
||||
View Count: 1 peržiūrėti | {count} peržiūrų
|
||||
Watching Count: 1 žiūri | {count} žiūri
|
||||
Version {versionNumber} is now available! Click for more details: 'Versija {versionNumber}
|
||||
jau prieinama! Spustelėkite, jei norite gauti daugiau informacijos'
|
||||
Download From Site: 'Atsisiųsti iš svetainės'
|
||||
|
@ -842,7 +845,7 @@ Local API Error (Click to copy): 'Vietinė API klaida (spustelėkite, jei norite
|
|||
Invidious API Error (Click to copy): 'Invidious API klaida (spustelėkite, jei norite
|
||||
kopijuoti)'
|
||||
Falling back to Invidious API: 'Grįžtama prie Invidious API'
|
||||
Falling back to the local API: 'Grįžtama prie vietinio API'
|
||||
Falling back to Local API: 'Grįžtama prie vietinio API'
|
||||
This video is unavailable because of missing formats. This can happen due to country unavailability.: 'Šis
|
||||
vaizdo įrašas nepasiekiamas, nes trūksta formatų. Tai gali nutikti dėl to, kad šalis
|
||||
yra nepasiekiama.'
|
||||
|
@ -887,12 +890,6 @@ Channels:
|
|||
Unsubscribe: Atšaukti prenumeratą
|
||||
Unsubscribed: '{channelName} buvo pašalintas iš jūsų prenumeratų'
|
||||
Unsubscribe Prompt: Ar tikrai norite atšaukti {channelName} prenumeratą?
|
||||
Age Restricted:
|
||||
Type:
|
||||
Channel: Kanalas
|
||||
Video: Vaizdo įrašas
|
||||
This {videoOrPlaylist} is age restricted: Šis {videoOrPlaylist} ribojamas pagal
|
||||
amžių
|
||||
Downloading has completed: „{videoTitle}“ atsisiuntimas baigtas
|
||||
Starting download: Pradedamas „{videoTitle}“ atsisiuntimas
|
||||
Downloading failed: Atsisiunčiant „{videoTitle}“ kilo problema
|
||||
|
@ -910,3 +907,4 @@ Clipboard:
|
|||
be saugaus ryšio
|
||||
Preferences: Nuostatos
|
||||
Go to page: Eiti į {page}
|
||||
Close Banner: Uždaryti baneris
|
||||
|
|
|
@ -828,7 +828,7 @@ Tooltips:
|
|||
Local API Error (Click to copy): ''
|
||||
Invidious API Error (Click to copy): ''
|
||||
Falling back to Invidious API: ''
|
||||
Falling back to the local API: ''
|
||||
Falling back to Local API: ''
|
||||
This video is unavailable because of missing formats. This can happen due to country unavailability.: ''
|
||||
Subscriptions have not yet been implemented: ''
|
||||
Unknown YouTube url type, cannot be opened in app: ''
|
||||
|
@ -848,11 +848,6 @@ Canceled next video autoplay: ''
|
|||
Default Invidious instance has been set to {instance}: ''
|
||||
Default Invidious instance has been cleared: ''
|
||||
'The playlist has ended. Enable loop to continue playing': ''
|
||||
Age Restricted:
|
||||
This {videoOrPlaylist} is age restricted: ''
|
||||
Type:
|
||||
Channel: ''
|
||||
Video: ''
|
||||
External link opening has been disabled in the general settings: ''
|
||||
Downloading has completed: ''
|
||||
Starting download: ''
|
||||
|
|
|
@ -784,7 +784,7 @@ Up Next: 'Neste'
|
|||
Local API Error (Click to copy): 'Lokal API-feil (Klikk her for å kopiere)'
|
||||
Invidious API Error (Click to copy): 'Invidious-API-feil (Klikk her for å kopiere)'
|
||||
Falling back to Invidious API: 'Faller tilbake til Invidious-API-et'
|
||||
Falling back to the local API: 'Faller tilbake til det lokale API-et'
|
||||
Falling back to Local API: 'Faller tilbake til det lokale API-et'
|
||||
Subscriptions have not yet been implemented: 'Abonnement har ikke blitt implementert
|
||||
enda'
|
||||
Loop is now disabled: 'Gjenta er nå deaktivert'
|
||||
|
@ -947,11 +947,6 @@ Channels:
|
|||
Unsubscribe: Opphev abonnement
|
||||
Unsubscribed: '{channelName} ble fjernet fra dine abonnementer'
|
||||
Unsubscribe Prompt: Opphev abonnement på «{channelName}»?
|
||||
Age Restricted:
|
||||
Type:
|
||||
Channel: Kanal
|
||||
Video: Video
|
||||
This {videoOrPlaylist} is age restricted: Denne {videoOrPlaylist} er aldersbegrenset
|
||||
Chapters:
|
||||
Chapters: Kapitler
|
||||
'Chapters list visible, current chapter: {chapterName}': 'Kapittelliste synlig.
|
||||
|
|
|
@ -45,6 +45,8 @@ Global:
|
|||
Watching Count: 1 aan het kijken | {count} aan het kijken
|
||||
Channel Count: 1 kanaal | {count} kanalen
|
||||
Community: Gemeenschap
|
||||
Input Tags:
|
||||
Length Requirement: Tag moet minstens {number} tekens lang zijn
|
||||
Search / Go to URL: 'Zoeken / Ga naar URL'
|
||||
# In Filter Button
|
||||
Search Filters:
|
||||
|
@ -143,10 +145,28 @@ User Playlists:
|
|||
CreatePlaylistPrompt:
|
||||
Create: Aanmaken
|
||||
New Playlist Name: Naam voor nieuwe afspeellijst
|
||||
Toast:
|
||||
Playlist {playlistName} has been successfully created.: Afspeellijst ‘{playlistName}’
|
||||
is succesvol aangemaakt.
|
||||
There was an issue with creating the playlist.: Er is een probleem opgetreden
|
||||
bij het maken van de afspeellijst.
|
||||
There is already a playlist with this name. Please pick a different name.: Er
|
||||
is al een afspeellijst met deze naam. Kies een andere naam.
|
||||
AddVideoPrompt:
|
||||
Save: Opslaan
|
||||
N playlists selected: '{playlistCount} geselecteerd'
|
||||
Search in Playlists: Zoeken in afspeellijsten
|
||||
Toast:
|
||||
You haven't selected any playlist yet.: U heeft nog geen afspeellijst geselecteerd.
|
||||
"{videoCount} video(s) added to 1 playlist": 1 video toegevoegd aan een afspeellijst
|
||||
| {videoCount} video's toegevoegd aan een afspeellijst
|
||||
"{videoCount} video(s) added to {playlistCount} playlists": 1 video toegevoegd
|
||||
aan {playlistCount} afspeellijsten | {videoCount} video's toegevoegd aan
|
||||
{playlistCount} afspeellijsten
|
||||
Select a playlist to add your N videos to: Selecteer een afspeellijst om uw video
|
||||
aan toe te voegen | Selecteer een afspeellijst om uw {videoCount} video's aan
|
||||
toe te voegen
|
||||
Added {count} Times: '{count} keer toegevoegd | {count} keer toegevoegd'
|
||||
Save Changes: Wijzigingen opslaan
|
||||
Copy Playlist: Afspeellijst kopiëren
|
||||
Create New Playlist: Nieuwe afspeellijst aanmaken
|
||||
|
@ -164,6 +184,41 @@ User Playlists:
|
|||
Video has been removed: Video is verwijderd
|
||||
Quick bookmark disabled: Snelle bladwijzers uitgeschakeld
|
||||
Playlist has been updated.: De afspeellijst is bijgewerkt.
|
||||
This video cannot be moved up.: Deze video kan niet omhoog verplaatst worden.
|
||||
This video cannot be moved down.: Deze video kan niet omlaag verplaatst worden.
|
||||
Playlist {playlistName} has been deleted.: Afspeellijst ‘{playlistName}’ is
|
||||
verwijderd.
|
||||
This playlist does not exist: Deze afspeellijst bestaat niet
|
||||
There were no videos to remove.: Er zijn geen video's om te verwijderen.
|
||||
There was a problem with removing this video: Er is een probleem opgetreden
|
||||
bij het verwijderen van deze video
|
||||
This playlist is now used for quick bookmark: Deze afspeellijst wordt nu gebruikt
|
||||
voor snelle bladwijzers
|
||||
This playlist is now used for quick bookmark instead of {oldPlaylistName}. Click here to undo: Deze
|
||||
afspeellijst wordt nu gebruikt voor snelle bladwijzers in plaats van {oldPlaylistName}.
|
||||
Druk hier om ongedaan te maken
|
||||
Reverted to use {oldPlaylistName} for quick bookmark: Teruggekeerd naar het
|
||||
gebruik van {oldPlaylistName} voor snelle bladwijzers
|
||||
Some videos in the playlist are not loaded yet. Click here to copy anyway.: Sommige
|
||||
video's in de afspeellijst zijn nog niet geladen. Druk hier om toch te kopiëren.
|
||||
"{videoCount} video(s) have been removed": 1 video verwijderd | {videoCount}
|
||||
video's verwijderd
|
||||
This playlist is protected and cannot be removed.: Deze afspeellijst is beschermd
|
||||
en kan niet worden verwijderd.
|
||||
Playlist name cannot be empty. Please input a name.: De naam van de afspeellijst
|
||||
mag niet leeg zijn. Voer een naam in.
|
||||
There was an issue with updating this playlist.: Er is een probleem opgetreden
|
||||
bij het bijwerken van deze afspeellijst.
|
||||
You have no playlists. Click on the create new playlist button to create a new one.: U
|
||||
heeft geen afspeellijsten. Druk op de knop om er één aan te maken.
|
||||
This playlist currently has no videos.: Deze afspeellijst bevat geen video's.
|
||||
Enable Quick Bookmark With This Playlist: Snelle bladwijzers inschakelen voor deze
|
||||
afspeellijst
|
||||
Are you sure you want to remove all watched videos from this playlist? This cannot be undone: Weet
|
||||
u zeker dat u alle bekeken video's uit deze afspeellijst wilt verwijderen? Dit
|
||||
kan niet ongedaan gemaakt worden.
|
||||
Are you sure you want to delete this playlist? This cannot be undone: Weet u zeker
|
||||
dat u deze afspeellijst wilt verwijderen? Dit kan niet ongedaan gemaakt worden.
|
||||
History:
|
||||
# On History Page
|
||||
History: 'Geschiedenis'
|
||||
|
@ -358,12 +413,17 @@ Settings:
|
|||
Save Watched Videos With Last Viewed Playlist: Houd bekeken video's bij met de
|
||||
afspeellijst ‘Laatst bekeken’
|
||||
Remove All Playlists: Alle afspeellijsten verwijderen
|
||||
All playlists have been removed: Alle afspeellijsten zijn verwijderd
|
||||
Are you sure you want to remove all your playlists?: Weet u zeker dat u al uw
|
||||
afspeellijsten wilt verwijderen?
|
||||
Subscription Settings:
|
||||
Subscription Settings: 'Abonnementinstellingen'
|
||||
Hide Videos on Watch: 'Bekeken video''s verbergen'
|
||||
Manage Subscriptions: 'Abonnementen beheren'
|
||||
Fetch Feeds from RSS: Verzamel feeds via RSS
|
||||
Fetch Automatically: Haal feed automatisch op
|
||||
Only Show Latest Video for Each Channel: Alleen nieuwste video voor elk kanaal
|
||||
tonen
|
||||
Advanced Settings:
|
||||
Advanced Settings: 'Geavanceerde Instellingen'
|
||||
Enable Debug Mode (Prints data to the console): 'Schakel Debug Modus in (Print
|
||||
|
@ -440,6 +500,14 @@ Settings:
|
|||
Subscription File: Abonnementenbestand
|
||||
History File: Geschiedenisbestand
|
||||
Playlist File: Afspeellijstbestand
|
||||
Export Playlists For Older FreeTube Versions:
|
||||
Label: Afspeellijsten exporteren voor oudere FreeTube-versies
|
||||
Tooltip: "Deze optie exporteert video's van alle afspeellijsten naar één afspeellijst
|
||||
met de naam ‘Favorieten’.\nVideo's exporteren en importeren in afspeellijsten
|
||||
voor een oudere versie van FreeTube:\n1. Exporteer uw afspeellijsten met
|
||||
deze optie ingeschakeld.\n2. Verwijder al uw bestaande afspeellijsten met
|
||||
de optie ‘Alle afspeellijsten verwijderen’ onder ‘Privacyinstellingen’.\n
|
||||
3. Start de oudere versie van FreeTube en importeer de geëxporteerde afspeellijsten."
|
||||
Distraction Free Settings:
|
||||
Hide Live Chat: Livechat verbergen
|
||||
Hide Popular Videos: Populaire video's verbergen
|
||||
|
@ -456,8 +524,8 @@ Settings:
|
|||
Hide Video Description: Video-omschrijving verbergen
|
||||
Hide Comments: Opmerkingen verbergen
|
||||
Hide Live Streams: Verberg rechtstreekse uitzendingen
|
||||
Display Titles Without Excessive Capitalisation: Toon titels zonder overmatig
|
||||
hoofdlettergebruik
|
||||
Display Titles Without Excessive Capitalisation: Titels tonen zonder overmatig
|
||||
hoofdlettergebruik en interpunctie
|
||||
Sections:
|
||||
Side Bar: Zijbalk
|
||||
General: Algemeen
|
||||
|
@ -481,6 +549,16 @@ Settings:
|
|||
Hide Profile Pictures in Comments: Profielfoto's in opmerkingen verbergen
|
||||
Hide Subscriptions Community: Abonnementgemeenschappen verbergen
|
||||
Hide Channels Already Exists: Kanaal ID bestaat reeds
|
||||
Hide Channels Invalid: Opgegeven kanaal-id is ongeldig
|
||||
Hide Videos and Playlists Containing Text Placeholder: Woord, woordfragment of
|
||||
zin
|
||||
Hide Videos and Playlists Containing Text: Video's en afspeellijsten die tekst
|
||||
bevatten verbergen
|
||||
Hide Channels API Error: Fout bij het ophalen van de gebruiker met de opgegeven
|
||||
ID. Controleer nogmaals of de ID correct is.
|
||||
Hide Channels Disabled Message: Sommige kanalen zijn geblokkeerd met behulp van
|
||||
ID en zijn niet verwerkt. De functie is geblokkeerd terwijl deze ID's worden
|
||||
bijgewerkt
|
||||
The app needs to restart for changes to take effect. Restart and apply change?: De
|
||||
app moet opnieuw worden gestart om veranderingen aan te brengen. Wilt u de app
|
||||
opnieuw starten en veranderingen toepassen?
|
||||
|
@ -515,6 +593,9 @@ Settings:
|
|||
Do Nothing: Niets doen
|
||||
Category Color: Categoriekleur
|
||||
UseDeArrowTitles: DeArrow-videotitels gebruiken
|
||||
UseDeArrowThumbnails: DeArrow gebruiken voor miniaturen
|
||||
'DeArrow Thumbnail Generator API Url (Default is https://dearrow-thumb.ajay.app)': API-URL
|
||||
van DeArrow-miniatuurgenerator (standaard is https://dearrow-thumb.ajay.app)
|
||||
External Player Settings:
|
||||
Custom External Player Arguments: Aangepaste argumenten voor externe videospeler
|
||||
Custom External Player Executable: Uitvoerbaar bestand van externe videospeler
|
||||
|
@ -668,6 +749,7 @@ Channel:
|
|||
votes: '{votes} stemmen'
|
||||
This channel currently does not have any posts: Dit kanaal heeft momenteel geen
|
||||
posts
|
||||
Video hidden by FreeTube: Video verborgen door FreeTube
|
||||
Releases:
|
||||
Releases: Uitgaven
|
||||
This channel does not currently have any releases: Dit kanaal heeft momenteel
|
||||
|
@ -821,6 +903,7 @@ Video:
|
|||
is niet beschikbaar voor deze stream. Mogelijk is deze uitgeschakeld door de uploader.
|
||||
Hide Channel: Kanaal verbergen
|
||||
Unhide Channel: Kanaal tonen
|
||||
More Options: Meer opties
|
||||
Videos:
|
||||
#& Sort By
|
||||
Sort By:
|
||||
|
@ -904,7 +987,7 @@ Up Next: 'Volgende'
|
|||
Local API Error (Click to copy): 'Fout in lokale API (Klik om te kopiëren)'
|
||||
Invidious API Error (Click to copy): 'Fout in API van Invidious (Klik op te kopiëren)'
|
||||
Falling back to Invidious API: 'Terugvallen op Invidious API'
|
||||
Falling back to the local API: 'Terugvallen op lokale API'
|
||||
Falling back to Local API: 'Terugvallen op lokale API'
|
||||
Subscriptions have not yet been implemented: 'Abonnementen zijn nog niet geïmplementeerd'
|
||||
Loop is now disabled: 'Herhalen is nu uitgeschakeld'
|
||||
Loop is now enabled: 'Herhalen is nu ingeschakeld'
|
||||
|
@ -983,10 +1066,10 @@ Tooltips:
|
|||
Legacy gaat niet hoger dan 720p maar gebruikt minder bandbreedte. Audio zal
|
||||
alleen het geluid streamen.
|
||||
Force Local Backend for Legacy Formats: Dit zal alleen werken wanneer Invidious
|
||||
is geselecteerd als de standaard API. Wanneer ingeschakeld zal de lokale API
|
||||
legacy video indelingen gebruiken in plaats van de video indeling die worden
|
||||
teruggegeven door Invidious. Dit kan helpen wanneer een video die wordt gestreamed
|
||||
via Invidious niet afspeelt in verband met regio restricties.
|
||||
is geselecteerd als de standaard-API. Wanneer ingeschakeld zal de lokale API
|
||||
legacy videoindelingen gebruiken in plaats van de videoindeling die worden
|
||||
teruggegeven door Invidious. Dit kan helpen wanneer een video die wordt gestreamed
|
||||
via Invidious niet afspeelt in verband met regiorestricties.
|
||||
Proxy Videos Through Invidious: FreeTube zal verbinden met Invidious en daar de
|
||||
video's downloaden in de plaats van de video's rechtstreeks bij YouTube vandaan
|
||||
te halen. Dit overschrijft de ingestelde API voorkeur.
|
||||
|
@ -1041,16 +1124,23 @@ Tooltips:
|
|||
in de gekozen externe videospeler kan worden geopend. Let op: Invidious-instellingen
|
||||
beïnvloeden externe videospelers niet.'
|
||||
DefaultCustomArgumentsTemplate: "(standaard: ‘{defaultCustomArguments}’)"
|
||||
Ignore Default Arguments: Stuurt geen standaardargumenten naar de externe speler,
|
||||
afgezien van de video-URL (bijvoorbeeld afspeelsnelheid, afspeellijst-URL,
|
||||
enz.). Aangepaste argumenten worden nog steeds doorgegeven.
|
||||
Distraction Free Settings:
|
||||
Hide Channels: Voer een kanaalnaam of kanaal-ID in om alle video's, afspeellijsten
|
||||
en het kanaal zelf te verbergen zodat ze niet worden weergegeven in zoeken,
|
||||
trending, populairst en aanbevolen. De ingevoerde kanaalnaam moet volledig overeenkomen
|
||||
en is hoofdlettergevoelig.
|
||||
Hide Channels: Voer een kanaal-ID in om alle video's, afspeellijsten en het kanaal
|
||||
zelf te verbergen zodat ze niet worden weergegeven in zoeken, trending, populairst
|
||||
en aanbevolen. De ingevoerde kanaal-ID moet volledig overeenkomen en is hoofdlettergevoelig.
|
||||
Hide Subscriptions Live: Deze instelling wordt overschreven door de app-brede
|
||||
instelling ‘{appWideSetting}’, in het gedeelte ‘{subsection}’ van ‘{settingsSection}’
|
||||
Hide Videos and Playlists Containing Text: Voer een woord, woordfragment of woordgroep
|
||||
in (niet hoofdlettergevoelig) om alle video's en afspeellijsten waarvan de
|
||||
oorspronkelijke titel dit bevat, in heel FreeTube te verbergen, met uitzondering
|
||||
van alleen geschiedenis, uw afspeellijsten en video's in afspeellijsten.
|
||||
SponsorBlock Settings:
|
||||
UseDeArrowTitles: Vervangt videotitels met door gebruikers ingediende titels van
|
||||
DeArrow.
|
||||
UseDeArrowThumbnails: Videominiaturen vervangen met miniaturen van DeArrow.
|
||||
Experimental Settings:
|
||||
Replace HTTP Cache: Schakelt de schijfgebaseerde HTTP-cache van Electron uit en
|
||||
schakelt een aangepaste afbeeldingscache in het geheugen in. Zal leiden tot
|
||||
|
@ -1079,12 +1169,6 @@ Downloading failed: Probleem bij download van "{videoTitle}"
|
|||
Download folder does not exist: De download map "$" bestaat niet. Valt terug op "vraag
|
||||
map" modus.
|
||||
New Window: Nieuw venster
|
||||
Age Restricted:
|
||||
The currently set default instance is {instance}: Deze {instance} is leeftijdsbeperkt
|
||||
Type:
|
||||
Channel: Kanaal
|
||||
Video: Video
|
||||
This {videoOrPlaylist} is age restricted: Deze {videoOrPlaylist} heeft een leeftijdsbeperking
|
||||
Screenshot Success: Schermafbeelding opgeslagen als "{filePath}"
|
||||
Channels:
|
||||
Title: Kanaallijst
|
||||
|
@ -1117,3 +1201,12 @@ Playlist will pause when current video is finished: Afspeellijst zal pauzeren wa
|
|||
Playlist will not pause when current video is finished: Afspeellijst zal niet pauzeren
|
||||
wanneer de huidige video is afgelopen
|
||||
Go to page: Ga naar {page}
|
||||
Tag already exists: Tag ‘{tagName}’ bestaat al
|
||||
Channel Unhidden: ‘{channel}’ verwijderd uit kanaalfilter
|
||||
Channel Hidden: ‘{channel}’ toegevoegd aan kanaalfilter
|
||||
Close Banner: Banier sluiten
|
||||
Age Restricted:
|
||||
This channel is age restricted: Dit kanaal heeft een leeftijdsbeperking
|
||||
This video is age restricted: Deze video heeft een leeftijdsbeperking
|
||||
Trimmed input must be at least N characters long: Bijgesneden invoer moet minimaal
|
||||
1 teken lang zijn | Bijgesneden invoer moet minimaal {length} tekens lang zijn
|
||||
|
|
|
@ -770,9 +770,9 @@ Tooltips:
|
|||
Invidious Instance: 'Invidious-førekomsten som FreeTube vil kople til for API-kall.'
|
||||
Region for Trending: 'Trendsregionen lar deg enkelt velje kva lands populære videoar
|
||||
du ynskjer å vise.'
|
||||
External Link Handling: "Vel kva FreeTube skal gjer, når ein trykker på ei lenke,\
|
||||
\ som ikkje kan bli opna av FreeTube. \nFreeTube vil vanlegvis opne lenka i\
|
||||
\ din standardnettlesar.\n"
|
||||
External Link Handling: "Vel kva FreeTube skal gjer, når ein trykker på ei lenke,
|
||||
som ikkje kan bli opna av FreeTube. \nFreeTube vil vanlegvis opne lenka i din
|
||||
standardnettlesar.\n"
|
||||
Player Settings:
|
||||
Force Local Backend for Legacy Formats: 'Fungerer berre med Invidious-API-et som
|
||||
standard. Når det er påslått, vil det lokale API-et køyre og bruke dei utdaterte
|
||||
|
@ -825,7 +825,7 @@ Tooltips:
|
|||
Local API Error (Click to copy): 'Lokal API-feil (Klikk her for å kopiere)'
|
||||
Invidious API Error (Click to copy): 'Invidious-API-feil (Klikk her for å kopiere)'
|
||||
Falling back to Invidious API: 'Faller tilbake til Invidious-API-et'
|
||||
Falling back to the local API: 'Faller tilbake til det lokale API-et'
|
||||
Falling back to Local API: 'Faller tilbake til det lokale API-et'
|
||||
This video is unavailable because of missing formats. This can happen due to country unavailability.: 'Denne
|
||||
videoen er utilgjengeleg grunna manglande format. Dette kan skuldast tilgangsavgrensingar
|
||||
i ditt land.'
|
||||
|
@ -868,11 +868,6 @@ Channels:
|
|||
Unsubscribe Prompt: Er du sikker på at du vil avslutte abonnementet på "{channelName}"?
|
||||
Unsubscribe: Opphev abonnement
|
||||
Screenshot Success: Lagra skjermbilete som "{filePath}"
|
||||
Age Restricted:
|
||||
This {videoOrPlaylist} is age restricted: Denne {videoOrPlaylist} er alderavgrensa
|
||||
Type:
|
||||
Video: Video
|
||||
Channel: Kanal
|
||||
Screenshot Error: Skjermbilete feila. {error}
|
||||
Downloading has completed: Nedlastinga av "{videoTitle}" er fullført
|
||||
Ok: OK
|
||||
|
|
|
@ -109,4 +109,3 @@ Channel:
|
|||
Video:
|
||||
External Player: {}
|
||||
Tooltips: {}
|
||||
Age Restricted: {}
|
||||
|
|
|
@ -143,6 +143,7 @@ User Playlists:
|
|||
dodać swój film | Wybierz playlistę, do której chcesz dodać swoje {videoCount}
|
||||
film(y/ów)
|
||||
N playlists selected: Zaznaczono {playlistCount}
|
||||
Added {count} Times: Dodano {count} raz | Dodano {count} razy
|
||||
SinglePlaylistView:
|
||||
Toast:
|
||||
There were no videos to remove.: Nie było żadnych filmów do usunięcia.
|
||||
|
@ -534,8 +535,8 @@ Settings:
|
|||
Hide Upcoming Premieres: Schowaj nadchodzące premiery
|
||||
Hide Channels: Schowaj filmy z kanałów
|
||||
Hide Channels Placeholder: ID kanału
|
||||
Display Titles Without Excessive Capitalisation: Wyświetlaj tytuły bez nadmiernych
|
||||
wielkich liter
|
||||
Display Titles Without Excessive Capitalisation: Wyświetlaj tytuły nie nadużywając
|
||||
wielkich liter i interpunkcji
|
||||
Hide Channel Community: Schowaj społeczność kanału
|
||||
Hide Channel Shorts: Schowaj filmy Short kanału
|
||||
Hide Featured Channels: Schowaj polecane kanały
|
||||
|
@ -917,6 +918,7 @@ Video:
|
|||
Pause on Current Video: Zatrzymaj po tym filmie
|
||||
Unhide Channel: Pokaż kanał
|
||||
Hide Channel: Ukryj kanał
|
||||
More Options: Więcej opcji
|
||||
Videos:
|
||||
#& Sort By
|
||||
Sort By:
|
||||
|
@ -999,7 +1001,7 @@ Up Next: 'Następne'
|
|||
Local API Error (Click to copy): 'Błąd lokalnego API (kliknij by skopiować)'
|
||||
Invidious API Error (Click to copy): 'Błąd API Invidious (kliknij by skopiować)'
|
||||
Falling back to Invidious API: 'Wycofywanie do API Invidious'
|
||||
Falling back to the local API: 'Wycofywanie do lokalnego API'
|
||||
Falling back to Local API: 'Wycofywanie do lokalnego API'
|
||||
Subscriptions have not yet been implemented: 'Subskrypcje nie zostały jeszcze wprowadzone'
|
||||
Loop is now disabled: 'Zapętlenie jest teraz wyłączone'
|
||||
Loop is now enabled: 'Zapętlenie jest teraz włączone'
|
||||
|
@ -1181,13 +1183,6 @@ Download folder does not exist: Katalog pobierania "$" nie istnieje. Przełączo
|
|||
tryb "pytaj o folder".
|
||||
Screenshot Error: Wykonanie zrzutu nie powiodło się. {error}
|
||||
Screenshot Success: Zapisano zrzut ekranu jako „{filePath}”
|
||||
Age Restricted:
|
||||
Type:
|
||||
Channel: kanał
|
||||
Video: film
|
||||
The currently set default instance is {instance}: Ten {instance} ma ograniczenie
|
||||
wiekowe
|
||||
This {videoOrPlaylist} is age restricted: '{videoOrPlaylist} ma ograniczenie wiekowe'
|
||||
New Window: Nowe okno
|
||||
Channels:
|
||||
Title: Lista kanałów
|
||||
|
@ -1224,3 +1219,7 @@ Channel Unhidden: '{channel} usunięty z filtra kanału'
|
|||
Tag already exists: Tag „{tagName}” już istnieje
|
||||
Trimmed input must be at least N characters long: Przycięte wyrażenie musi mieć przynajmniej
|
||||
1 znak | Przycięte wyrażenie musi mieć przynajmniej {length} znaki/ów
|
||||
Age Restricted:
|
||||
This video is age restricted: Ten film ma ograniczenie wiekowe
|
||||
This channel is age restricted: Ten kanał ma ograniczenie wiekowe
|
||||
Close Banner: Zamknij Baner
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1035,7 +1035,7 @@ Tooltips:
|
|||
Local API Error (Click to copy): Erro na API local (clique para copiar)
|
||||
Invidious API Error (Click to copy): Erro na API Invidious (clique para copiar)
|
||||
Falling back to Invidious API: Ocorreu um erro e vamos usar a API Invidious
|
||||
Falling back to the local API: Ocorreu um erro e vamos usar a API local
|
||||
Falling back to Local API: Ocorreu um erro e vamos usar a API local
|
||||
This video is unavailable because of missing formats. This can happen due to country unavailability.: Este
|
||||
vídeo não está disponível porque faltam formatos. Isto pode acontecer devido à indisponibilidade
|
||||
no seu país.
|
||||
|
@ -1083,13 +1083,6 @@ Channels:
|
|||
Unsubscribe: Anular subscrição
|
||||
Unsubscribed: '{channelName} foi removido das suas subscrições'
|
||||
Unsubscribe Prompt: Tem a certeza de que pretende anular a subscrição de "{channelName}"?
|
||||
Age Restricted:
|
||||
The currently set default instance is {instance}: Este {instance} tem restrição
|
||||
de idade
|
||||
Type:
|
||||
Channel: Canal
|
||||
Video: Vídeo
|
||||
This {videoOrPlaylist} is age restricted: '{videoOrPlaylist} tem restrição de idade'
|
||||
Downloading has completed: '"{videoTitle}" foi descarregado'
|
||||
Starting download: A descarregar "{videoTitle}"
|
||||
Downloading failed: Ocorreu um erro ao descarregar "{videoTitle}"
|
||||
|
|
|
@ -1037,7 +1037,7 @@ Up Next: 'A seguir'
|
|||
Local API Error (Click to copy): 'Erro na API local (clique para copiar)'
|
||||
Invidious API Error (Click to copy): 'Erro na API Invidious (clique para copiar)'
|
||||
Falling back to Invidious API: 'Ocorreu um erro e vamos usar a API Invidious'
|
||||
Falling back to the local API: 'Ocorreu um erro e vamos usar a API local'
|
||||
Falling back to Local API: 'Ocorreu um erro e vamos usar a API local'
|
||||
Subscriptions have not yet been implemented: 'As subscrições ainda não foram implementadas'
|
||||
Loop is now disabled: 'Repetição desativada'
|
||||
Loop is now enabled: 'Repetição ativada'
|
||||
|
@ -1153,13 +1153,6 @@ Downloading failed: Ocorreu um erro ao descarregar "{videoTitle}"
|
|||
Downloading has completed: '"{videoTitle}" foi descarregado'
|
||||
Screenshot Success: Captura de ecrã guardada como "{filePath}"
|
||||
Screenshot Error: Erro ao capturar o ecrã. {error}
|
||||
Age Restricted:
|
||||
The currently set default instance is {instance}: Este {instance} tem restrição
|
||||
de idade
|
||||
Type:
|
||||
Channel: Canal
|
||||
Video: Vídeo
|
||||
This {videoOrPlaylist} is age restricted: '{videoOrPlaylist} tem restrição de idade'
|
||||
New Window: Nova janela
|
||||
Channels:
|
||||
Count: '{number} canais encontrados.'
|
||||
|
|
|
@ -42,6 +42,8 @@ Global:
|
|||
View Count: 1 vizionare | {count} vizionări
|
||||
Channel Count: 1 canal | {count} canale
|
||||
Watching Count: 1 se uită | {count} se uită
|
||||
Input Tags:
|
||||
Length Requirement: Tag-ul trebuie să aibă cel puțin {number} caractere
|
||||
Version {versionNumber} is now available! Click for more details: 'Versiunea {versionNumber}
|
||||
este acum disponibilă! Click pentru mai multe detalii'
|
||||
Download From Site: 'Descărcați de pe site'
|
||||
|
@ -108,6 +110,8 @@ Subscriptions:
|
|||
All Subscription Tabs Hidden: Toate filele de abonament sunt ascunse. Pentru a vedea
|
||||
conținutul aici, vă rugăm să afișați unele file din secțiunea "{subsection}” din
|
||||
"{settingsSection}”.
|
||||
Empty Posts: Canalele tale abonate nu au momentan nicio postare.
|
||||
Load More Posts: Încarcă mai multe postări
|
||||
Trending:
|
||||
Trending: 'Tendințe'
|
||||
Trending Tabs: File în tendințe
|
||||
|
@ -853,7 +857,7 @@ Up Next: 'În continuare'
|
|||
Local API Error (Click to copy): 'Eroare API locală (Faceți clic pentru a copia)'
|
||||
Invidious API Error (Click to copy): 'Eroare API Invidious (Faceți clic pentru a copia)'
|
||||
Falling back to Invidious API: 'Revenine la Invidious API'
|
||||
Falling back to the local API: 'Revenire la API-ul local'
|
||||
Falling back to Local API: 'Revenire la API-ul local'
|
||||
This video is unavailable because of missing formats. This can happen due to country unavailability.: 'Acest
|
||||
videoclip nu este disponibil din cauza lipsei de formate. Acest lucru se poate întâmpla
|
||||
din cauza indisponibilității țării.'
|
||||
|
@ -972,14 +976,6 @@ Starting download: Se începe descărcarea a "{videoTitle}"
|
|||
Downloading failed: A existat o problemă la descărcarea "{videoTitle}"
|
||||
Downloading has completed: '"{videoTitle}" s-a terminat de descărcat'
|
||||
New Window: Fereastră nouă
|
||||
Age Restricted:
|
||||
The currently set default instance is {instance}: Acest {instance} este restricționat
|
||||
datorită vârstei
|
||||
Type:
|
||||
Channel: Canal
|
||||
Video: Video
|
||||
This {videoOrPlaylist} is age restricted: Acest {videoOrPlaylist} are restricții
|
||||
de vârstă
|
||||
Channels:
|
||||
Channels: Canale
|
||||
Title: Listă de canale
|
||||
|
@ -1011,3 +1007,5 @@ Playlist will pause when current video is finished: Lista de redare se va între
|
|||
când videoclipul curent este terminat
|
||||
Playlist will not pause when current video is finished: Lista de redare nu se va întrerupe
|
||||
când videoclipul curent este terminat
|
||||
Go to page: Mergeți la {page}
|
||||
Close Banner: Închideți bannerul
|
||||
|
|
|
@ -955,7 +955,7 @@ Local API Error (Click to copy): 'Ошибка локального набора
|
|||
Invidious API Error (Click to copy): 'Ошибка набора функций Invidious (Нажмите, чтобы
|
||||
скопировать)'
|
||||
Falling back to Invidious API: 'Возврат к набору функций Invidious'
|
||||
Falling back to the local API: 'Возврат к локальному набору функций'
|
||||
Falling back to Local API: 'Возврат к локальному набору функций'
|
||||
Subscriptions have not yet been implemented: 'Подписки еще не реализованы'
|
||||
Loop is now disabled: 'Повторение теперь отключено'
|
||||
Loop is now enabled: 'Повторение теперь включено'
|
||||
|
@ -1128,13 +1128,6 @@ Downloading failed: Возникла проблема с загрузкой «{v
|
|||
Screenshot Success: Снимок экрана сохранён как «{filePath}»
|
||||
Screenshot Error: Снимок экрана не удался. {error}
|
||||
New Window: Новое окно
|
||||
Age Restricted:
|
||||
The currently set default instance is {instance}: У {instance} ограничение по возрасту
|
||||
Type:
|
||||
Channel: Канал
|
||||
Video: Видео
|
||||
This {videoOrPlaylist} is age restricted: '{videoOrPlaylist} имеет ограничение по
|
||||
возрасту'
|
||||
Channels:
|
||||
Title: Список каналов
|
||||
Count: '{number} канал(ов) найдено.'
|
||||
|
|
|
@ -646,7 +646,7 @@ Up Next: 'Nasledujúci'
|
|||
Local API Error (Click to copy): 'Local API chyba (kliknutím skopírujete)'
|
||||
Invidious API Error (Click to copy): 'Invidious API chyba (kliknutím skopírujete)'
|
||||
Falling back to Invidious API: 'Návrat k Invidious API'
|
||||
Falling back to the local API: 'Návrat k local API'
|
||||
Falling back to Local API: 'Návrat k local API'
|
||||
Subscriptions have not yet been implemented: 'Odbery ešte nie sú implementované'
|
||||
Loop is now disabled: 'Opakovanie je teraz deaktivované'
|
||||
Loop is now enabled: 'Opakovanie je teraz povolené'
|
||||
|
|
|
@ -709,7 +709,7 @@ Up Next: 'Naslednje na sporedu'
|
|||
Local API Error (Click to copy): 'Napaka lokalnega APV (kliknite za kopiranje)'
|
||||
Invidious API Error (Click to copy): 'Napaka Invidious APV (kliknite za kopiranje)'
|
||||
Falling back to Invidious API: 'Začasno bo uporabljen Invidious APV'
|
||||
Falling back to the local API: 'Začasno bo uporabljen lokalni APV'
|
||||
Falling back to Local API: 'Začasno bo uporabljen lokalni APV'
|
||||
This video is unavailable because of missing formats. This can happen due to country unavailability.: 'Videoposnetek
|
||||
zaradi mankajočih oblik ni dostopen. To se lahko zgodi, ko v vaši državi ni na razpolago.'
|
||||
Subscriptions have not yet been implemented: 'Naročnine še niso bile implementirane'
|
||||
|
|
|
@ -814,7 +814,7 @@ Tooltips:
|
|||
Local API Error (Click to copy): ''
|
||||
Invidious API Error (Click to copy): ''
|
||||
Falling back to Invidious API: ''
|
||||
Falling back to the local API: ''
|
||||
Falling back to Local API: ''
|
||||
This video is unavailable because of missing formats. This can happen due to country unavailability.: ''
|
||||
Subscriptions have not yet been implemented: ''
|
||||
Unknown YouTube url type, cannot be opened in app: ''
|
||||
|
@ -834,11 +834,6 @@ Canceled next video autoplay: ''
|
|||
Default Invidious instance has been set to {instance}: ''
|
||||
Default Invidious instance has been cleared: ''
|
||||
'The playlist has ended. Enable loop to continue playing': ''
|
||||
Age Restricted:
|
||||
This {videoOrPlaylist} is age restricted: ''
|
||||
Type:
|
||||
Channel: ''
|
||||
Video: ''
|
||||
External link opening has been disabled in the general settings: ''
|
||||
Downloading has completed: ''
|
||||
Starting download: ''
|
||||
|
|
|
@ -149,6 +149,7 @@ User Playlists:
|
|||
да додате видео снимак | Изаберите плејлисту на коју желите да додате {videoCount}
|
||||
видео снимака
|
||||
N playlists selected: 'Изабрано: {playlistCount}'
|
||||
Added {count} Times: Додато {count} пут | Додато {count} пута
|
||||
SinglePlaylistView:
|
||||
Toast:
|
||||
There were no videos to remove.: Није било видео снимака за уклањање.
|
||||
|
@ -296,6 +297,7 @@ Settings:
|
|||
Hot Pink: Врућа розе
|
||||
Catppuccin Mocha: Catppuccin Mocha
|
||||
System Default: Системски подразумевано
|
||||
Nordic: Нордичка
|
||||
Main Color Theme:
|
||||
Main Color Theme: 'Главна тема боја'
|
||||
Red: 'Црвена'
|
||||
|
@ -466,7 +468,7 @@ Settings:
|
|||
Hide Subscriptions Live: Сакриј стримове уживо канала које пратите
|
||||
Hide Subscriptions Shorts: Сакриј Shorts снимке канала које пратите
|
||||
Display Titles Without Excessive Capitalisation: Прикажи наслове без претераног
|
||||
коришћења великих слова
|
||||
писања великих слова и интерпункције
|
||||
Hide Featured Channels: Сакриј истакнуте канале
|
||||
Hide Profile Pictures in Comments: Сакриј слике профила у коментарима
|
||||
Hide Upcoming Premieres: Сакриј предстојеће премијере
|
||||
|
@ -883,6 +885,7 @@ Video:
|
|||
уживо није доступно за овај стрим. Можда га је онемогућио аутор.
|
||||
Unhide Channel: Прикажи канал
|
||||
Hide Channel: Сакриј канал
|
||||
More Options: Више опција
|
||||
Tooltips:
|
||||
Subscription Settings:
|
||||
Fetch Feeds from RSS: 'Када је омогућено, FreeTube ће користити RSS уместо свог
|
||||
|
@ -970,11 +973,6 @@ Tooltips:
|
|||
Subscriptions have not yet been implemented: 'Праћења још увек нису имплементирана'
|
||||
Open New Window: Отвори нови прозор
|
||||
Shuffle is now disabled: Мешање је сада онемогућено
|
||||
Age Restricted:
|
||||
Type:
|
||||
Video: Видео снимак
|
||||
Channel: Канал
|
||||
This {videoOrPlaylist} is age restricted: '{videoOrPlaylist} је старосно ограничен(а)'
|
||||
New Window: Нови прозор
|
||||
Clipboard:
|
||||
Copy failed: Копирање у привремену меморију није успело
|
||||
|
@ -1044,7 +1042,7 @@ Share:
|
|||
меморију
|
||||
YouTube Embed URL copied to clipboard: YouTube уграђени URL је копиран у привремену
|
||||
меморију
|
||||
Falling back to the local API: Повратак на локални API
|
||||
Falling back to Local API: Повратак на локални API
|
||||
Unknown YouTube url type, cannot be opened in app: Непозната врста YouTube URL адресе,
|
||||
не може се отворити у апликацији
|
||||
Search Bar:
|
||||
|
@ -1118,3 +1116,7 @@ Channel Unhidden: '{channel} је уклоњен из филтера канал
|
|||
Trimmed input must be at least N characters long: Исечени унос мора да има најмање
|
||||
1 знак | Исечени унос мора да има најмање {length} знакова
|
||||
Tag already exists: Ознака „{tagName}“ већ постоји
|
||||
Close Banner: Затвори банер
|
||||
Age Restricted:
|
||||
This channel is age restricted: Овај канал је ограничен према узрасту
|
||||
This video is age restricted: Овај видео снимак је ограничен према узрасту
|
||||
|
|
|
@ -916,7 +916,7 @@ Up Next: 'Kommer härnäst'
|
|||
Local API Error (Click to copy): 'Lokalt API-fel (Klicka för att kopiera koden)'
|
||||
Invidious API Error (Click to copy): 'Invidious API-fel (Klicka för att kopiera koden)'
|
||||
Falling back to Invidious API: 'Faller tillbaka till Invidious API'
|
||||
Falling back to the local API: 'Faller tillbaka till lokal API'
|
||||
Falling back to Local API: 'Faller tillbaka till lokal API'
|
||||
This video is unavailable because of missing formats. This can happen due to country unavailability.: 'Den
|
||||
här videon är inte tillgänglig på grund av format som saknas. Detta kan hända på
|
||||
grund av landets otillgänglighet.'
|
||||
|
@ -1037,11 +1037,6 @@ Preferences: Preferenser
|
|||
Ok: Okej
|
||||
Screenshot Success: Sparade skärmdump som "{filePath}"
|
||||
Screenshot Error: Skärmdump misslyckades {felkod}
|
||||
Age Restricted:
|
||||
Type:
|
||||
Channel: Kanal
|
||||
Video: Video
|
||||
This {videoOrPlaylist} is age restricted: Denna {videoOrPlaylist} är åldersbegränsad
|
||||
Clipboard:
|
||||
Cannot access clipboard without a secure connection: Har inte tillgång till urklipp
|
||||
utan en säker anslutning
|
||||
|
|
|
@ -11,4 +11,3 @@ Channel:
|
|||
About: {}
|
||||
Video: {}
|
||||
Tooltips: {}
|
||||
Age Restricted: {}
|
||||
|
|
|
@ -178,6 +178,7 @@ User Playlists:
|
|||
kullanımına geri dönüldü
|
||||
This playlist is now used for quick bookmark: Bu oynatma listesi artık hızlı
|
||||
yer imi için kullanılıyor
|
||||
Search for Videos: Video Ara
|
||||
AddVideoPrompt:
|
||||
Select a playlist to add your N videos to: Videonuzu eklemek için bir oynatma
|
||||
listesi seçin | {videoCount} videonuzu eklemek için bir oynatma listesi seçin
|
||||
|
@ -191,6 +192,7 @@ User Playlists:
|
|||
| {videoCount} video 1 oynatma listesine eklendi
|
||||
N playlists selected: '{playlistCount} Seçildi'
|
||||
Search in Playlists: Oynatma Listelerinde Ara
|
||||
Added {count} Times: '{count} Defa Eklendi | {count} Defa Eklendi'
|
||||
CreatePlaylistPrompt:
|
||||
New Playlist Name: Yeni Oynatma Listesi Adı
|
||||
Create: Oluştur
|
||||
|
@ -532,8 +534,8 @@ Settings:
|
|||
Hide Upcoming Premieres: Yaklaşan İlk Gösterimleri Gizle
|
||||
Hide Channels Placeholder: Kanal Kimliği
|
||||
Hide Channels: Kanallardan Videoları Gizle
|
||||
Display Titles Without Excessive Capitalisation: Başlıkları Aşırı Büyük Harf Kullanmadan
|
||||
Görüntüle
|
||||
Display Titles Without Excessive Capitalisation: Başlıkları Aşırı Büyük Harf ve
|
||||
Noktalama İşaretleri Kullanmadan Görüntüle
|
||||
Hide Featured Channels: Öne Çıkan Kanalları Gizle
|
||||
Hide Channel Playlists: Kanal Oynatma Listelerini Gizle
|
||||
Hide Channel Community: Kanal Topluluğunu Gizle
|
||||
|
@ -960,6 +962,7 @@ Video:
|
|||
Pause on Current Video: Geçerli Videoda Duraklat
|
||||
Unhide Channel: Kanalı Göster
|
||||
Hide Channel: Kanalı Gizle
|
||||
More Options: Daha Fazla Seçenek
|
||||
Videos:
|
||||
#& Sort By
|
||||
Sort By:
|
||||
|
@ -1040,7 +1043,7 @@ Up Next: 'Sonraki'
|
|||
Local API Error (Click to copy): 'Yerel API Hatası (Kopyalamak için tıklayın)'
|
||||
Invidious API Error (Click to copy): 'Invidious API Hatası (Kopyalamak için tıklayın)'
|
||||
Falling back to Invidious API: 'Invidious API''ye geri dönülüyor'
|
||||
Falling back to the local API: 'Yerel API''ye geri dönülüyor'
|
||||
Falling back to Local API: 'Yerel API''ye geri dönülüyor'
|
||||
Subscriptions have not yet been implemented: 'Abonelikler henüz uygulanmadı'
|
||||
Loop is now disabled: 'Döngü artık devre dışı'
|
||||
Loop is now enabled: 'Döngü artık etkin'
|
||||
|
@ -1171,12 +1174,6 @@ Download folder does not exist: İndirme dizini "$" mevcut değil. "Klasör sor"
|
|||
Screenshot Success: Ekran görüntüsü "{filePath}" olarak kaydedildi
|
||||
Screenshot Error: Ekran görüntüsü başarısız oldu. {error}
|
||||
New Window: Yeni Pencere
|
||||
Age Restricted:
|
||||
The currently set default instance is {instance}: Bu {instance} yaş kısıtlamalıdır
|
||||
Type:
|
||||
Channel: Kanal
|
||||
Video: Video
|
||||
This {videoOrPlaylist} is age restricted: Bu {videoOrPlaylist} yaş kısıtlamalıdır
|
||||
Channels:
|
||||
Empty: Kanal listeniz şu anda boş.
|
||||
Channels: Kanallar
|
||||
|
@ -1212,3 +1209,7 @@ Channel Unhidden: '{channel} kanal filtresinden kaldırıldı'
|
|||
Trimmed input must be at least N characters long: Kırpılan girdi en az 1 karakter
|
||||
uzunluğunda olmalıdır | Kırpılan girdi en az {length} karakter uzunluğunda olmalıdır
|
||||
Tag already exists: '"{tagName}" etiketi zaten var'
|
||||
Close Banner: Afişi Kapat
|
||||
Age Restricted:
|
||||
This video is age restricted: Bu videoda yaş sınırlaması var
|
||||
This channel is age restricted: Bu kanalda yaş sınırlaması var
|
||||
|
|
|
@ -43,6 +43,8 @@ Global:
|
|||
Subscriber Count: 1 підписник | {count} підписників
|
||||
View Count: 1 перегляд | {count} переглядів
|
||||
Watching Count: 1 глядач | {count} глядачів
|
||||
Input Tags:
|
||||
Length Requirement: Тег повинен мати довжину не менше {number} символів
|
||||
Version {versionNumber} is now available! Click for more details: 'Доступна нова
|
||||
версія {versionNumber}! Натисніть, щоб переглянути подробиці'
|
||||
Download From Site: 'Завантажити з сайту'
|
||||
|
@ -116,17 +118,36 @@ Trending:
|
|||
Music: Музика
|
||||
Default: Типово
|
||||
Most Popular: 'Найпопулярніші'
|
||||
Playlists: 'Добірки'
|
||||
Playlists: 'Списки відтворення'
|
||||
User Playlists:
|
||||
Your Playlists: 'Ваші добірки'
|
||||
Your Playlists: 'Ваші списки відтворення'
|
||||
Your saved videos are empty. Click on the save button on the corner of a video to have it listed here: Збережені
|
||||
відео порожні. Клацніть на кнопку збереження у куті відео, щоб воно було перелічено
|
||||
тут
|
||||
Playlist Message: Ця сторінка не показує повністю робочих добірок. На ній перелічено
|
||||
лише відео, які ви зберегли або вибрали. Коли робота завершиться, усі відео, які
|
||||
зараз знаходяться тут, буде переміщено до добірки "Вибране".
|
||||
Playlist Message: Ця сторінка не показує повністю робочих списків відтворення. На
|
||||
ній перелічено лише відео, які ви зберегли або вибрали. Коли робота завершиться,
|
||||
усі відео, які зараз знаходяться тут, буде переміщено до списку відтворення "Вибране".
|
||||
Search bar placeholder: Шукати у добірці
|
||||
Empty Search Message: Немає відео в цій добірці, які відповідають вашому запиту
|
||||
Create New Playlist: Створити новий список відтворення
|
||||
Add to Playlist: Додати список відтворення
|
||||
Remove from Favorites: Вилучити з {playlistName}
|
||||
Move Video Up: Посунути відео вгору
|
||||
Move Video Down: Посунути відео вниз
|
||||
Remove from Playlist: Вилучити зі списку відтворення
|
||||
Playlist Description: Опис списку відтворення
|
||||
Save Changes: Зберегти зміни
|
||||
Cancel: Скасувати
|
||||
Copy Playlist: Скопіювати список відтворення
|
||||
You have no playlists. Click on the create new playlist button to create a new one.: У
|
||||
вас немає списків відтворення. Натисніть на кнопку створити новий список відтворення,
|
||||
щоб створити його.
|
||||
This playlist currently has no videos.: Наразі у цьому списку відтворення немає
|
||||
відео.
|
||||
Add to Favorites: Додати до {playlistName}
|
||||
Playlist Name: Назва списку відтворення
|
||||
Edit Playlist Info: Змінити інформацію списку відтворення
|
||||
Remove Watched Videos: Вилучити з переглянутих відео
|
||||
History:
|
||||
# On History Page
|
||||
History: 'Історія'
|
||||
|
@ -321,8 +342,8 @@ Settings:
|
|||
Are you sure you want to remove all subscriptions and profiles? This cannot be undone.: 'Справді
|
||||
хочете вилучити всі підписки та профілі? Цю дію не можна скасувати.'
|
||||
Automatically Remove Video Meta Files: Автоматично вилучати метафайли відео
|
||||
Save Watched Videos With Last Viewed Playlist: Зберегти переглянуті відео в добірку,
|
||||
яку ви переглядали останнім часом
|
||||
Save Watched Videos With Last Viewed Playlist: Зберегти переглянуті відео у список
|
||||
відтворення, який ви переглядали останнім часом
|
||||
Subscription Settings:
|
||||
Subscription Settings: 'Налаштування підписки'
|
||||
Hide Videos on Watch: 'Ховати відео при перегляді'
|
||||
|
@ -342,7 +363,7 @@ Settings:
|
|||
Hide Popular Videos: 'Не показувати популярні відео'
|
||||
Hide Live Chat: 'Не показувати живий чат'
|
||||
Hide Active Subscriptions: Сховати активні підписки
|
||||
Hide Playlists: Сховати добірки
|
||||
Hide Playlists: Сховати списки відтворення
|
||||
Hide Video Description: Сховати опис відео
|
||||
Hide Comments: Сховати коментарі
|
||||
Hide Sharing Actions: Сховати дії поширення
|
||||
|
@ -354,7 +375,7 @@ Settings:
|
|||
Display Titles Without Excessive Capitalisation: Показувати заголовки без надмірно
|
||||
великих літер
|
||||
Hide Featured Channels: Сховати пропоновані канали
|
||||
Hide Channel Playlists: Сховати добірки з каналів
|
||||
Hide Channel Playlists: Сховати списки відтворення каналу
|
||||
Hide Channel Community: Сховати спільноту каналу
|
||||
Hide Channel Shorts: Сховати Shorts каналу
|
||||
Sections:
|
||||
|
@ -414,13 +435,13 @@ Settings:
|
|||
Unknown data key: 'Невідомий ключ даних'
|
||||
How do I import my subscriptions?: 'Як імпортувати свої підписки?'
|
||||
Manage Subscriptions: Керування підписками
|
||||
Playlist insufficient data: Недостатньо даних для добірки "{playlist}", пропуск
|
||||
елемента
|
||||
All playlists has been successfully exported: Усі добірки успішно експортовано
|
||||
Playlist insufficient data: Недостатньо даних для списку відтворення "{playlist}",
|
||||
пропуск елемента
|
||||
All playlists has been successfully exported: Усі списки відтворення успішно експортовано
|
||||
Import Playlists: Імпорт добірок
|
||||
Export Playlists: Експорт добірок
|
||||
All playlists has been successfully imported: Усі добірки успішно імпортовано
|
||||
Playlist File: Файл добірки
|
||||
All playlists has been successfully imported: Усі списки відтворення успішно імпортовано
|
||||
Playlist File: Файл списку відтворення
|
||||
Subscription File: Файл підписки
|
||||
History File: Файл історії
|
||||
Advanced Settings: {}
|
||||
|
@ -590,7 +611,7 @@ Channel:
|
|||
Oldest: 'Найдавніші'
|
||||
Most Popular: 'Найпопулярніші'
|
||||
Playlists:
|
||||
Playlists: 'Добірки'
|
||||
Playlists: 'Списки відтворення'
|
||||
This channel does not currently have any playlists: 'Цей канал наразі не має добірок'
|
||||
Sort Types:
|
||||
Last Video Added: 'Останнє додане відео'
|
||||
|
@ -646,9 +667,9 @@ Video:
|
|||
Open Channel in Invidious: 'Відкрити канал у Invidious'
|
||||
Copy Invidious Channel Link: 'Копіювати посилання на канал Invidious'
|
||||
Views: 'Перегляди'
|
||||
Loop Playlist: 'Зациклити добірку'
|
||||
Shuffle Playlist: 'Перемішати добірку'
|
||||
Reverse Playlist: 'Змінити напрямок добірки'
|
||||
Loop Playlist: 'Повторювати список відтворення'
|
||||
Shuffle Playlist: 'Перемішати список відтворення'
|
||||
Reverse Playlist: 'Зворотний напрямок списку відтворення'
|
||||
Play Next Video: 'Відтворити наступне відео'
|
||||
Play Previous Video: 'Відтворити попереднє відео'
|
||||
Watched: 'Переглянуто'
|
||||
|
@ -739,7 +760,7 @@ Video:
|
|||
starting video at offset: запуск відео зі зміщенням
|
||||
UnsupportedActionTemplate: '{externalPlayer} не підтримує: {action}'
|
||||
OpeningTemplate: Відкриття {videoOrPlaylist} у {externalPlayer}...
|
||||
playlist: добірка
|
||||
playlist: список відтворення
|
||||
video: відео
|
||||
OpenInTemplate: Відкрити у {externalPlayer}
|
||||
Premieres on: Прем'єри
|
||||
|
@ -782,7 +803,7 @@ Videos:
|
|||
#& Playlists
|
||||
Playlist:
|
||||
#& About
|
||||
View Full Playlist: 'Переглянути всю добірку'
|
||||
View Full Playlist: 'Переглянути весь список відтворення'
|
||||
Videos: 'Відео'
|
||||
View: 'Перегляд'
|
||||
Views: 'Переглядів'
|
||||
|
@ -791,7 +812,7 @@ Playlist:
|
|||
# On Video Watch Page
|
||||
#* Published
|
||||
#& Views
|
||||
Playlist: Добірка
|
||||
Playlist: Список відтворення
|
||||
Toggle Theatre Mode: 'Перемкнути режим театру'
|
||||
Change Format:
|
||||
Change Media Formats: 'Зміна форматів відео'
|
||||
|
@ -804,7 +825,7 @@ Change Format:
|
|||
відео'
|
||||
Share:
|
||||
Share Video: 'Поділитися відео'
|
||||
Share Playlist: 'Поділитися добіркою'
|
||||
Share Playlist: 'Поділитися списком відтворення'
|
||||
Include Timestamp: 'Включити позначку часу'
|
||||
Copy Link: 'Копіювати посилання'
|
||||
Open Link: 'Відкрити посилання'
|
||||
|
@ -915,8 +936,8 @@ Tooltips:
|
|||
програвач можна знайти за допомогою змінної середовища PATH. Якщо потрібно,
|
||||
тут можна призначити нетиповий шлях.
|
||||
External Player: Якщо обрано зовнішній програвач, з'явиться піктограма для відкриття
|
||||
відео (добірка, якщо підтримується) у зовнішньому програвачі, на мініатюрі.
|
||||
Увага, налаштування Invidious не застосовуються до сторонніх програвачів.
|
||||
відео (список відтворення, якщо підтримується) у зовнішньому програвачі, на
|
||||
мініатюрі. Увага, налаштування Invidious не застосовуються до сторонніх програвачів.
|
||||
DefaultCustomArgumentsTemplate: "(Типово: '{defaultCustomArguments}')"
|
||||
Experimental Settings:
|
||||
Replace HTTP Cache: Вимикає дисковий HTTP-кеш Electron і вмикає власний кеш зображень
|
||||
|
@ -932,7 +953,7 @@ Tooltips:
|
|||
Local API Error (Click to copy): 'Помилка локального API (натисніть, щоб скопіювати)'
|
||||
Invidious API Error (Click to copy): 'Помилка Invidious API (натисніть, щоб скопіювати)'
|
||||
Falling back to Invidious API: 'Повернення до API Invidious'
|
||||
Falling back to the local API: 'Повернення до локального API'
|
||||
Falling back to Local API: 'Повернення до локального API'
|
||||
This video is unavailable because of missing formats. This can happen due to country unavailability.: 'Це
|
||||
відео недоступне через відсутність форматів. Це може статися через недоступність
|
||||
країни.'
|
||||
|
@ -941,12 +962,12 @@ Loop is now disabled: 'Цикл вимкнено'
|
|||
Loop is now enabled: 'Цикл увімкнено'
|
||||
Shuffle is now disabled: 'Випадковий порядок вимкнено'
|
||||
Shuffle is now enabled: 'Випадковий порядок увімкнено'
|
||||
The playlist has been reversed: 'Добірку обернено'
|
||||
The playlist has been reversed: 'Список відтворення обернено'
|
||||
Playing Next Video: 'Відтворення наступного відео'
|
||||
Playing Previous Video: 'Відтворення попереднього відео'
|
||||
Canceled next video autoplay: 'Скасовано автовідтворення наступного відео'
|
||||
'The playlist has ended. Enable loop to continue playing': 'Добірка завершилася. Увімкніть
|
||||
цикл, щоб продовжити відтворення'
|
||||
'The playlist has ended. Enable loop to continue playing': 'Список відтворення завершився.
|
||||
Увімкніть повторення, щоб продовжити відтворення'
|
||||
|
||||
Yes: 'Так'
|
||||
No: 'Ні'
|
||||
|
@ -977,13 +998,6 @@ Download folder does not exist: Каталог завантаження "$" не
|
|||
Screenshot Success: Знімок екрана збережено як «{filePath}»
|
||||
Screenshot Error: Не вдалося зробити знімок екрана. {error}
|
||||
New Window: Нове вікно
|
||||
Age Restricted:
|
||||
The currently set default instance is {instance}: Цей {instance} має обмеження за
|
||||
віком
|
||||
Type:
|
||||
Video: Відео
|
||||
Channel: Канал
|
||||
This {videoOrPlaylist} is age restricted: '{videoOrPlaylist} має вікове обмеження'
|
||||
Channels:
|
||||
Count: 'Знайдено каналів: {number}.'
|
||||
Empty: Ваш список каналів наразі порожній.
|
||||
|
@ -1008,10 +1022,11 @@ Ok: Гаразд
|
|||
Hashtag:
|
||||
Hashtag: Хештег
|
||||
This hashtag does not currently have any videos: За цим хештегом наразі немає відео
|
||||
Playlist will pause when current video is finished: Добірка призупиняється, коли поточне
|
||||
відео завершено
|
||||
Playlist will not pause when current video is finished: Добірка не призупиняється,
|
||||
Playlist will pause when current video is finished: Список відтворення призупиняється,
|
||||
коли поточне відео завершено
|
||||
Playlist will not pause when current video is finished: Список відтворення не призупиняється,
|
||||
коли поточне відео завершено
|
||||
Channel Hidden: '{channel} додано до фільтра каналу'
|
||||
Go to page: Перейти до {page}
|
||||
Channel Unhidden: '{channel} вилучено з фільтра каналу'
|
||||
Close Banner: Закрити банер
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue