1
0
mirror of https://github.com/TeamNewPipe/NewPipe synced 2024-06-20 12:20:02 +00:00

Merge branch 'dev' into feature/notifications

This commit is contained in:
TobiGr 2022-02-19 12:34:44 +01:00
commit ff8e44e4f3
248 changed files with 5894 additions and 1665 deletions

1
.github/FUNDING.yml vendored
View File

@ -1 +1,2 @@
liberapay: TeamNewPipe
custom: 'https://newpipe.net/donate/'

View File

@ -1,65 +0,0 @@
---
name: Bug report
about: Create a bug report to help us improve
labels: bug
assignees: ''
---
<!--
Oh no, a bug! It happens. Thanks for reporting an issue with NewPipe. To make it easier for us to help you please enter detailed information in the template we have provided below. If a section isn't relevant, just delete it, though it would be helpful to still provide as much detail as possible.
-->
<!-- IF YOU DON'T FILL IN THE TEMPLATE PROPERLY, YOUR ISSUE IS LIABLE TO BE CLOSED. If you feel tired/lazy right now, open your issue some other time. We'll wait. -->
<!-- The comments between these brackets won't show up in the submitted issue (as you can see in the Preview). -->
### Checklist
<!-- This checklist is COMPULSORY. The first box has been checked for you to show you how it is done. -->
- [x] I am using the latest version - x.xx.x <!-- Check https://github.com/TeamNewPipe/NewPipe/releases -->
- [ ] I checked, but didn't find any duplicates (open OR closed) of this issue in the repo. <!-- Seriously, check. O_O -->
- [ ] I have read the contribution guidelines given at https://github.com/TeamNewPipe/NewPipe/blob/HEAD/.github/CONTRIBUTING.md.
- [ ] This issue contains only one bug. I will open one issue for every bug report I want to file.
### Steps to reproduce the bug
<!--
1. Go to '...'
2. Press on '....'
3. Swipe down to '....'
-->
<!-- If you can't cause the bug to show up again reliably (and hence don't have a proper set of steps to give us), please still try to give as many details as possible on how you think you encountered the bug. -->
### Actual behavior
<!-- Tell us what happens with the steps given above. -->
### Expected behavior
<!-- Tell us what you expect to happen. -->
### Screenshots/Screen recordings
<!-- If applicable, add screenshots or a screen recording to help explain your problem. GitHub supports uploading them directly in the issue text box. If your file is too big for Github to accept, feel free to paste a link from an image/video hoster here instead. -->
<!-- DON'T POST SCREENSHOTS OF THE ERROR PAGE. Use the buttons given on the error page to paste the error as text in the Logs section below. -->
### Logs
<!-- If your bug includes a crash (where you're shown the Error Report page with a bunch of info), tap on "Copy formatted report" at the bottom and paste it here: -->
<!-- That's right, here! -->
<!-- Please fill this section if you did not provide a log generated by NewPipe -->
### Device info
- Android version/Custom ROM version:
- Device model:

113
.github/ISSUE_TEMPLATE/bug_report.yml vendored Normal file
View File

@ -0,0 +1,113 @@
name: Bug report
description: Create a bug report to help us improve
labels: [bug]
body:
- type: markdown
attributes:
value: |
Thank you for helping to make NewPipe better by reporting a bug. :hugs:
Please fill in as much information as possible about your bug so that we don't have to play "information ping-pong" and can help you immediately.
- type: checkboxes
id: checklist
attributes:
label: "Checklist"
options:
- label: "I am able to reproduce the bug with the [latest version](https://github.com/TeamNewPipe/NewPipe/releases/latest)."
required: true
- label: "I made sure that there are *no existing issues* - [open](https://github.com/TeamNewPipe/NewPipe/issues) or [closed](https://github.com/TeamNewPipe/NewPipe/issues?q=is%3Aissue+is%3Aclosed) - which I could contribute my information to."
required: true
- label: "I have taken the time to fill in all the required details. I understand that the bug report will be dismissed otherwise."
required: true
- label: "This issue contains only one bug."
required: true
- label: "I have read and understood the [contribution guidelines](https://github.com/TeamNewPipe/NewPipe/blob/dev/.github/CONTRIBUTING.md)."
required: true
- type: input
id: app-version
attributes:
label: Affected version
description: "In which NewPipe version did you encounter the bug?"
placeholder: "x.xx.x - Can be seen in the app from the 'About' section in the sidebar"
validations:
required: true
- type: textarea
id: steps-to-reproduce
attributes:
label: Steps to reproduce the bug
description: |
What did you do for the bug to show up?
If you can't cause the bug to show up again reliably (and hence don't have a proper set of steps to give us), please still try to give as many details as possible on how you think you encountered the bug.
placeholder: |
1. Go to '...'
2. Press on '....'
3. Swipe down to '....'
validations:
required: true
- type: textarea
id: expected-behavior
attributes:
label: Expected behavior
description: |
Tell us what you expect to happen.
- type: textarea
id: actual-behavior
attributes:
label: Actual behavior
description: |
Tell us what happens with the steps given above.
- type: textarea
id: screen-media
attributes:
label: Screenshots/Screen recordings
description: |
A picture or video is worth a thousand words.
If applicable, add screenshots or a screen recording to help explain your problem.
GitHub supports uploading them directly in the text box.
If your file is too big for Github to accept, try to compress it (ZIP-file) or feel free to paste a link to an image/video hoster here instead.
:heavy_exclamation_mark: DON'T POST SCREENSHOTS OF THE ERROR PAGE.
Instead, follow the instructions in the "Logs" section below.
- type: textarea
id: logs
attributes:
label: Logs
description: |
If your bug includes a crash (where you're shown the Error Report page with a bunch of info), tap on "Copy formatted report" at the bottom and paste it here.
- type: input
id: device-os-info
attributes:
label: Affected Android/Custom ROM version
description: |
With what operating system (+ version) did you encounter the bug?
placeholder: "Example: Android 12 / LineageOS 18.1"
- type: input
id: device-model-info
attributes:
label: Affected device model
description: |
On what device did you encounter the bug?
placeholder: "Example: Huawei P20 lite (ANE-LX1) / Samsung Galaxy S20"
- type: textarea
id: additional-information
attributes:
label: Additional information
description: |
Any other information you'd like to include, for instance that
* the affected device is foldable or a TV
* you have disabled all animations on your device
* your cat disabled your network connection
* ...

View File

@ -1,24 +0,0 @@
---
name: Feature request
about: Suggest an idea for this project
labels: enhancement
assignees: ''
---
<!-- IF YOU DON'T FILL IN THE TEMPLATE PROPERLY, YOUR ISSUE IS LIABLE TO BE CLOSED. If you are currently unable to do so for any reason, open your issue some other time. We'll wait. -->
<!-- The comments between these brackets won't show up in the submitted issue (as you can see in the Preview tab). -->
### Checklist
<!-- This checklist is COMPULSORY. The first box has been checked for you to show you how it is done. -->
- [x] I checked, but didn't find any duplicates (open OR closed) of this issue in the repo. <!-- Seriously, check. O_O -->
- [ ] I have read the contribution guidelines given at https://github.com/TeamNewPipe/NewPipe/blob/HEAD/.github/CONTRIBUTING.md.
- [ ] This issue contains only one feature request. I will open one issue for every feature I want to request.
#### What feature do you want?
<!-- Explain how you want the app's look or behavior to change to suit your needs. -->
#### Why do you want this feature?
<!-- Describe any problem or limitation you come across while using the app which would be solved by this feature. -->

View File

@ -0,0 +1,51 @@
name: Feature request
description: Suggest an idea for this project
labels: [enhancement]
body:
- type: markdown
attributes:
value: |
Thank you for helping to make NewPipe better by suggesting a feature. :hugs:
Your ideas are highly welcome! The app is made for you, the users, after all.
- type: checkboxes
id: checklist
attributes:
label: "Checklist"
options:
- label: "I made sure that there are *no existing issues* - [open](https://github.com/TeamNewPipe/NewPipe/issues) or [closed](https://github.com/TeamNewPipe/NewPipe/issues?q=is%3Aissue+is%3Aclosed) - which I could contribute my information to."
required: true
- label: "I'm aware that this is a request for NewPipe itself and that requests for adding a new service need to be made at [NewPipeExtractor](https://github.com/TeamNewPipe/NewPipeExtractor/issues)."
required: true
- label: "I have taken the time to fill in all the required details. I understand that the feature request will be dismissed otherwise."
required: true
- label: "This issue contains only one feature request."
required: true
- label: "I have read and understood the [contribution guidelines](https://github.com/TeamNewPipe/NewPipe/blob/dev/.github/CONTRIBUTING.md)."
required: true
- type: textarea
id: feature-description
attributes:
label: Feature description
description: |
Explain how you want the app's look or behavior to change to suit your needs.
validations:
required: true
- type: textarea
id: why-is-the-feature-requested
attributes:
label: Why do you want this feature?
description: |
Describe any problem or limitation you come across while using the app which would be solved by this feature.
validations:
required: true
- type: textarea
id: additional-information
attributes:
label: Additional information
description: Any other information you'd like to include, for instance sketches, mockups, pictures of cats, etc.

View File

@ -1,24 +0,0 @@
---
name: Question
about: Ask about anything NewPipe-related
labels: question
assignees: ''
---
<!-- IF YOU DON'T FILL IN THE TEMPLATE PROPERLY, YOUR ISSUE IS LIABLE TO BE CLOSED. If you feel tired/lazy right now, open your issue some other time. We'll wait. -->
<!-- The comments between these brackets won't show up in the submitted issue (as you can see in the Preview). -->
### Checklist
<!-- This checklist is COMPULSORY. The first box has been checked for you to show you how it is done. -->
- [x] I checked, but didn't find any duplicates (open OR closed) of this issue in the repo. <!-- Seriously, check. O_O (If there's already an issue but you'd like to see if something changed, just make a comment on the issue instead of opening a new one.) -->
- [ ] I have read the contribution guidelines given at https://github.com/TeamNewPipe/NewPipe/blob/HEAD/.github/CONTRIBUTING.md.
#### What's your question(s)?
#### Additional context
<!-- Add any other context, like screenshots or links, about the question here.
Example: *Here's a photo of my cat!* -->

35
.github/ISSUE_TEMPLATE/question.yml vendored Normal file
View File

@ -0,0 +1,35 @@
name: Question
description: Ask about anything NewPipe-related
labels: [question]
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to fill out this issue! :hugs:
Note that you can also ask questions on our [IRC channel](https://web.libera.chat/#newpipe).
- type: checkboxes
id: checklist
attributes:
label: "Checklist"
options:
- label: "I made sure that there are *no existing issues* - [open](https://github.com/TeamNewPipe/NewPipe/issues) or [closed](https://github.com/TeamNewPipe/NewPipe/issues?q=is%3Aissue+is%3Aclosed) - which I could contribute my information to."
required: true
- label: "I have taken the time to fill in all the required details. I understand that the question will be dismissed otherwise."
required: true
- label: "I have read and understood the [contribution guidelines](https://github.com/TeamNewPipe/NewPipe/blob/dev/.github/CONTRIBUTING.md)."
required: true
- type: textarea
id: what-is-the-question
attributes:
label: What is/are your question(s)?
validations:
required: true
- type: textarea
id: additional-information
attributes:
label: Additional information
description: Any other information you'd like to include, for instance sketches, mockups, pictures of cats, etc.

View File

@ -7,19 +7,25 @@ on:
- dev
- master
paths-ignore:
- 'README*.md'
- 'README.md'
- 'doc/**'
- 'fastlane/**'
- 'assets/**'
- '.github/**/*.md'
- '.github/FUNDING.yml'
- '.github/ISSUE_TEMPLATE/**'
push:
branches:
- dev
- master
paths-ignore:
- 'README*.md'
- 'README.md'
- 'doc/**'
- 'fastlane/**'
- 'assets/**'
- '.github/**/*.md'
- '.github/FUNDING.yml'
- '.github/ISSUE_TEMPLATE/**'
jobs:
build-and-test-jvm:

130
.github/workflows/image-minimizer.js vendored Normal file
View File

@ -0,0 +1,130 @@
/*
* Script for minimizing big images (jpg,gif,png) when they are uploaded to GitHub and not edited otherwise
*/
module.exports = async ({github, context}) => {
const IGNORE_KEY = '<!-- IGNORE IMAGE MINIFY -->';
const IGNORE_ALT_NAME_END = 'ignoreImageMinify';
// Targeted maximum height
const IMG_MAX_HEIGHT_PX = 600;
// maximum width of GitHub issues/comments
const IMG_MAX_WIDTH_PX = 800;
// all images that have a lower aspect ratio (-> have a smaller width) than this will be minimized
const MIN_ASPECT_RATIO = IMG_MAX_WIDTH_PX / IMG_MAX_HEIGHT_PX
// Get the body of the image
let initialBody = null;
if (context.eventName == 'issue_comment') {
initialBody = context.payload.comment.body;
} else if (context.eventName == 'issues') {
initialBody = context.payload.issue.body;
} else {
console.log('Aborting: No body found');
return;
}
console.log(`Found body: \n${initialBody}\n`);
// Check if we should ignore the currently processing element
if (initialBody.includes(IGNORE_KEY)) {
console.log('Ignoring: Body contains IGNORE_KEY');
return;
}
// Regex for finding images (simple variant) ![ALT_TEXT](https://*.githubusercontent.com/<number>/<variousHexStringsAnd->.<fileExtension>)
const REGEX_IMAGE_LOOKUP = /\!\[(.*)\]\((https:\/\/[-a-z0-9]+\.githubusercontent\.com\/\d+\/[-0-9a-f]{32,512}\.(jpg|gif|png))\)/gm;
// Check if we found something
let foundSimpleImages = REGEX_IMAGE_LOOKUP.test(initialBody);
if (!foundSimpleImages) {
console.log('Found no simple images to process');
return;
}
console.log('Found at least one simple image to process');
// Require the probe lib for getting the image dimensions
const probe = require('probe-image-size');
var wasMatchModified = false;
// Try to find and replace the images with minimized ones
let newBody = await replaceAsync(initialBody, REGEX_IMAGE_LOOKUP, async (match, g1, g2) => {
console.log(`Found match '${match}'`);
if (g1.endsWith(IGNORE_ALT_NAME_END)) {
console.log(`Ignoring match '${match}': IGNORE_ALT_NAME_END`);
return match;
}
let shouldModify = false;
try {
console.log(`Probing ${g2}`);
let probeResult = await probe(g2);
if (probeResult == null) {
throw 'No probeResult';
}
if (probeResult.hUnits != 'px') {
throw `Unexpected probeResult.hUnits (expected px but got ${probeResult.hUnits})`;
}
if (probeResult.height <= 0) {
throw `Unexpected probeResult.height (height is invalid: ${probeResult.height})`;
}
if (probeResult.wUnits != 'px') {
throw `Unexpected probeResult.wUnits (expected px but got ${probeResult.wUnits})`;
}
if (probeResult.width <= 0) {
throw `Unexpected probeResult.width (width is invalid: ${probeResult.width})`;
}
console.log(`Probing resulted in ${probeResult.width}x${probeResult.height}px`);
shouldModify = probeResult.height > IMG_MAX_HEIGHT_PX && (probeResult.width / probeResult.height) < MIN_ASPECT_RATIO;
} catch(e) {
console.log('Probing failed:', e);
// Immediately abort
return match;
}
if (shouldModify) {
wasMatchModified = true;
console.log(`Modifying match '${match}'`);
return `<img alt="${g1}" src="${g2}" height=${IMG_MAX_HEIGHT_PX} />`;
}
console.log(`Match '${match}' is ok/will not be modified`);
return match;
});
if (!wasMatchModified) {
console.log('Nothing was modified. Skipping update');
return;
}
// Update the corresponding element
if (context.eventName == 'issue_comment') {
console.log('Updating comment with id', context.payload.comment.id);
await github.rest.issues.updateComment({
comment_id: context.payload.comment.id,
owner: context.repo.owner,
repo: context.repo.repo,
body: newBody
})
} else if (context.eventName == 'issues') {
console.log('Updating issue', context.payload.issue.number);
await github.rest.issues.update({
issue_number: context.payload.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: newBody
});
}
// Asnyc replace function from https://stackoverflow.com/a/48032528
async function replaceAsync(str, regex, asyncFn) {
const promises = [];
str.replace(regex, (match, ...args) => {
const promise = asyncFn(match, ...args);
promises.push(promise);
});
const data = await Promise.all(promises);
return str.replace(regex, () => data.shift());
}
}

29
.github/workflows/image-minimizer.yml vendored Normal file
View File

@ -0,0 +1,29 @@
name: Image Minimizer
on:
issue_comment:
types: [created, edited]
issues:
types: [opened, edited]
jobs:
try-minimize:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: 16
- name: Install probe-image-size
run: npm i probe-image-size@7.2.3 --ignore-scripts
- name: Minimize simple images
uses: actions/github-script@v5
timeout-minutes: 3
with:
script: |
const script = require('.github/workflows/image-minimizer.js');
await script({github, context});

4
.gitignore vendored
View File

@ -8,8 +8,8 @@ captures/
*~
.weblate
*.class
**/debug/
**/release/
app/debug/
app/release/
# vscode / eclipse files
*.classpath

View File

@ -17,7 +17,7 @@
<p align="center"><a href="https://newpipe.net">Website</a> &bull; <a href="https://newpipe.net/blog/">Blog</a> &bull; <a href="https://newpipe.net/FAQ/">FAQ</a> &bull; <a href="https://newpipe.net/press/">Press</a></p>
<hr>
*Read this in other languages: [English](README.md), [Español](README.es.md), [한국어](README.ko.md), [Soomaali](README.so.md), [Português Brasil](README.pt_BR.md), [日本語](README.ja.md), [Română](README.ro.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md).*
*Read this in other languages: [English](README.md), [Español](doc/README.es.md), [한국어](doc/README.ko.md), [Soomaali](doc/README.so.md), [Português Brasil](doc/README.pt_BR.md), [Polski](doc/README.pl.md), [日本語](doc/README.ja.md), [Română](doc/README.ro.md), [Türkçe](doc/README.tr.md), [正體中文](doc/README.zh_TW.md).*
<b>WARNING: THIS IS A BETA VERSION, THEREFORE YOU MAY ENCOUNTER BUGS. IF YOU DO, OPEN AN ISSUE VIA OUR GITHUB REPOSITORY.</b>
@ -140,7 +140,7 @@ Therefore, the app does not collect any data without your consent. NewPipe's pri
## License
[![GNU GPLv3 Image](https://www.gnu.org/graphics/gplv3-127x51.png)](https://www.gnu.org/licenses/gpl-3.0.en.html)
NewPipe is Free Software: You can use, study share and improve it at your
NewPipe is Free Software: You can use, study, share, and improve it at
will. Specifically you can redistribute and/or modify it under the terms of the
[GNU General Public License](https://www.gnu.org/licenses/gpl.html) as
published by the Free Software Foundation, either version 3 of the License, or

View File

@ -8,16 +8,16 @@ plugins {
}
android {
compileSdkVersion 30
compileSdk 30
buildToolsVersion '30.0.3'
defaultConfig {
applicationId "org.schabi.newpipe"
resValue "string", "app_name", "NewPipe"
minSdkVersion 19
targetSdkVersion 29
versionCode 981
versionName "0.21.15"
minSdk 19
targetSdk 29
versionCode 983
versionName "0.22.0"
multiDexEnabled true
@ -65,7 +65,7 @@ android {
}
}
lintOptions {
lint {
checkReleaseBuilds false
// Or, if you prefer, you can continue to check for errors in release builds,
// but continue the build even when errors are found:
@ -98,7 +98,7 @@ android {
}
ext {
checkstyleVersion = '9.2'
checkstyleVersion = '9.2.1'
androidxLifecycleVersion = '2.3.1'
androidxRoomVersion = '2.3.0'
@ -190,7 +190,7 @@ dependencies {
// name and the commit hash with the commit hash of the (pushed) commit you want to test
// This works thanks to JitPack: https://jitpack.io/
implementation 'com.github.TeamNewPipe:nanojson:1d9e1aea9049fc9f85e68b43ba39fe7be1c1f751'
implementation 'com.github.TeamNewPipe:NewPipeExtractor:10f6cc71'
implementation 'com.github.TeamNewPipe:NewPipeExtractor:v0.21.14'
/** Checkstyle **/
checkstyle "com.puppycrawl.tools:checkstyle:${checkstyleVersion}"
@ -263,7 +263,7 @@ dependencies {
implementation "com.nononsenseapps:filepicker:4.2.1"
// Crash reporting
implementation "ch.acra:acra-core:5.7.0"
implementation "ch.acra:acra-core:5.8.4"
// Properly restarting
implementation 'com.jakewharton:process-phoenix:2.1.2'

View File

@ -97,14 +97,23 @@ class HistoryRecordManagerTest {
assertThat(database.searchHistoryDAO().all.blockingFirst()).isEmpty()
}
@Test
fun getRelatedSearches_emptyQuery() {
private fun insertShuffledRelatedSearches(relatedSearches: Collection<SearchHistoryEntry>) {
// shuffle to make sure the order of items returned by queries depends only on
// SearchHistoryEntry.creationDate, not on the actual insertion time, so that we can
// verify that the `ORDER BY` clause does its job
database.searchHistoryDAO().insertAll(relatedSearches.shuffled())
// make sure all entries were inserted
database.searchHistoryDAO().insertAll(RELATED_SEARCHES_ENTRIES)
assertEquals(
RELATED_SEARCHES_ENTRIES.size,
relatedSearches.size,
database.searchHistoryDAO().all.blockingFirst().size
)
}
@Test
fun getRelatedSearches_emptyQuery() {
insertShuffledRelatedSearches(RELATED_SEARCHES_ENTRIES)
// make sure correct number of searches is returned and in correct order
val searches = manager.getRelatedSearches("", 6, 4).blockingFirst()
@ -117,14 +126,29 @@ class HistoryRecordManagerTest {
}
@Test
fun getRelatedSearched_nonEmptyQuery() {
// make sure all entries were inserted
database.searchHistoryDAO().insertAll(RELATED_SEARCHES_ENTRIES)
assertEquals(
RELATED_SEARCHES_ENTRIES.size,
database.searchHistoryDAO().all.blockingFirst().size
fun getRelatedSearches_emptyQuery_manyDuplicates() {
insertShuffledRelatedSearches(
listOf(
SearchHistoryEntry(time.minusSeconds(9), 3, "A"),
SearchHistoryEntry(time.minusSeconds(8), 3, "AB"),
SearchHistoryEntry(time.minusSeconds(7), 3, "A"),
SearchHistoryEntry(time.minusSeconds(6), 3, "A"),
SearchHistoryEntry(time.minusSeconds(5), 3, "BA"),
SearchHistoryEntry(time.minusSeconds(4), 3, "A"),
SearchHistoryEntry(time.minusSeconds(3), 3, "A"),
SearchHistoryEntry(time.minusSeconds(2), 0, "A"),
SearchHistoryEntry(time.minusSeconds(1), 2, "AA"),
)
)
val searches = manager.getRelatedSearches("", 9, 3).blockingFirst()
assertThat(searches).containsExactly("AA", "A", "BA")
}
@Test
fun getRelatedSearched_nonEmptyQuery() {
insertShuffledRelatedSearches(RELATED_SEARCHES_ENTRIES)
// make sure correct number of searches is returned and in correct order
val searches = manager.getRelatedSearches("A", 3, 5).blockingFirst()
assertThat(searches).containsExactly(

View File

@ -0,0 +1,20 @@
package org.schabi.newpipe.settings;
import android.content.Intent;
import leakcanary.LeakCanary;
/**
* Build variant dependent (BVD) leak canary API implementation for the debug settings fragment.
* This class is loaded via reflection by
* {@link DebugSettingsFragment.DebugSettingsBVDLeakCanaryAPI}.
*/
@SuppressWarnings("unused") // Class is used but loaded via reflection
public class DebugSettingsBVDLeakCanary
implements DebugSettingsFragment.DebugSettingsBVDLeakCanaryAPI {
@Override
public Intent getNewLeakDisplayActivityIntent() {
return LeakCanary.INSTANCE.newLeakDisplayActivityIntent();
}
}

View File

@ -0,0 +1,148 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.text.similarity;
import java.util.Locale;
/**
* A matching algorithm that is similar to the searching algorithms implemented in editors such
* as Sublime Text, TextMate, Atom and others.
*
* <p>
* One point is given for every matched character. Subsequent matches yield two bonus points.
* A higher score indicates a higher similarity.
* </p>
*
* <p>
* This code has been adapted from Apache Commons Lang 3.3.
* </p>
*
* @since 1.0
*
* Note: This class was forked from
* <a href="https://git.io/JyYJg">
* apache/commons-text (8cfdafc) FuzzyScore.java
* </a>
*/
public class FuzzyScore {
/**
* Locale used to change the case of text.
*/
private final Locale locale;
/**
* This returns a {@link Locale}-specific {@link FuzzyScore}.
*
* @param locale The string matching logic is case insensitive.
A {@link Locale} is necessary to normalize both Strings to lower case.
* @throws IllegalArgumentException
* This is thrown if the {@link Locale} parameter is {@code null}.
*/
public FuzzyScore(final Locale locale) {
if (locale == null) {
throw new IllegalArgumentException("Locale must not be null");
}
this.locale = locale;
}
/**
* Find the Fuzzy Score which indicates the similarity score between two
* Strings.
*
* <pre>
* score.fuzzyScore(null, null) = IllegalArgumentException
* score.fuzzyScore("not null", null) = IllegalArgumentException
* score.fuzzyScore(null, "not null") = IllegalArgumentException
* score.fuzzyScore("", "") = 0
* score.fuzzyScore("Workshop", "b") = 0
* score.fuzzyScore("Room", "o") = 1
* score.fuzzyScore("Workshop", "w") = 1
* score.fuzzyScore("Workshop", "ws") = 2
* score.fuzzyScore("Workshop", "wo") = 4
* score.fuzzyScore("Apache Software Foundation", "asf") = 3
* </pre>
*
* @param term a full term that should be matched against, must not be null
* @param query the query that will be matched against a term, must not be
* null
* @return result score
* @throws IllegalArgumentException if the term or query is {@code null}
*/
public Integer fuzzyScore(final CharSequence term, final CharSequence query) {
if (term == null || query == null) {
throw new IllegalArgumentException("CharSequences must not be null");
}
// fuzzy logic is case insensitive. We normalize the Strings to lower
// case right from the start. Turning characters to lower case
// via Character.toLowerCase(char) is unfortunately insufficient
// as it does not accept a locale.
final String termLowerCase = term.toString().toLowerCase(locale);
final String queryLowerCase = query.toString().toLowerCase(locale);
// the resulting score
int score = 0;
// the position in the term which will be scanned next for potential
// query character matches
int termIndex = 0;
// index of the previously matched character in the term
int previousMatchingCharacterIndex = Integer.MIN_VALUE;
for (int queryIndex = 0; queryIndex < queryLowerCase.length(); queryIndex++) {
final char queryChar = queryLowerCase.charAt(queryIndex);
boolean termCharacterMatchFound = false;
for (; termIndex < termLowerCase.length()
&& !termCharacterMatchFound; termIndex++) {
final char termChar = termLowerCase.charAt(termIndex);
if (queryChar == termChar) {
// simple character matches result in one point
score++;
// subsequent character matches further improve
// the score.
if (previousMatchingCharacterIndex + 1 == termIndex) {
score += 2;
}
previousMatchingCharacterIndex = termIndex;
// we can leave the nested loop. Every character in the
// query can match at most one character in the term.
termCharacterMatchFound = true;
}
}
}
return score;
}
/**
* Gets the locale.
*
* @return The locale
*/
public Locale getLocale() {
return locale;
}
}

View File

@ -13,13 +13,8 @@ import androidx.preference.PreferenceManager;
import com.jakewharton.processphoenix.ProcessPhoenix;
import org.acra.ACRA;
import org.acra.config.ACRAConfigurationException;
import org.acra.config.CoreConfiguration;
import org.acra.config.CoreConfigurationBuilder;
import org.schabi.newpipe.error.ErrorInfo;
import org.schabi.newpipe.error.ErrorUtil;
import org.schabi.newpipe.error.ReCaptchaActivity;
import org.schabi.newpipe.error.UserAction;
import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.downloader.Downloader;
import org.schabi.newpipe.ktx.ExceptionUtils;
@ -210,16 +205,9 @@ public class App extends MultiDexApplication {
return;
}
try {
final CoreConfiguration acraConfig = new CoreConfigurationBuilder(this)
.setBuildConfigClass(BuildConfig.class)
.build();
ACRA.init(this, acraConfig);
} catch (final ACRAConfigurationException exception) {
exception.printStackTrace();
ErrorUtil.openActivity(this, new ErrorInfo(exception,
UserAction.SOMETHING_ELSE, "Could not initialize ACRA crash report"));
}
final CoreConfigurationBuilder acraConfig = new CoreConfigurationBuilder(this)
.withBuildConfigClass(BuildConfig.class);
ACRA.init(this, acraConfig);
}
private void initNotificationChannels() {

View File

@ -14,6 +14,7 @@ import org.schabi.newpipe.local.dialog.PlaylistDialog;
import org.schabi.newpipe.player.playqueue.PlayQueue;
import org.schabi.newpipe.player.playqueue.PlayQueueItem;
import org.schabi.newpipe.util.NavigationHelper;
import org.schabi.newpipe.util.SaveUploaderUrlHelper;
import java.util.Collections;
@ -61,11 +62,13 @@ public final class QueueItemMenuUtil {
return true;
case R.id.menu_item_channel_details:
// An intent must be used here.
// Opening with FragmentManager transactions is not working,
// as PlayQueueActivity doesn't use fragments.
NavigationHelper.openChannelFragmentUsingIntent(context, item.getServiceId(),
item.getUploaderUrl(), item.getUploader());
SaveUploaderUrlHelper.saveUploaderUrlIfNeeded(context, item,
// An intent must be used here.
// Opening with FragmentManager transactions is not working,
// as PlayQueueActivity doesn't use fragments.
uploaderUrl -> NavigationHelper.openChannelFragmentUsingIntent(
context, item.getServiceId(), uploaderUrl, item.getUploader()
));
return true;
case R.id.menu_item_share:
shareText(context, item.getTitle(), item.getUrl(),

View File

@ -185,7 +185,11 @@ class AboutActivity : AppCompatActivity() {
SoftwareComponent(
"RxJava", "2016 - 2020", "RxJava Contributors",
"https://github.com/ReactiveX/RxJava", StandardLicenses.APACHE2
)
),
SoftwareComponent(
"SearchPreference", "2018", "ByteHamster",
"https://github.com/ByteHamster/SearchPreference", StandardLicenses.MIT
),
)
private const val POS_ABOUT = 0
private const val POS_LICENSE = 1

View File

@ -500,6 +500,10 @@ public final class VideoDetailFragment
break;
case R.id.detail_thumbnail_root_layout:
autoPlayEnabled = true; // forcefully start playing
// FIXME Workaround #7427
if (isPlayerAvailable()) {
player.setRecovery();
}
openVideoPlayerAutoFullscreen();
break;
case R.id.detail_title_root_layout:

View File

@ -352,7 +352,7 @@ public abstract class BaseListFragment<I, N> extends BaseStateFragment<I>
}
final List<StreamDialogEntry> entries = new ArrayList<>();
if (PlayerHolder.getInstance().isPlayerOpen()) {
if (PlayerHolder.getInstance().isPlayQueueReady()) {
entries.add(StreamDialogEntry.enqueue);
if (PlayerHolder.getInstance().getQueueSize() > 1) {

View File

@ -149,7 +149,7 @@ public class PlaylistFragment extends BaseListInfoFragment<PlaylistInfo> {
final ArrayList<StreamDialogEntry> entries = new ArrayList<>();
if (PlayerHolder.getInstance().isPlayerOpen()) {
if (PlayerHolder.getInstance().isPlayQueueReady()) {
entries.add(StreamDialogEntry.enqueue);
if (PlayerHolder.getInstance().getQueueSize() > 1) {

View File

@ -25,7 +25,6 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.animation.DecelerateInterpolator;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.TextView;
@ -34,7 +33,6 @@ import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.TooltipCompat;
import androidx.core.content.ContextCompat;
import androidx.core.text.HtmlCompat;
import androidx.preference.PreferenceManager;
import androidx.recyclerview.widget.ItemTouchHelper;
@ -65,6 +63,7 @@ import org.schabi.newpipe.settings.NewPipeSettings;
import org.schabi.newpipe.util.Constants;
import org.schabi.newpipe.util.DeviceUtils;
import org.schabi.newpipe.util.ExtractorHelper;
import org.schabi.newpipe.util.KeyboardUtil;
import org.schabi.newpipe.util.NavigationHelper;
import org.schabi.newpipe.util.ServiceHelper;
@ -670,31 +669,15 @@ public class SearchFragment extends BaseListFragment<SearchInfo, ListExtractor.I
if (DEBUG) {
Log.d(TAG, "showKeyboardSearch() called");
}
if (searchEditText == null) {
return;
}
if (searchEditText.requestFocus()) {
final InputMethodManager imm = ContextCompat.getSystemService(activity,
InputMethodManager.class);
imm.showSoftInput(searchEditText, InputMethodManager.SHOW_FORCED);
}
KeyboardUtil.showKeyboard(activity, searchEditText);
}
private void hideKeyboardSearch() {
if (DEBUG) {
Log.d(TAG, "hideKeyboardSearch() called");
}
if (searchEditText == null) {
return;
}
final InputMethodManager imm = ContextCompat.getSystemService(activity,
InputMethodManager.class);
imm.hideSoftInputFromWindow(searchEditText.getWindowToken(),
InputMethodManager.RESULT_UNCHANGED_SHOWN);
searchEditText.clearFocus();
KeyboardUtil.hideKeyboard(activity, searchEditText);
}
private void showDeleteSuggestionDialog(final SuggestionItem item) {

View File

@ -75,6 +75,7 @@ fun View.animate(
}
animate().setListener(null).cancel()
isVisible = true
when (animationType) {
AnimationType.ALPHA -> animateAlpha(enterOrExit, duration, delay, execOnEnd)
AnimationType.SCALE_AND_ALPHA -> animateScaleAndAlpha(enterOrExit, duration, delay, execOnEnd)

View File

@ -362,7 +362,7 @@ class FeedFragment : BaseStateFragment<FeedState>() {
if (context == null || context.resources == null || activity == null) return
val entries = ArrayList<StreamDialogEntry>()
if (PlayerHolder.getInstance().isPlayerOpen) {
if (PlayerHolder.getInstance().isPlayQueueReady) {
entries.add(StreamDialogEntry.enqueue)
if (PlayerHolder.getInstance().queueSize > 1) {

View File

@ -338,7 +338,7 @@ public class StatisticsPlaylistFragment
final ArrayList<StreamDialogEntry> entries = new ArrayList<>();
if (PlayerHolder.getInstance().isPlayerOpen()) {
if (PlayerHolder.getInstance().isPlayQueueReady()) {
entries.add(StreamDialogEntry.enqueue);
if (PlayerHolder.getInstance().getQueueSize() > 1) {

View File

@ -753,7 +753,7 @@ public class LocalPlaylistFragment extends BaseLocalListFragment<List<PlaylistSt
final ArrayList<StreamDialogEntry> entries = new ArrayList<>();
if (PlayerHolder.getInstance().isPlayerOpen()) {
if (PlayerHolder.getInstance().isPlayQueueReady()) {
entries.add(StreamDialogEntry.enqueue);
if (PlayerHolder.getInstance().getQueueSize() > 1) {

View File

@ -51,9 +51,6 @@ import static java.util.concurrent.TimeUnit.MILLISECONDS;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.content.BroadcastReceiver;
import android.content.Context;
@ -154,6 +151,7 @@ import org.schabi.newpipe.info_list.StreamSegmentAdapter;
import org.schabi.newpipe.ktx.AnimationType;
import org.schabi.newpipe.local.history.HistoryRecordManager;
import org.schabi.newpipe.player.MainPlayer.PlayerType;
import org.schabi.newpipe.player.event.DisplayPortion;
import org.schabi.newpipe.player.event.PlayerEventListener;
import org.schabi.newpipe.player.event.PlayerGestureListener;
import org.schabi.newpipe.player.event.PlayerServiceEventListener;
@ -188,6 +186,7 @@ import org.schabi.newpipe.util.StreamTypeUtil;
import org.schabi.newpipe.util.external_communication.KoreUtils;
import org.schabi.newpipe.util.external_communication.ShareUtils;
import org.schabi.newpipe.views.ExpandableSurfaceView;
import org.schabi.newpipe.views.player.PlayerFastSeekOverlay;
import java.io.IOException;
import java.util.ArrayList;
@ -247,6 +246,7 @@ public final class Player implements
public static final int DEFAULT_CONTROLS_DURATION = 300; // 300 millis
public static final int DEFAULT_CONTROLS_HIDE_TIME = 2000; // 2 Seconds
public static final int DPAD_CONTROLS_HIDE_TIME = 7000; // 7 Seconds
public static final int SEEK_OVERLAY_DURATION = 450; // 450 millis
/*//////////////////////////////////////////////////////////////////////////
// Other constants
@ -260,7 +260,8 @@ public final class Player implements
// Playback
//////////////////////////////////////////////////////////////////////////*/
private PlayQueue playQueue;
// play queue might be null e.g. while player is starting
@Nullable private PlayQueue playQueue;
private PlayQueueAdapter playQueueAdapter;
private StreamSegmentAdapter segmentAdapter;
@ -313,7 +314,6 @@ public final class Player implements
private PlayerBinding binding;
private ValueAnimator controlViewAnimator;
private final Handler controlsVisibilityHandler = new Handler();
// fullscreen player
@ -365,6 +365,7 @@ public final class Player implements
private int maxGestureLength; // scaled
private GestureDetectorCompat gestureDetector;
private PlayerGestureListener playerGestureListener;
/*//////////////////////////////////////////////////////////////////////////
// Listeners and disposables
@ -449,6 +450,8 @@ public final class Player implements
initPlayer(true);
}
initListeners();
setupPlayerSeekOverlay();
}
private void initViews(@NonNull final PlayerBinding playerBinding) {
@ -525,9 +528,9 @@ public final class Player implements
binding.resizeTextView.setOnClickListener(this);
binding.playbackLiveSync.setOnClickListener(this);
final PlayerGestureListener listener = new PlayerGestureListener(this, service);
gestureDetector = new GestureDetectorCompat(context, listener);
binding.getRoot().setOnTouchListener(listener);
playerGestureListener = new PlayerGestureListener(this, service);
gestureDetector = new GestureDetectorCompat(context, playerGestureListener);
binding.getRoot().setOnTouchListener(playerGestureListener);
binding.queueButton.setOnClickListener(this);
binding.segmentsButton.setOnClickListener(this);
@ -569,15 +572,83 @@ public final class Player implements
});
// PlaybackControlRoot already consumed window insets but we should pass them to
// player_overlays too. Without it they will be off-centered
// player_overlays and fast_seek_overlay too. Without it they will be off-centered.
binding.playbackControlRoot.addOnLayoutChangeListener(
(v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) ->
binding.playerOverlays.setPadding(
v.getPaddingLeft(),
v.getPaddingTop(),
v.getPaddingRight(),
v.getPaddingBottom()));
(v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> {
binding.playerOverlays.setPadding(
v.getPaddingLeft(),
v.getPaddingTop(),
v.getPaddingRight(),
v.getPaddingBottom());
binding.fastSeekOverlay.setPadding(
v.getPaddingLeft(),
v.getPaddingTop(),
v.getPaddingRight(),
v.getPaddingBottom());
});
}
/**
* Initializes the Fast-For/Backward overlay.
*/
private void setupPlayerSeekOverlay() {
binding.fastSeekOverlay
.seekSecondsSupplier(
() -> (int) (retrieveSeekDurationFromPreferences(this) / 1000.0f))
.performListener(new PlayerFastSeekOverlay.PerformListener() {
@Override
public void onDoubleTap() {
animate(binding.fastSeekOverlay, true, SEEK_OVERLAY_DURATION);
}
@Override
public void onDoubleTapEnd() {
animate(binding.fastSeekOverlay, false, SEEK_OVERLAY_DURATION);
}
@Override
public FastSeekDirection getFastSeekDirection(
@NonNull final DisplayPortion portion
) {
if (exoPlayerIsNull()) {
// Abort seeking
playerGestureListener.endMultiDoubleTap();
return FastSeekDirection.NONE;
}
if (portion == DisplayPortion.LEFT) {
// Check if it's possible to rewind
// Small puffer to eliminate infinite rewind seeking
if (simpleExoPlayer.getCurrentPosition() < 500L) {
return FastSeekDirection.NONE;
}
return FastSeekDirection.BACKWARD;
} else if (portion == DisplayPortion.RIGHT) {
// Check if it's possible to fast-forward
if (currentState == STATE_COMPLETED
|| simpleExoPlayer.getCurrentPosition()
>= simpleExoPlayer.getDuration()) {
return FastSeekDirection.NONE;
}
return FastSeekDirection.FORWARD;
}
/* portion == DisplayPortion.MIDDLE */
return FastSeekDirection.NONE;
}
@Override
public void seek(final boolean forward) {
playerGestureListener.keepInDoubleTapMode();
if (forward) {
fastForward();
} else {
fastRewind();
}
}
});
playerGestureListener.doubleTapControls(binding.fastSeekOverlay);
}
//endregion
@ -1796,71 +1867,6 @@ public final class Player implements
return binding != null && binding.playbackControlRoot.getVisibility() == View.VISIBLE;
}
/**
* Show a animation, and depending on goneOnEnd, will stay on the screen or be gone.
*
* @param drawableId the drawable that will be used to animate,
* pass -1 to clear any animation that is visible
* @param goneOnEnd will set the animation view to GONE on the end of the animation
*/
public void showAndAnimateControl(final int drawableId, final boolean goneOnEnd) {
if (DEBUG) {
Log.d(TAG, "showAndAnimateControl() called with: "
+ "drawableId = [" + drawableId + "], goneOnEnd = [" + goneOnEnd + "]");
}
if (controlViewAnimator != null && controlViewAnimator.isRunning()) {
if (DEBUG) {
Log.d(TAG, "showAndAnimateControl: controlViewAnimator.isRunning");
}
controlViewAnimator.end();
}
if (drawableId == -1) {
if (binding.controlAnimationView.getVisibility() == View.VISIBLE) {
controlViewAnimator = ObjectAnimator.ofPropertyValuesHolder(
binding.controlAnimationView,
PropertyValuesHolder.ofFloat(View.ALPHA, 1.0f, 0.0f),
PropertyValuesHolder.ofFloat(View.SCALE_X, 1.4f, 1.0f),
PropertyValuesHolder.ofFloat(View.SCALE_Y, 1.4f, 1.0f)
).setDuration(DEFAULT_CONTROLS_DURATION);
controlViewAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(final Animator animation) {
binding.controlAnimationView.setVisibility(View.GONE);
}
});
controlViewAnimator.start();
}
return;
}
final float scaleFrom = goneOnEnd ? 1f : 1f;
final float scaleTo = goneOnEnd ? 1.8f : 1.4f;
final float alphaFrom = goneOnEnd ? 1f : 0f;
final float alphaTo = goneOnEnd ? 0f : 1f;
controlViewAnimator = ObjectAnimator.ofPropertyValuesHolder(
binding.controlAnimationView,
PropertyValuesHolder.ofFloat(View.ALPHA, alphaFrom, alphaTo),
PropertyValuesHolder.ofFloat(View.SCALE_X, scaleFrom, scaleTo),
PropertyValuesHolder.ofFloat(View.SCALE_Y, scaleFrom, scaleTo)
);
controlViewAnimator.setDuration(goneOnEnd ? 1000 : 500);
controlViewAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(final Animator animation) {
binding.controlAnimationView.setVisibility(goneOnEnd ? View.GONE : View.VISIBLE);
}
});
binding.controlAnimationView.setVisibility(View.VISIBLE);
binding.controlAnimationView.setImageDrawable(
AppCompatResources.getDrawable(context, drawableId));
controlViewAnimator.start();
}
public void showControlsThenHide() {
if (DEBUG) {
Log.d(TAG, "showControlsThenHide() called");
@ -1905,6 +1911,7 @@ public final class Player implements
}
private void showHideShadow(final boolean show, final long duration) {
animate(binding.playbackControlsShadow, show, duration, AnimationType.ALPHA, 0, null);
animate(binding.playerTopShadow, show, duration, AnimationType.ALPHA, 0, null);
animate(binding.playerBottomShadow, show, duration, AnimationType.ALPHA, 0, null);
}
@ -2048,7 +2055,7 @@ public final class Player implements
if (currentState == STATE_BLOCKED) {
changeState(STATE_BUFFERING);
}
simpleExoPlayer.setMediaSource(mediaSource);
simpleExoPlayer.setMediaSource(mediaSource, false);
simpleExoPlayer.prepare();
}
@ -2102,8 +2109,8 @@ public final class Player implements
startProgressLoop();
}
controlsVisibilityHandler.removeCallbacksAndMessages(null);
animate(binding.playbackControlRoot, false, DEFAULT_CONTROLS_DURATION);
// if we are e.g. switching players, hide controls
hideControls(DEFAULT_CONTROLS_DURATION, 0);
binding.playbackSeekBar.setEnabled(false);
binding.playbackSeekBar.getThumb()
@ -2130,8 +2137,6 @@ public final class Player implements
updateStreamRelatedViews();
showAndAnimateControl(-1, true);
binding.playbackSeekBar.setEnabled(true);
binding.playbackSeekBar.getThumb()
.setColorFilter(new PorterDuffColorFilter(Color.RED, PorterDuff.Mode.SRC_IN));
@ -2179,18 +2184,21 @@ public final class Player implements
stopProgressLoop();
}
showControls(400);
binding.loadingPanel.setVisibility(View.GONE);
animate(binding.playPauseButton, false, 80, AnimationType.SCALE_AND_ALPHA, 0,
() -> {
binding.playPauseButton.setImageResource(R.drawable.ic_play_arrow);
animatePlayButtons(true, 200);
if (!isQueueVisible) {
binding.playPauseButton.requestFocus();
}
});
// Don't let UI elements popup during double tap seeking. This state is entered sometimes
// during seeking/loading. This if-else check ensures that the controls aren't popping up.
if (!playerGestureListener.isDoubleTapping()) {
showControls(400);
binding.loadingPanel.setVisibility(View.GONE);
animate(binding.playPauseButton, false, 80, AnimationType.SCALE_AND_ALPHA, 0,
() -> {
binding.playPauseButton.setImageResource(R.drawable.ic_play_arrow);
animatePlayButtons(true, 200);
if (!isQueueVisible) {
binding.playPauseButton.requestFocus();
}
});
}
changePopupWindowFlags(IDLE_WINDOW_FLAGS);
// Remove running notification when user does not want minimization to background or popup
@ -2208,7 +2216,6 @@ public final class Player implements
if (DEBUG) {
Log.d(TAG, "onPausedSeek() called");
}
showAndAnimateControl(-1, true);
animatePlayButtons(false, 100);
binding.getRoot().setKeepScreenOn(true);
@ -2517,23 +2524,11 @@ public final class Player implements
Log.e(TAG, "ExoPlayer - onPlayerError() called with:", error);
saveStreamProgressState();
// create error notification
final ErrorInfo errorInfo;
if (currentMetadata == null) {
errorInfo = new ErrorInfo(error, UserAction.PLAY_STREAM,
"Player error[type=" + error.type + "] occurred, currentMetadata is null");
} else {
errorInfo = new ErrorInfo(error, UserAction.PLAY_STREAM,
"Player error[type=" + error.type + "] occurred while playing "
+ currentMetadata.getMetadata().getUrl(),
currentMetadata.getMetadata());
}
ErrorUtil.createNotification(context, errorInfo);
boolean isCatchableException = false;
switch (error.type) {
case ExoPlaybackException.TYPE_SOURCE:
processSourceError(error.getSourceException());
isCatchableException = processSourceError(error.getSourceException());
break;
case ExoPlaybackException.TYPE_UNEXPECTED:
setRecovery();
@ -2546,22 +2541,60 @@ public final class Player implements
break;
}
if (isCatchableException) {
return;
}
createErrorNotification(error);
if (fragmentListener != null) {
fragmentListener.onPlayerError(error);
}
}
private void processSourceError(final IOException error) {
if (exoPlayerIsNull() || playQueue == null) {
return;
private void createErrorNotification(@NonNull final ExoPlaybackException error) {
final ErrorInfo errorInfo;
if (currentMetadata == null) {
errorInfo = new ErrorInfo(error, UserAction.PLAY_STREAM,
"Player error[type=" + error.type + "] occurred, currentMetadata is null");
} else {
errorInfo = new ErrorInfo(error, UserAction.PLAY_STREAM,
"Player error[type=" + error.type + "] occurred while playing "
+ currentMetadata.getMetadata().getUrl(),
currentMetadata.getMetadata());
}
ErrorUtil.createNotification(context, errorInfo);
}
/**
* Process an {@link IOException} returned by {@link ExoPlaybackException#getSourceException()}
* for {@link ExoPlaybackException#TYPE_SOURCE} exceptions.
*
* <p>
* This method sets the recovery position and sends an error message to the play queue if the
* exception is not a {@link BehindLiveWindowException}.
* </p>
* @param error the source error which was thrown by ExoPlayer
* @return whether the exception thrown is a {@link BehindLiveWindowException} ({@code false}
* is always returned if ExoPlayer or the play queue is null)
*/
private boolean processSourceError(final IOException error) {
if (exoPlayerIsNull() || playQueue == null) {
return false;
}
setRecovery();
if (error instanceof BehindLiveWindowException) {
reloadPlayQueueManager();
} else {
playQueue.error();
simpleExoPlayer.seekToDefaultPosition();
simpleExoPlayer.prepare();
// Inform the user that we are reloading the stream by switching to the buffering state
onBuffering();
return true;
}
playQueue.error();
return false;
}
//endregion
@ -2838,7 +2871,6 @@ public final class Player implements
}
seekBy(retrieveSeekDurationFromPreferences(this));
triggerProgressUpdate();
showAndAnimateControl(R.drawable.ic_fast_forward, true);
}
public void fastRewind() {
@ -2847,7 +2879,6 @@ public final class Player implements
}
seekBy(-retrieveSeekDurationFromPreferences(this));
triggerProgressUpdate();
showAndAnimateControl(R.drawable.ic_fast_rewind, true);
}
//endregion
@ -4202,6 +4233,7 @@ public final class Player implements
}
@Nullable
public PlayQueue getPlayQueue() {
return playQueue;
}
@ -4279,6 +4311,10 @@ public final class Player implements
return binding.currentDisplaySeek;
}
public PlayerFastSeekOverlay getFastSeekOverlay() {
return binding.fastSeekOverlay;
}
@Nullable
public WindowManager.LayoutParams getPopupLayoutParams() {
return popupLayoutParams;

View File

@ -411,7 +411,7 @@ abstract class BasePlayerGestureListener(
var doubleTapControls: DoubleTapListener? = null
private set
val isDoubleTapEnabled: Boolean
private val isDoubleTapEnabled: Boolean
get() = doubleTapDelay > 0
var isDoubleTapping = false
@ -459,10 +459,6 @@ abstract class BasePlayerGestureListener(
doubleTapControls?.onDoubleTapFinished()
}
fun enableMultiDoubleTap(enable: Boolean) = apply {
doubleTapDelay = if (enable) DOUBLE_TAP_DELAY else 0
}
// ///////////////////////////////////////////////////////////////////
// Utils
// ///////////////////////////////////////////////////////////////////

View File

@ -55,12 +55,10 @@ public class PlayerGestureListener
player.hideControls(0, 0);
}
if (portion == DisplayPortion.LEFT) {
player.fastRewind();
if (portion == DisplayPortion.LEFT || portion == DisplayPortion.RIGHT) {
startMultiDoubleTap(event);
} else if (portion == DisplayPortion.MIDDLE) {
player.playPause();
} else if (portion == DisplayPortion.RIGHT) {
player.fastForward();
}
}
@ -232,10 +230,10 @@ public class PlayerGestureListener
if (DEBUG) {
Log.d(TAG, "onPopupResizingStart called");
}
player.showAndAnimateControl(-1, true);
player.getLoadingPanel().setVisibility(View.GONE);
player.hideControls(0, 0);
animate(player.getFastSeekOverlay(), false, 0);
animate(player.getCurrentDisplaySeek(), false, 0, ALPHA, 0);
}

View File

@ -9,6 +9,7 @@ import com.google.android.exoplayer2.source.SingleSampleMediaSource;
import com.google.android.exoplayer2.source.dash.DashMediaSource;
import com.google.android.exoplayer2.source.dash.DefaultDashChunkSource;
import com.google.android.exoplayer2.source.hls.HlsMediaSource;
import com.google.android.exoplayer2.source.hls.playlist.DefaultHlsPlaylistTracker;
import com.google.android.exoplayer2.source.smoothstreaming.DefaultSsChunkSource;
import com.google.android.exoplayer2.source.smoothstreaming.SsMediaSource;
import com.google.android.exoplayer2.upstream.DataSource;
@ -17,9 +18,18 @@ import com.google.android.exoplayer2.upstream.DefaultLoadErrorHandlingPolicy;
import com.google.android.exoplayer2.upstream.TransferListener;
public class PlayerDataSource {
public static final int LIVE_STREAM_EDGE_GAP_MILLIS = 10000;
/**
* An approximately 4.3 times greater value than the
* {@link DefaultHlsPlaylistTracker#DEFAULT_PLAYLIST_STUCK_TARGET_DURATION_COEFFICIENT default}
* to ensure that (very) low latency livestreams which got stuck for a moment don't crash too
* early.
*/
private static final double PLAYLIST_STUCK_TARGET_DURATION_COEFFICIENT = 15;
private static final int MANIFEST_MINIMUM_RETRY = 5;
private static final int EXTRACTOR_MINIMUM_RETRY = Integer.MAX_VALUE;
public static final int LIVE_STREAM_EDGE_GAP_MILLIS = 10000;
private final DataSource.Factory cacheDataSourceFactory;
private final DataSource.Factory cachelessDataSourceFactory;
@ -44,8 +54,13 @@ public class PlayerDataSource {
public HlsMediaSource.Factory getLiveHlsMediaSourceFactory() {
return new HlsMediaSource.Factory(cachelessDataSourceFactory)
.setAllowChunklessPreparation(true)
.setLoadErrorHandlingPolicy(
new DefaultLoadErrorHandlingPolicy(MANIFEST_MINIMUM_RETRY));
.setLoadErrorHandlingPolicy(new DefaultLoadErrorHandlingPolicy(
MANIFEST_MINIMUM_RETRY))
.setPlaylistTrackerFactory((dataSourceFactory, loadErrorHandlingPolicy,
playlistParserFactory) ->
new DefaultHlsPlaylistTracker(dataSourceFactory, loadErrorHandlingPolicy,
playlistParserFactory, PLAYLIST_STUCK_TARGET_DURATION_COEFFICIENT)
);
}
public DashMediaSource.Factory getLiveDashMediaSourceFactory() {

View File

@ -38,12 +38,12 @@ public final class PlayerHolder {
private static final boolean DEBUG = MainActivity.DEBUG;
private static final String TAG = PlayerHolder.class.getSimpleName();
private PlayerServiceExtendedEventListener listener;
@Nullable private PlayerServiceExtendedEventListener listener;
private final PlayerServiceConnection serviceConnection = new PlayerServiceConnection();
private boolean bound;
private MainPlayer playerService;
private Player player;
@Nullable private MainPlayer playerService;
@Nullable private Player player;
/**
* Returns the current {@link MainPlayer.PlayerType} of the {@link MainPlayer} service,
@ -70,12 +70,25 @@ public final class PlayerHolder {
return player != null;
}
/**
* Use this method to only allow the user to manipulate the play queue (e.g. by enqueueing via
* the stream long press menu) when there actually is a play queue to manipulate.
* @return true only if the player is open and its play queue is ready (i.e. it is not null)
*/
public boolean isPlayQueueReady() {
return player != null && player.getPlayQueue() != null;
}
public boolean isBound() {
return bound;
}
public int getQueueSize() {
return isPlayerOpen() ? player.getPlayQueue().size() : 0;
if (player == null || player.getPlayQueue() == null) {
// player play queue might be null e.g. while player is starting
return 0;
}
return player.getPlayQueue().size();
}
public void setListener(@Nullable final PlayerServiceExtendedEventListener newListener) {

View File

@ -2,7 +2,6 @@ package org.schabi.newpipe.settings;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.widget.Toast;
@ -15,14 +14,10 @@ import org.schabi.newpipe.util.Constants;
import org.schabi.newpipe.util.ThemeHelper;
public class AppearanceSettingsFragment extends BasePreferenceFragment {
private static final boolean CAPTIONING_SETTINGS_ACCESSIBLE =
Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
private String captionSettingsKey;
@Override
public void onCreatePreferences(final Bundle savedInstanceState, final String rootKey) {
addPreferencesFromResource(R.xml.appearance_settings);
addPreferencesFromResourceRegistry();
final String themeKey = getString(R.string.theme_key);
// the key of the active theme when settings were opened (or recreated after theme change)
@ -51,16 +46,11 @@ public class AppearanceSettingsFragment extends BasePreferenceFragment {
} else {
removePreference(nightThemeKey);
}
captionSettingsKey = getString(R.string.caption_settings_key);
if (!CAPTIONING_SETTINGS_ACCESSIBLE) {
removePreference(captionSettingsKey);
}
}
@Override
public boolean onPreferenceTreeClick(final Preference preference) {
if (captionSettingsKey.equals(preference.getKey()) && CAPTIONING_SETTINGS_ACCESSIBLE) {
if (preference.getKey().equals(getString(R.string.caption_settings_key))) {
try {
startActivity(new Intent(Settings.ACTION_CAPTIONING_SETTINGS));
} catch (final ActivityNotFoundException e) {

View File

@ -28,6 +28,11 @@ public abstract class BasePreferenceFragment extends PreferenceFragmentCompat {
super.onCreate(savedInstanceState);
}
protected void addPreferencesFromResourceRegistry() {
addPreferencesFromResource(
SettingsResourceRegistry.getInstance().getPreferencesResId(this.getClass()));
}
@Override
public void onViewCreated(@NonNull final View rootView,
@Nullable final Bundle savedInstanceState) {

View File

@ -1,5 +1,8 @@
package org.schabi.newpipe.settings;
import static org.schabi.newpipe.extractor.utils.Utils.isBlank;
import static org.schabi.newpipe.util.Localization.assureCorrectAppLanguage;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
@ -21,7 +24,6 @@ import org.schabi.newpipe.DownloaderImpl;
import org.schabi.newpipe.NewPipeDatabase;
import org.schabi.newpipe.R;
import org.schabi.newpipe.error.ErrorUtil;
import org.schabi.newpipe.error.ReCaptchaActivity;
import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.localization.ContentCountry;
import org.schabi.newpipe.extractor.localization.Localization;
@ -38,9 +40,6 @@ import java.util.Date;
import java.util.Locale;
import java.util.Objects;
import static org.schabi.newpipe.extractor.utils.Utils.isBlank;
import static org.schabi.newpipe.util.Localization.assureCorrectAppLanguage;
public class ContentSettingsFragment extends BasePreferenceFragment {
private static final String ZIP_MIME_TYPE = "application/zip";
@ -70,7 +69,7 @@ public class ContentSettingsFragment extends BasePreferenceFragment {
importExportDataPathKey = getString(R.string.import_export_data_path);
youtubeRestrictedModeEnabledKey = getString(R.string.youtube_restricted_mode_enabled);
addPreferencesFromResource(R.xml.content_settings);
addPreferencesFromResourceRegistry();
final Preference importDataPreference = requirePreference(R.string.import_data);
importDataPreference.setOnPreferenceClickListener((Preference p) -> {
@ -105,21 +104,6 @@ public class ContentSettingsFragment extends BasePreferenceFragment {
.getPreferredContentCountry(requireContext());
initialLanguage = defaultPreferences.getString(getString(R.string.app_language_key), "en");
final Preference clearCookiePref = requirePreference(R.string.clear_cookie_key);
clearCookiePref.setOnPreferenceClickListener(preference -> {
defaultPreferences.edit()
.putString(getString(R.string.recaptcha_cookies_key), "").apply();
DownloaderImpl.getInstance().setCookie(ReCaptchaActivity.RECAPTCHA_COOKIES_KEY, "");
Toast.makeText(getActivity(), R.string.recaptcha_cookies_cleared,
Toast.LENGTH_SHORT).show();
clearCookiePref.setVisible(false);
return true;
});
if (defaultPreferences.getString(getString(R.string.recaptcha_cookies_key), "").isEmpty()) {
clearCookiePref.setVisible(false);
}
findPreference(getString(R.string.download_thumbnail_key)).setOnPreferenceChangeListener(
(preference, newValue) -> {
PicassoHelper.setShouldLoadImages((Boolean) newValue);

View File

@ -1,5 +1,6 @@
package org.schabi.newpipe.settings;
import android.content.Intent;
import android.os.Bundle;
import androidx.preference.Preference;
@ -11,13 +12,17 @@ import org.schabi.newpipe.error.UserAction;
import org.schabi.newpipe.util.PicassoHelper;
import org.schabi.newpipe.local.feed.notifications.NotificationWorker;
import leakcanary.LeakCanary;
import java.util.Optional;
public class DebugSettingsFragment extends BasePreferenceFragment {
private static final String DUMMY = "Dummy";
@Override
public void onCreatePreferences(final Bundle savedInstanceState, final String rootKey) {
addPreferencesFromResource(R.xml.debug_settings);
addPreferencesFromResourceRegistry();
final Preference allowHeapDumpingPreference
= findPreference(getString(R.string.allow_heap_dumping_key));
final Preference showMemoryLeaksPreference
= findPreference(getString(R.string.show_memory_leaks_key));
final Preference showImageIndicatorsPreference
@ -31,6 +36,7 @@ public class DebugSettingsFragment extends BasePreferenceFragment {
final Preference createErrorNotificationPreference
= findPreference(getString(R.string.create_error_notification_key));
assert allowHeapDumpingPreference != null;
assert showMemoryLeaksPreference != null;
assert showImageIndicatorsPreference != null;
assert checkNewStreamsPreference != null;
@ -38,10 +44,22 @@ public class DebugSettingsFragment extends BasePreferenceFragment {
assert showErrorSnackbarPreference != null;
assert createErrorNotificationPreference != null;
showMemoryLeaksPreference.setOnPreferenceClickListener(preference -> {
startActivity(LeakCanary.INSTANCE.newLeakDisplayActivityIntent());
return true;
});
final Optional<DebugSettingsBVDLeakCanaryAPI> optBVLeakCanary = getBVDLeakCanary();
allowHeapDumpingPreference.setEnabled(optBVLeakCanary.isPresent());
showMemoryLeaksPreference.setEnabled(optBVLeakCanary.isPresent());
if (optBVLeakCanary.isPresent()) {
final DebugSettingsBVDLeakCanaryAPI pdLeakCanary = optBVLeakCanary.get();
showMemoryLeaksPreference.setOnPreferenceClickListener(preference -> {
startActivity(pdLeakCanary.getNewLeakDisplayActivityIntent());
return true;
});
} else {
allowHeapDumpingPreference.setSummary(R.string.leak_canary_not_available);
showMemoryLeaksPreference.setSummary(R.string.leak_canary_not_available);
}
showImageIndicatorsPreference.setOnPreferenceChangeListener((preference, newValue) -> {
PicassoHelper.setIndicatorsEnabled((Boolean) newValue);
@ -54,19 +72,46 @@ public class DebugSettingsFragment extends BasePreferenceFragment {
});
crashTheAppPreference.setOnPreferenceClickListener(preference -> {
throw new RuntimeException();
throw new RuntimeException(DUMMY);
});
showErrorSnackbarPreference.setOnPreferenceClickListener(preference -> {
ErrorUtil.showUiErrorSnackbar(DebugSettingsFragment.this,
"Dummy", new RuntimeException("Dummy"));
DUMMY, new RuntimeException(DUMMY));
return true;
});
createErrorNotificationPreference.setOnPreferenceClickListener(preference -> {
ErrorUtil.createNotification(requireContext(),
new ErrorInfo(new RuntimeException("Dummy"), UserAction.UI_ERROR, "Dummy"));
new ErrorInfo(new RuntimeException(DUMMY), UserAction.UI_ERROR, DUMMY));
return true;
});
}
/**
* Tries to find the {@link DebugSettingsBVDLeakCanaryAPI#IMPL_CLASS} and loads it if available.
* @return An {@link Optional} which is empty if the implementation class couldn't be loaded.
*/
private Optional<DebugSettingsBVDLeakCanaryAPI> getBVDLeakCanary() {
try {
// Try to find the implementation of the LeakCanary API
return Optional.of((DebugSettingsBVDLeakCanaryAPI)
Class.forName(DebugSettingsBVDLeakCanaryAPI.IMPL_CLASS)
.getDeclaredConstructor()
.newInstance());
} catch (final Exception e) {
return Optional.empty();
}
}
/**
* Build variant dependent (BVD) leak canary API for this fragment.
* Why is LeakCanary not used directly? Because it can't be assured
*/
public interface DebugSettingsBVDLeakCanaryAPI {
String IMPL_CLASS =
"org.schabi.newpipe.settings.DebugSettingsBVDLeakCanary";
Intent getNewLeakDisplayActivityIntent();
}
}

View File

@ -54,7 +54,7 @@ public class DownloadSettingsFragment extends BasePreferenceFragment {
@Override
public void onCreatePreferences(final Bundle savedInstanceState, final String rootKey) {
addPreferencesFromResource(R.xml.download_settings);
addPreferencesFromResourceRegistry();
downloadPathVideoPreference = getString(R.string.download_path_video_key);
downloadPathAudioPreference = getString(R.string.download_path_audio_key);

View File

@ -8,9 +8,11 @@ import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.preference.Preference;
import org.schabi.newpipe.DownloaderImpl;
import org.schabi.newpipe.R;
import org.schabi.newpipe.error.ErrorInfo;
import org.schabi.newpipe.error.ErrorUtil;
import org.schabi.newpipe.error.ReCaptchaActivity;
import org.schabi.newpipe.error.UserAction;
import org.schabi.newpipe.local.history.HistoryRecordManager;
import org.schabi.newpipe.util.InfoCache;
@ -29,7 +31,7 @@ public class HistorySettingsFragment extends BasePreferenceFragment {
@Override
public void onCreatePreferences(final Bundle savedInstanceState, final String rootKey) {
addPreferencesFromResource(R.xml.history_settings);
addPreferencesFromResourceRegistry();
cacheWipeKey = getString(R.string.metadata_cache_wipe_key);
viewsHistoryClearKey = getString(R.string.clear_views_history_key);
@ -37,6 +39,21 @@ public class HistorySettingsFragment extends BasePreferenceFragment {
searchHistoryClearKey = getString(R.string.clear_search_history_key);
recordManager = new HistoryRecordManager(getActivity());
disposables = new CompositeDisposable();
final Preference clearCookiePref = requirePreference(R.string.clear_cookie_key);
clearCookiePref.setOnPreferenceClickListener(preference -> {
defaultPreferences.edit()
.putString(getString(R.string.recaptcha_cookies_key), "").apply();
DownloaderImpl.getInstance().setCookie(ReCaptchaActivity.RECAPTCHA_COOKIES_KEY, "");
Toast.makeText(getActivity(), R.string.recaptcha_cookies_cleared,
Toast.LENGTH_SHORT).show();
clearCookiePref.setEnabled(false);
return true;
});
if (defaultPreferences.getString(getString(R.string.recaptcha_cookies_key), "").isEmpty()) {
clearCookiePref.setEnabled(false);
}
}
@Override

View File

@ -1,8 +1,11 @@
package org.schabi.newpipe.settings;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import androidx.preference.Preference;
import androidx.annotation.NonNull;
import org.schabi.newpipe.App;
import org.schabi.newpipe.CheckForNewAppVersion;
@ -12,16 +15,58 @@ import org.schabi.newpipe.R;
public class MainSettingsFragment extends BasePreferenceFragment {
public static final boolean DEBUG = MainActivity.DEBUG;
private SettingsActivity settingsActivity;
@Override
public void onCreatePreferences(final Bundle savedInstanceState, final String rootKey) {
addPreferencesFromResource(R.xml.main_settings);
addPreferencesFromResourceRegistry();
setHasOptionsMenu(true); // Otherwise onCreateOptionsMenu is not called
// Check if the app is updatable
if (!CheckForNewAppVersion.isReleaseApk(App.getApp())) {
final Preference update
= findPreference(getString(R.string.update_pref_screen_key));
getPreferenceScreen().removePreference(update);
getPreferenceScreen().removePreference(
findPreference(getString(R.string.update_pref_screen_key)));
defaultPreferences.edit().putBoolean(getString(R.string.update_app_key), false).apply();
}
// Hide debug preferences in RELEASE build variant
if (!DEBUG) {
getPreferenceScreen().removePreference(
findPreference(getString(R.string.debug_pref_screen_key)));
}
}
@Override
public void onCreateOptionsMenu(
@NonNull final Menu menu,
@NonNull final MenuInflater inflater
) {
super.onCreateOptionsMenu(menu, inflater);
// -- Link settings activity and register menu --
settingsActivity = (SettingsActivity) getActivity();
inflater.inflate(R.menu.menu_settings_main_fragment, menu);
final MenuItem menuSearchItem = menu.getItem(0);
settingsActivity.setMenuSearchItem(menuSearchItem);
menuSearchItem.setOnMenuItemClickListener(ev -> {
settingsActivity.setSearchActive(true);
return true;
});
}
@Override
public void onDestroy() {
// Unlink activity so that we don't get memory problems
if (settingsActivity != null) {
settingsActivity.setMenuSearchItem(null);
settingsActivity = null;
}
super.onDestroy();
}
}

View File

@ -0,0 +1,19 @@
package org.schabi.newpipe.settings
import android.os.Build
import android.os.Bundle
import androidx.preference.Preference
import org.schabi.newpipe.R
class NotificationSettingsFragment : BasePreferenceFragment() {
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
addPreferencesFromResourceRegistry()
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
val colorizePref: Preference? = findPreference(getString(R.string.notification_colorize_key))
colorizePref?.let {
preferenceScreen.removePreference(it)
}
}
}
}

View File

@ -7,7 +7,7 @@ import org.schabi.newpipe.R
class PlayerNotificationSettingsFragment : BasePreferenceFragment() {
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
addPreferencesFromResource(R.xml.player_notification_settings)
addPreferencesFromResourceRegistry()
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
val colorizePref: Preference? = findPreference(getString(R.string.notification_colorize_key))

View File

@ -1,6 +1,5 @@
package org.schabi.newpipe.settings;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
@ -51,16 +50,11 @@ public class SelectKioskFragment extends DialogFragment {
private SelectKioskAdapter selectKioskAdapter = null;
private OnSelectedListener onSelectedListener = null;
private OnCancelListener onCancelListener = null;
public void setOnSelectedListener(final OnSelectedListener listener) {
onSelectedListener = listener;
}
public void setOnCancelListener(final OnCancelListener listener) {
onCancelListener = listener;
}
/*//////////////////////////////////////////////////////////////////////////
// Init
//////////////////////////////////////////////////////////////////////////*/
@ -91,14 +85,6 @@ public class SelectKioskFragment extends DialogFragment {
// Handle actions
//////////////////////////////////////////////////////////////////////////*/
@Override
public void onCancel(@NonNull final DialogInterface dialogInterface) {
super.onCancel(dialogInterface);
if (onCancelListener != null) {
onCancelListener.onCancel();
}
}
private void clickedItem(final SelectKioskAdapter.Entry entry) {
if (onSelectedListener != null) {
onSelectedListener.onKioskSelected(entry.serviceId, entry.kioskId, entry.kioskName);
@ -114,10 +100,6 @@ public class SelectKioskFragment extends DialogFragment {
void onKioskSelected(int serviceId, String kioskId, String kioskName);
}
public interface OnCancelListener {
void onCancel();
}
private class SelectKioskAdapter
extends RecyclerView.Adapter<SelectKioskAdapter.SelectKioskItemHolder> {
private final List<Entry> kioskList = new Vector<>();

View File

@ -1,22 +1,49 @@
package org.schabi.newpipe.settings;
import static org.schabi.newpipe.util.Localization.assureCorrectAppLanguage;
import android.content.Context;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
import androidx.annotation.IdRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.preference.Preference;
import androidx.preference.PreferenceFragmentCompat;
import com.jakewharton.rxbinding4.widget.RxTextView;
import org.schabi.newpipe.App;
import org.schabi.newpipe.CheckForNewAppVersion;
import org.schabi.newpipe.MainActivity;
import org.schabi.newpipe.R;
import org.schabi.newpipe.databinding.SettingsLayoutBinding;
import org.schabi.newpipe.settings.preferencesearch.PreferenceParser;
import org.schabi.newpipe.settings.preferencesearch.PreferenceSearchConfiguration;
import org.schabi.newpipe.settings.preferencesearch.PreferenceSearchFragment;
import org.schabi.newpipe.settings.preferencesearch.PreferenceSearchItem;
import org.schabi.newpipe.settings.preferencesearch.PreferenceSearchResultHighlighter;
import org.schabi.newpipe.settings.preferencesearch.PreferenceSearchResultListener;
import org.schabi.newpipe.settings.preferencesearch.PreferenceSearcher;
import org.schabi.newpipe.util.DeviceUtils;
import org.schabi.newpipe.util.KeyboardUtil;
import org.schabi.newpipe.util.ThemeHelper;
import org.schabi.newpipe.views.FocusOverlayView;
import static org.schabi.newpipe.util.Localization.assureCorrectAppLanguage;
import java.util.concurrent.TimeUnit;
import icepick.Icepick;
import icepick.State;
/*
* Created by Christian Schabesberger on 31.08.15.
@ -38,21 +65,54 @@ import static org.schabi.newpipe.util.Localization.assureCorrectAppLanguage;
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
*/
public class SettingsActivity extends AppCompatActivity
implements BasePreferenceFragment.OnPreferenceStartFragmentCallback {
public class SettingsActivity extends AppCompatActivity implements
PreferenceFragmentCompat.OnPreferenceStartFragmentCallback,
PreferenceSearchResultListener {
private static final String TAG = "SettingsActivity";
private static final boolean DEBUG = MainActivity.DEBUG;
@IdRes
private static final int FRAGMENT_HOLDER_ID = R.id.settings_fragment_holder;
private PreferenceSearchFragment searchFragment;
@Nullable
private MenuItem menuSearchItem;
private View searchContainer;
private EditText searchEditText;
// State
@State
String searchText;
@State
boolean wasSearchActive;
@Override
protected void onCreate(final Bundle savedInstanceBundle) {
setTheme(ThemeHelper.getSettingsThemeStyle(this));
assureCorrectAppLanguage(this);
super.onCreate(savedInstanceBundle);
Icepick.restoreInstanceState(this, savedInstanceBundle);
final boolean restored = savedInstanceBundle != null;
final SettingsLayoutBinding settingsLayoutBinding =
SettingsLayoutBinding.inflate(getLayoutInflater());
setContentView(settingsLayoutBinding.getRoot());
initSearch(settingsLayoutBinding, restored);
setSupportActionBar(settingsLayoutBinding.settingsToolbarLayout.toolbar);
if (savedInstanceBundle == null) {
if (restored) {
// Restore state
if (this.wasSearchActive) {
setSearchActive(true);
if (!TextUtils.isEmpty(this.searchText)) {
this.searchEditText.setText(this.searchText);
}
}
} else {
getSupportFragmentManager().beginTransaction()
.replace(R.id.settings_fragment_holder, new MainSettingsFragment())
.commit();
@ -63,6 +123,12 @@ public class SettingsActivity extends AppCompatActivity
}
}
@Override
protected void onSaveInstanceState(@NonNull final Bundle outState) {
super.onSaveInstanceState(outState);
Icepick.saveInstanceState(this, outState);
}
@Override
public boolean onCreateOptionsMenu(final Menu menu) {
final ActionBar actionBar = getSupportActionBar();
@ -74,10 +140,25 @@ public class SettingsActivity extends AppCompatActivity
return super.onCreateOptionsMenu(menu);
}
@Override
public void onBackPressed() {
if (isSearchActive()) {
setSearchActive(false);
return;
}
super.onBackPressed();
}
@Override
public boolean onOptionsItemSelected(final MenuItem item) {
final int id = item.getItemId();
if (id == android.R.id.home) {
// Check if the search is active and if so: Close it
if (isSearchActive()) {
setSearchActive(false);
return true;
}
if (getSupportFragmentManager().getBackStackEntryCount() == 0) {
finish();
} else {
@ -91,14 +172,223 @@ public class SettingsActivity extends AppCompatActivity
@Override
public boolean onPreferenceStartFragment(final PreferenceFragmentCompat caller,
final Preference preference) {
final Fragment fragment = Fragment
.instantiate(this, preference.getFragment(), preference.getExtras());
showSettingsFragment(instantiateFragment(preference.getFragment()));
return true;
}
private Fragment instantiateFragment(@NonNull final String className) {
return getSupportFragmentManager()
.getFragmentFactory()
.instantiate(this.getClassLoader(), className);
}
private void showSettingsFragment(final Fragment fragment) {
getSupportFragmentManager().beginTransaction()
.setCustomAnimations(R.animator.custom_fade_in, R.animator.custom_fade_out,
R.animator.custom_fade_in, R.animator.custom_fade_out)
.replace(R.id.settings_fragment_holder, fragment)
.replace(FRAGMENT_HOLDER_ID, fragment)
.addToBackStack(null)
.commit();
return true;
}
@Override
protected void onDestroy() {
setMenuSearchItem(null);
searchFragment = null;
super.onDestroy();
}
/*//////////////////////////////////////////////////////////////////////////
// Search
//////////////////////////////////////////////////////////////////////////*/
//region Search
private void initSearch(
final SettingsLayoutBinding settingsLayoutBinding,
final boolean restored
) {
searchContainer =
settingsLayoutBinding.settingsToolbarLayout.toolbar
.findViewById(R.id.toolbar_search_container);
// Configure input field for search
searchEditText = searchContainer.findViewById(R.id.toolbar_search_edit_text);
RxTextView.textChanges(searchEditText)
// Wait some time after the last input before actually searching
.debounce(200, TimeUnit.MILLISECONDS)
.subscribe(v -> runOnUiThread(this::onSearchChanged));
// Configure clear button
searchContainer.findViewById(R.id.toolbar_search_clear)
.setOnClickListener(ev -> resetSearchText());
ensureSearchRepresentsApplicationState();
// Build search configuration using SettingsResourceRegistry
final PreferenceSearchConfiguration config = new PreferenceSearchConfiguration();
// Build search items
final Context searchContext = getApplicationContext();
assureCorrectAppLanguage(searchContext);
final PreferenceParser parser = new PreferenceParser(searchContext, config);
final PreferenceSearcher searcher = new PreferenceSearcher(config);
// Find all searchable SettingsResourceRegistry fragments
SettingsResourceRegistry.getInstance().getAllEntries().stream()
.filter(SettingsResourceRegistry.SettingRegistryEntry::isSearchable)
// Get the resId
.map(SettingsResourceRegistry.SettingRegistryEntry::getPreferencesResId)
// Parse
.map(parser::parse)
// Add it to the searcher
.forEach(searcher::add);
if (restored) {
searchFragment = (PreferenceSearchFragment) getSupportFragmentManager()
.findFragmentByTag(PreferenceSearchFragment.NAME);
if (searchFragment != null) {
// Hide/Remove the search fragment otherwise we get an exception
// when adding it (because it's already present)
hideSearchFragment();
}
}
if (searchFragment == null) {
searchFragment = new PreferenceSearchFragment();
}
searchFragment.setSearcher(searcher);
}
/**
* Ensures that the search shows the correct/available search results.
* <br/>
* Some features are e.g. only available for debug builds, these should not
* be found when searching inside a release.
*/
private void ensureSearchRepresentsApplicationState() {
// Check if the update settings are available
if (!CheckForNewAppVersion.isReleaseApk(App.getApp())) {
SettingsResourceRegistry.getInstance()
.getEntryByPreferencesResId(R.xml.update_settings)
.setSearchable(false);
}
// Hide debug preferences in RELEASE build variant
if (DEBUG) {
SettingsResourceRegistry.getInstance()
.getEntryByPreferencesResId(R.xml.debug_settings)
.setSearchable(true);
}
}
public void setMenuSearchItem(final MenuItem menuSearchItem) {
this.menuSearchItem = menuSearchItem;
// Ensure that the item is in the correct state when adding it. This is due to
// Android's lifecycle (the Activity is recreated before the Fragment that registers this)
if (menuSearchItem != null) {
menuSearchItem.setVisible(!isSearchActive());
}
}
public void setSearchActive(final boolean active) {
if (DEBUG) {
Log.d(TAG, "setSearchActive called active=" + active);
}
// Ignore if search is already in correct state
if (isSearchActive() == active) {
return;
}
wasSearchActive = active;
searchContainer.setVisibility(active ? View.VISIBLE : View.GONE);
if (menuSearchItem != null) {
menuSearchItem.setVisible(!active);
}
if (active) {
getSupportFragmentManager()
.beginTransaction()
.add(FRAGMENT_HOLDER_ID, searchFragment, PreferenceSearchFragment.NAME)
.addToBackStack(PreferenceSearchFragment.NAME)
.commit();
KeyboardUtil.showKeyboard(this, searchEditText);
} else if (searchFragment != null) {
hideSearchFragment();
getSupportFragmentManager()
.popBackStack(
PreferenceSearchFragment.NAME,
FragmentManager.POP_BACK_STACK_INCLUSIVE);
KeyboardUtil.hideKeyboard(this, searchEditText);
}
resetSearchText();
}
private void hideSearchFragment() {
getSupportFragmentManager().beginTransaction().remove(searchFragment).commit();
}
private void resetSearchText() {
searchEditText.setText("");
}
private boolean isSearchActive() {
return searchContainer.getVisibility() == View.VISIBLE;
}
private void onSearchChanged() {
if (!isSearchActive()) {
return;
}
if (searchFragment != null) {
searchText = this.searchEditText.getText().toString();
searchFragment.updateSearchResults(searchText);
}
}
@Override
public void onSearchResultClicked(@NonNull final PreferenceSearchItem result) {
if (DEBUG) {
Log.d(TAG, "onSearchResultClicked called result=" + result);
}
// Hide the search
setSearchActive(false);
// -- Highlight the result --
// Find out which fragment class we need
final Class<? extends Fragment> targetedFragmentClass =
SettingsResourceRegistry.getInstance()
.getFragmentClass(result.getSearchIndexItemResId());
if (targetedFragmentClass == null) {
// This should never happen
Log.w(TAG, "Unable to locate fragment class for resId="
+ result.getSearchIndexItemResId());
return;
}
// Check if the currentFragment is the one which contains the result
Fragment currentFragment =
getSupportFragmentManager().findFragmentById(FRAGMENT_HOLDER_ID);
if (!targetedFragmentClass.equals(currentFragment.getClass())) {
// If it's not the correct one display the correct one
currentFragment = instantiateFragment(targetedFragmentClass.getName());
showSettingsFragment(currentFragment);
}
// Run the highlighting
if (currentFragment instanceof PreferenceFragmentCompat) {
PreferenceSearchResultHighlighter
.highlight(result, (PreferenceFragmentCompat) currentFragment);
}
}
//endregion
}

View File

@ -0,0 +1,149 @@
package org.schabi.newpipe.settings;
import androidx.annotation.NonNull;
import androidx.annotation.XmlRes;
import androidx.fragment.app.Fragment;
import org.schabi.newpipe.R;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
/**
* A registry that contains information about SettingsFragments.
* <br/>
* includes:
* <ul>
* <li>Class of the SettingsFragment</li>
* <li>XML-Resource</li>
* <li>...</li>
* </ul>
*
* E.g. used by the preference search.
*/
public final class SettingsResourceRegistry {
private static final SettingsResourceRegistry INSTANCE = new SettingsResourceRegistry();
private final Set<SettingRegistryEntry> registeredEntries = new HashSet<>();
private SettingsResourceRegistry() {
add(MainSettingsFragment.class, R.xml.main_settings).setSearchable(false);
add(AppearanceSettingsFragment.class, R.xml.appearance_settings);
add(ContentSettingsFragment.class, R.xml.content_settings);
add(DebugSettingsFragment.class, R.xml.debug_settings).setSearchable(false);
add(DownloadSettingsFragment.class, R.xml.download_settings);
add(HistorySettingsFragment.class, R.xml.history_settings);
add(NotificationSettingsFragment.class, R.xml.notifications_settings);
add(PlayerNotificationSettingsFragment.class, R.xml.player_notification_settings);
add(UpdateSettingsFragment.class, R.xml.update_settings);
add(VideoAudioSettingsFragment.class, R.xml.video_audio_settings);
}
private SettingRegistryEntry add(
@NonNull final Class<? extends Fragment> fragmentClass,
@XmlRes final int preferencesResId
) {
final SettingRegistryEntry entry =
new SettingRegistryEntry(fragmentClass, preferencesResId);
this.registeredEntries.add(entry);
return entry;
}
public SettingRegistryEntry getEntryByFragmentClass(
final Class<? extends Fragment> fragmentClass
) {
Objects.requireNonNull(fragmentClass);
return registeredEntries.stream()
.filter(e -> Objects.equals(e.getFragmentClass(), fragmentClass))
.findFirst()
.orElse(null);
}
public SettingRegistryEntry getEntryByPreferencesResId(@XmlRes final int preferencesResId) {
return registeredEntries.stream()
.filter(e -> Objects.equals(e.getPreferencesResId(), preferencesResId))
.findFirst()
.orElse(null);
}
public int getPreferencesResId(@NonNull final Class<? extends Fragment> fragmentClass) {
final SettingRegistryEntry entry = getEntryByFragmentClass(fragmentClass);
if (entry == null) {
return -1;
}
return entry.getPreferencesResId();
}
public Class<? extends Fragment> getFragmentClass(@XmlRes final int preferencesResId) {
final SettingRegistryEntry entry = getEntryByPreferencesResId(preferencesResId);
if (entry == null) {
return null;
}
return entry.getFragmentClass();
}
public Set<SettingRegistryEntry> getAllEntries() {
return new HashSet<>(registeredEntries);
}
public static SettingsResourceRegistry getInstance() {
return INSTANCE;
}
public static class SettingRegistryEntry {
@NonNull
private final Class<? extends Fragment> fragmentClass;
@XmlRes
private final int preferencesResId;
private boolean searchable = true;
public SettingRegistryEntry(
@NonNull final Class<? extends Fragment> fragmentClass,
@XmlRes final int preferencesResId
) {
this.fragmentClass = Objects.requireNonNull(fragmentClass);
this.preferencesResId = preferencesResId;
}
@SuppressWarnings("HiddenField")
public SettingRegistryEntry setSearchable(final boolean searchable) {
this.searchable = searchable;
return this;
}
public Class<? extends Fragment> getFragmentClass() {
return fragmentClass;
}
public int getPreferencesResId() {
return preferencesResId;
}
public boolean isSearchable() {
return searchable;
}
@Override
public boolean equals(final Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
final SettingRegistryEntry that = (SettingRegistryEntry) o;
return getPreferencesResId() == that.getPreferencesResId()
&& getFragmentClass().equals(that.getFragmentClass());
}
@Override
public int hashCode() {
return Objects.hash(getFragmentClass(), getPreferencesResId());
}
}
}

View File

@ -38,7 +38,7 @@ public class UpdateSettingsFragment extends BasePreferenceFragment {
@Override
public void onCreatePreferences(final Bundle savedInstanceState, final String rootKey) {
addPreferencesFromResource(R.xml.update_settings);
addPreferencesFromResourceRegistry();
findPreference(getString(R.string.update_app_key))
.setOnPreferenceChangeListener(updatePreferenceChange);

View File

@ -23,7 +23,7 @@ public class VideoAudioSettingsFragment extends BasePreferenceFragment {
@Override
public void onCreatePreferences(final Bundle savedInstanceState, final String rootKey) {
addPreferencesFromResource(R.xml.video_audio_settings);
addPreferencesFromResourceRegistry();
updateSeekOptions();

View File

@ -0,0 +1,111 @@
package org.schabi.newpipe.settings.preferencesearch;
import android.text.TextUtils;
import org.apache.commons.text.similarity.FuzzyScore;
import java.util.Comparator;
import java.util.Locale;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Stream;
public class PreferenceFuzzySearchFunction
implements PreferenceSearchConfiguration.PreferenceSearchFunction {
private static final FuzzyScore FUZZY_SCORE = new FuzzyScore(Locale.ROOT);
@Override
public Stream<PreferenceSearchItem> search(
final Stream<PreferenceSearchItem> allAvailable,
final String keyword
) {
final int maxScore = (keyword.length() + 1) * 3 - 2; // First can't get +2 bonus score
return allAvailable
// General search
// Check all fields if anyone contains something that kind of matches the keyword
.map(item -> new FuzzySearchGeneralDTO(item, keyword))
.filter(dto -> dto.getScore() / maxScore >= 0.3f)
.map(FuzzySearchGeneralDTO::getItem)
// Specific search - Used for determining order of search results
// Calculate a score based on specific search fields
.map(item -> new FuzzySearchSpecificDTO(item, keyword))
.sorted(Comparator.comparing(FuzzySearchSpecificDTO::getScore).reversed())
.map(FuzzySearchSpecificDTO::getItem)
// Limit the amount of search results
.limit(20);
}
static class FuzzySearchGeneralDTO {
private final PreferenceSearchItem item;
private final float score;
FuzzySearchGeneralDTO(
final PreferenceSearchItem item,
final String keyword) {
this.item = item;
this.score = FUZZY_SCORE.fuzzyScore(
TextUtils.join(";", item.getAllRelevantSearchFields()),
keyword);
}
public PreferenceSearchItem getItem() {
return item;
}
public float getScore() {
return score;
}
}
static class FuzzySearchSpecificDTO {
private static final Map<Function<PreferenceSearchItem, String>, Float> WEIGHT_MAP = Map.of(
// The user will most likely look for the title -> prioritize it
PreferenceSearchItem::getTitle, 1.5f,
// The summary is also important as it usually contains a larger desc
// Example: Searching for '4k' 'show higher resolution' is shown
PreferenceSearchItem::getSummary, 1f,
// Entries are also important as they provide all known/possible values
// Example: Searching where the resolution can be changed to 720p
PreferenceSearchItem::getEntries, 1f
);
private final PreferenceSearchItem item;
private final float score;
FuzzySearchSpecificDTO(
final PreferenceSearchItem item,
final String keyword) {
this.item = item;
float attributeScoreSum = 0;
int countOfAttributesWithScore = 0;
for (final Map.Entry<Function<PreferenceSearchItem, String>, Float> we
: WEIGHT_MAP.entrySet()) {
final String valueToProcess = we.getKey().apply(item);
if (valueToProcess.isEmpty()) {
continue;
}
attributeScoreSum +=
FUZZY_SCORE.fuzzyScore(valueToProcess, keyword) * we.getValue();
countOfAttributesWithScore++;
}
if (countOfAttributesWithScore != 0) {
this.score = attributeScoreSum / countOfAttributesWithScore;
} else {
this.score = 0;
}
}
public PreferenceSearchItem getItem() {
return item;
}
public float getScore() {
return score;
}
}
}

View File

@ -0,0 +1,199 @@
package org.schabi.newpipe.settings.preferencesearch;
import android.content.Context;
import android.text.TextUtils;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.XmlRes;
import androidx.preference.PreferenceManager;
import org.xmlpull.v1.XmlPullParser;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* Parses the corresponding preference-file(s).
*/
public class PreferenceParser {
private static final String TAG = "PreferenceParser";
private static final String NS_ANDROID = "http://schemas.android.com/apk/res/android";
private static final String NS_SEARCH = "http://schemas.android.com/apk/preferencesearch";
private final Context context;
private final Map<String, ?> allPreferences;
private final PreferenceSearchConfiguration searchConfiguration;
public PreferenceParser(
final Context context,
final PreferenceSearchConfiguration searchConfiguration
) {
this.context = context;
this.allPreferences = PreferenceManager.getDefaultSharedPreferences(context).getAll();
this.searchConfiguration = searchConfiguration;
}
public List<PreferenceSearchItem> parse(
@XmlRes final int resId
) {
final List<PreferenceSearchItem> results = new ArrayList<>();
final XmlPullParser xpp = context.getResources().getXml(resId);
try {
xpp.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
xpp.setFeature(XmlPullParser.FEATURE_REPORT_NAMESPACE_ATTRIBUTES, true);
final List<String> breadcrumbs = new ArrayList<>();
while (xpp.getEventType() != XmlPullParser.END_DOCUMENT) {
if (xpp.getEventType() == XmlPullParser.START_TAG) {
final PreferenceSearchItem result = parseSearchResult(
xpp,
joinBreadcrumbs(breadcrumbs),
resId
);
if (!searchConfiguration.getParserIgnoreElements().contains(xpp.getName())
&& result.hasData()
&& !"true".equals(getAttribute(xpp, NS_SEARCH, "ignore"))) {
results.add(result);
}
if (searchConfiguration.getParserContainerElements().contains(xpp.getName())) {
// This code adds breadcrumbs for certain containers (e.g. PreferenceScreen)
// Example: Video and Audio > Player
breadcrumbs.add(result.getTitle() == null ? "" : result.getTitle());
}
} else if (xpp.getEventType() == XmlPullParser.END_TAG
&& searchConfiguration.getParserContainerElements()
.contains(xpp.getName())) {
breadcrumbs.remove(breadcrumbs.size() - 1);
}
xpp.next();
}
} catch (final Exception e) {
Log.w(TAG, "Failed to parse resid=" + resId, e);
}
return results;
}
private String joinBreadcrumbs(final List<String> breadcrumbs) {
return breadcrumbs.stream()
.filter(crumb -> !TextUtils.isEmpty(crumb))
.collect(Collectors.joining(" > "));
}
private String getAttribute(
final XmlPullParser xpp,
@NonNull final String attribute
) {
final String nsSearchAttr = getAttribute(xpp, NS_SEARCH, attribute);
if (nsSearchAttr != null) {
return nsSearchAttr;
}
return getAttribute(xpp, NS_ANDROID, attribute);
}
private String getAttribute(
final XmlPullParser xpp,
@NonNull final String namespace,
@NonNull final String attribute
) {
return xpp.getAttributeValue(namespace, attribute);
}
private PreferenceSearchItem parseSearchResult(
final XmlPullParser xpp,
final String breadcrumbs,
@XmlRes final int searchIndexItemResId
) {
final String key = readString(getAttribute(xpp, "key"));
final String[] entries = readStringArray(getAttribute(xpp, "entries"));
final String[] entryValues = readStringArray(getAttribute(xpp, "entryValues"));
return new PreferenceSearchItem(
key,
tryFillInPreferenceValue(
readString(getAttribute(xpp, "title")),
key,
entries,
entryValues),
tryFillInPreferenceValue(
readString(getAttribute(xpp, "summary")),
key,
entries,
entryValues),
TextUtils.join(",", entries),
breadcrumbs,
searchIndexItemResId
);
}
private String[] readStringArray(@Nullable final String s) {
if (s == null) {
return new String[0];
}
if (s.startsWith("@")) {
try {
return context.getResources().getStringArray(Integer.parseInt(s.substring(1)));
} catch (final Exception e) {
Log.w(TAG, "Unable to readStringArray from '" + s + "'", e);
}
}
return new String[0];
}
private String readString(@Nullable final String s) {
if (s == null) {
return "";
}
if (s.startsWith("@")) {
try {
return context.getString(Integer.parseInt(s.substring(1)));
} catch (final Exception e) {
Log.w(TAG, "Unable to readString from '" + s + "'", e);
}
}
return s;
}
private String tryFillInPreferenceValue(
@Nullable final String s,
@Nullable final String key,
final String[] entries,
final String[] entryValues
) {
if (s == null) {
return "";
}
if (key == null) {
return s;
}
// Resolve value
Object prefValue = allPreferences.get(key);
if (prefValue == null) {
return s;
}
/*
* Resolve ListPreference values
*
* entryValues = Values/Keys that are saved
* entries = Actual human readable names
*/
if (entries.length > 0 && entryValues.length == entries.length) {
final int entryIndex = Arrays.asList(entryValues).indexOf(prefValue);
if (entryIndex != -1) {
prefValue = entries[entryIndex];
}
}
return String.format(s, prefValue.toString());
}
}

View File

@ -0,0 +1,87 @@
package org.schabi.newpipe.settings.preferencesearch;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import org.schabi.newpipe.databinding.SettingsPreferencesearchListItemResultBinding;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
class PreferenceSearchAdapter
extends RecyclerView.Adapter<PreferenceSearchAdapter.PreferenceViewHolder> {
private List<PreferenceSearchItem> dataset = new ArrayList<>();
private Consumer<PreferenceSearchItem> onItemClickListener;
@NonNull
@Override
public PreferenceViewHolder onCreateViewHolder(
@NonNull final ViewGroup parent,
final int viewType
) {
return new PreferenceViewHolder(
SettingsPreferencesearchListItemResultBinding.inflate(
LayoutInflater.from(parent.getContext()),
parent,
false));
}
@Override
public void onBindViewHolder(
@NonNull final PreferenceViewHolder holder,
final int position
) {
final PreferenceSearchItem item = dataset.get(position);
holder.binding.title.setText(item.getTitle());
if (TextUtils.isEmpty(item.getSummary())) {
holder.binding.summary.setVisibility(View.GONE);
} else {
holder.binding.summary.setVisibility(View.VISIBLE);
holder.binding.summary.setText(item.getSummary());
}
if (TextUtils.isEmpty(item.getBreadcrumbs())) {
holder.binding.breadcrumbs.setVisibility(View.GONE);
} else {
holder.binding.breadcrumbs.setVisibility(View.VISIBLE);
holder.binding.breadcrumbs.setText(item.getBreadcrumbs());
}
holder.itemView.setOnClickListener(v -> {
if (onItemClickListener != null) {
onItemClickListener.accept(item);
}
});
}
void setContent(final List<PreferenceSearchItem> items) {
dataset = new ArrayList<>(items);
this.notifyDataSetChanged();
}
@Override
public int getItemCount() {
return dataset.size();
}
void setOnItemClickListener(final Consumer<PreferenceSearchItem> onItemClickListener) {
this.onItemClickListener = onItemClickListener;
}
static class PreferenceViewHolder extends RecyclerView.ViewHolder {
final SettingsPreferencesearchListItemResultBinding binding;
PreferenceViewHolder(final SettingsPreferencesearchListItemResultBinding binding) {
super(binding.getRoot());
this.binding = binding;
}
}
}

View File

@ -0,0 +1,43 @@
package org.schabi.newpipe.settings.preferencesearch;
import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceScreen;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Stream;
public class PreferenceSearchConfiguration {
private PreferenceSearchFunction searcher = new PreferenceFuzzySearchFunction();
private final List<String> parserIgnoreElements = Arrays.asList(
PreferenceCategory.class.getSimpleName());
private final List<String> parserContainerElements = Arrays.asList(
PreferenceCategory.class.getSimpleName(),
PreferenceScreen.class.getSimpleName());
public void setSearcher(final PreferenceSearchFunction searcher) {
this.searcher = Objects.requireNonNull(searcher);
}
public PreferenceSearchFunction getSearcher() {
return searcher;
}
public List<String> getParserIgnoreElements() {
return parserIgnoreElements;
}
public List<String> getParserContainerElements() {
return parserContainerElements;
}
@FunctionalInterface
public interface PreferenceSearchFunction {
Stream<PreferenceSearchItem> search(
Stream<PreferenceSearchItem> allAvailable,
String keyword);
}
}

View File

@ -0,0 +1,80 @@
package org.schabi.newpipe.settings.preferencesearch;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import org.schabi.newpipe.databinding.SettingsPreferencesearchFragmentBinding;
import java.util.ArrayList;
import java.util.List;
/**
* Displays the search results.
*/
public class PreferenceSearchFragment extends Fragment {
public static final String NAME = PreferenceSearchFragment.class.getSimpleName();
private PreferenceSearcher searcher;
private SettingsPreferencesearchFragmentBinding binding;
private PreferenceSearchAdapter adapter;
public void setSearcher(final PreferenceSearcher searcher) {
this.searcher = searcher;
}
@Nullable
@Override
public View onCreateView(
@NonNull final LayoutInflater inflater,
@Nullable final ViewGroup container,
@Nullable final Bundle savedInstanceState
) {
binding = SettingsPreferencesearchFragmentBinding.inflate(inflater, container, false);
binding.searchResults.setLayoutManager(new LinearLayoutManager(getContext()));
adapter = new PreferenceSearchAdapter();
adapter.setOnItemClickListener(this::onItemClicked);
binding.searchResults.setAdapter(adapter);
return binding.getRoot();
}
public void updateSearchResults(final String keyword) {
if (adapter == null || searcher == null) {
return;
}
final List<PreferenceSearchItem> results =
!TextUtils.isEmpty(keyword)
? searcher.searchFor(keyword)
: new ArrayList<>();
adapter.setContent(new ArrayList<>(results));
setEmptyViewShown(results.isEmpty());
}
private void setEmptyViewShown(final boolean shown) {
binding.emptyStateView.setVisibility(shown ? View.VISIBLE : View.GONE);
binding.searchResults.setVisibility(shown ? View.GONE : View.VISIBLE);
}
public void onItemClicked(final PreferenceSearchItem item) {
if (!(getActivity() instanceof PreferenceSearchResultListener)) {
throw new ClassCastException(
getActivity().toString() + " must implement SearchPreferenceResultListener");
}
((PreferenceSearchResultListener) getActivity()).onSearchResultClicked(item);
}
}

View File

@ -0,0 +1,102 @@
package org.schabi.newpipe.settings.preferencesearch;
import androidx.annotation.NonNull;
import androidx.annotation.XmlRes;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
/**
* Represents a preference-item inside the search.
*/
public class PreferenceSearchItem {
/**
* Key of the setting/preference. E.g. used inside {@link android.content.SharedPreferences}.
*/
@NonNull
private final String key;
/**
* Title of the setting, e.g. 'Default resolution' or 'Show higher resolutions'.
*/
@NonNull
private final String title;
/**
* Summary of the setting, e.g. '480p' or 'Only some devices can play 2k/4k'.
*/
@NonNull
private final String summary;
/**
* Possible entries of the setting, e.g. 480p,720p,...
*/
@NonNull
private final String entries;
/**
* Breadcrumbs - a hint where the setting is located e.g. 'Video and Audio > Player'
*/
@NonNull
private final String breadcrumbs;
/**
* The xml-resource where this item was found/built from.
*/
@XmlRes
private final int searchIndexItemResId;
public PreferenceSearchItem(
@NonNull final String key,
@NonNull final String title,
@NonNull final String summary,
@NonNull final String entries,
@NonNull final String breadcrumbs,
@XmlRes final int searchIndexItemResId
) {
this.key = Objects.requireNonNull(key);
this.title = Objects.requireNonNull(title);
this.summary = Objects.requireNonNull(summary);
this.entries = Objects.requireNonNull(entries);
this.breadcrumbs = Objects.requireNonNull(breadcrumbs);
this.searchIndexItemResId = searchIndexItemResId;
}
public String getKey() {
return key;
}
public String getTitle() {
return title;
}
public String getSummary() {
return summary;
}
public String getEntries() {
return entries;
}
public String getBreadcrumbs() {
return breadcrumbs;
}
public int getSearchIndexItemResId() {
return searchIndexItemResId;
}
boolean hasData() {
return !key.isEmpty() && !title.isEmpty();
}
public List<String> getAllRelevantSearchFields() {
return Arrays.asList(
getTitle(),
getSummary(),
getEntries(),
getBreadcrumbs());
}
@Override
public String toString() {
return "PreferenceItem: " + title + " " + summary + " " + key;
}
}

View File

@ -0,0 +1,127 @@
package org.schabi.newpipe.settings.preferencesearch;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.RippleDrawable;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.util.TypedValue;
import androidx.appcompat.content.res.AppCompatResources;
import androidx.preference.Preference;
import androidx.preference.PreferenceFragmentCompat;
import androidx.preference.PreferenceGroup;
import androidx.recyclerview.widget.RecyclerView;
import org.schabi.newpipe.R;
public final class PreferenceSearchResultHighlighter {
private static final String TAG = "PrefSearchResHighlter";
private PreferenceSearchResultHighlighter() {
}
/**
* Highlight the specified preference.
* <br/>
* Note: This function is Thread independent (can be called from outside of the main thread).
*
* @param item The item to highlight
* @param prefsFragment The fragment where the items is located on
*/
public static void highlight(
final PreferenceSearchItem item,
final PreferenceFragmentCompat prefsFragment
) {
new Handler(Looper.getMainLooper()).post(() -> doHighlight(item, prefsFragment));
}
private static void doHighlight(
final PreferenceSearchItem item,
final PreferenceFragmentCompat prefsFragment
) {
final Preference prefResult = prefsFragment.findPreference(item.getKey());
if (prefResult == null) {
Log.w(TAG, "Preference '" + item.getKey() + "' not found on '" + prefsFragment + "'");
return;
}
final RecyclerView recyclerView = prefsFragment.getListView();
final RecyclerView.Adapter<?> adapter = recyclerView.getAdapter();
if (adapter instanceof PreferenceGroup.PreferencePositionCallback) {
final int position = ((PreferenceGroup.PreferencePositionCallback) adapter)
.getPreferenceAdapterPosition(prefResult);
if (position != RecyclerView.NO_POSITION) {
recyclerView.scrollToPosition(position);
recyclerView.postDelayed(() -> {
final RecyclerView.ViewHolder holder =
recyclerView.findViewHolderForAdapterPosition(position);
if (holder != null) {
final Drawable background = holder.itemView.getBackground();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP
&& background instanceof RippleDrawable) {
showRippleAnimation((RippleDrawable) background);
return;
}
}
highlightFallback(prefsFragment, prefResult);
}, 200);
return;
}
}
highlightFallback(prefsFragment, prefResult);
}
/**
* Alternative highlighting (shows an arrow in front of the setting)if ripple does not work.
*
* @param prefsFragment
* @param prefResult
*/
private static void highlightFallback(
final PreferenceFragmentCompat prefsFragment,
final Preference prefResult
) {
// Get primary color from text for highlight icon
final TypedValue typedValue = new TypedValue();
final Resources.Theme theme = prefsFragment.getActivity().getTheme();
theme.resolveAttribute(android.R.attr.textColorPrimary, typedValue, true);
final TypedArray arr = prefsFragment.getActivity()
.obtainStyledAttributes(
typedValue.data,
new int[]{android.R.attr.textColorPrimary});
final int color = arr.getColor(0, 0xffE53935);
arr.recycle();
// Show highlight icon
final Drawable oldIcon = prefResult.getIcon();
final boolean oldSpaceReserved = prefResult.isIconSpaceReserved();
final Drawable highlightIcon =
AppCompatResources.getDrawable(
prefsFragment.requireContext(),
R.drawable.ic_play_arrow);
highlightIcon.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN));
prefResult.setIcon(highlightIcon);
prefsFragment.scrollToPreference(prefResult);
new Handler(Looper.getMainLooper()).postDelayed(() -> {
prefResult.setIcon(oldIcon);
prefResult.setIconSpaceReserved(oldSpaceReserved);
}, 1000);
}
private static void showRippleAnimation(final RippleDrawable rippleDrawable) {
rippleDrawable.setState(
new int[]{android.R.attr.state_pressed, android.R.attr.state_enabled});
new Handler(Looper.getMainLooper())
.postDelayed(() -> rippleDrawable.setState(new int[]{}), 1000);
}
}

View File

@ -0,0 +1,7 @@
package org.schabi.newpipe.settings.preferencesearch;
import androidx.annotation.NonNull;
public interface PreferenceSearchResultListener {
void onSearchResultClicked(@NonNull PreferenceSearchItem result);
}

View File

@ -0,0 +1,35 @@
package org.schabi.newpipe.settings.preferencesearch;
import android.text.TextUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class PreferenceSearcher {
private final List<PreferenceSearchItem> allEntries = new ArrayList<>();
private final PreferenceSearchConfiguration configuration;
public PreferenceSearcher(final PreferenceSearchConfiguration configuration) {
this.configuration = configuration;
}
public void add(final List<PreferenceSearchItem> items) {
allEntries.addAll(items);
}
List<PreferenceSearchItem> searchFor(final String keyword) {
if (TextUtils.isEmpty(keyword)) {
return new ArrayList<>();
}
return configuration.getSearcher()
.search(allEntries.stream(), keyword)
.collect(Collectors.toList());
}
public void clear() {
allEntries.clear();
}
}

View File

@ -0,0 +1,10 @@
/**
* Contains classes for searching inside the preferences.
* <br/>
* This code is based on
* <a href="https://github.com/ByteHamster/SearchPreference">ByteHamster/SearchPreference</a>
* (MIT license) but was heavily modified/refactored for our use.
*
* @author litetex
*/
package org.schabi.newpipe.settings.preferencesearch;

View File

@ -44,8 +44,6 @@ import java.util.List;
import static org.schabi.newpipe.settings.tabs.Tab.typeFrom;
public class ChooseTabsFragment extends Fragment {
private static final int MENU_ITEM_RESTORE_ID = 123456;
private TabsManager tabsManager;
private final List<Tab> tabList = new ArrayList<>();
@ -110,21 +108,14 @@ public class ChooseTabsFragment extends Fragment {
@NonNull final MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
final MenuItem restoreItem = menu.add(Menu.NONE, MENU_ITEM_RESTORE_ID, Menu.NONE,
R.string.restore_defaults);
final MenuItem restoreItem = menu.add(R.string.restore_defaults);
restoreItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
restoreItem.setIcon(AppCompatResources.getDrawable(requireContext(),
R.drawable.ic_settings_backup_restore));
}
@Override
public boolean onOptionsItemSelected(final MenuItem item) {
if (item.getItemId() == MENU_ITEM_RESTORE_ID) {
restoreItem.setOnMenuItemClickListener(ev -> {
restoreDefaults();
return true;
}
return super.onOptionsItemSelected(item);
});
}
/*//////////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,43 @@
package org.schabi.newpipe.util;
import android.app.Activity;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import androidx.core.content.ContextCompat;
/**
* Utility class for the Android keyboard.
* <p>
* See also <a href="https://stackoverflow.com/q/1109022">https://stackoverflow.com/q/1109022</a>
* </p>
*/
public final class KeyboardUtil {
private KeyboardUtil() {
}
public static void showKeyboard(final Activity activity, final EditText editText) {
if (activity == null || editText == null) {
return;
}
if (editText.requestFocus()) {
final InputMethodManager imm = ContextCompat.getSystemService(activity,
InputMethodManager.class);
imm.showSoftInput(editText, InputMethodManager.SHOW_FORCED);
}
}
public static void hideKeyboard(final Activity activity, final EditText editText) {
if (activity == null || editText == null) {
return;
}
final InputMethodManager imm = ContextCompat.getSystemService(activity,
InputMethodManager.class);
imm.hideSoftInputFromWindow(editText.getWindowToken(),
InputMethodManager.RESULT_UNCHANGED_SHOWN);
editText.clearFocus();
}
}

View File

@ -0,0 +1,94 @@
package org.schabi.newpipe.util;
import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty;
import android.content.Context;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import org.schabi.newpipe.NewPipeDatabase;
import org.schabi.newpipe.R;
import org.schabi.newpipe.error.ErrorInfo;
import org.schabi.newpipe.error.ErrorUtil;
import org.schabi.newpipe.error.UserAction;
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
import org.schabi.newpipe.player.playqueue.PlayQueueItem;
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.schedulers.Schedulers;
/**
* Utility class for putting the uploader url into the database - when required.
*/
public final class SaveUploaderUrlHelper {
private SaveUploaderUrlHelper() {
}
// Public functions which call the function that does
// the actual work with the correct parameters
public static void saveUploaderUrlIfNeeded(@NonNull final Fragment fragment,
@NonNull final StreamInfoItem infoItem,
@NonNull final SaveUploaderUrlCallback callback) {
saveUploaderUrlIfNeeded(fragment.requireContext(),
infoItem.getServiceId(),
infoItem.getUrl(),
infoItem.getUploaderUrl(),
callback);
}
public static void saveUploaderUrlIfNeeded(@NonNull final Context context,
@NonNull final PlayQueueItem queueItem,
@NonNull final SaveUploaderUrlCallback callback) {
saveUploaderUrlIfNeeded(context,
queueItem.getServiceId(),
queueItem.getUrl(),
queueItem.getUploaderUrl(),
callback);
}
/**
* Fetches and saves the uploaderUrl if it is empty (meaning that it does
* not exist in the video item). The callback is called with either the
* fetched uploaderUrl, or the already saved uploaderUrl, but it is always
* called with a valid uploaderUrl that can be used to show channel details.
*
* @param context Context
* @param serviceId The serviceId of the item
* @param url The item url
* @param uploaderUrl The uploaderUrl of the item, if null or empty, it
* will be fetched using the item url.
* @param callback The callback that returns the fetched or existing
* uploaderUrl
*/
private static void saveUploaderUrlIfNeeded(@NonNull final Context context,
final int serviceId,
@NonNull final String url,
// Only used if not null or empty
@Nullable final String uploaderUrl,
@NonNull final SaveUploaderUrlCallback callback) {
if (isNullOrEmpty(uploaderUrl)) {
Toast.makeText(context, R.string.loading_channel_details,
Toast.LENGTH_SHORT).show();
ExtractorHelper.getStreamInfo(serviceId, url, false)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(result -> {
NewPipeDatabase.getInstance(context).streamDAO()
.setUploaderUrl(serviceId, url, result.getUploaderUrl())
.subscribeOn(Schedulers.io()).subscribe();
callback.onCallback(result.getUploaderUrl());
}, throwable -> ErrorUtil.createNotification(context,
new ErrorInfo(throwable, UserAction.REQUESTED_CHANNEL,
"Could not load channel details")
));
} else {
callback.onCallback(uploaderUrl);
}
}
public interface SaveUploaderUrlCallback {
void onCallback(@NonNull String uploaderUrl);
}
}

View File

@ -3,12 +3,10 @@ package org.schabi.newpipe.util;
import android.content.Context;
import android.net.Uri;
import android.util.Log;
import android.widget.Toast;
import androidx.fragment.app.Fragment;
import androidx.preference.PreferenceManager;
import org.schabi.newpipe.NewPipeDatabase;
import org.schabi.newpipe.R;
import org.schabi.newpipe.database.stream.model.StreamEntity;
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
@ -27,36 +25,14 @@ import java.util.function.Consumer;
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.schedulers.Schedulers;
import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty;
public enum StreamDialogEntry {
//////////////////////////////////////
// enum values with DEFAULT actions //
//////////////////////////////////////
show_channel_details(R.string.show_channel_details, (fragment, item) -> {
if (isNullOrEmpty(item.getUploaderUrl())) {
final int serviceId = item.getServiceId();
final String url = item.getUrl();
Toast.makeText(fragment.getContext(), R.string.loading_channel_details,
Toast.LENGTH_SHORT).show();
ExtractorHelper.getStreamInfo(serviceId, url, false)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(result -> {
NewPipeDatabase.getInstance(fragment.requireContext()).streamDAO()
.setUploaderUrl(serviceId, url, result.getUploaderUrl())
.subscribeOn(Schedulers.io()).subscribe();
openChannelFragment(fragment, item, result.getUploaderUrl());
}, throwable -> Toast.makeText(
// TODO: Open the Error Activity
fragment.getContext(),
R.string.error_show_channel_details,
Toast.LENGTH_SHORT
).show());
} else {
openChannelFragment(fragment, item, item.getUploaderUrl());
}
SaveUploaderUrlHelper.saveUploaderUrlIfNeeded(fragment, item,
uploaderUrl -> openChannelFragment(fragment, item, uploaderUrl));
}),
/**

View File

@ -0,0 +1,89 @@
package org.schabi.newpipe.views.player
import android.content.Context
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.Path
import android.util.AttributeSet
import android.view.View
class CircleClipTapView(context: Context?, attrs: AttributeSet) : View(context, attrs) {
private var backgroundPaint = Paint()
private var widthPx = 0
private var heightPx = 0
// Background
private var shapePath = Path()
private var arcSize: Float = 80f
private var isLeft = true
init {
requireNotNull(context) { "Context is null." }
backgroundPaint.apply {
style = Paint.Style.FILL
isAntiAlias = true
color = 0x30000000
}
val dm = context.resources.displayMetrics
widthPx = dm.widthPixels
heightPx = dm.heightPixels
updatePathShape()
}
fun updateArcSize(baseView: View) {
val newArcSize = baseView.height / 11.4f
if (arcSize != newArcSize) {
arcSize = newArcSize
updatePathShape()
}
}
fun updatePosition(newIsLeft: Boolean) {
if (isLeft != newIsLeft) {
isLeft = newIsLeft
updatePathShape()
}
}
private fun updatePathShape() {
val halfWidth = widthPx * 0.5f
shapePath.reset()
val w = if (isLeft) 0f else widthPx.toFloat()
val f = if (isLeft) 1 else -1
shapePath.moveTo(w, 0f)
shapePath.lineTo(f * (halfWidth - arcSize) + w, 0f)
shapePath.quadTo(
f * (halfWidth + arcSize) + w,
heightPx.toFloat() / 2,
f * (halfWidth - arcSize) + w,
heightPx.toFloat()
)
shapePath.lineTo(w, heightPx.toFloat())
shapePath.close()
invalidate()
}
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
super.onSizeChanged(w, h, oldw, oldh)
widthPx = w
heightPx = h
updatePathShape()
}
override fun onDraw(canvas: Canvas?) {
super.onDraw(canvas)
canvas?.clipPath(shapePath)
canvas?.drawPath(shapePath, backgroundPaint)
}
}

View File

@ -0,0 +1,145 @@
package org.schabi.newpipe.views.player
import android.content.Context
import android.util.AttributeSet
import android.util.Log
import android.view.LayoutInflater
import androidx.annotation.NonNull
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.ConstraintLayout.LayoutParams.END
import androidx.constraintlayout.widget.ConstraintLayout.LayoutParams.PARENT_ID
import androidx.constraintlayout.widget.ConstraintLayout.LayoutParams.START
import androidx.constraintlayout.widget.ConstraintSet
import org.schabi.newpipe.MainActivity
import org.schabi.newpipe.R
import org.schabi.newpipe.player.event.DisplayPortion
import org.schabi.newpipe.player.event.DoubleTapListener
class PlayerFastSeekOverlay(context: Context, attrs: AttributeSet?) :
ConstraintLayout(context, attrs), DoubleTapListener {
private var secondsView: SecondsView
private var circleClipTapView: CircleClipTapView
private var rootConstraintLayout: ConstraintLayout
private var wasForwarding: Boolean = false
init {
LayoutInflater.from(context).inflate(R.layout.player_fast_seek_overlay, this, true)
secondsView = findViewById(R.id.seconds_view)
circleClipTapView = findViewById(R.id.circle_clip_tap_view)
rootConstraintLayout = findViewById(R.id.root_constraint_layout)
addOnLayoutChangeListener { view, _, _, _, _, _, _, _, _ ->
circleClipTapView.updateArcSize(view)
}
}
private var performListener: PerformListener? = null
fun performListener(listener: PerformListener) = apply {
performListener = listener
}
private var seekSecondsSupplier: () -> Int = { 0 }
fun seekSecondsSupplier(supplier: () -> Int) = apply {
seekSecondsSupplier = supplier
}
// Indicates whether this (double) tap is the first of a series
// Decides whether to call performListener.onAnimationStart or not
private var initTap: Boolean = false
override fun onDoubleTapStarted(portion: DisplayPortion) {
if (DEBUG)
Log.d(TAG, "onDoubleTapStarted called with portion = [$portion]")
initTap = false
secondsView.stopAnimation()
}
override fun onDoubleTapProgressDown(portion: DisplayPortion) {
val shouldForward: Boolean =
performListener?.getFastSeekDirection(portion)?.directionAsBoolean ?: return
if (DEBUG)
Log.d(
TAG,
"onDoubleTapProgressDown called with " +
"shouldForward = [$shouldForward], " +
"wasForwarding = [$wasForwarding], " +
"initTap = [$initTap], "
)
/*
* Check if a initial tap occurred or if direction was switched
*/
if (!initTap || wasForwarding != shouldForward) {
// Reset seconds and update position
secondsView.seconds = 0
changeConstraints(shouldForward)
circleClipTapView.updatePosition(!shouldForward)
secondsView.setForwarding(shouldForward)
wasForwarding = shouldForward
if (!initTap) {
initTap = true
}
}
performListener?.onDoubleTap()
secondsView.seconds += seekSecondsSupplier.invoke()
performListener?.seek(forward = shouldForward)
}
override fun onDoubleTapFinished() {
if (DEBUG)
Log.d(TAG, "onDoubleTapFinished called with initTap = [$initTap]")
if (initTap) performListener?.onDoubleTapEnd()
initTap = false
secondsView.stopAnimation()
}
private fun changeConstraints(forward: Boolean) {
val constraintSet = ConstraintSet()
with(constraintSet) {
clone(rootConstraintLayout)
clear(secondsView.id, if (forward) START else END)
connect(
secondsView.id, if (forward) END else START,
PARENT_ID, if (forward) END else START
)
secondsView.startAnimation()
applyTo(rootConstraintLayout)
}
}
interface PerformListener {
fun onDoubleTap()
fun onDoubleTapEnd()
/**
* Determines if the playback should forward/rewind or do nothing.
*/
@NonNull
fun getFastSeekDirection(portion: DisplayPortion): FastSeekDirection
fun seek(forward: Boolean)
enum class FastSeekDirection(val directionAsBoolean: Boolean?) {
NONE(null),
FORWARD(true),
BACKWARD(false);
}
}
companion object {
private const val TAG = "PlayerFastSeekOverlay"
private val DEBUG = MainActivity.DEBUG
}
}

View File

@ -0,0 +1,181 @@
package org.schabi.newpipe.views.player
import android.animation.Animator
import android.animation.ValueAnimator
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.widget.LinearLayout
import org.schabi.newpipe.R
import org.schabi.newpipe.databinding.PlayerFastSeekSecondsViewBinding
import org.schabi.newpipe.util.DeviceUtils
class SecondsView(context: Context, attrs: AttributeSet?) : LinearLayout(context, attrs) {
companion object {
const val ICON_ANIMATION_DURATION = 750L
}
var cycleDuration: Long = ICON_ANIMATION_DURATION
set(value) {
firstAnimator.duration = value / 5
secondAnimator.duration = value / 5
thirdAnimator.duration = value / 5
fourthAnimator.duration = value / 5
fifthAnimator.duration = value / 5
field = value
}
var seconds: Int = 0
set(value) {
binding.tvSeconds.text = context.resources.getQuantityString(
R.plurals.seconds, value, value
)
field = value
}
// Done as a field so that we don't have to compute on each tab if animations are enabled
private val animationsEnabled = DeviceUtils.hasAnimationsAnimatorDurationEnabled(context)
val binding = PlayerFastSeekSecondsViewBinding.inflate(LayoutInflater.from(context), this)
init {
orientation = VERTICAL
layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)
}
fun setForwarding(isForward: Boolean) {
binding.triangleContainer.rotation = if (isForward) 0f else 180f
}
fun startAnimation() {
stopAnimation()
if (animationsEnabled) {
firstAnimator.start()
} else {
// If no animations are enable show the arrow(s) without animation
showWithoutAnimation()
}
}
fun stopAnimation() {
firstAnimator.cancel()
secondAnimator.cancel()
thirdAnimator.cancel()
fourthAnimator.cancel()
fifthAnimator.cancel()
reset()
}
private fun reset() {
binding.icon1.alpha = 0f
binding.icon2.alpha = 0f
binding.icon3.alpha = 0f
}
private fun showWithoutAnimation() {
binding.icon1.alpha = 1f
binding.icon2.alpha = 1f
binding.icon3.alpha = 1f
}
private val firstAnimator: ValueAnimator = CustomValueAnimator(
{
binding.icon1.alpha = 0f
binding.icon2.alpha = 0f
binding.icon3.alpha = 0f
},
{
binding.icon1.alpha = it
},
{
secondAnimator.start()
}
)
private val secondAnimator: ValueAnimator = CustomValueAnimator(
{
binding.icon1.alpha = 1f
binding.icon2.alpha = 0f
binding.icon3.alpha = 0f
},
{
binding.icon2.alpha = it
},
{
thirdAnimator.start()
}
)
private val thirdAnimator: ValueAnimator = CustomValueAnimator(
{
binding.icon1.alpha = 1f
binding.icon2.alpha = 1f
binding.icon3.alpha = 0f
},
{
binding.icon1.alpha = 1f - binding.icon3.alpha
binding.icon3.alpha = it
},
{
fourthAnimator.start()
}
)
private val fourthAnimator: ValueAnimator = CustomValueAnimator(
{
binding.icon1.alpha = 0f
binding.icon2.alpha = 1f
binding.icon3.alpha = 1f
},
{
binding.icon2.alpha = 1f - it
},
{
fifthAnimator.start()
}
)
private val fifthAnimator: ValueAnimator = CustomValueAnimator(
{
binding.icon1.alpha = 0f
binding.icon2.alpha = 0f
binding.icon3.alpha = 1f
},
{
binding.icon3.alpha = 1f - it
},
{
firstAnimator.start()
}
)
private inner class CustomValueAnimator(
start: () -> Unit,
update: (value: Float) -> Unit,
end: () -> Unit
) : ValueAnimator() {
init {
duration = cycleDuration / 5
setFloatValues(0f, 1f)
addUpdateListener { update(it.animatedValue as Float) }
addListener(object : AnimatorListener {
override fun onAnimationStart(animation: Animator?) {
start()
}
override fun onAnimationEnd(animation: Animator?) {
end()
}
override fun onAnimationCancel(animation: Animator?) = Unit
override fun onAnimationRepeat(animation: Animator?) = Unit
})
}
}
}

View File

@ -0,0 +1,11 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="16dp"
android:height="20dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FFFFFF"
android:pathData="M3,2 L22,12 L3,22 Z" />
</vector>

View File

@ -54,11 +54,21 @@
tools:ignore="ContentDescription"
tools:visibility="visible" />
<View
android:id="@+id/playbackControlsShadow"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignBottom="@+id/playbackControlRoot"
android:background="@color/video_overlay_color"
android:visibility="gone"
tools:visibility="visible" />
<!-- transparent background is needed for selectableItemBackgroundBorderless to work -->
<RelativeLayout
android:id="@+id/playbackControlRoot"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/video_overlay_color"
android:background="@color/transparent_background_color"
android:fitsSystemWindows="true"
android:visibility="gone"
tools:visibility="visible">
@ -469,8 +479,8 @@
android:padding="@dimen/player_main_buttons_padding"
android:scaleType="fitCenter"
android:visibility="gone"
app:tint="@color/white"
app:srcCompat="@drawable/ic_fullscreen"
app:tint="@color/white"
tools:ignore="ContentDescription,RtlHardcoded"
tools:visibility="visible" />
</LinearLayout>
@ -493,8 +503,8 @@
android:clickable="true"
android:focusable="true"
android:scaleType="fitCenter"
app:tint="@color/white"
app:srcCompat="@drawable/ic_previous"
app:tint="@color/white"
tools:ignore="ContentDescription" />
@ -505,8 +515,8 @@
android:layout_weight="1"
android:background="?attr/selectableItemBackgroundBorderless"
android:scaleType="fitCenter"
app:tint="@color/white"
app:srcCompat="@drawable/ic_pause"
app:tint="@color/white"
tools:ignore="ContentDescription" />
<androidx.appcompat.widget.AppCompatImageButton
@ -519,8 +529,8 @@
android:clickable="true"
android:focusable="true"
android:scaleType="fitCenter"
app:tint="@color/white"
app:srcCompat="@drawable/ic_next"
app:tint="@color/white"
tools:ignore="ContentDescription" />
</LinearLayout>
@ -572,8 +582,8 @@
android:focusable="true"
android:padding="10dp"
android:scaleType="fitXY"
app:tint="@color/white"
app:srcCompat="@drawable/ic_close" />
app:srcCompat="@drawable/ic_close"
app:tint="@color/white" />
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/repeatButton"
@ -637,24 +647,6 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:id="@+id/controlAnimationView"
android:layout_width="100dp"
android:layout_height="100dp"
android:background="@drawable/background_oval_black_transparent"
android:padding="15dp"
android:visibility="gone"
tools:ignore="ContentDescription"
tools:src="@drawable/ic_fast_rewind"
tools:visibility="visible" />
</LinearLayout>
<RelativeLayout
android:id="@+id/loading_panel"
android:layout_width="match_parent"
@ -754,4 +746,11 @@
android:textColor="@color/white"
android:visibility="gone" />
<org.schabi.newpipe.views.player.PlayerFastSeekOverlay
android:id="@+id/fast_seek_overlay"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:alpha="0"
android:visibility="invisible" /> <!-- Required for the first appearance fading correctly -->
</RelativeLayout>

View File

@ -54,11 +54,21 @@
tools:ignore="ContentDescription"
tools:visibility="visible" />
<View
android:id="@+id/playbackControlsShadow"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"
android:layout_alignBottom="@+id/playbackControlRoot"
android:background="@color/video_overlay_color"
tools:visibility="visible" />
<!-- transparent background is needed for selectableItemBackgroundBorderless to work -->
<RelativeLayout
android:id="@+id/playbackControlRoot"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/video_overlay_color"
android:background="@color/transparent_background_color"
android:fitsSystemWindows="true"
android:visibility="gone"
tools:visibility="visible">
@ -633,24 +643,6 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:id="@+id/controlAnimationView"
android:layout_width="100dp"
android:layout_height="100dp"
android:background="@drawable/background_oval_black_transparent"
android:padding="15dp"
android:visibility="gone"
tools:ignore="ContentDescription"
tools:src="@drawable/ic_fast_rewind"
tools:visibility="visible" />
</LinearLayout>
<RelativeLayout
android:id="@+id/loading_panel"
android:layout_width="match_parent"
@ -751,4 +743,11 @@
android:textColor="@color/white"
android:visibility="gone" />
<org.schabi.newpipe.views.player.PlayerFastSeekOverlay
android:id="@+id/fast_seek_overlay"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:alpha="0"
android:visibility="invisible" /> <!-- Required for the first appearance fading correctly -->
</RelativeLayout>

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/root_constraint_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<org.schabi.newpipe.views.player.CircleClipTapView
android:id="@+id/circle_clip_tap_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="false"
android:focusable="false" />
<org.schabi.newpipe.views.player.SecondsView
android:id="@+id/seconds_view"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:clickable="false"
android:focusable="false"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_default="percent"
app:layout_constraintWidth_percent="0.5" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:ignore="ContentDescription"
tools:layout_height="wrap_content"
tools:layout_width="match_parent"
tools:orientation="vertical"
tools:parentTag="android.widget.LinearLayout">
<LinearLayout
android:id="@+id/triangle_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:orientation="horizontal">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/icon_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:srcCompat="@drawable/ic_play_seek_triangle"
tools:alpha="0.18" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/icon_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:srcCompat="@drawable/ic_play_seek_triangle"
tools:alpha="0.5" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/icon_3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:srcCompat="@drawable/ic_play_seek_triangle"
tools:alpha="1" />
</LinearLayout>
<TextView
android:id="@+id/tv_seconds"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:padding="4dp"
android:textColor="@android:color/white"
android:textSize="14sp"
tools:text="20 seconds" />
</merge>

View File

@ -6,14 +6,14 @@
android:orientation="vertical"
tools:context="org.schabi.newpipe.MainActivity">
<include
android:id="@+id/settings_toolbar_layout"
layout="@layout/toolbar_layout" />
<androidx.fragment.app.FragmentContainerView
android:id="@+id/settings_fragment_holder"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="?attr/actionBarSize" />
<include
layout="@layout/toolbar_layout"
android:id="@+id/settings_toolbar_layout"/>
</RelativeLayout>

View File

@ -0,0 +1,49 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:orientation="vertical"
android:background="?android:attr/windowBackground">
<View
android:layout_width="match_parent"
android:layout_height="4dp"
android:background="?attr/toolbar_shadow" />
<LinearLayout
android:id="@+id/empty_state_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
android:visibility="gone"
tools:visibility="gone">
<org.schabi.newpipe.views.NewPipeTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginBottom="10dp"
android:fontFamily="monospace"
android:text="╰(°●°╰)"
android:textSize="35sp"
tools:ignore="HardcodedText,UnusedAttribute" />
<org.schabi.newpipe.views.NewPipeTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/search_no_results"
android:textSize="24sp" />
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/searchResults"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:scrollbars="vertical" />
</LinearLayout>

View File

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/selectableItemBackground"
android:orientation="vertical"
android:padding="16dp"
android:paddingTop="12dp"
android:paddingBottom="12dp">
<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="?android:attr/editTextColor"
android:textSize="16sp"
tools:text="Title" />
<TextView
android:id="@+id/summary"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="?android:attr/editTextColor"
android:textSize="14sp"
tools:text="Summary" />
<TextView
android:id="@+id/breadcrumbs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:alpha="0.6"
android:textColor="?android:attr/editTextColor"
android:textSize="14sp"
tools:text="Breadcrumb" />
</LinearLayout>

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_search"
android:icon="@drawable/ic_search"
android:orderInCategory="1"
android:title="@string/search"
app:showAsAction="always" />
</menu>

View File

@ -98,7 +98,7 @@
<string name="undo">تراجع</string>
<string name="play_all">تشغيل الكل</string>
<string name="notification_channel_name">تنبيهات NewPipe</string>
<string name="notification_channel_description">تنبيهات مشغل NewPipe للخلفية والنوافذ المنبثقة</string>
<string name="notification_channel_description">تنبيهات مشغل NewPipe</string>
<string name="unknown_content">[غير معروف]</string>
<string name="could_not_setup_download_menu">تعذر إعداد قائمة التنزيل</string>
<string name="app_ui_crash">تعطل التطبيق / واجهة المستخدم</string>
@ -107,7 +107,7 @@
<string name="player_recoverable_failure">استرداد المشغل من الخطأ</string>
<string name="sorry_string">عذرًا، لم ينبغِ أن يحدث ذلك.</string>
<string name="error_report_button_text">الإبلاغ عن هذا الخطأ عبر البريد الإلكتروني</string>
<string name="error_snackbar_message">عذرا، حدث خطأ ما.</string>
<string name="error_snackbar_message">عذرًا، حدث خطأ ما.</string>
<string name="error_snackbar_action">أبلِغ</string>
<string name="what_device_headline">معلومات:</string>
<string name="what_happened_headline">ماذا حدث:</string>
@ -157,7 +157,7 @@
<string name="tab_licenses">التراخيص</string>
<string name="app_description">تطبيق مجاني خفيف البث على أندرويد.</string>
<string name="contribution_title">ساهم</string>
<string name="contribution_encouragement">إذا كانت لديك أفكار؛ أو ترجمة، أو تغييرات تخص التصميم، أو تنظيف و تحسين الشفرة البرمجية ، أو تعديلات عميقة عليها، فتذكر أنّ مساعدتك دائما موضع ترحيب. وكلما أتممنا شيئا كلما كان ذلك أفضل !</string>
<string name="contribution_encouragement">إذا كانت لديك أفكار؛ أو ترجمة، أو تغييرات تخص التصميم، أو تنظيف و تحسين الشفرة البرمجية، أو تعديلات عميقة عليها، فتذكر أنّ مساعدتك دائما موضع ترحيب. وكلما أتممنا شيئا كلما كان ذلك أفضل!</string>
<string name="view_on_github">عرض على GitHub</string>
<string name="donation_title">تبرع</string>
<string name="donation_encouragement">يتم تطوير NewPipe من قبل متطوعين يقضون وقت فراغهم لتقديم أفضل تجربة لك. حان الوقت لرد المساعدة مع المطورين وجعل NewPipe أكثر و أفضل بينما يستمتعون بفنجان من القهوة.</string>
@ -214,7 +214,7 @@
<string name="import_data_title">استيراد قاعدة البيانات</string>
<string name="export_data_title">تصدير قاعدة البيانات</string>
<string name="import_data_summary">يلغي السجل الحالي والاشتراكات وقوائم التشغيل والإعدادات (اختياريًا)</string>
<string name="export_data_summary">تصديرالسجل، وقوائم تشغيل، والإعدادات، والاشتراكات</string>
<string name="export_data_summary">تصدير السجل، وقوائم تشغيل، والإعدادات، والاشتراكات</string>
<string name="show_info">عرض المعلومات</string>
<string name="controls_add_to_playlist_title">إضافة إلى</string>
<string name="settings_category_debug_title">تحليل</string>
@ -238,7 +238,7 @@
<string name="delete_playlist_prompt">هل تريد حذف قائمة التشغيل هذه؟</string>
<string name="playlist_creation_success">تم إنشاء قائمة التشغيل</string>
<string name="playlist_add_stream_success">تمت إضافتها إلى قائمة التشغيل</string>
<string name="resize_fill">ملئ الشاشة</string>
<string name="resize_fill">ملء الشاشة</string>
<string name="resize_zoom">تكبير</string>
<string name="controls_download_desc">تنزيل ملف البث</string>
<string name="tab_bookmarks">الإشارات المرجعية</string>
@ -255,9 +255,9 @@
<string name="resize_fit">تناسب مع الشاشة</string>
<string name="caption_auto_generated">توليد تلقائي</string>
<string name="import_title">إستيراد</string>
<string name="import_from">إستعادة مِن</string>
<string name="import_from">استعادة مِن</string>
<string name="export_to">تصدير إلى</string>
<string name="import_ongoing">عملية الإستعادة جارية …</string>
<string name="import_ongoing">عملية الاستعادة جارية …</string>
<string name="export_ongoing">عملية التصدير جارية …</string>
<string name="import_file_title">إستيراد ملف</string>
<string name="import_soundcloud_instructions_hint">معرفك, soundcloud.com/هويتك</string>
@ -290,7 +290,7 @@
<string name="no_streams_available_download">لا يوجد بث متاح للتنزيل</string>
<string name="one_item_deleted">تم حذف عنصر واحد.</string>
<string name="toast_no_player">لم يتم تثبيت أي تطبيق لتشغيل هذا الملف</string>
<string name="app_license">NewPipe هو برنامج مفتوح المصدر و بحقوق متروكة: يمكنك استخدام الكود ودراسته وتحسينه كما شئت. و على وجه التحديد يمكنك إعادة توزيعه / أو تعديله تحت شروط رخصة GNU العمومية والتي نشرتها مؤسسة البرمجيات الحرة، سواء الإصدار 3 من الرخصة، أو (باختيارك) أي إصدار جديد.</string>
<string name="app_license">NewPipe هو برنامج مفتوح المصدر وبحقوق متروكة: يمكنك استخدام الكود ودراسته وتحسينه كما شئت. وعلى وجه التحديد يمكنك إعادة توزيعه / أو تعديله تحت شروط رخصة GNU العمومية والتي نشرتها مؤسسة البرمجيات الحرة، سواء الإصدار 3 من الرخصة، أو (باختيارك) أي إصدار جديد.</string>
<string name="title_last_played">آخر ما تم تشغيله</string>
<string name="title_most_played">الأكثر تشغيلا</string>
<string name="override_current_data">هذا سوف يُزيل إعداداتك الحالية.</string>
@ -325,10 +325,10 @@
<string name="unhook_checkbox">إلغاء الإرتباط (قد يسبب تشويه)</string>
<string name="import_settings">هل تريد أيضا استيراد الإعدادات؟</string>
<string name="privacy_policy_title">سياسة خصوصية NewPipe</string>
<string name="privacy_policy_encouragement">يأخذ مشروع NewPipe خصوصيتك على محمل الجد. لذلك ، لا يجمع التطبيق أي بيانات دون موافقتك.
<string name="privacy_policy_encouragement">يأخذ مشروع NewPipe خصوصيتك على محمل الجد. لذلك، لا يجمع التطبيق أي بيانات دون موافقتك.
\nتوضح سياسة خصوصية NewPipe بالتفصيل البيانات التي يتم إرسالها وتخزينها عند إرسال تقرير الأعطال.</string>
<string name="read_privacy_policy">الإطلاع على سياسة الخصوصية</string>
<string name="start_accept_privacy_policy">من أجل الامتثال للائحة الأوروبية العامة لحماية البيانات (GDPR) ، فإننا نلفت انتباهك إلى سياسة خصوصية NewPipe. يرجى قراءتها بعناية.
<string name="start_accept_privacy_policy">من أجل الامتثال للائحة الأوروبية العامة لحماية البيانات (GDPR)، فإننا نلفت انتباهك إلى سياسة خصوصية NewPipe. يرجى قراءتها بعناية.
\nو يجب عليك قبولها لإرسال تقرير الأخطاء إلينا.</string>
<string name="accept">قبول</string>
<string name="decline">رفض</string>
@ -353,7 +353,7 @@
<string name="brightness_gesture_control_summary">استخدام الإيماءات للتحكم بسطوع المشغّل</string>
<string name="settings_category_updates_title">التحديثات</string>
<string name="file_deleted">تم حذف الملف</string>
<string name="app_update_notification_channel_name">تتبيه تحديث التطبيق</string>
<string name="app_update_notification_channel_name">تنبيه تحديث التطبيق</string>
<string name="volume_gesture_control_title">إيماء التحكم بالصوت</string>
<string name="events">الأحداث</string>
<string name="app_update_notification_channel_description">إشعارات لإصدار NewPipe الجديد</string>
@ -378,7 +378,7 @@
<string name="paused">متوقف</string>
<string name="queued">في قائمة الانتظار</string>
<string name="post_processing">قيد المعالجة</string>
<string name="enqueue">طابور</string>
<string name="enqueue">قائمة الانتظار</string>
<string name="permission_denied">تم رفضها من قبل النظام</string>
<string name="download_failed">فشل التنزيل</string>
<string name="generate_unique_name">إنشاء اسم فريد</string>
@ -411,7 +411,7 @@
<string name="enable_playback_state_lists_title">المواضع في القوائم</string>
<string name="enable_playback_state_lists_summary">إظهار مؤشّرات وضع التشغيل في القوائم</string>
<string name="settings_category_clear_data_title">امسح البيانات</string>
<string name="watch_history_states_deleted">تم حذف وضع التشغيل</string>
<string name="watch_history_states_deleted">تم حذف كل مواقف التشغيل</string>
<string name="missing_file">نقل الملف أو حذفه</string>
<string name="overwrite_unrelated_warning">يوجد ملف بهذا الاسم مسبقاً</string>
<string name="overwrite_failed">لا يمكن الكتابة فوق الملف</string>
@ -420,11 +420,11 @@
<string name="error_insufficient_storage">لم يتبقى مساحة في الجهاز</string>
<string name="error_progress_lost">تم فقد التقدم بسبب حذف الملف</string>
<string name="error_timeout">انتهى وقت الاتصال</string>
<string name="confirm_prompt">هل تريد محو سجل التنزيل أو حذف جميع الملفات التي تم تنزيلها؟</string>
<string name="confirm_prompt">هل تريد محو سجل التنزيل، أم تريد حذف جميع الملفات التي تم تنزيلها؟</string>
<string name="enable_queue_limit">حد قائمة انتظار التنزيل</string>
<string name="enable_queue_limit_desc">سيتم تشغيل تنزيل واحد في نفس الوقت</string>
<string name="start_downloads">بدء التنزيلات</string>
<string name="pause_downloads">إيقاف التحميل مؤقتا</string>
<string name="pause_downloads">إيقاف التحميل مؤقتًا</string>
<string name="downloads_storage_ask_title">اسأل عن مكان التنزيل</string>
<string name="downloads_storage_ask_summary">سيتم سؤالك عن مكان حفظ كل تنزيل.
\nتمكين منتقي مجلد النظام (SAF) إذا كنت تريد التنزيل إلى بطاقة SD خارجية</string>
@ -433,7 +433,7 @@
<string name="clear_playback_states_title">حذف مواقف التشغيل</string>
<string name="clear_playback_states_summary">حذف كل مواقف التشغيل</string>
<string name="delete_playback_states_alert">حذف كل مواقف التشغيل؟</string>
<string name="drawer_header_description">تبديل الخدمة ، المحدد حاليًا:</string>
<string name="drawer_header_description">تبديل الخدمة، المحدد حاليًا:</string>
<string name="default_kiosk_page_summary">الكشك الافتراضي</string>
<string name="no_one_watching">لا توجد مشاهدة</string>
<string name="no_one_listening">لا أحد يستمع</string>
@ -465,7 +465,7 @@
<string name="local">محلي</string>
<string name="recently_added">أُضيف مؤخرًا</string>
<string name="most_liked">الأكثر إعجابًا</string>
<string name="playlist_no_uploader">تم إنشاؤه-تلقائيًا (لم يتم العثور على برنامج تحميل)</string>
<string name="playlist_no_uploader">مُنشأة تلقائيًا (لم يتم العثور على رافع)</string>
<string name="recovering">استرد</string>
<string name="error_download_resource_gone">لا يمكن استرداد هذا التنزيل</string>
<string name="choose_instance_prompt">اختيار مثيل</string>
@ -480,21 +480,21 @@
<string name="videos_string">الفيديوهات</string>
<plurals name="seconds">
<item quantity="zero">%d ثانية</item>
<item quantity="one">%d ثواني</item>
<item quantity="two">%d ثواني</item>
<item quantity="one">%d ثانية</item>
<item quantity="two">%d ثانية</item>
<item quantity="few">%d ثواني</item>
<item quantity="many">%d ثواني</item>
<item quantity="other">%d ثواني</item>
<item quantity="many">%d ثانية</item>
<item quantity="other">%d ثانية</item>
</plurals>
<string name="feed_use_dedicated_fetch_method_help_text">هل تعتقد تحميل تغذية بطيء جدا؟ إذا كان الأمر كذلك ، فحاول تمكين التحميل السريع (يمكنك تغييره في الإعدادات أو بالضغط على الزر أدناه).
<string name="feed_use_dedicated_fetch_method_help_text">هل تعتقد أن تحميل التغذية بطيءٌ جدًا؟ إذا كان الأمر كذلك، فحاول تمكين التحميل السريع (يمكنك تغييره في الإعدادات أو بالضغط على الزر أدناه).
\n
\nيقدم NewPipe استراتيجيتين لتحميل الخلاصة:
\n• جلب قناة الاشتراك بأكملها ، وهي بطيئة ولكنها كاملة.
\n• استخدام نقطة نهاية خدمة مخصصة ، وهي سريعة ولكنها عادة لا تكتمل.
\n• جلب قناة الاشتراك بأكملها، وهي بطيئة ولكنها كاملة.
\n• استخدام نقطة نهاية خدمة مخصصة، وهي سريعة ولكنها عادةً لا تكتمل.
\n
\nالفرق بين الاثنين هو أن العنصر السريع عادة ما يفتقر إلى بعض المعلومات ، مثل مدة العنصر أو نوعه (لا يمكن التمييز بين مقاطع الفيديو المباشرة والأخرى العادية) وقد يعيد عناصر أقل.
\nالفرق بين الاثنين هو أن العنصر السريع عادة ما يفتقر إلى بعض المعلومات، مثل مدة العنصر أو نوعه (لا يمكن التمييز بين مقاطع الفيديو المباشرة والأخرى العادية) وقد يعيد عناصر أقل.
\n
\n يوتيوب هو مثال على الخدمة التي تقدمها هذه طريقة سريعة مع تغذية RSS الخاصة بها.
\nيوتيوب هو مثال على الخدمة التي تقدمها هذه طريقة سريعة مع تغذية RSS الخاصة بها.
\n
\nلذا فإن الاختيار يتلخص في ما تفضله: السرعة أو المعلومات الدقيقة.</string>
<string name="feed_use_dedicated_fetch_method_disable_button">تعطيل الوضع السريع</string>
@ -525,35 +525,35 @@
<string name="feed_groups_header_title">مجموعات القنوات</string>
<plurals name="days">
<item quantity="zero">%d يوم</item>
<item quantity="one">%d أيام</item>
<item quantity="one">%d يوم</item>
<item quantity="two">%d أيام</item>
<item quantity="few">%d أيام</item>
<item quantity="many">%d أيام</item>
<item quantity="other">%d أيام</item>
<item quantity="many">%d يومًا</item>
<item quantity="other">%d يومًا</item>
</plurals>
<plurals name="hours">
<item quantity="zero">%d ساعة</item>
<item quantity="one">%d ساعات</item>
<item quantity="two">%d ساعات</item>
<item quantity="one">%d ساعة</item>
<item quantity="two">%d ساعة</item>
<item quantity="few">%d ساعات</item>
<item quantity="many">%d ساعات</item>
<item quantity="other">%d ساعات</item>
<item quantity="many">%d ساعة</item>
<item quantity="other">%d ساعة</item>
</plurals>
<plurals name="minutes">
<item quantity="zero">%d دقيقة</item>
<item quantity="one">%d الدقائق</item>
<item quantity="two">%d الدقائق</item>
<item quantity="few">%d الدقائق</item>
<item quantity="many">%d الدقائق</item>
<item quantity="other">%d الدقائق</item>
<item quantity="one">%d دقيقة</item>
<item quantity="two">%d دقيقة</item>
<item quantity="few">%d دقائق</item>
<item quantity="many">%d دقيقة</item>
<item quantity="other">%d دقيقة</item>
</plurals>
<string name="new_seek_duration_toast">نظرا لقيود مشغل ExoPlayer مدة التقديم تم ضبطها الى %d ثانية</string>
<string name="unmute">إلغاء كتم الصوت</string>
<string name="mute">كتم الصوت</string>
<string name="help">مساعدة</string>
<string name="content_not_supported">هذا المحتوى ليس مدعوم من قبل NewPipe.
<string name="content_not_supported">هذا المحتوى ليس مدعومًا من قبل NewPipe.
\n
\nنأمل أن يكون مدعوما في التحديثات القادمة.</string>
\nنأمل أن يكون مدعومًا في التحديثات القادمة.</string>
<string name="infinite_videos">∞ فيديو</string>
<string name="more_than_100_videos">+100 فيديو</string>
<string name="artists">الفنانين</string>
@ -577,7 +577,7 @@
<string name="feed_group_show_only_ungrouped_subscriptions">إظهار الاشتراكات غير المجمعة فقط</string>
<string name="no_playlist_bookmarked_yet">لا توجد إشارات مرجعية لقائمة التشغيل حتى الآن</string>
<string name="select_a_playlist">اختر قائمة تشغيل</string>
<string name="error_report_open_github_notice">يرجى مراجعة ما إذا توجد بالفعل مشكلة تناقش التحطم الموجود بالفعل.عند إنشاء تذاكر مكررة، فإنك تستغرق منا وقتًا يمكن أن نقضيه في إصلاح الخطأ الفعلي.</string>
<string name="error_report_open_github_notice">يرجى مراجعة ما إذا توجد بالفعل مشكلة تناقش التحطم الموجود بالفعل. عند إنشاء تذاكر مكررة، فإنك تستغرق منا وقتًا يمكن أن نقضيه في إصلاح الخطأ الفعلي.</string>
<string name="error_report_open_issue_button_text">تقرير على GitHub</string>
<string name="copy_for_github">نسخ التقرير مُنسق</string>
<string name="search_showing_result_for">عرض نتائج ل: %s</string>
@ -593,7 +593,7 @@
<string name="notification_action_nothing">لا شيء</string>
<string name="notification_action_buffering">جارٍ التحميل</string>
<string name="notification_action_shuffle">خلط</string>
<string name="notification_action_repeat">كرّر</string>
<string name="notification_action_repeat">تكرار</string>
<string name="notification_actions_at_most_three">يمكنك تحديد ثلاثة إجراءات كحد أقصى لإظهارها في الإشعار المضغوط!</string>
<string name="notification_actions_summary">قم بتحرير كل إشعار أدناه من خلال النقر عليه. حدد ما يصل إلى ثلاثة منها لتظهر في الإشعار المضغوط باستخدام مربعات الاختيار الموجودة على اليمين</string>
<string name="notification_action_4_title">زر الإجراء الخامس</string>
@ -617,7 +617,7 @@
<string name="show_thumbnail_title">إظهار الصورة المصغرة</string>
<string name="show_meta_info_summary">قم بإيقاف التشغيل لإخفاء مربعات المعلومات الوصفية بمعلومات إضافية حول منشئ، البث أو محتوى البث أو طلب البحث</string>
<string name="show_meta_info_title">إظهار معلومات التعريف</string>
<string name="recent">الأخيرة</string>
<string name="recent">حديثة</string>
<string name="msg_calculating_hash">حساب التجزئة</string>
<string name="hash_channel_description">إشعارات لتقدم تجزئة الفيديو</string>
<string name="hash_channel_name">إشعار تجزئة الفيديو</string>
@ -630,19 +630,19 @@
<string name="show_description_title">إظهار الوصف</string>
<string name="open_with">فتح مع</string>
<string name="paid_content">يتوفر هذا المحتوى فقط للمستخدمين الذين قاموا بالدفع، لذلك لا يمكن بثه أو تنزيله عبر NewPipe.</string>
<string name="youtube_music_premium_content">يتوفر هذا الفيديو فقط لأعضاء YouTube Music Premium ، لذلك لا يمكن بثه أو تنزيله من قبل NewPipe.</string>
<string name="youtube_music_premium_content">يتوفر هذا الفيديو فقط لأعضاء YouTube Music Premium، لذلك لا يمكن بثه أو تنزيله من قبل NewPipe.</string>
<string name="private_content">هذا المحتوى خاص، لذلك لا يمكن دفقه أو تنزيله بواسطة NewPipe.</string>
<string name="soundcloud_go_plus_content">هذا هو مسار SoundCloud Go+ ، على الأقل في بلدك ، لذلك لا يمكن بثها أو تنزيلها من قبل NewPipe.</string>
<string name="soundcloud_go_plus_content">هذا مسار SoundCloud Go+، على الأقل في بلدك، لذلك لا يمكن دفقه أو تنزيله بواسطة NewPipe.</string>
<string name="georestricted_content">هذا المحتوى غير متوفر في بلدك.</string>
<string name="crash_the_app">اغلق التطبيق قسريا</string>
<string name="restricted_video_no_stream">هذا الفيديو مقيد بالفئة العمرية.
\nنظرا لسياسات YouTube الجديدة المتعلقة بمقاطع الفيديو المقيدة بالفئة العمرية، لا يمكن ل NewPipe الوصول إلى أي من مقاطع الفيديو الخاصة بها وبالتالي يتعذر تشغيلها.</string>
\nنظرا لسياسات YouTube الجديدة المتعلقة بمقاطع الفيديو المقيدة بالفئة العمرية، لا يمكن لـNewPipe الوصول إلى أي من مقاطع الفيديو الخاصة بها وبالتالي لا يمكن تشغيلها.</string>
<string name="radio">إذاعة</string>
<string name="featured">المميزة</string>
<string name="recaptcha_solve">حل</string>
<string name="download_has_started">بدأ التنزيل</string>
<string name="select_night_theme_toast">يمكنك اختيار نسقك الليلي المفضل أدناه</string>
<string name="night_theme_summary">حدد موضوعك الليلي المفضل - %s</string>
<string name="night_theme_summary">حدد موضوعك الليلي المفضل %s</string>
<string name="auto_device_theme_title">تلقائي (سمة الجهاز)</string>
<string name="night_theme_title">الثيم الليلي</string>
<string name="show_channel_details">إظهار تفاصيل القناة</string>
@ -652,14 +652,14 @@
<string name="metadata_privacy_private">خاص</string>
<string name="metadata_privacy_unlisted">غير مدرج</string>
<string name="metadata_privacy_public">عامة</string>
<string name="metadata_thumbnail_url">عنوان URL للصورة المصغرة</string>
<string name="metadata_thumbnail_url">رابط الصورة المصغرة</string>
<string name="metadata_host">المضيف</string>
<string name="metadata_support">الدعم</string>
<string name="metadata_language">اللغة</string>
<string name="metadata_age_limit">الحد العمري</string>
<string name="metadata_privacy">الخصوصيّة</string>
<string name="metadata_licence">الرخصة</string>
<string name="metadata_tags">الفئة</string>
<string name="metadata_tags">الوسوم</string>
<string name="metadata_category">الصنف</string>
<string name="description_select_disable">تعطيل تحديد النص في الوصف</string>
<string name="description_select_enable">تمكين تحديد نص في الوصف</string>
@ -671,12 +671,12 @@
<string name="feed_load_error_terminated">حساب منشئ المحتوى قد تم إنهائه.
\nلن يتمكن NewPipe من تحميل هذه الخلاصة في المستقبل.
\nهل تريد إلغاء الاشتراك من هذه القناة؟</string>
<string name="feed_load_error_account_info">تعذر تحميل تغذية ل \'%s\'.</string>
<string name="feed_load_error_account_info">تعذر تحميل تغذية لـ\'%s\'.</string>
<string name="feed_load_error">خطأ في تحميل الخلاصة</string>
<string name="downloads_storage_use_saf_summary_api_29">بدءًا من Android 10 ، يتم دعم \"Storage Access Framework\" فقط</string>
<string name="downloads_storage_use_saf_summary_api_19">لا يتم دعم \"Storage Access Framework\" على Android KitKat والإصدارات الأقدم</string>
<string name="downloads_storage_use_saf_summary_api_29">بدءًا من Android 10، يتم دعم \"Storage Access Framework\" فقط</string>
<string name="downloads_storage_use_saf_summary_api_19">\"Storage Access Framework\" غير مدعوم على Android KitKat والإصدارات الأقدم</string>
<string name="downloads_storage_ask_summary_no_saf_notice">سيتم سؤالك عن مكان حفظ كل تنزيل</string>
<string name="no_dir_yet">لم يتم تعيين مجلد التحميل ، الرجاء اختيار مجلد التحميل الافتراضي الآن</string>
<string name="no_dir_yet">لم يتم تعيين مجلد التحميل، الرجاء اختيار مجلد التحميل الافتراضي الآن</string>
<string name="off">إيقاف</string>
<string name="on">تشغيل</string>
<string name="tablet_mode_title">وضع الجهاز اللوحي</string>
@ -687,7 +687,7 @@
<string name="high_quality_larger">جودة عالية (أكبر)</string>
<string name="seekbar_preview_thumbnail_title">معاينة مصغرة على شريط التمرير</string>
<string name="mark_as_watched">علّمه كفيديو تمت مشاهدته</string>
<string name="detail_heart_img_view_description">اعجب بها منشئ المحتوى</string>
<string name="detail_heart_img_view_description">أعجب بها منشئ المحتوى</string>
<string name="loading_channel_details">جاري تحميل تفاصيل القناة…</string>
<string name="error_show_channel_details">خطأ في عرض تفاصيل القناة</string>
<string name="show_image_indicators_summary">أظهر أشرطة ملونة لبيكاسو أعلى الصور تشير إلى مصدرها: الأحمر للشبكة والأزرق للقرص والأخضر للذاكرة</string>
@ -696,12 +696,12 @@
<string name="local_search_suggestions">اقتراحات البحث المحلية</string>
<string name="main_page_content_swipe_remove">اسحب العناصر لإزالتها</string>
<plurals name="deleted_downloads_toast">
<item quantity="zero">اكتمل %1$s التنزيل</item>
<item quantity="one">اكتمل %1$s التنزيل</item>
<item quantity="two">اكتمل %1$s التنزيل</item>
<item quantity="few">اكتملت %1$s التنزيلات</item>
<item quantity="many">اكتملت %1$s التنزيلات</item>
<item quantity="other">اكتملت %1$s التنزيلات</item>
<item quantity="zero">اكتمل %1$s تنزيل</item>
<item quantity="one">اكتمل %1$s تنزيل</item>
<item quantity="two">اكتمل %1$s تنزيل</item>
<item quantity="few">اكتملت %1$s تنزيلات</item>
<item quantity="many">اكتمل %1$s تنزيل</item>
<item quantity="other">اكتمل %1$s تنزيل</item>
</plurals>
<plurals name="download_finished_notification">
<item quantity="zero">اكتمل التنزيل</item>
@ -720,9 +720,20 @@
<string name="manual_update_description">التحقق يدويا من وجود إصدارات جديدة</string>
<string name="checking_updates_toast">جاري التحقق من وجود تحديثات…</string>
<string name="feed_new_items">عناصر تغذية جديدة</string>
<string name="report_player_errors_title">الإبلاغ عن أخطاء المشغل</string>
<string name="show_crash_the_player_summary">إظهار خيار تعطل عند استخدام المشغل</string>
<string name="show_crash_the_player_title">إظهار \"تعطل المشغل\"</string>
<string name="crash_the_player">تحطيم المشغل</string>
<string name="report_player_errors_summary">رفع تقرير لأخطاء المشغل بالتفصيل الكامل بدلا من إظهار رسالة اشعار قصيرة الأجل (مفيدة لتشخيص المشاكل)</string>
<string name="error_report_channel_name">إشعار الإبلاغ عن الأخطاء</string>
<string name="error_report_channel_description">التنبيهات المتعلقة بالإبلاغ عن الأخطاء</string>
<string name="error_report_notification_title">واجه NewPipe خطأ، اضغط للتقرير</string>
<string name="error_report_notification_toast">حدث خطأ، انظر للإشعار</string>
<string name="create_error_notification">قم بإنشاء تنبيه بالخطأ</string>
<string name="no_appropriate_file_manager_message">لم يتم العثور على مدير ملفات مناسب لهذا الإجراء.
\nالرجاء تثبيت مدير ملفات أو محاولة تعطيل \"%s\" في إعدادات التنزيل.</string>
<string name="show_error_snackbar">إظهار خطأ snackbar</string>
<string name="no_appropriate_file_manager_message_android_10">لم يتم العثور على مدير ملفات مناسب لهذا الإجراء.
\nالرجاء تثبيت مدير ملفات متوافق مع Storage Access Framework.</string>
<string name="background_player_already_playing_toast">يتم تشغيله في الخلفية</string>
<string name="detail_pinned_comment_view_description">تعليق مثبت</string>
<string name="leak_canary_not_available">LeakCanary غير متوفر</string>
</resources>

View File

@ -33,7 +33,7 @@
<plurals name="videos">
<item quantity="other">%s 个视频</item>
</plurals>
<string name="disabled">停用</string>
<string name="disabled">停用</string>
<string name="controls_background_title">后台播放</string>
<string name="show_search_suggestions_title">显示搜索建议</string>
<string name="subscribe_button_title">订阅</string>
@ -58,7 +58,7 @@
<string name="settings_category_updates_title">更新</string>
<string name="file_deleted">文件已删除</string>
<string name="subscribers_count_not_available">无法得知订阅人数</string>
<string name="updates_setting_description">发布新版本时,通知我升级应用</string>
<string name="updates_setting_description">有新版本时,显示通知提示更新应用</string>
<string name="grid">网格</string>
<string name="app_update_notification_content_title">NewPipe 可更新!</string>
<string name="error_http_unsupported_range">服务器不接受多线程下载, 使用 @string/msg_threads = 1 重试</string>
@ -115,7 +115,7 @@
<string name="missions_header_pending">等待中</string>
<string name="paused">已暂停</string>
<string name="queued">已加入队列</string>
<string name="enqueue">排队</string>
<string name="enqueue">加入队列</string>
<string name="permission_denied">操作已被系统拒绝</string>
<string name="download_failed">下载失败</string>
<string name="no_comments">没有评论</string>
@ -148,7 +148,7 @@
<string name="app_ui_crash">App/UI 崩溃</string>
<string name="sorry_string">抱歉, 这本不该发生。</string>
<string name="error_report_button_text">使用电子邮件反馈错误</string>
<string name="error_snackbar_message">抱歉, 发生了一些错误。</string>
<string name="error_snackbar_message">抱歉发生了一些错误。</string>
<string name="error_snackbar_action">反馈</string>
<string name="what_device_headline">信息:</string>
<string name="what_happened_headline">发生了什么:</string>
@ -174,7 +174,7 @@
<string name="use_external_video_player_summary">部分分辨率下没有音频</string>
<string name="show_search_suggestions_summary">选择搜索时显示的建议</string>
<string name="best_resolution">最佳分辨率</string>
<string name="app_description">开源且小巧的 Android 媒体播放器。</string>
<string name="app_description">自由且小巧的 Android 媒体播放器。</string>
<string name="view_on_github">在 GitHub 上查看</string>
<string name="app_license_title">NewPipe 的许可证</string>
<string name="contribution_encouragement">你是否想过要翻译、设计、清理或重构代码——我们始终欢迎你来贡献!</string>
@ -194,7 +194,7 @@
<string name="title_activity_history">历史记录</string>
<string name="action_history">历史记录</string>
<string name="notification_channel_name">NewPipe 通知</string>
<string name="notification_channel_description">NewPipe 在后台播放和悬浮窗播放时在通知栏中显示通知</string>
<string name="notification_channel_description">NewPipe 播放器的通知</string>
<string name="default_video_format_title">默认视频格式</string>
<string name="settings_category_player_behavior_title">行为</string>
<string name="empty_subscription_feed_subtitle">空空如也</string>
@ -249,7 +249,7 @@
<string name="import_complete_toast">导入成功</string>
<string name="no_valid_zip_file">没有有效的 ZIP 文件</string>
<string name="could_not_import_all_files">警告:无法导入所有文件。</string>
<string name="override_current_data">此操作会<b>覆盖当前设置</b></string>
<string name="override_current_data">此操作会覆盖当前设置。</string>
<string name="show_info">显示信息</string>
<string name="tab_bookmarks">收藏</string>
<string name="title_last_played">最近观看</string>
@ -272,8 +272,8 @@
<string name="resize_zoom">缩放画面</string>
<string name="settings_category_debug_title">调试</string>
<string name="caption_auto_generated">自动生成</string>
<string name="enable_leak_canary_summary">『内存泄漏监视』可能导致应用在『核心转储』时无响应</string>
<string name="enable_disposed_exceptions_title">报告『提前结束Android生命周期』错误</string>
<string name="enable_leak_canary_summary">内存泄漏监测可能会导致应用在堆转储时无响应</string>
<string name="enable_disposed_exceptions_title">报告超出生命周期的错误</string>
<string name="enable_disposed_exceptions_summary">强制报告处理后的未送达的 Activity 或 Fragment 生命周期之外的 Rx 异常</string>
<string name="use_inexact_seek_title">使用快速寻址(不精确)</string>
<string name="use_inexact_seek_summary">快速寻址定位允许播放器以较低精确度为代价换取更快的寻址定位速度。此功能不适用于以 5、15 或 25 秒为隔的寻址定位</string>
@ -300,8 +300,8 @@
\n3. 单击“包含所有数据”,然后单击“取消全选”,然后仅选择“订阅”并单击“确定”
\n4. 点击“下一步”,然后点击“创建导出作业”
\n5. 出现“下载”按钮后点击它
\n6. 单击下面的导入文件并选择下载的 zip 文件
\n7.【如果 zip 导入失败】解压 .csv文件通常在“YouTube和YouTube Music/subscriptions/subscriptions.csv”下点击下方的导入文件选择解压出来的 csv 文件</string>
\n6. 单击下面的导入文件并选择下载的 .zip 文件
\n7.(如果 .zip 导入失败)解压 .csv文件通常在“YouTube和YouTube Music/subscriptions/subscriptions.csv”下点击下方的导入文件选择解压出来的 csv 文件</string>
<string name="import_soundcloud_instructions">通过输入网址或你的 ID 导入 SoundCloud 配置文件:
\n
\n1. 在浏览器中启用“电脑模式“(该网站未适配移动设备);
@ -332,7 +332,7 @@
<string name="clear_search_history_summary">清空搜索历史关键词</string>
<string name="delete_search_history_alert">是否删除全部搜索历史?</string>
<string name="search_history_deleted">搜索历史已删除</string>
<string name="app_license">NewPipe 是版权自由软件:您可以随时使用、研究共享和改进它。您可以根据自由软件基金会发布的 GNU 通用公共许可证 GPLv3 或(由您选择的)任何更高版本的许可证重新分发或修改该许可证。</string>
<string name="app_license">NewPipe 是 Copyleft 的自由软件:您可以随时使用、研究共享和改进它。您可以根据自由软件基金会发布的 GNU 通用公共许可证 GPLv3 或(由您选择的)任何更高版本的许可证重新分发或修改该许可证。</string>
<string name="import_settings">是否要导入设置?</string>
<string name="privacy_policy_title">NewPipe 隐私政策</string>
<string name="privacy_policy_encouragement">NewPipe 项目非常重视您的隐私。因此,未经您的同意,应用程序不会收集任何数据。
@ -358,7 +358,7 @@
<string name="brightness_gesture_control_summary">使用手势控制播放器的亮度</string>
<string name="content_language_title">视频默认语言</string>
<string name="app_update_notification_channel_name">应用更新通知</string>
<string name="app_update_notification_channel_description">当 NewPipe 有新版本时发送通知</string>
<string name="app_update_notification_channel_description">NewPipe 新版本的通知</string>
<string name="download_to_sdcard_error_title">外置存储不可用</string>
<string name="download_to_sdcard_error_message">无法下载到外部 SD 卡,修改下载文件夹位置?</string>
<string name="saved_tabs_invalid_json">读取已保存标签时发生错误,因此使用默认标签</string>
@ -521,7 +521,7 @@
<string name="remove_watched_popup_title">移除看过的视频?</string>
<string name="remove_watched">移除看过的视频</string>
<string name="show_original_time_ago_summary">来自服务的原始文本将在串流项目中可见</string>
<string name="show_original_time_ago_title">显示原始时间</string>
<string name="show_original_time_ago_title">在项目上显示原始时间</string>
<string name="youtube_restricted_mode_enabled_title">启用 YouTube“受限模式”</string>
<string name="feed_group_show_only_ungrouped_subscriptions">仅显示未分组订阅</string>
<string name="playlist_page_summary">播放列表页</string>
@ -660,9 +660,20 @@
<string name="checking_updates_toast">检查更新中…</string>
<string name="manual_update_title">检查更新</string>
<string name="feed_new_items">新订阅源条目</string>
<string name="report_player_errors_summary">完整报告播放器错误而不是弹出一个临时Toast对诊断应用很有用</string>
<string name="show_crash_the_player_title">显示\"使播放器崩溃\"</string>
<string name="show_crash_the_player_summary">在使用播放器时显示一个崩溃选项</string>
<string name="crash_the_player">使播放器崩溃</string>
<string name="report_player_errors_title">报告播放器错误</string>
<string name="error_report_channel_name">错误报告通知</string>
<string name="error_report_channel_description">提示报告错误的通知</string>
<string name="error_report_notification_toast">发生错误,详见通知</string>
<string name="show_error_snackbar">显示错误警示SnackBar</string>
<string name="create_error_notification">创建一条错误通知</string>
<string name="no_appropriate_file_manager_message">找不到适合此操作的文件管理器。
\n请安装一文件管理器或尝试在下载设置中禁用“%s”。</string>
<string name="no_appropriate_file_manager_message_android_10">找不到适合此操作的文件管理器。
\n请安装与存储访问框架(SAF)兼容的文件管理器。</string>
<string name="error_report_notification_title">NewPipe 遇到了一个错误,点击此处报告此错误</string>
<string name="background_player_already_playing_toast">已经在后台播放</string>
<string name="detail_pinned_comment_view_description">置顶评论</string>
<string name="leak_canary_not_available">LeakCanary 不可用</string>
</resources>

View File

@ -126,7 +126,7 @@
<string name="thumbnail_cache_wipe_complete_notice">S\'ha eliminat la memòria cau d\'imatges</string>
<string name="metadata_cache_wipe_title">Elimina les metadades de la memòria cau</string>
<string name="metadata_cache_wipe_complete_notice">S\'ha esborrat la memòria cau de metadades</string>
<string name="auto_queue_title">Afegeix vídeos relacionats a la cua</string>
<string name="auto_queue_title">Posa a la cua el següent flux</string>
<string name="show_search_suggestions_title">Suggeriments de cerca</string>
<string name="show_search_suggestions_summary">Mostra suggeriments durant la cerca</string>
<string name="enable_search_history_title">Historial de cerca</string>
@ -136,8 +136,8 @@
<string name="content_language_title">Llengua per defecte dels continguts</string>
<string name="background_player_playing_toast">S\'està reproduint en rerefons</string>
<string name="popup_playing_toast">S\'està reproduint en mode emergent</string>
<string name="notification_channel_name">Notificació del NewPipe</string>
<string name="notification_channel_description">Notificacions dels reproductors en rerefons o emergents del NewPipe</string>
<string name="notification_channel_name">Notificació de NewPipe</string>
<string name="notification_channel_description">Notificacions per al reproductor de NewPipe</string>
<string name="could_not_load_thumbnails">No s\'han pogut carregar totes les miniatures</string>
<string name="youtube_signature_deobfuscation_error">No s\'ha pogut desxifrar la signatura de l\'URL del vídeo</string>
<string name="parsing_error">No s\'ha pogut processar el lloc web</string>
@ -270,7 +270,7 @@
<string name="unhook_checkbox">Desvincula (pot causar deformació)</string>
<string name="metadata_cache_wipe_summary">Elimina totes les dades de llocs web de la memòria cau</string>
<string name="auto_queue_summary">Acaba de reproduir la cua (sense repetició) quan s\'hi afegeixi un vídeo relacionat</string>
<string name="show_hold_to_append_title">Mostra els missatges d\'ajuda</string>
<string name="show_hold_to_append_title">Mostra l\'indicador «Mantenir per posar a la cua»</string>
<string name="show_hold_to_append_summary">Mostra un missatge d\'ajuda quan el botó de mode en segon pla o emergent estigui premut a la pàgina de detalls d\'un vídeo</string>
<string name="info_labels">Què ha passat:\\nPetició:\\nIdioma del contingut:\\nPaís del contingut:\\nLlengua de l\'aplicació:\\nServei:\\nHora GMT:\\nPaquet:\\nVersió:\\nVersió del SO:</string>
<string name="preferred_open_action_settings_title">Acció d\'obertura preferida</string>
@ -285,7 +285,8 @@
\n3. Premeu \"Totes les dades incloses\", després \"Dessel·lecciona-ho tot\", llavors sel·leccioneu només \"Subscripcions\" i finalment premeu \"D\'acord\".
\n4. Premeu \"Pas següent\" i llavors a \"Crea una exportació\"
\n5. Premeu el botó \"Baixa\" un cop hagi aparegut
\n6. Del fitxer comprimit baixat, extreieu-ne el fitxer subscripcions.json (es troba a \"Takeout/YouTube i YouTube Music/subscripcions/subscripcions.json\") i importeu-lo aquí.</string>
\n6. Premeu a IMPORTA EL FITXER i sel·leccioneu el fitxer .zip descarregat
\n7. [En cas que la importació del fitxer .zip hagi fallat] extreieu-ne el fitxer subscripcions.csv (es troba generalment a \"Takeout/YouTube i YouTube Music/subscripcions/subscripcions.csv\"), premeu a IMPORTA EL FITXER i sel·leccioneu el fitxer .csv extret.</string>
<string name="import_soundcloud_instructions">Importeu un perfil del SoundCloud mitjançant l\'URL o l\'identificador del vostre perfil:
\n
\n1. Activeu el «Mode d\'ordinador» en un navegador (el lloc web no està disponible per a dispositius mòbils)
@ -401,7 +402,8 @@
<string name="enable_queue_limit">Limita la cua de baixades</string>
<string name="start_downloads">Inicia les baixades</string>
<string name="pause_downloads">Pausa les baixades</string>
<string name="downloads_storage_ask_summary">Si us demanarà la ubicació de cada baixada</string>
<string name="downloads_storage_ask_summary">Se us demanarà la ubicació de cada baixada.
\nHeu d\'activar el SAF si voleu descarregar-ho a una targeta SD externa</string>
<string name="enable_playback_state_lists_title">Posicions a les llistes</string>
<string name="enable_playback_state_lists_summary">Mostra els indicadors de posició de reproducció a les llistes</string>
<string name="settings_category_clear_data_title">Neteja les dades</string>
@ -414,9 +416,8 @@
<string name="watch_history_states_deleted">S\'ha esborrat les posicions de reproducció</string>
<string name="missing_file">El fitxer s\'ha mogut o suprimit</string>
<string name="enable_queue_limit_desc">Només una baixada alhora</string>
<string name="downloads_storage_use_saf_title">Utilitza SAF</string>
<string name="downloads_storage_use_saf_summary">El SAF (Storage Access Framework; estructura d\'accés a l\'emmagatzematge) us permet realitzar baixades a una memòria externa com una targeta SD.
\nAlguns dispositius no en són compatibles</string>
<string name="downloads_storage_use_saf_title">Fes servir el SAF</string>
<string name="downloads_storage_use_saf_summary">El SAF (Storage Access Framework; estructura d\'accés a l\'emmagatzematge) us permet realitzar baixades a una memòria externa com una targeta SD.</string>
<string name="clear_playback_states_title">Esborra les posicions de reproducció</string>
<string name="clear_playback_states_summary">Esborra totes les posicions de reproducció</string>
<string name="delete_playback_states_alert">Voleu suprimir tots els punts de reproducció\?</string>
@ -482,7 +483,7 @@
\nEn definitiva, l\'elecció depèn de si preferiu rapidesa a assegurar-vos que l\'informació és precisa.</string>
<string name="feed_use_dedicated_fetch_method_disable_button">Desactiva el mode ràpid</string>
<string name="feed_use_dedicated_fetch_method_enable_button">Activa el mode ràpid</string>
<string name="feed_use_dedicated_fetch_method_summary">Disponible en alguns serveis, normalment és més ràpid, però podria només incloure un nombre limitat de contingut i sovint informació incomplerta (per exemple, sense durada, tipus…).</string>
<string name="feed_use_dedicated_fetch_method_summary">Disponible en alguns serveis, normalment és més ràpid, però podria només incloure un nombre limitat de contingut i sovint informació incomplerta (per exemple, sense durada, tipus…)</string>
<string name="feed_use_dedicated_fetch_method_title">Recupera des d\'un feed dedicat si és possible</string>
<string name="feed_update_threshold_option_always_update">Actualitza sempre</string>
<string name="feed_update_threshold_summary">Temps que ha de passar perquè una subscripció es consideri obsoleta — %s</string>
@ -558,7 +559,7 @@
<string name="youtube_restricted_mode_enabled_summary">YouTube proporciona un \"mode restringit\" que amaga contingut potencialment inadequat per a infants</string>
<string name="show_age_restricted_content_summary">Mostra contingut que podria ser inadequat pels infants</string>
<string name="unsupported_url_dialog_message">No s\'ha pogut reconèixer l\'adreça URL. Obrir-la amb una altra aplicació\?</string>
<string name="auto_queue_toggle">Cua automàtica</string>
<string name="auto_queue_toggle">Posa a la cua automàticament</string>
<string name="show_meta_info_summary">Desactiveu-ho per deixar de mostrar les metadades, que contenen informació addicional sobre el creador del directe, el contingut o una sol·licitud de cerca</string>
<string name="show_meta_info_title">Mostra les metadades</string>
<string name="clear_queue_confirmation_description">La cua de reproducció activa serà sobreescrita</string>
@ -651,4 +652,40 @@
<string name="start_main_player_fullscreen_title">Inicia el reproductor principal en pantalla completa</string>
<string name="main_page_content_swipe_remove">Llisqueu els elements per eliminar-los</string>
<string name="start_main_player_fullscreen_summary">Si la rotació automàtica està bloquejada, no inicieu vídeos al mini reproductor, sinó que aneu directament al mode de pantalla completa. Podeu accedir igualment al mini reproductor sortint de pantalla completa</string>
<string name="background_player_already_playing_toast">Ja s\'està reproduint en segon pla</string>
<string name="error_report_channel_name">Notificació d\'informe d\'error</string>
<string name="crash_the_player">Tancar abruptament el reproductor</string>
<string name="manual_update_title">Comprovar si hi ha actualitzacions</string>
<string name="manual_update_description">Comprovar manualment si hi ha noves versions</string>
<plurals name="download_finished_notification">
<item quantity="one">Baixada finalitzada</item>
<item quantity="other">%s baixades finalitzades</item>
</plurals>
<string name="seekbar_preview_thumbnail_title">Vista prèvia de les miniatures de la barra de cerca</string>
<string name="no_appropriate_file_manager_message_android_10">No s\'ha trobat cap gestor de fitxers adequat per a aquesta acció.
\nInstal·leu un gestor de fitxers compatible amb l\'entorn d\'accés d\'emmagatzematge.</string>
<string name="no_appropriate_file_manager_message">No s\'ha trobat cap gestor de fitxers adequat per a aquesta acció.
\nInstal·leu un gestor de fitxers o intenteu desactivar «%s» als paràmetres de baixada.</string>
<string name="error_report_notification_toast">S\'ha produït un error, consulteu la notificació</string>
<string name="enqueued_next">Afegit el següent vídeo a la cua</string>
<string name="error_report_notification_title">NewPipe ha trobat un error, toca per informar</string>
<string name="enqueue_next_stream">Posa a la cua el següent vídeo</string>
<string name="create_error_notification">Crear una notificació d\'error</string>
<string name="error_show_channel_details">Error en mostrar els detalls del canal</string>
<string name="error_report_channel_description">Notificacions per informar d\'errors</string>
<string name="show_error_snackbar">Mostra una barra d\'errors</string>
<string name="checking_updates_toast">S\'estan comprovant les actualitzacions…</string>
<plurals name="deleted_downloads_toast">
<item quantity="one">S\'ha suprimit %1$s baixada</item>
<item quantity="other">S\'han suprimit %1$s baixades</item>
</plurals>
<string name="downloads_storage_use_saf_summary_api_19">El \"Sistema d\'Accés a l\'Emmagatzematge\" no està implementat a Android KitKat i a versions anteriors</string>
<string name="downloads_storage_use_saf_summary_api_29">A partir de l\'Android 10 només s\'admet el \"Sistema d\'Accés a l\'Emmagatzematge\"</string>
<string name="feed_new_items">Elements de feed nous</string>
<string name="feed_load_error_fast_unknown">El mode d\'alimentació ràpida no proporciona més informació sobre això.</string>
<string name="detail_pinned_comment_view_description">Comentari fixat</string>
<string name="show_crash_the_player_title">Mostrar \"tancar de forma violenta el reproductor\"</string>
<string name="show_crash_the_player_summary">Mostra una opció de fallada quan s\'utilitza el reproductor</string>
<string name="show_image_indicators_summary">Mostra les cintes de color Picasso a la part superior de les imatges que indiquen la seva font: vermell per a la xarxa, blau per al disc i verd per a la memòria</string>
<string name="leak_canary_not_available">El LeakCanary no està disponible</string>
</resources>

View File

@ -45,7 +45,7 @@
<string name="clear_search_history_title">سڕینەوەی مێژووی گەڕان</string>
<string name="msg_error">هەڵە</string>
<string name="override_current_data">ئەمە لەسەر ڕێکخستنەکانی ئێستات جێگیر دەبێت.</string>
<string name="notification_channel_name">ئاگانامەکانی نیوپایپ</string>
<string name="notification_channel_name">پەیامەکانی نیوپایپ</string>
<string name="donation_encouragement">نیوپایپ لەلایەن چەند خۆبەخشێکەوە دروستکراوە کە کاته‌كانی خۆیان پێ بەخشیووە تاکو باشترین خزمەتگوزاریت پێشکەش بکەن. هیچ نەبێت بە کڕینی کوپێک قاوە یارمەتی گەشەپێدەرەکانمان بدە بۆ ئەوەی کاتی زیاتر تەرخان بکەین بۆ بەرەوپێشبردنی نیوپایپ.</string>
<string name="short_billion">ملیار</string>
<string name="show_search_suggestions_title">گەڕانی پێشنیارکراوەکان</string>
@ -191,7 +191,7 @@
<string name="no_views">بینراو نییە</string>
<string name="invalid_file">ئەو فایله‌ بوونی نییە یان دەسەڵاتی خوێندنەوە و نوسینی لاوازە</string>
<string name="parsing_error">ناتوانرێت ماڵپەڕ شیبکرێتەوە</string>
<string name="settings_file_charset_title">ڕه‌نووسه‌ ڕێ پێدراوه‌كانله‌ فایله‌ ناوییه‌كاندا</string>
<string name="settings_file_charset_title">ڕه‌نووسه‌ ڕێپێدراوه‌كان له‌ فایله‌ ناوییه‌كاندا</string>
<string name="import_soundcloud_instructions_hint">ئایدییەکەت ، soundcloud.com/yourid</string>
<string name="help">یارمەتی</string>
<string name="fragment_feed_title">چی نوێ هه‌یه‌</string>
@ -237,9 +237,9 @@
<string name="open_in_browser">كردنه‌وه‌ له‌ وێبگه‌ر</string>
<string name="error_http_no_content">ڕاژەکە هیچ داتایەک نانێرێت</string>
<string name="watch_history_states_deleted">شوێنی کارپێکراوەکان سڕانەوە</string>
<string name="app_update_notification_channel_description">ئاگانامەکانی وەشانی نوێی نیوپایپ</string>
<string name="app_update_notification_channel_description">پەیامەکانی وەشانە نوێیەکانی نیوپایپ</string>
<string name="show_higher_resolutions_summary">تەنها چەند مۆبایلێک پشتگیری لێدانی ڤیدیۆی 2K/4K دەکەن</string>
<string name="notification_channel_description">ئاگانامەکانی پاشبنەمای نیوپایپ و لێدانه‌كانی پەنجەرە</string>
<string name="notification_channel_description">پەیامەکانی لێدەری نیوپایپ</string>
<string name="feed_use_dedicated_fetch_method_summary">لەهەندێ خزمەتگوزاریدا بەردەستە، بەزۆری خێراترینە بەڵام ڕەنگە هەندێک لە بابەتەکان زانیارییەکانیان ناتەواو بێت (وەک نەبوونی ماوە، جۆری بابەت ، نەبوونی پەخش)</string>
<plurals name="seconds">
<item quantity="one">%d چرکە</item>
@ -275,7 +275,7 @@
<string name="video_streams_empty">هیچ پەخشێکی ڤیدیۆیی نەدۆزرایەوە</string>
<string name="import_from">هاوردە لە</string>
<string name="subtitle_activity_recaptcha">كرتە بکە لەسەر ”كرا” کاتێك کە چارەسەرکرا</string>
<string name="app_update_notification_channel_name">ئاگانامەی نوێکاری بەرنامە</string>
<string name="app_update_notification_channel_name">پەیامی نوێکردنەوەی بەرنامە</string>
<string name="could_not_load_thumbnails">ناتوانرێت هەموو وێنۆچکەکان باربکرێن</string>
<string name="previous_export">هەناردەی پێشووتر</string>
<string name="no_valid_zip_file">فایلی ZIP دروست نییە</string>
@ -394,7 +394,7 @@
<string name="bookmark_playlist">نیشانه‌كردنی خشته‌لێدان</string>
<string name="file_name_empty_error">ناوی فایل ناکرێت بەتاڵ بێت</string>
<string name="youtube_signature_deobfuscation_error">ناتوانرێت واژووی بەستەری ڤیدیۆ بخوێنرێتەوە</string>
<string name="updates_setting_description">پیشاندانی ئاگانامەیەک بۆ ئامادەبوونی به‌رنامه‌ لەکاتی بەردەست بوونی وەشانی نوێ</string>
<string name="updates_setting_description">پیشاندانی پەیامێک بۆ ئامادەبوونی به‌رنامه‌ لەکاتی بەردەست بوونی وەشانی نوێ</string>
<string name="enable_watch_history_title">مێژووی سەیرکردن</string>
<string name="enable_disposed_exceptions_title">سکاڵا لەسەر کێشەکان</string>
<string name="playlist_no_uploader">خۆکار-دانراو (هیچ بەرزکەرەوەیەک نەدۆزرایەوە)</string>
@ -462,9 +462,9 @@
<string name="settings_file_replacement_character_title">ڕه‌نووسی جێگۆڕین</string>
<string name="settings">ڕێكخستنه‌كان</string>
<string name="missions_header_finished">دابه‌زێنراو</string>
<string name="import_youtube_instructions">بۆ هاورده‌ كردنی بەژداربوونەکانی یوتوب له‌ گووگڵه‌وه‌:
<string name="import_youtube_instructions">بۆ هاورده‌كردنی بەژداربوونەکانی یوتوب له‌ گووگڵه‌وه‌:
\n
\n1. ئەم بەستەرە بکەوە: %1$s
\n1. ئەم بەستەرە بکەرەوە: %1$s
\n2. بچۆرەژوورەوە گەر داوای‌ کرد
\n3. كرته‌ بكه‌ له‌ \"All data included\"، پاشان كرته‌ بكه‌ له‌ \"Deselect all\" ، پاشان ته‌نیا \"subscriptions\" هه‌ڵبژێره‌ پاشان كرته‌ له‌ \"OK\" بكه‌
\n4. كرته‌ بكه‌ له‌ \"Next step\" و دواتر له‌ \"Create export\"
@ -551,14 +551,14 @@
<string name="notification_action_buffering">نێوانگری</string>
<string name="notification_action_shuffle">تێکەڵکردن</string>
<string name="notification_action_repeat">دووبارە</string>
<string name="notification_actions_at_most_three">دەتوانیت تا سێ كردار دیار بكه‌یت تا پیشان بدرێن له‌ ئاگانامه‌كه‌دا!</string>
<string name="notification_actions_summary">ده‌ستكاری هه‌ر یه‌كێك له‌م كردارانه‌ی خواره‌وه‌ بكه‌ له‌ڕێگه‌ی كرته‌ له‌سه‌ریان. ده‌توانیت تا زیاتر له‌ سێ دانه‌یان هه‌ڵبژێریت له‌ ڕێگای چوارگۆشه‌كانی لای ڕاسته‌وه‌یان، تا پیشان بدرێن له‌ ئاگانامه‌كاندا</string>
<string name="notification_actions_at_most_three">دەتوانیت تا سێ كردار دیار بكه‌یت تا پیشان بدرێن له‌ پەیامەکەدا!</string>
<string name="notification_actions_summary">ده‌ستكاری هه‌ر یه‌كێك له‌م كردارانه‌ی خواره‌وه‌ بكه‌ له‌ڕێگه‌ی كرته‌ له‌سه‌ریان. ده‌توانیت تا زیاتر له‌ سێ دانه‌یان هه‌ڵبژێریت له‌ ڕێگای چوارگۆشه‌كانی لای ڕاسته‌وه‌یان، تا پیشان بدرێن له‌ پەیامەکاندا</string>
<string name="notification_action_4_title">پێنجه‌م كرداری دوگمه‌</string>
<string name="notification_action_3_title">چواره‌م كرداری دوگمه‌</string>
<string name="notification_action_2_title">سێیه‌م كرداری دوگمه‌</string>
<string name="notification_action_1_title">دووه‌م كرداری دوگمه‌</string>
<string name="notification_action_0_title">یه‌كه‌م كرداری دوگمه‌</string>
<string name="notification_scale_to_square_image_summary">وێنۆچكه‌ی ڤیدیۆ پێوانه‌ ده‌كرێته‌وه‌ له‌ ئاگانامه‌كاندا له‌ ڕه‌هه‌ندی 16:9 ه‌وه‌ بۆ ڕه‌هه‌ندی 1:1</string>
<string name="notification_scale_to_square_image_summary">وێنۆچكه‌ی ڤیدیۆ پێوانه‌ ده‌كرێته‌وه‌ له‌ پەیامەکاندا له‌ ڕه‌هه‌ندی 16:9 ه‌وه‌ بۆ ڕه‌هه‌ندی 1:1</string>
<string name="notification_scale_to_square_image_title">پێوانەكردنی وێنۆچكه‌ بۆ ڕه‌هه‌ندی 1:1</string>
<string name="search_showing_result_for">پیشاندانی ئەنجامەکانی: %s</string>
<string name="open_with">كردنه‌وه‌ له‌</string>
@ -567,8 +567,8 @@
<string name="show_description_summary">ناكارایبكه‌ بۆ شاردنه‌وه‌ی دیسکریپشن له‌سه‌ر ڤیدیۆ و زانیاری زیاتر</string>
<string name="show_description_title">پیشاندانی دیسکریپشن</string>
<string name="night_theme_title">ڕووكاری شه‌و</string>
<string name="notification_colorize_summary">ئه‌ندرۆید ڕه‌نگی ئاگانامه‌ دڵخواز ده‌كات به‌پێی ڕه‌نگی سه‌ره‌كی وێنۆچكه‌كه‌ ( ڕه‌چاوی ئه‌وه‌ بكه‌ كه‌ ئه‌م تایبه‌تمه‌ندییه‌ هه‌موو ئامێرێك ناگرێته‌وه‌ )</string>
<string name="notification_colorize_title">ڕه‌نگكردنی ئاگانامه‌</string>
<string name="notification_colorize_summary">ئه‌ندرۆید ڕه‌نگی پەیام دڵخواز ده‌كات به‌پێی ڕه‌نگی سه‌ره‌كی وێنۆچكه‌كه‌ ( ڕه‌چاوی ئه‌وه‌ بكه‌ كه‌ ئه‌م تایبه‌تمه‌ندییه‌ هه‌موو ئامێرێك ناگرێته‌وه‌ )</string>
<string name="notification_colorize_title">ڕه‌نگكردنی پەیام</string>
<string name="youtube_restricted_mode_enabled_summary">یوتوب ”دۆخی قه‌ده‌غه‌كراو” پێشكه‌ش ده‌كات كه‌ بابەتە نه‌شیاوه‌كان ده‌شارێته‌وه‌</string>
<string name="msg_calculating_hash">ئه‌ژماركردنی هاش</string>
<string name="comments_are_disabled">لێدوانه‌كان ناكاراكراون</string>
@ -580,8 +580,8 @@
<string name="clear_cookie_summary">خاوێنكردنه‌وی ئه‌و شه‌كرۆكانه‌ی كه‌ له‌ نیوپایپ كۆگاكراون ، ئه‌مه‌ش له‌دوای شیكار كردنی reCAPTCHA</string>
<string name="recaptcha_cookies_cleared">شه‌كرۆكه‌كانی reCAPTCHA خاوێنكرانه‌وه‌</string>
<string name="clear_cookie_title">سڕینه‌وه‌ی شه‌كرۆكه‌كانی reCAPTCHA</string>
<string name="hash_channel_description">ئاگانامه‌كانی ئه‌نجامدانی هاشكردنی ڤیدیۆ</string>
<string name="hash_channel_name">ئاگانامه‌ی هاشی ڤیدیۆ</string>
<string name="hash_channel_description">پەیامەکانی ئه‌نجامدانی هاش كردنی ڤیدیۆ</string>
<string name="hash_channel_name">پەیامی هاش ڤیدیۆ</string>
<string name="description_select_disable">ناکاراکردنی دیار کردنی نوسینی نێو دیسکریبشن</string>
<string name="description_select_enable">کاراکردنی دیار کردنی نوسینی نێو دیسکریبشن</string>
<string name="description_select_note">لە ئێستادا دەتوانیت نوسینی نێو دیسکریپشن دیار بکەیت. بەڵام ڕەچاوی ئەوە بکە کە ئەو پەڕەیە ڕەنگە تێکبچێت و لینکەکان کرتەیان لەسەر نەکرێت لە دۆخی دیار کردندا.</string>
@ -620,7 +620,7 @@
<string name="no_app_to_open_intent">هیچ به‌رنامه‌یه‌كی نێو مۆبایله‌كه‌ت ناتوانێت ئه‌مه‌ بكاته‌وه‌</string>
<string name="chapters">به‌شه‌كان</string>
<string name="recent">دواین</string>
<string name="show_thumbnail_summary">وێنۆچكه‌كه‌ بۆ پاشبنه‌مای ڕوونماداخراو و ئاگانامه‌كان به‌كاربهێنرێن</string>
<string name="show_thumbnail_summary">وێنۆچكه‌كه‌ بۆ پاشبنه‌مای ڕوونماداخراو و پەیامەکان به‌كاردەهێنرێن</string>
<string name="show_thumbnail_title">پیشاندانی وێنۆچكه‌</string>
<string name="feed_toggle_show_played_items">تەماشاکراوەکان پیشان بدرێن</string>
<string name="downloads_storage_ask_summary_no_saf_notice">بۆ دابه‌زاندنی هه‌ر بابه‌تێك پرست پێ ده‌كرێت له‌باره‌ی شوێنی دابه‌زاندنیان</string>
@ -667,4 +667,24 @@
<string name="enqueue_next_stream">لە نۆبەت دانان بۆ دواتر</string>
<string name="enqueued_next">لە نۆبەت دانرا بۆ دواتر</string>
<string name="processing_may_take_a_moment">جێبەجێ دەکرێت... ڕەنگە ساتێک بخایەنێت</string>
<string name="checking_updates_toast">دەپشکنرێت بۆ نوێکردنەوە…</string>
<string name="manual_update_description">پشکنینی خۆیی بۆ وەشانی نوێ</string>
<string name="show_crash_the_player_summary">بژاردەی کڕاش کردن پیشان دەدات لەکاتی بەکارهێنانی لێدەرەکە</string>
<string name="error_report_notification_toast">کێشەیەک ڕوویدا ، پەیامەکە ببینە</string>
<string name="error_report_notification_title">نیوپایپ تووشی کێشەیەک بوو ، کرتە بکە بۆ سکاڵاکردن</string>
<string name="show_crash_the_player_title">پیشاندانی ”کڕاش کردنی لێدەرەکە“</string>
<string name="create_error_notification">سازاندنی پەیامی کێشەیەک</string>
<string name="manual_update_title">پشکنین بۆ نوێکردنەوە</string>
<string name="background_player_already_playing_toast">وا لە پاشبنەمادا لێدەدرێت</string>
<string name="error_report_channel_name">کێشە لە سکاڵا کردنی پەیام</string>
<string name="error_report_channel_description">پەیامەکانی سکاڵاکردن لە کێشەکان</string>
<string name="feed_new_items">بابەتە نوێیەکانی فیید</string>
<string name="detail_pinned_comment_view_description">لێدوانی هەڵواسراو</string>
<string name="crash_the_player">کڕاش کردنی لێدەر</string>
<string name="show_error_snackbar">پیشاندانی هەڵەی سناکباڕ</string>
<string name="no_appropriate_file_manager_message">هیچ ڕێکخەرێکی فایلی گونجاو نەدۆزرایەوە بۆ ئەم کردارە.
\nتکایە ڕێکخەری فایلییەک دابمەزرێنە لۆ هەوڵدانی ناکاراکردنی \'%s\' لە ڕێکخستنەکانی دابەزاندندا.</string>
<string name="leak_canary_not_available">LeakCanary بەردەست نییە</string>
<string name="no_appropriate_file_manager_message_android_10">هیچ ڕێکخەرێکی فایلی گونجاو نەدۆزرایەوە بۆ ئەم کردارە.
\nتکایە ڕێکخەرێکی فایلی دابمەزرێنە کە گونجاوبێت لەگەڵ دەسەڵاتی گەیشتن بە بیرگە.</string>
</resources>

View File

@ -123,7 +123,7 @@
<string name="best_resolution">Nejlepší rozlišení</string>
<string name="undo">Vrátit</string>
<string name="notification_channel_name">Oznámení NewPipe</string>
<string name="notification_channel_description">Oznámení pro NewPipe přehrávače v pozadí a v okně</string>
<string name="notification_channel_description">Oznámení pro NewPipe přehrávač</string>
<string name="search_no_results">Žádné výsledky</string>
<string name="empty_subscription_feed_subtitle">Je tu sranda jak v márnici</string>
<string name="short_billion">mld.</string>
@ -164,7 +164,7 @@
<string name="contribution_title">Podílet se</string>
<string name="title_activity_history">Historie</string>
<string name="action_history">Historie</string>
<string name="show_hold_to_append_title">Zobrazovat tip \"Podržet pro přidání\"</string>
<string name="show_hold_to_append_title">Zobrazit tip \"Podržet pro vložení do fronty\"</string>
<string name="show_hold_to_append_summary">Ukázat tip po stisku na pozadí nebo na popup tlačítko v \"Podrobnostech\" o videu</string>
<string name="play_all">Přehrát vše</string>
<string name="player_stream_failure">Tento stream nelze přehrát</string>
@ -258,7 +258,7 @@
<string name="metadata_cache_wipe_title">Vymazat metadata v mezipaměti</string>
<string name="metadata_cache_wipe_summary">Odebrat všechna data uložená v mezipaměti</string>
<string name="metadata_cache_wipe_complete_notice">Mezipaměť metadat vymazána</string>
<string name="auto_queue_title">Automatická fronta dalšího streamu</string>
<string name="auto_queue_title">Další stream automaticky vložit do fronty</string>
<string name="auto_queue_summary">Pokračovat konečnou (neopakující se) frontu playbacku připojením souvisejícího streamu</string>
<string name="file">Soubor</string>
<string name="invalid_directory">Neexistující složka</string>
@ -275,15 +275,15 @@
<string name="previous_export">Předchozí export</string>
<string name="subscriptions_import_unsuccessful">Odběry nelze importovat</string>
<string name="subscriptions_export_unsuccessful">Odběry nelze exportovat</string>
<string name="import_youtube_instructions">Importovat YouTube odběry stáhnutím exportního souboru:
<string name="import_youtube_instructions">Importovat YouTube odběry z Google:
\n
\n1. Přejděte na tuto URL adresu: %1$s
\n2. Na vyžádání se přihlašte
\n3. Klikněte na \"Jsou zahrnuta všechna data z YouTube\" pak na \"Zrušit výběr všech\" a pak vyberte jen \"odběry\" a klikněte na OK
\n3. Klikněte na \"Jsou zahrnuta všechna data\", \"Zrušit výběr všech\" a pak vyberte jen \"odběry\" a klikněte na OK
\n4. Klikněte na \"Další krok\" a pak na \"Vytvořit export\"
\n5. Vyčkejte než se objeví tlačítko \"Stáhnout\" a klikněte na něj
\n6. Klikněte IMPORTOVAT SOUBOR a vyberte stažený .zip soubor z předchozího kroku
\n7. [Pokud se import .zip souboru nezdaří] Rozbalte soubor subscriptions.csv (měl by se nacházet v adresáři \"YouTube and YouTube Music/subscriptions/subscriptions.csv\"), stiskněte IMPORTOVAT SOUBOR níže a vyberte rozbalený soubor subscriptions.csv</string>
\n7. [Pokud se import .zip souboru nezdaří] Rozbalte soubor .csv (měl by to být soubor \"YouTube and YouTube Music/subscriptions/subscriptions.csv\"), stiskněte IMPORTOVAT SOUBOR níže a vyberte rozbalený csv soubor</string>
<string name="import_soundcloud_instructions">Importovat SoundCloud profil zadáním URL adresy nebo vašeho ID:
\n
\n1. Ve svém prohlížeči povolte \"režim pro PC\" (pro mobilní zařízení není stránka dostupná)
@ -346,7 +346,7 @@
<string name="settings_category_updates_title">Aktualizace</string>
<string name="file_deleted">Soubor smazán</string>
<string name="app_update_notification_channel_name">Oznámení o aktualizaci aplikace</string>
<string name="app_update_notification_channel_description">Oznámení o nové verzi NewPipe</string>
<string name="app_update_notification_channel_description">Oznámení o nových verzích NewPipe</string>
<string name="download_to_sdcard_error_title">Externí úložiště není k dispozici</string>
<string name="saved_tabs_invalid_json">Nelze načíst uložené karty, takže se použijí výchozí karty</string>
<string name="restore_defaults">Obnovit do výchozího nastavení</string>
@ -680,4 +680,23 @@
<string name="main_page_content_swipe_remove">Tažením položky odstraníte</string>
<string name="start_main_player_fullscreen_title">Spustit hlavní přehrávač na celé obrazovce</string>
<string name="processing_may_take_a_moment">Zpracovávám... může trvat moment</string>
<string name="manual_update_description">Ručně zkontrolovat zda je k dispozici nová verze</string>
<string name="manual_update_title">Kontrola aktualizací</string>
<string name="error_report_notification_title">NewPipe narazil na problém, klikněte pro nahlášení</string>
<string name="error_report_notification_toast">Došlo k chybě, více v oznámení</string>
<string name="create_error_notification">Vytvořit oznámení o chybě</string>
<string name="checking_updates_toast">Kontrola aktualizací…</string>
<string name="show_crash_the_player_title">Ukázat \"Zřícení přehávače\"</string>
<string name="background_player_already_playing_toast">Hraje již v pozadí</string>
<string name="feed_new_items">Nové položky feedů</string>
<string name="no_appropriate_file_manager_message_android_10">Pro tuto akci nebyl nalezen žádný vhodný správce souborů.
\nProsím, nainstalujte správce souborů kompatibilní se Storage Access Framework.</string>
<string name="error_report_channel_name">Oznámení o hlášení chyb</string>
<string name="error_report_channel_description">Oznámení za účelem hlášení chyb</string>
<string name="no_appropriate_file_manager_message">Pro tuto akci nebyl nalezen žádný vhodný správce souborů.
\nProsím, nainstalujte správce souborů nebo zkuste vypnout %s v nastaveních stahování.</string>
<string name="show_crash_the_player_summary">Ukáže volbu pro zřícení během používání přehrávače</string>
<string name="show_error_snackbar">Ukázat krátké oznámení o chybě</string>
<string name="detail_pinned_comment_view_description">Připnutý komentář</string>
<string name="crash_the_player">Zřícení přehrávače</string>
</resources>

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="main_bg_subtitle">Tryk søg for at komme i gang</string>
<string name="main_bg_subtitle">Tryk på forstørrelsesglasset for at komme i gang.</string>
<string name="upload_date_text">Udgivet %1$s</string>
<string name="no_player_found">Ingen streamafspiller blev fundet. Vil du installere VLC\?</string>
<string name="no_player_found">Ingen streamafspiller blev fundet. Installer VLC\?</string>
<string name="no_player_found_toast">Ingen streamafspiller fundet (du kan installere VLC for at afspille den).</string>
<string name="install">Installer</string>
<string name="cancel">Annuller</string>
@ -396,4 +396,5 @@
<string name="notification_action_2_title">Tredje handlingstast</string>
<string name="search_showing_result_for">Viser resultater for: %s</string>
<string name="open_with">Åben med</string>
<string name="leak_canary_not_available">LeakCanary er ikke tilgængelig</string>
</resources>

View File

@ -139,7 +139,7 @@
<string name="subscription_update_failed">Abonnement konnte nicht aktualisiert werden</string>
<string name="resume_on_audio_focus_gain_summary">Nach Unterbrechungen (z.B. Telefonaten) Wiedergabe fortsetzen</string>
<string name="notification_channel_name">NewPipe-Benachrichtigung</string>
<string name="notification_channel_description">Benachrichtigungen für NewPipe-Hintergrund- und Pop-up Wiedergabe</string>
<string name="notification_channel_description">Benachrichtigungen für den NewPipe-Player</string>
<string name="settings_category_player_behavior_title">Verhalten</string>
<string name="settings_category_history_title">Verlauf und Cache</string>
<string name="undo">Rückgängig machen</string>
@ -346,8 +346,8 @@
<string name="settings_category_player_notification_title">Wiedergabebenachrichtigung</string>
<string name="settings_category_player_notification_summary">Konfiguriert die Benachrichtigung zum aktuell abgespielten Stream</string>
<string name="file_deleted">Datei gelöscht</string>
<string name="app_update_notification_channel_name">Aktualisierungsbenachrichtigung</string>
<string name="app_update_notification_channel_description">Benachrichtigung bei neuer NewPipe-Version</string>
<string name="app_update_notification_channel_name">Benachrichtigung über App-Update</string>
<string name="app_update_notification_channel_description">Benachrichtigungen über neue NewPipe-Versionen</string>
<string name="download_to_sdcard_error_title">Kein externer Speicher verfügbar</string>
<string name="download_to_sdcard_error_message">Herunterladen auf externe SD-Karte ist nicht möglich. Downloadordner zurücksetzen\?</string>
<string name="saved_tabs_invalid_json">Konnte gespeicherte Tabs nicht lesen, daher werden die Voreinstellungen genutzt</string>
@ -372,7 +372,7 @@
<string name="paused">pausiert</string>
<string name="queued">eingereiht</string>
<string name="post_processing">Nachbearbeitung</string>
<string name="enqueue">Warteschlange</string>
<string name="enqueue">In Wiedergabe einreihen</string>
<string name="permission_denied">System verweigert den Zugriff</string>
<string name="download_failed">Herunterladen fehlgeschlagen</string>
<string name="generate_unique_name">Eindeutigen Namen erzeugen</string>
@ -583,8 +583,8 @@
<string name="show_thumbnail_summary">Vorschaubild für Sperrbildschirmhintergrund und Benachrichtigungen verwenden</string>
<string name="show_thumbnail_title">Vorschaubild anzeigen</string>
<string name="msg_calculating_hash">Hash wird berechnet</string>
<string name="hash_channel_description">Benachrichtigungen für den Video-hashing Fortschritt</string>
<string name="hash_channel_name">Video Hash Benachrichtigung</string>
<string name="hash_channel_description">Benachrichtigungen über den Hashing-Fortschritt von Videos</string>
<string name="hash_channel_name">Video-Hash Benachrichtigung</string>
<string name="recent">Letzte</string>
<string name="show_meta_info_title">Metadaten anzeigen</string>
<string name="show_meta_info_summary">Deaktiviere diese Option, um Meta-Infofelder mit zusätzlichen Informationen zum Stream-Ersteller, zum Stream-Inhalt oder zu einer Suchanforderung auszublenden</string>
@ -601,7 +601,7 @@
<string name="youtube_music_premium_content">Dieses Video ist nur für YouTube Music Premium-Mitglieder verfügbar und kann daher nicht von NewPipe gestreamt oder heruntergeladen werden.</string>
<string name="soundcloud_go_plus_content">Dies ist ein SoundCloud Go+ Track, zumindest in deinem Land, kann er von NewPipe nicht gestreamt oder heruntergeladen werden.</string>
<string name="georestricted_content">Dieser Inhalt ist in deinem Land nicht verfügbar.</string>
<string name="crash_the_app">Absturz der App</string>
<string name="crash_the_app">App abstürzen lassen</string>
<string name="restricted_video_no_stream">Dieses Video ist altersbeschränkt.
\nAufgrund neuer YouTube-Richtlinien mit altersbeschränkten Videos kann NewPipe auf keinen dieser Videostreams zugreifen und ist daher nicht in der Lage, es abzuspielen.</string>
<string name="radio">Radio</string>
@ -674,9 +674,20 @@
<string name="checking_updates_toast">Suche nach Aktualisierungen…</string>
<string name="manual_update_description">Manuelle Prüfung auf neue Versionen</string>
<string name="feed_new_items">Neue Feed-Elemente</string>
<string name="show_crash_the_player_title">\"Absturz des Players\" anzeigen</string>
<string name="crash_the_player">Absturz des Players</string>
<string name="report_player_errors_summary">Meldet Playerfehler mit allen Details, anstatt eine kurzlebige Popupmeldung anzuzeigen (nützlich für die Diagnose von Problemen)</string>
<string name="show_crash_the_player_title">\"Player abstürzen lassen\" anzeigen</string>
<string name="crash_the_player">Player abstürzen lassen</string>
<string name="show_crash_the_player_summary">Zeigt eine Absturzoption an, wenn der Player verwendet wird</string>
<string name="report_player_errors_title">Playerfehler melden</string>
<string name="error_report_channel_name">Benachrichtigung über Fehlerberichte</string>
<string name="error_report_channel_description">Benachrichtigungen zur Meldung von Fehlern</string>
<string name="error_report_notification_title">Bei NewPipe ist ein Fehler aufgetreten. Zum Melden antippen</string>
<string name="error_report_notification_toast">Ein Fehler ist aufgetreten, siehe die Benachrichtigung</string>
<string name="create_error_notification">Eine Fehlermeldung erstellen</string>
<string name="show_error_snackbar">Fehler-Kurzmeldung anzeigen</string>
<string name="no_appropriate_file_manager_message">Es wurde kein geeigneter Dateimanager für diese Aktion gefunden.
\nBitte installiere einen Dateimanager oder versuche, \'%s\' in den Downloadeinstellungen zu deaktivieren.</string>
<string name="no_appropriate_file_manager_message_android_10">Es wurde kein geeigneter Dateimanager für diese Aktion gefunden.
\nBitte installiere einen Storage Access Framework kompatiblen Dateimanager.</string>
<string name="background_player_already_playing_toast">Wird bereits im Hintergrund abgespielt</string>
<string name="detail_pinned_comment_view_description">Angehefteter Kommentar</string>
<string name="leak_canary_not_available">LeakCanary ist nicht verfügbar</string>
</resources>

View File

@ -79,7 +79,7 @@
<string name="subscription_change_failed">Αδύνατη η αλλαγή της εγγραφής</string>
<string name="subscription_update_failed">Αδύνατη η ενημέρωση της εγγραφής</string>
<string name="tab_subscriptions">Συνδρομές</string>
<string name="tab_bookmarks">Αγαπημένες λίστες αναπαραγωγής</string>
<string name="tab_bookmarks">Λίστες αναπαραγωγής με σελιδοδείκτες</string>
<string name="fragment_feed_title">Τι νέο υπάρχει</string>
<string name="controls_background_title">Στο παρασκήνιο</string>
<string name="controls_popup_title">Αναδυόμενο παράθυρο</string>
@ -130,7 +130,7 @@
<string name="just_once">Μόνο μία φορά</string>
<string name="file">Αρχείο</string>
<string name="notification_channel_name">Ειδοποίηση NewPipe</string>
<string name="notification_channel_description">Ειδοποιήσεις αναπαραγωγής παρασκηνίου και αναδυόμενου παραθύρου</string>
<string name="notification_channel_description">Ειδοποιήσεις του αναπαραγωγέα του NewPipe</string>
<string name="unknown_content">[Άγνωστο]</string>
<string name="switch_to_background">Αλλαγή σε Παρασκήνιο</string>
<string name="switch_to_popup">Αλλαγή σε Αναδυόμενο Παράθυρο</string>
@ -343,7 +343,7 @@
<string name="settings_category_updates_title">Ενημερώσεις</string>
<string name="events">Συμβάντα</string>
<string name="file_deleted">Το αρχείο διαγράφηκε</string>
<string name="app_update_notification_channel_name">Ειδοποίηση Ενημέρωσης Εφαρμογής</string>
<string name="app_update_notification_channel_name">Ειδοποίηση ενημέρωσης εφαρμογής</string>
<string name="app_update_notification_channel_description">Ειδοποίηση για νεότερη έκδοση του NewPipe</string>
<string name="download_to_sdcard_error_title">Εξωτερική μνήμη αποθήκευσης μη διαθέσιμη</string>
<string name="download_to_sdcard_error_message">Η αποθήκευση στην SD κάρτα δεν είναι δυνατή. Επαναφορά στην αρχική τοποθεσία λήψης;</string>
@ -366,7 +366,7 @@
<string name="paused">σε παύση</string>
<string name="queued">σε ουρά</string>
<string name="post_processing">σε μετεπεξεργασία</string>
<string name="enqueue">Ουρά</string>
<string name="enqueue">Προσθήκη σε ουρά</string>
<string name="permission_denied">Η ενέργεια απορρίφθηκε από το σύστημα</string>
<string name="download_failed">Η λήψη απέτυχε</string>
<string name="generate_unique_name">Δημιουργία μοναδικού ονόματος</string>
@ -672,9 +672,20 @@
<string name="manual_update_description">Χειροκίνητος έλεγχος για νέα έκδοση</string>
<string name="manual_update_title">Έλεγχος αναβάθμισης</string>
<string name="feed_new_items">Νέα αντικείμενα τροφοδοσίας</string>
<string name="show_crash_the_player_title">Εμφάνιση «κατάρρευσης αναπαραγωγέα»</string>
<string name="show_crash_the_player_title">Εμφάνιση «Κατάρρευσης αναπαραγωγέα»</string>
<string name="show_crash_the_player_summary">Εμφανίζει μια επιλογή κατάρρευσης κατά τη χρήση του αναπαραγωγέα</string>
<string name="report_player_errors_title">Αναφορά σφαλμάτων αναπαραγωγέα</string>
<string name="report_player_errors_summary">Αναφορά σφαλμάτων αναπαραγωγέα με λεπτομέρειες αντί για ένα σύντομο μήνυμα (χρήσιμο για διάγνωση προβλημάτων)</string>
<string name="crash_the_player">Κατάρρευση αναπαραγωγέα</string>
<string name="error_report_channel_name">Ειδοποίηση αναφοράς σφάλματος</string>
<string name="error_report_channel_description">Ειδοποιήσεις για την αναφορά σφαλμάτων</string>
<string name="error_report_notification_toast">Συνέβη ένα σφάλμα. Δείτε την ειδοποίηση</string>
<string name="create_error_notification">Δημιουργία ειδοποίησης σφάλματος</string>
<string name="no_appropriate_file_manager_message">Δε βρέθηκε κατάλληλος διαχειριστής αρχείων για αυτή την ενέργεια.
\nΕγκαταστήστε έναν ή δοκιμάστε να απενεργοποιήσετε το \'%s\' στις ρυθμίσεις λήψεων.</string>
<string name="no_appropriate_file_manager_message_android_10">Δε βρέθηκε κατάλληλος διαχειριστής αρχείων για αυτή την ενέργεια.
\nΕγκαταστήστε έναν συμβατό με το Πλαίσιο Πρόσβασης Αποθήκευσης.</string>
<string name="error_report_notification_title">Το NewPipe παρουσίασε ένα σφάλμα. Πατήστε για αναφορά</string>
<string name="show_error_snackbar">Εμφάνιση μιας snackbar σφάλματος</string>
<string name="background_player_already_playing_toast">Αναπαράγεται ήδη στο παρασκήνιο</string>
<string name="detail_pinned_comment_view_description">Καρφιτσωμένο σχόλιο</string>
<string name="leak_canary_not_available">Το LeakCanary δεν είναι διαθέσιμο</string>
</resources>

View File

@ -16,8 +16,9 @@
\n2. Log in when asked
\n3. Click on All data included, then on Deselect all, then select only subscriptions and click OK
\n4. Click on Next step and then on Create export
\n5. Click on the Download button after it appears and
\n6. From the downloaded takeout zip extract the .json file (usually under YouTube and YouTube Music/subscriptions/subscriptions.json) and import it here.</string>
\n5. Click on the Download button after it appears
\n6. Click on IMPORT FILE below and select the downloaded .zip file
\n7. [If the .zip import fails] Extract the .csv file (usually under YouTube and YouTube Music/subscriptions/subscriptions.csv), click on IMPORT FILE below and select the extracted csv file</string>
<string name="subtitle_activity_recaptcha">Press Done when solved</string>
<string name="restricted_video">This video is age restricted.
\n

View File

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<resources></resources>

View File

@ -139,7 +139,7 @@
<string name="title_activity_history">Historial</string>
<string name="action_history">Historial</string>
<string name="notification_channel_name">Notificación de NewPipe</string>
<string name="notification_channel_description">Notificaciones para reproductores en segundo plano y emergentes de NewPipe</string>
<string name="notification_channel_description">Notificaciones para el reproductor de NewPipe</string>
<string name="settings_category_player_title">Reproductor</string>
<string name="settings_category_player_behavior_title">Funcionamiento</string>
<string name="settings_category_history_title">Historial y caché</string>
@ -396,7 +396,7 @@
<string name="settings_category_updates_title">Actualizaciones</string>
<string name="events">Eventos</string>
<string name="app_update_notification_channel_name">Notificación de actualización de la aplicación</string>
<string name="app_update_notification_channel_description">Notificaciones de versiones nuevas de NewPipe</string>
<string name="app_update_notification_channel_description">Notificaciones de nuevas versiones de NewPipe</string>
<string name="download_to_sdcard_error_title">Almacenamiento externo no disponible</string>
<string name="download_to_sdcard_error_message">No es posible descargar a una tarjeta SD externa. \¿Restablecer la ubicación de la carpeta de descarga\?</string>
<string name="saved_tabs_invalid_json">No se pudo leer las pestañas guardadas, se usarán las pestañas predefinidas</string>
@ -588,7 +588,7 @@
<string name="related_items_tab_description">Transmisiones relacionadas</string>
<string name="comments_tab_description">Comentarios</string>
<string name="hash_channel_description">Notificaciones sobre el progreso del hashing del vídeo</string>
<string name="hash_channel_name">Notificación del hash de vídeo</string>
<string name="hash_channel_name">Notificación de hash de vídeo</string>
<string name="show_meta_info_title">Mostrar metainformación</string>
<string name="show_description_title">Mostrar descripción</string>
<string name="open_with">Abrir con</string>
@ -676,8 +676,19 @@
<string name="checking_updates_toast">Buscando actualizaciones…</string>
<string name="feed_new_items">Nuevos elementos en el muro</string>
<string name="crash_the_player">Cerrar abruptamente el reproductor</string>
<string name="report_player_errors_title">Informar de errores del reproductor</string>
<string name="show_crash_the_player_summary">Muestra una opción de cierre abrupto al usar el reproductor</string>
<string name="report_player_errors_summary">Informar de errores del reproductor con detalle en lugar de mostrar un mensaje emergente efímero (útil para diagnosticar problemas)</string>
<string name="show_crash_the_player_title">Mostrar \"Cerrar abruptamente el reproductor\"</string>
<string name="error_report_channel_description">Notificaciones para informar errores</string>
<string name="error_report_channel_name">Notificación de informe de errores</string>
<string name="error_report_notification_title">NewPipe ha detectado un error, pulse aquí para informar</string>
<string name="error_report_notification_toast">Se produjo un error, vea la notificación</string>
<string name="create_error_notification">Crear una notificación de error</string>
<string name="show_error_snackbar">Mostrar un snackbar de error</string>
<string name="no_appropriate_file_manager_message">No se encontró ningún gestor de archivos adecuado para esta acción.
\nPor favor instale un gestor de archivos o intente deshabilitar \"%s\" en lo ajustes de descargas.</string>
<string name="no_appropriate_file_manager_message_android_10">No se encontró ningún gestor de archivos adecuado para esta acción.
\nPor favor instale un gestor de archivos compatible con \"Sistema de Acceso al Almacenamiento\".</string>
<string name="detail_pinned_comment_view_description">Comentario fijado</string>
<string name="background_player_already_playing_toast">Ya se reproduce en segundo plano</string>
<string name="leak_canary_not_available">LeakCanary no está disponible</string>
</resources>

View File

@ -103,7 +103,7 @@
<string name="just_once">Üks kord</string>
<string name="file">Fail</string>
<string name="notification_channel_name">NewPipe teavitus</string>
<string name="notification_channel_description">Teavitused NewPipe tausta- ja hüpikpleierile</string>
<string name="notification_channel_description">Teavitused NewPipe pleierile</string>
<string name="unknown_content">[Tundmatu]</string>
<string name="switch_to_background">Lülita taustale</string>
<string name="switch_to_popup">Lülita hüpikpleierile</string>
@ -287,8 +287,8 @@
\n3. Klõpsa \"Kõigi andmetega\", vali \"Tühista kõik\", vali ainult \"Tellimused\" ja klõpsa \"OK\".
\n4. Klõpsa \"Järgmine samm\" ja seejärel \"Loo eksport\".
\n5. Klõpsa nupul \"Laadi alla\" siis, kui ta ilmub.
\n6. Klõpsi siitsamast \"Impordi fail\" linki ning vali allalaaditud zip fail.
\n7. Kui zip faili importimine ei toimi, siis paki .csv fail lahti (tavaliselt on see fail \"YouTube ja YouTube Muusika/tellimused/tellimused\" või \"YouTube and YouTube Music/subscriptions/subscriptions\") ja klõpsi siitsamast \"Impordi fail\" linki ning vali lahtipakitud csv fail.</string>
\n6. Klõpsi siitsamast \"Impordi fail\" linki ning vali allalaaditud .zip fail.
\n7. Kui .zip faili importimine ei toimi, siis paki .csv fail lahti (tavaliselt on see fail \"YouTube ja YouTube Muusika/tellimused/tellimused\" või \"YouTube and YouTube Music/subscriptions/subscriptions\") ja klõpsi siitsamast \"Impordi fail\" linki ning vali lahtipakitud csv fail.</string>
<string name="import_network_expensive_warning">See toiming võib põhjustada suurt võrguliiklust.
\n
\nKas jätkata?</string>
@ -312,11 +312,11 @@
<string name="give_back">Anneta</string>
<string name="privacy_policy_encouragement">NewPipe võtab privaatsust väga tõsiselt. Seetõttu ei kogu rakendus ilma nõusolekuta mingeid andmeid.
\nNewPipe privaatsuspoliitika selgitab üksikasjalikult, milliseid andmeid saadetakse ja kogutakse veateate saatmisel.</string>
<string name="app_license">NewPipe vaba avatud koodiga tarkvara. Seada võib kasutada, uurida, jagada ja parandada. Täpsemalt - seda võib levitada ja/või muuta vastavalt Vaba Tarkvara Sihtasutuse avaldatud GNU Üldise Avaliku Litsentsi v.3 (või hilisem) tingimustele.</string>
<string name="app_license">NewPipe vaba avatud koodiga tarkvara. Seada võid kasutada, uurida, jagada ja parandada nii, nagu õigemaks pead. Täpsemalt - seda võid levitada ja/või muuta vastavalt Vaba Tarkvara Sihtasutuse avaldatud GNU Üldise Avaliku Litsentsi v.3 (või sinu valikul hilisema versiooni) tingimustele.</string>
<string name="enable_disposed_exceptions_title">Teavita elutsüklist väljas vigadest</string>
<string name="import_soundcloud_instructions">Impordi SoundCloudi profiil trükkides URL või oma ID:
\n
\n1. Luba \"töölaua režiim\" veebilehitsejas (lmobiilsete seadmete jaoks leht pole kättesaadav)
\n1. Luba \"töölaua režiim\" veebilehitsejas (mobiilsete seadmete jaoks leht pole kättesaadav)
\n2. Ava URL: %1$s
\n3. Logi sisse
\n4. Kopeeri suunatud profiili URL.</string>
@ -343,8 +343,8 @@
<string name="settings_category_updates_title">Uuendused</string>
<string name="events">Sündmused</string>
<string name="file_deleted">Fail kustutati</string>
<string name="app_update_notification_channel_name">Rakenduse värskenduse teatis</string>
<string name="app_update_notification_channel_description">NewPipe uuest versioonist teavitamine</string>
<string name="app_update_notification_channel_name">Rakenduse värskenduse teavitus</string>
<string name="app_update_notification_channel_description">Teavitus NewPipe uuetest versioonidest</string>
<string name="download_to_sdcard_error_title">Väline andmekandja pole saadaval</string>
<string name="download_to_sdcard_error_message">Allalaadimine välisele SD-kaardile ei ole võimalik. Kas lähtestada allalaadimiste kataloogi asukoht\?</string>
<string name="saved_tabs_invalid_json">Tõrge salvestatud vahekaaride lugemisel; kasutatakse vaikeväärtusi</string>
@ -366,7 +366,7 @@
<string name="paused">peatatud</string>
<string name="queued">järjekorras</string>
<string name="post_processing">järeltöötlus</string>
<string name="enqueue">Esitusjärjekord</string>
<string name="enqueue">Lisa esitusjärjekorda</string>
<string name="permission_denied">Tegevus keelati süsteemi poolt</string>
<string name="download_failed">Allalaadimine nurjus</string>
<string name="generate_unique_name">Loo kordumatu nimi</string>
@ -672,4 +672,20 @@
<string name="manual_update_title">Kontrolli uuendusi</string>
<string name="manual_update_description">Kontrolli uuendusi käsitsi</string>
<string name="feed_new_items">Uued andmevoo kirjed</string>
<string name="show_crash_the_player_title">Näita „Jooksuta meediamängija kokku“ nupukest</string>
<string name="show_crash_the_player_summary">Näitab valikut meediamängija kokkujooksutamiseks</string>
<string name="error_report_notification_title">NewPipe töös tekkis viga, sellest teavitamiseks klõpsi</string>
<string name="crash_the_player">Jooksuta meediamängija kokku</string>
<string name="show_error_snackbar">Näita veateate akent</string>
<string name="background_player_already_playing_toast">Meedia esitamine taustal toimib juba</string>
<string name="error_report_channel_name">Teavitus vigadest</string>
<string name="error_report_channel_description">Teavitused vigadest informeerimiseks</string>
<string name="error_report_notification_toast">Tekkis viga, vaata vastavat teadet</string>
<string name="create_error_notification">Koosta veateade</string>
<string name="no_appropriate_file_manager_message">Selle tegevuse jaoks ei leidunud sobilikku failihaldurit.
\nPalun paigalda nutiseadmesse failihaldur või proovi allalaadimiste seadistustest „%s“ välja lülitada.</string>
<string name="no_appropriate_file_manager_message_android_10">Selle tegevuse jaoks ei leidunud sobilikku failihaldurit.
\nPalun paigalda nutiseadmesse failihaldur, mis järgib Storage Access Framework reeglistikku.</string>
<string name="detail_pinned_comment_view_description">Esiletõstetud kommentaar</string>
<string name="leak_canary_not_available">LeakCanary pole saadaval</string>
</resources>

View File

@ -141,7 +141,7 @@
<string name="settings_category_player_behavior_title">Portaera</string>
<string name="settings_category_history_title">Historia eta cache-a</string>
<string name="undo">Desegin</string>
<string name="notification_channel_description">Atzeko planoko eta laster-leihoko NewPipe erreproduzigailuen jakinarazpenak</string>
<string name="notification_channel_description">NewPipe erreproduzigailuaren jakinarazpenak</string>
<string name="search_no_results">Emaitzarik ez</string>
<string name="empty_subscription_feed_subtitle">Kilkerrak besterik ez daude hemen</string>
<string name="no_subscribers">Harpidedunik ez</string>
@ -217,7 +217,7 @@
<string name="metadata_cache_wipe_title">Ezabatu cacheko metadatuak</string>
<string name="metadata_cache_wipe_summary">Kendu cachetik webguneen datu guztiak</string>
<string name="metadata_cache_wipe_complete_notice">Metadatuen cachea ezabatuta</string>
<string name="auto_queue_title">Gehitu ilarara hurrengo jarioa</string>
<string name="auto_queue_title">Gehitu hurrengo jarioa ilarara</string>
<string name="auto_queue_summary">Jarraitu bukaerako (errepikapenik gabe) ilara erlazionatutako jario bat gehituz</string>
<string name="settings_category_debug_title">Arazketa</string>
<string name="file">Fitxategia</string>
@ -292,7 +292,7 @@
\n4. Egin klik \"Hurrengo pausua\"-n eta \"Sortu esportazioa\"
\n5. Egin klik \"Deskargatu\" botoian agertzen denean
\n6. Egin klik INPORTATU FITXATEGIA botoian eta hautatu deskargatutako zip fitxategia
\n6. [Zip inportazioak huts egiten badu] Erauzi .csv fitxategia deskargatutako takeout zip-etik (normalean \"Youtube eta Youtube Music/harpidetzak/harpidetzak.csv\"), egin klik INPORTATU FITXATEGIA botoian eta hautatu erauzitako csv fitxategia</string>
\n7. [.zip inportazioak huts egiten badu] Erauzi .csv fitxategia deskargatutako takeout zip-etik (normalean \"Youtube eta Youtube Music/harpidetzak/harpidetzak.csv\"), egin klik INPORTATU FITXATEGIA botoian eta hautatu erauzitako csv fitxategia</string>
<string name="import_soundcloud_instructions">Inportatu SoundCloud profila URL-a edo zure ID-a idatziz:
\n
\n1. Gaitu \"mahaigain modua\" web nabigatzailean (gunea ez dabil mugikorretan)
@ -343,7 +343,7 @@
<string name="settings_category_updates_title">Eguneraketak</string>
<string name="events">Gertaerak</string>
<string name="file_deleted">Fitxategia ezabatu da</string>
<string name="app_update_notification_channel_name">Aplikazioaren eguneraketaren jakinarazpena</string>
<string name="app_update_notification_channel_name">Aplikazioaren eguneraketen jakinarazpena</string>
<string name="app_update_notification_channel_description">NewPipe aplikazioaren bertsio berrien jakinarazpena</string>
<string name="download_to_sdcard_error_title">Kanpo biltegiratzea ez dago eskuragarri</string>
<string name="download_to_sdcard_error_message">Ezin da SD txartel batera deskargatu. Deskargen karpeta berrezarri nahi duzu\?</string>
@ -366,7 +366,7 @@
<string name="paused">pausatuta</string>
<string name="queued">ilaran</string>
<string name="post_processing">post-prozesua</string>
<string name="enqueue">Gehitu ilarara</string>
<string name="enqueue">Enkargatu</string>
<string name="permission_denied">Ekintza sistemak ukatu du</string>
<string name="download_failed">Deskargak huts egin du</string>
<string name="generate_unique_name">Sortu izen bakana</string>
@ -667,4 +667,24 @@
<string name="start_main_player_fullscreen_title">Hasi erreproduzitzaile nagusia pantaila osoan</string>
<string name="enqueued_next">Isatsari bideo hau erantsita</string>
<string name="enqueue_next_stream">Gehitu bideo hau isatsari</string>
<string name="show_crash_the_player_title">Erakutsi \"itxi erreproduzigailua\"</string>
<string name="processing_may_take_a_moment">Prozesatzen... Itxoin mesedez</string>
<string name="background_player_already_playing_toast">Atzeko planoan erreproduzitzen dagoeneko</string>
<string name="error_report_channel_name">Erroreen txostenen jakinarazpena</string>
<string name="error_report_channel_description">Jakinarazpenak erroreen berri emateko</string>
<string name="error_report_notification_title">NewPipe-k errore bat aurkitu du, sakatu berri emateko</string>
<string name="error_report_notification_toast">Errore bat gertatu da, ikusi jakinarazpena</string>
<string name="manual_update_title">Bilatu eguneraketak</string>
<string name="manual_update_description">Bilatu bertsio berriak eskuz</string>
<string name="feed_new_items">Elementu berriak jarioan</string>
<string name="no_appropriate_file_manager_message_android_10">Ez da fitxategi kudeatzaile bat aurkitu ekintza honetarako.
\nMesedez, instalatu Storage Access Framework-ekin bateragarria den fitxategi kudeatzaile bat.</string>
<string name="detail_pinned_comment_view_description">Ainguratutako iruzkina</string>
<string name="crash_the_player">Itxi erreproduzigailua</string>
<string name="checking_updates_toast">Eguneraketak bilatzen…</string>
<string name="no_appropriate_file_manager_message">Ez da fitxategi kudeatzaile bat aurkitu ekintza honetarako.
\nMesedez, instalatu fitxategi kudeatzaile bat edo saiatu \'%s\' desgaitzen deskarga ezarpenetan.</string>
<string name="show_crash_the_player_summary">Erreproduzigailua erabiltzean ustekabean ixteko aukera ematen du</string>
<string name="show_error_snackbar">Erakutsi errore barra bat</string>
<string name="create_error_notification">Sortu errore jakinarazpen bat</string>
</resources>

View File

@ -14,12 +14,12 @@
<string name="share_dialog_title">هم‌رسانی با</string>
<string name="use_external_video_player_title">استفاده از پخش‌کنندهٔ ویدیوی خارجی</string>
<string name="use_external_audio_player_title">استفاده از پخش‌کنندهٔ صدای خارجی</string>
<string name="download_path_title">پوشه بارگیری ویدیو</string>
<string name="download_path_summary">ویدیوهای بارگیری شده اینجا ذخیره می‌شوند</string>
<string name="download_path_dialog_title">پوشه بارگیری ویدیوها را انتخاب کنید</string>
<string name="download_path_audio_title">پوشه بارگیری صدا</string>
<string name="download_path_audio_summary">صداهای بارگیری شده در این‌جا ذخیره می‌شوند</string>
<string name="download_path_audio_dialog_title">پوشه بارگیری صداها را انتخاب کنید</string>
<string name="download_path_title">شاخهٔ بارگیری ویدیو</string>
<string name="download_path_summary">پرونده‌های ویدیویی بارگرفته این‌جا ذخیره می‌شوند</string>
<string name="download_path_dialog_title">گزینش شاخه برای بارگیری پرونده‌های ویدیویی</string>
<string name="download_path_audio_title">شاخهٔ بارگیری صدا</string>
<string name="download_path_audio_summary">پرونده‌های صوتی بارگرفته این‌جا ذخیره می‌شوند</string>
<string name="download_path_audio_dialog_title">گزینش شاخهٔ بارگیری برای پرونده‌های صوتی</string>
<string name="default_resolution_title">وضوح پیش‌گزیده</string>
<string name="play_with_kodi_title">پخش با کودی</string>
<string name="kore_not_found">کارهٔ کُره (Kore) پیدا نشد. نصب شود؟</string>
@ -78,9 +78,9 @@
<string name="msg_wait">لطفاً صبر کنید…</string>
<string name="msg_copied">در حافظه رونوشت شد</string>
<string name="no_available_dir">پوشه بارگیری را بعدا در تنظیمات مشخص کنید</string>
<string name="no_player_found_toast">هیچ پخش کننده جریانی پیدا نشد (شما می‌توانید برنامه وی‌ال‌سی را برای پخش آن نصب کنید).</string>
<string name="controls_download_desc">بارگیری پرونده جریان</string>
<string name="use_external_video_player_summary">حذف صدا در برخی کیفیت‌ها</string>
<string name="no_player_found_toast">هیچ پخش کنندهٔ جریانی پیدا نشد (می‌توانید برای پخشش وی‌ال‌سی را نصب کنید).</string>
<string name="controls_download_desc">بارگیری پروندهٔ جریان</string>
<string name="use_external_video_player_summary">صدا را در برخی وضوح‌ها برمی‌دارد</string>
<string name="subscribe_button_title">اشتراک</string>
<string name="subscribed_button_title">مشترک شده</string>
<string name="channel_unsubscribed">اشتراک کانال لغو شد</string>
@ -88,11 +88,11 @@
<string name="subscription_update_failed">ناتوانی در به‌روزرسانی اشتراک</string>
<string name="show_info">نمایش اطلاعات</string>
<string name="tab_subscriptions">اشتراک‌ها</string>
<string name="tab_bookmarks">فهرست‌های پخش دارای نشانک</string>
<string name="tab_bookmarks">سیاههٔ پخش‌های نشان شده</string>
<string name="fragment_feed_title">موارد جدید</string>
<string name="controls_background_title">پس زمینه</string>
<string name="controls_background_title">پسزمینه</string>
<string name="controls_add_to_playlist_title">افزودن به</string>
<string name="show_higher_resolutions_title">نمایش کیفیت بالاتر</string>
<string name="show_higher_resolutions_title">نمایش وضوح‌های بالاتر</string>
<string name="show_higher_resolutions_summary">تنها برخی دستگاه‌ها توانایی پخش ویدیوهای 2K و 4K را دارند</string>
<string name="default_video_format_title">قالب ویدیویی پیش‌گزیده</string>
<string name="black_theme_title">سیاه</string>
@ -116,7 +116,7 @@
<string name="always">همیشه</string>
<string name="just_once">فقط یک‌بار</string>
<string name="file">پرونده</string>
<string name="notification_channel_name">اعلان نیوپایپ</string>
<string name="notification_channel_name">آگاهی نیوپایپ</string>
<string name="unknown_content">[ناشناخته]</string>
<string name="import_data_title">وارد کردن پایگاه‌داده</string>
<string name="export_data_title">صادرکردن</string>
@ -225,14 +225,14 @@
<string name="caption_none">بدون توضیحات</string>
<string name="caption_setting_title">توضحیات</string>
<string name="unsubscribe">لغو اشتراک</string>
<string name="tab_choose">انتخاب زبانه</string>
<string name="tab_choose">گزینش زبانه</string>
<string name="enable_watch_history_title">تاریخچه تماشا</string>
<string name="settings_category_history_title">تاریخچه و حافظه نهان</string>
<string name="settings_category_debug_title">اشکال‌زدایی</string>
<string name="settings_category_updates_title">به‌روزرسانی‌ها</string>
<string name="open_in_popup_mode">گشودن در حالت تصویر در تصویر</string>
<string name="default_popup_resolution_title">دقّت پیش‌گزیدهٔ تصویر در تصویر</string>
<string name="controls_popup_title">تصویر در تصویر</string>
<string name="open_in_popup_mode">گشودن در حالت تصویردرتصویر</string>
<string name="default_popup_resolution_title">وضوح پیش‌گزیدهٔ تصویردرتصویر</string>
<string name="controls_popup_title">تصویردرتصویر</string>
<string name="popup_remember_size_pos_title">به یاد داشتن ویژگی‌های تصویر در تصویر</string>
<string name="popup_remember_size_pos_summary">به یاد داشتن آخرین اندازه و موقعیت تصویر در تصویر</string>
<string name="use_inexact_seek_title">زمان فعلی پخش کننده را به صورت تقریبی و سریع جلو ببر</string>
@ -246,8 +246,8 @@
<string name="import_settings">می‌خواهید تنظیمات را نیز وارد کنید؟</string>
<string name="playback_step">گام</string>
<string name="file_deleted">پرونده پاک شد</string>
<string name="app_update_notification_channel_name">اعلان به‌روزرسانی کاره</string>
<string name="app_update_notification_channel_description">اعلان‌ها برای نسخه جدید نیوپایپ</string>
<string name="app_update_notification_channel_name">آگاهی به‌روزرسانی کاره</string>
<string name="app_update_notification_channel_description">آگاهی‌ها برای نگارش‌های جدید نیوپایپ</string>
<string name="restore_defaults">بازنشانی پیش‌فرض‌ها</string>
<string name="restore_defaults_confirmation">می‌خواهید پیش‌فرض‌ها را بازنشانی کنید؟</string>
<string name="updates_setting_title">به‌روزرسانی‌ها</string>
@ -259,7 +259,7 @@
<string name="app_update_notification_content_text">برای بارگیری، لمس کنید</string>
<string name="missions_header_finished">تمام</string>
<string name="missions_header_pending">در انتظار</string>
<string name="enqueue">صف</string>
<string name="enqueue">صف‌گذاری</string>
<string name="download_failed">بارگیری ناموفق بود</string>
<string name="error_http_not_found">یافت نشد</string>
<string name="error_postprocessing_failed">شکست در پساپردازش</string>
@ -280,7 +280,7 @@
<string name="enable_playback_state_lists_summary">نمایش شاخص موقعیت پخش در فهرست‌ها</string>
<string name="settings_category_clear_data_title">پاک کردن داده‌ها</string>
<string name="resume_on_audio_focus_gain_summary">پخش بعد از قطع ناگهانی (مثل برقراری تماس) ادامه یابد</string>
<string name="show_hold_to_append_title">نمایش نکته «برای افزودن، نگه‌دارید»</string>
<string name="show_hold_to_append_title">نمایش نکته «برای صف‌گذاری، نگه‌دارید»</string>
<string name="show_hold_to_append_summary">نمایش راهنما هنگام فشردن پس زمینه یا دکمهٔ تصویر در تصویر در «جزییات:» ویدیو</string>
<string name="hold_to_append">برای در صف قرار دادن، نگه دارید</string>
<string name="volume_gesture_control_title">کنترل اشاره ای صدا</string>
@ -297,7 +297,7 @@
<string name="title_licenses">پروانه‌های شخص سوم</string>
<string name="copyright" formatted="true">© %1$s توسط %2$s تحت %3$s</string>
<string name="contribution_encouragement">اگر ایده‌ای برای ترجمه، تغییر طراحی، پاک‌سازی کد و یا تغییرات واقعا سنگین کدنویسی دارید، از کمک‌تان همواره استقبال می‌کنیم. هر چه بیشتر کار کنیم، نتایج بهتری می‌گیریم!</string>
<string name="notification_channel_description">آگاهی‌ها برای پخش‌کنندهٔ پس‌زمینه و تصویر در تصویر نیوپایپ</string>
<string name="notification_channel_description">آگاهی‌ها برای پخش‌کنندهٔ نیوپایپ</string>
<string name="empty_subscription_feed_subtitle">چیزی جز کریکت اینجا نیست</string>
<string name="no_subscribers">فاقد مشترک</string>
<string name="player_unrecoverable_failure">خطای عدم احیای پخش‌کننده رخ داد</string>
@ -353,7 +353,7 @@
<string name="preferred_open_action_settings_summary">کنش پیش‌فرض در زمان باز کردن محتوا — %s</string>
<string name="caption_setting_description">تغییر سبک پس‌زمینه و اندازه متن توضیحات پخش‌کننده. برای تأثیر، نیازمند آغاز دوبارهٔ کاره است</string>
<string name="clear_views_history_summary">پاک کردن تاریخچه جریان‌های پخش شه و موقعیت‌های پخش</string>
<string name="app_license">نیوپایپ، یک نرم‌افزار آزاد کپی‌لِفت است: شما می‌توانید از آن استفاده، آن را بررسی کرده و به دیگران بدهید و اگر مایل باشید، بهترش کنید. به طور خاص، شما می‌توانید آن را تحت پروانه عمومی همگانی گنو نسخه ۳ و یا در صورت تمایل بالاتر، که توسط بنیاد نرم‌افزار آزاد منتشر شده تغییر داده و بازنشر دهید.</string>
<string name="app_license">نیوپایپ یک نرم‌افزار آزاد کپی‌لفتی است: می‌توانید به دلخواه خود استفاده، بررسی، هم‌رسانی و بهترش کنید. به طور خاص می‌توانید ذیل نگارش ۳ یا هر نگارش بالاتری از پروانهٔ جامع همگانی گنو که به دست بنیاد نرم‌افزار آزاد منتشر شده، تغییر و بازنشرش دهید.</string>
<string name="privacy_policy_encouragement">حریم شخصی شما برای پروژه نیویایپ بسیاری جدی است. در نتیجه، این برنامه هیچ اطلاعاتی را بدون رضایت شما گردآوری نمی‌کند.
\nسیاستهای حریم شخصی نیوپایپ با جزئیات توضیح می‌دهد که وقتی گزارش یک خطا را می‌فرستید، چه داده‌هایی ذخیره و فرستاده می‌شود.</string>
<string name="start_accept_privacy_policy">به منظور هماهنگی با مقررات حفاظت داده عمومی اروپا (GDPR) در اینجا توجه شما را به سیاست حریم شخصی نیوپایپ جلب می‌کنیم. لطفا آن را به دقت مطالعه کنید.
@ -370,7 +370,7 @@
<string name="paused">متوقف</string>
<string name="queued">در صف</string>
<string name="post_processing">در حال پساپردازش</string>
<string name="permission_denied">این کنش توسط سیستم متوقف شد</string>
<string name="permission_denied">کنش به دست سامانه متوقف شد</string>
<string name="generate_unique_name">تولید نام یگانه</string>
<string name="overwrite">بازنویسی</string>
<string name="download_already_running">یک بارگیری دیگر با همین نام در جریان است</string>
@ -439,8 +439,8 @@
<string name="feed_create_new_group_button_title">جدید</string>
<string name="feed_group_dialog_delete_message">می‌خواهید این گروه را پاک کنید؟</string>
<plurals name="feed_group_dialog_selection_count">
<item quantity="one">%d مورد انتخاب شده</item>
<item quantity="other">%d مورد انتخاب شده</item>
<item quantity="one">%d مورد گزیده</item>
<item quantity="other">%d مورد گزیده</item>
</plurals>
<string name="feed_processing_message">پردازش خوراک…</string>
<string name="feed_notification_loading">بارگیری خوراک…</string>
@ -549,9 +549,9 @@
<string name="clear_queue_confirmation_summary">تغییر پخش کننده می‌تواند باعث جایگزین شدن صف شود</string>
<string name="clear_queue_confirmation_title">پیش از پاک کردن صف، سوال شود</string>
<string name="notification_action_nothing">هیچ</string>
<string name="notification_action_shuffle">برزنی</string>
<string name="notification_action_shuffle">بُرزنی</string>
<string name="notification_action_repeat">تکرار</string>
<string name="notification_actions_at_most_three">حداکثر تا سه کنش را می‌توانید برای نمایش در اعلان فشرده انتخاب کنید!</string>
<string name="notification_actions_at_most_three">می‌توانید تا سه کنش را برای نمایش در آگاهی فشرده برگزینید!</string>
<string name="notification_actions_summary">هر کنش آگاهی را با لمس کردنش ویرایش کنید. با استفاده از جعبه‌های تیک، تا سه کنش را برای نمایش در آگاهی فشرده بگزینید</string>
<string name="notification_action_4_title">پنجمین دکمه کنشی</string>
<string name="notification_action_3_title">چهارمین دکمه کنشی</string>
@ -609,7 +609,7 @@
<string name="night_theme_title">زمینهٔ شب</string>
<string name="notification_colorize_title">رنگی کردن آگاهی</string>
<string name="open_with">گشودن با</string>
<string name="mark_as_watched">نشانه به عنوان دیدهشده</string>
<string name="mark_as_watched">نشانه به عنوان دیده شده</string>
<string name="show_image_indicators_summary">نمایش روبان‌های رنگی پیکاسو در بالای تصویرها کهنشانگر منبعشان است: قرمز برای شبکه ، آبی برای دیسک و سبز برای حافظه</string>
<string name="notification_colorize_summary">درخواست از اندروید برای سفارشی‌سازی رنگ آگاهی براساس رنگ اصلی در بندانگشتی (توجّه داشته باشید که روی همهٔ افزاره‌ها در دسترس نیست)</string>
<string name="restricted_video">این ویدیو محدود به سن است.
@ -673,8 +673,19 @@
<string name="checking_updates_toast">بررسی کردن به‌روز رسانی‌ها…</string>
<string name="feed_new_items">موارد خوراک جدید</string>
<string name="crash_the_player">فروپاشی پخش‌کننده</string>
<string name="report_player_errors_title">گزارش خطاهای پخش کننده</string>
<string name="show_crash_the_player_summary">نمایش یک گزینهٔ فروپاشی هنگام استفاده از پخش کننده</string>
<string name="report_player_errors_summary">گزارش خطاهای پخش کننده با جزییات کامل به جای نشان دادن پیامی با عمر کوتاه (مناسب برای تشخیص مشکلات)</string>
<string name="show_crash_the_player_title">نمایش «فروپاشی پخش کننده»</string>
<string name="no_appropriate_file_manager_message">مدیر پروندهٔ مناسبی برای این کنش یافت نشد.
\nلطفاً مدیر پرونده‌ای نصب کرده یا در تنظیمات بارگیری، «%s» را خاموش کنید.</string>
<string name="error_report_channel_name">آگاهی گزارش خطا</string>
<string name="error_report_channel_description">آگاهی برای گزارش‌خطاها</string>
<string name="show_error_snackbar">نمایش یک نوار خطا</string>
<string name="create_error_notification">ایجاد یک آگاهی خطا</string>
<string name="no_appropriate_file_manager_message_android_10">مدیر پروندهٔ مناسبی برای این کنش یافت نشد.
\nلطفاً مدیر پرونده‌ای سازگار با چارچوب‌دسترسی ذخیره‌ساز نصب کنید.</string>
<string name="error_report_notification_title">نیوپایپ به خطایی برخورد. برای گزارش، بزنید</string>
<string name="error_report_notification_toast">خطایی رخ داد. آگاهی را ببینید</string>
<string name="detail_pinned_comment_view_description">نظر سنجاق شده</string>
<string name="background_player_already_playing_toast">در حال پخش در پس‌زمینه</string>
<string name="leak_canary_not_available">لیک‌کاناری موجود نیست</string>
</resources>

View File

@ -78,8 +78,8 @@
<string name="clear">Pyyhi</string>
<string name="best_resolution">Paras resoluutio</string>
<string name="undo">Peru</string>
<string name="notification_channel_name">NewPipe Ilmoitus</string>
<string name="notification_channel_description">Ilmoitukset NewPipen tausta- ja ponnahdusikkunasoittimille</string>
<string name="notification_channel_name">NewPipe ilmoitus</string>
<string name="notification_channel_description">Ilmoitukset NewPipen soittimille</string>
<string name="general_error">Virhe</string>
<string name="network_error">Verkkovirhe</string>
<string name="could_not_load_thumbnails">Kaikkia esikatselukuvia ei voitu ladata</string>
@ -304,7 +304,7 @@
\n3. Klikkaa \"Kaikki Youtube-data valittuna\", sitten \"Poista kaikki valinnat\", sitten ainoastaan \"tilaukset\" ja klikkaa \"OK\"
\n4. Klikkaa \"Seuraava vaihe\" ja \"Luo vienti\"
\n5. Klikkaa \"Lataa\"-painiketta tämän ilmestyessä
\n6. Klikkaa TUO TIEDOSTO alhaalta ja valitse ladattu tiedosto
\n6. Klikkaa TUO TIEDOSTO alhaalta ja valitse ladattu .zip-tiedosto
\n7. [Jos zip-tiedoston tuonti epäonnistuu] Pura .csv-tiedosto (yleensä sijainnissa \"Youtube ja Youtube Musiikki/tilaukset/tilaukset.csv\") ja klikkaa TUO TIEDOSTO alhaalta ja valitse purettu csv-tiedosto</string>
<string name="import_soundcloud_instructions">Tuo SoundCloud-profiili kirjoittamalla joko osoite tai ID:si:
\n
@ -337,7 +337,7 @@
<string name="unsubscribe">Peru tilaus</string>
<string name="tab_choose">Valitse välilehti</string>
<string name="missions_header_finished">Valmis</string>
<string name="enqueue">Jono</string>
<string name="enqueue">Lisää jonoon</string>
<string name="seek_duration_title">Eteen-/taaksepäinkelauksen aika-askeleen pituus</string>
<string name="recently_added">Hiljattain lisätyt</string>
<string name="local">Paikalliset</string>
@ -369,7 +369,7 @@
<string name="download_to_sdcard_error_message">Lataaminen ulkoiselle SD-kortille ei ole mahdollista. Nollataanko latauskansion sijainti\?</string>
<string name="download_to_sdcard_error_title">Ulkoinen tallennustila ei käytettävissä</string>
<string name="help">Ohje</string>
<string name="app_update_notification_channel_description">Ilmoitukset uudesta NewPipe-versiosta</string>
<string name="app_update_notification_channel_description">Ilmoitukset uusista NewPipe-versioista</string>
<string name="app_update_notification_channel_name">Sovelluspäivitysilmoitus</string>
<string name="file_deleted">Tiedosto poistettu</string>
<string name="artists">Esittäjät</string>
@ -671,4 +671,20 @@
<string name="manual_update_title">Tarkista päivitykset</string>
<string name="manual_update_description">Tarkista manuaalisesti onko uusia versioita saatavilla</string>
<string name="checking_updates_toast">Tarkistetaan päivityksiä…</string>
<string name="error_report_channel_description">Ilmoitukset, joilla raportoidaan virheistä</string>
<string name="detail_pinned_comment_view_description">Kiinnitetty kommentti</string>
<string name="error_report_channel_name">Virheraportti-ilmoitus</string>
<string name="error_report_notification_title">NewPipe kohtasi virheen, näpäytä raportoidaksesi</string>
<string name="error_report_notification_toast">Tapahtui virhe, katso ilmoitus</string>
<string name="create_error_notification">Luo virheilmoitus</string>
<string name="leak_canary_not_available">LeakCanary ei ole saatavilla</string>
<string name="show_crash_the_player_title">Näytä \"Kaada soitin\"</string>
<string name="crash_the_player">Kaada soitin</string>
<string name="no_appropriate_file_manager_message_android_10">Toiminnolle ei löytynyt sopivaa tiedostonhallintaohjelmaa.
\nAsenna tiedostonhallintaohjelma, joka on yhteensopiva Storage Access Frameworkin kanssa.</string>
<string name="no_appropriate_file_manager_message">Toiminnolle ei löytynyt sopivaa tiedostonhallintaohjelmaa.
\nAsenna tiedostonhallintaohjelma tai kokeile asettaa \'%s\' pois käytöstä latausasetuksista.</string>
<string name="show_crash_the_player_summary">Näytä soitinta käytettäessä soittimen kaatamisen vaihtoehto</string>
<string name="show_error_snackbar">Näytä virheen ponnahdusilmoitus</string>
<string name="feed_new_items">Uudet syötteet</string>
</resources>

View File

@ -142,7 +142,7 @@
<string name="settings_category_player_title">Lecteur</string>
<string name="settings_category_player_behavior_title">Comportement</string>
<string name="settings_category_history_title">Historique et cache</string>
<string name="notification_channel_description">Notifications pour les lecteurs en arrière-plan et flottant de NewPipe</string>
<string name="notification_channel_description">Notifications pour le lecteur de NewPipe</string>
<string name="search_no_results">Aucun résultat</string>
<string name="empty_subscription_feed_subtitle">Aucun contenu</string>
<string name="no_subscribers">Aucun abonné</string>
@ -310,7 +310,7 @@
<string name="delete_search_history_alert">Voulez-vous supprimer entièrement lhistorique de recherche\?</string>
<string name="search_history_deleted">Historique de recherche supprimé</string>
<string name="one_item_deleted">1 élément supprimé.</string>
<string name="app_license">NewPipe est un logiciel sous licence libre copyleft : vous pouvez lutiliser, létudier, le partager et laméliorer comme bon vous semble. Plus précisément, vous pouvez le redistribuer ou le modifier sous les termes de la licence générale publique GNU, comme publiée par la Free Software Foundation, dans sa version 3, ou, à votre convenance, dans une quelconque version ultérieure.</string>
<string name="app_license">NewPipe est un logiciel sous licence libre copyleft : vous pouvez lutiliser, létudier, le partager, et laméliorer comme bon vous semble. Plus précisément, vous pouvez le redistribuer ou le modifier sous les termes de la licence générale publique GNU, comme publiée par la Free Software Foundation, dans sa version 3, ou, à votre convenance, dans une quelconque version ultérieure.</string>
<string name="privacy_policy_title">Politique de confidentialité de NewPipe</string>
<string name="read_privacy_policy">Lire la politique de confidentialité</string>
<string name="import_settings">Voulez-vous également importer les paramètres\?</string>
@ -343,7 +343,7 @@
<string name="settings_category_updates_title">Mises à jour</string>
<string name="file_deleted">Fichier supprimé</string>
<string name="app_update_notification_channel_name">Notification de mise à jour de lapplication</string>
<string name="app_update_notification_channel_description">Notifications pour une nouvelle version de NewPipe</string>
<string name="app_update_notification_channel_description">Notifications pour des nouvelles versions de NewPipe</string>
<string name="download_to_sdcard_error_title">Stockage externe indisponible</string>
<string name="restore_defaults">Restaurer les valeurs par défaut</string>
<string name="restore_defaults_confirmation">Voulez-vous restaurer les valeurs par défaut\?</string>
@ -383,7 +383,7 @@
<string name="pause_downloads_on_mobile_desc">Utile lors du basculement aux données mobiles, bien que certains téléchargements ne peuvent pas être suspendus</string>
<string name="list_view_mode">Mode de vue en liste</string>
<string name="post_processing">post-traitement</string>
<string name="enqueue">Liste de lecture</string>
<string name="enqueue">Mettre en file d\'attente</string>
<string name="permission_denied">Action refusée par le système</string>
<string name="error_postprocessing_failed">Le post-traitement a échoué</string>
<string name="max_retry_msg">Nombre dessais maximum</string>
@ -674,9 +674,20 @@
<string name="checking_updates_toast">Vérification des mises à jour…</string>
<string name="manual_update_title">Vérifier les mises à jours</string>
<string name="feed_new_items">Nouveaux éléments du flux</string>
<string name="report_player_errors_summary">Reporter les erreurs du lecteur en détail au lieu de montrer un bref message éphémère (utile pour diagnostiquer les problèmes)</string>
<string name="report_player_errors_title">Reporter des erreurs du lecteur</string>
<string name="crash_the_player">Couper le lecteur</string>
<string name="show_crash_the_player_title">Montrer \"Couper le lecteur\"</string>
<string name="show_crash_the_player_summary">Montrer une option couper lors de l\'utilisation du lecteur</string>
<string name="crash_the_player">Faire planter le lecteur</string>
<string name="show_crash_the_player_title">Afficher « Faire planter le lecteur »</string>
<string name="show_crash_the_player_summary">Montrer une option de plantage lors de l\'utilisation du lecteur</string>
<string name="error_report_channel_name">Notification de rapport d\'erreur</string>
<string name="error_report_channel_description">Notifications pour signaler les erreurs</string>
<string name="error_report_notification_title">NewPipe a rencontré une erreur, appuyez pour la signaler</string>
<string name="error_report_notification_toast">Une erreur s\'est produite, voir la notification</string>
<string name="create_error_notification">Créer une notification d\'erreur</string>
<string name="no_appropriate_file_manager_message_android_10">Aucun gestionnaire de fichiers approprié n\'a été trouvé pour cette action.
\nVeuillez installer un gestionnaire de fichiers compatible avec l\'Infrastructure d\'accès au stockage.</string>
<string name="show_error_snackbar">Afficher une barre d\'erreur</string>
<string name="no_appropriate_file_manager_message">Aucun gestionnaire de fichier approprié n\'a été trouvé pour cette action.
\nVeuillez installer un gestionnaire de fichiers ou essayez de désactiver \'%s\' dans les paramètres de téléchargement.</string>
<string name="detail_pinned_comment_view_description">Commentaire épinglé</string>
<string name="background_player_already_playing_toast">Une lecture est déjà en arrière-plan</string>
<string name="leak_canary_not_available">LeakCanary n\'est pas disponible</string>
</resources>

View File

@ -73,7 +73,7 @@
<string name="resume_on_audio_focus_gain_summary">Continuar reproducindo o vídeo despois das interrupcións (como, por exemplo, as chamadas)</string>
<string name="download_dialog_title">Descarregar</string>
<string name="show_next_and_similar_title">Mostrar vídeos \"seguintes\" e \"semellantes\"</string>
<string name="show_hold_to_append_title">Mostrar a suxestión \"Manteña presionado para engadir á cola\"</string>
<string name="show_hold_to_append_title">Mostrar a suxestión \"Manteña presionado para engadir á fila\"</string>
<string name="show_hold_to_append_summary">Amosar o consello ao premer o fondo ou o botón emerxente \"Detalles:\" no vídeo</string>
<string name="unsupported_url">URL non soportado</string>
<string name="default_content_country_title">País predeterminado para o contido</string>
@ -86,7 +86,7 @@
<string name="background_player_playing_toast">Reproducindo en segundo plano</string>
<string name="popup_playing_toast">Reproducindo en modo «popup»</string>
<string name="content">Contido</string>
<string name="show_age_restricted_content_title">Contido restrinxido para certa idade</string>
<string name="show_age_restricted_content_title">Mostrar contido con restrición de idade</string>
<string name="duration_live">En directo</string>
<string name="downloads">Descargas</string>
<string name="downloads_title">Descargas</string>
@ -106,15 +106,15 @@
<string name="just_once">Só unha vez</string>
<string name="file">Ficheiro</string>
<string name="notification_channel_name">Notificación do NewPipe</string>
<string name="notification_channel_description">Notificacións para os reprodutores de fondo e reprodutores emerxentes de NewPipe</string>
<string name="notification_channel_description">Notificacións para o reprodutor de NewPipe</string>
<string name="unknown_content">[Descoñecido]</string>
<string name="switch_to_background">Mudar para o segundo plano</string>
<string name="switch_to_popup">Mudar para o «popup»</string>
<string name="switch_to_main">Mudar para principal</string>
<string name="import_data_title">Importar base de datos</string>
<string name="export_data_title">Exportar base de datos</string>
<string name="import_data_summary">Anula o teu historial e subscricións actuais</string>
<string name="export_data_summary">Exportar historial, subscricións e listas de reprodución</string>
<string name="import_data_summary">Anula o seu historial, subscricións, listas de reprodución e (opcionalmente) configuracións</string>
<string name="export_data_summary">Exportar historial, subscricións, listas de reprodución e configuración</string>
<string name="clear_views_history_title">Limpar historial de reproducións</string>
<string name="clear_views_history_summary">Elimina o historial de transmisións reproducidas e as posicións da reprodución</string>
<string name="delete_view_history_alert">Eliminar todo o historial de reproducións\?</string>
@ -145,7 +145,7 @@
<string name="no_streams_available_download">Non hai emisións para descargar</string>
<string name="sorry_string">Deculpe, isto non debería ter acontecido.</string>
<string name="error_report_button_text">Informar deste erro por enderezo electrónico</string>
<string name="error_snackbar_message">Desculpe, ocorreron algúns erros.</string>
<string name="error_snackbar_message">Desculpe, algo foi mal.</string>
<string name="error_snackbar_action">Informe</string>
<string name="what_device_headline">Información:</string>
<string name="what_happened_headline">Que ocorreu:</string>
@ -227,7 +227,7 @@
\nA política de privacidade do NewPipe explica con máis detalle que datos son enviados e gardados cando envía un relatorio de erros.</string>
<string name="read_privacy_policy">Ler a política de privacidade</string>
<string name="app_license_title">Licenza do NewPipe</string>
<string name="app_license">NewPipe é un software libre copyleft: Podes usar, estudar compartir e melloralo a vontade. En concreto, pode redistribuír e / ou modificala segundo os termos da Licenza Pública Xeral GNU publicada pola Free Software Foundation, xa sexa a versión 3 da licenza, ou (na súa opción) calquera outra versión posterior.</string>
<string name="app_license">NewPipe é un software libre copyleft: Pode usar, estudar compartir e melloralo a vontade. En concreto, pode redistribuír e / ou modificala segundo os termos da Licenza Pública Xeral GNU publicada pola Free Software Foundation, xa sexa a versión 3 da licenza, ou (na súa opción) calquera outra versión posterior.</string>
<string name="read_full_license">Ler a licenza</string>
<string name="title_activity_history">Historial</string>
<string name="action_history">Historial</string>
@ -494,7 +494,7 @@
<string name="subscribers_count_not_available">Non hai dispoñible conta de subscritores</string>
<string name="drawer_header_description">Cambiar o servizo actualmente seleccionado:</string>
<string name="error_report_open_github_notice">Verifique se xa existe un problema que fala do seu fallo. Ao crear billetes duplicados, gasta o tempo que nós poderiamos gastar en solucionar o erro real.</string>
<string name="error_report_open_issue_button_text">Informar dun erro en GitHub</string>
<string name="error_report_open_issue_button_text">Reportar en GitHub</string>
<string name="copy_for_github">Copia o informe con formato</string>
<string name="permission_display_over_apps">Dar permiso para mostrar noutros aplicativos</string>
<string name="restore_defaults_confirmation">Quere restaurar os valores predeterminados\?</string>
@ -508,7 +508,7 @@
<string name="delete_playback_states_alert">Eliminas todas as posicións de reprodución\?</string>
<string name="clear_playback_states_summary">Elimina todas as posicións de reprodución</string>
<string name="clear_playback_states_title">Elimina as posicións de reprodución</string>
<string name="app_update_notification_channel_description">Notificacións para a nova versión de NewPipe</string>
<string name="app_update_notification_channel_description">Notificacións para as novas versións de NewPipe</string>
<string name="app_update_notification_channel_name">Notificación da actualización do aplicativo</string>
<string name="file_deleted">Ficheiro eliminado</string>
<string name="artists">Artistas</string>
@ -518,8 +518,8 @@
<string name="videos_string">Vídeos</string>
<string name="restricted_video">Este vídeo está restrinxido por idade.
\n
\nSe desexa visualizalo, habilite \"%1$s\" nos axustes.</string>
<string name="youtube_restricted_mode_enabled_title">Modo restrinxido de YouTube</string>
\nSe desexa visualizalo, habilite \"%1$s\" nas opcións.</string>
<string name="youtube_restricted_mode_enabled_title">Activar modo restrinxido de YouTube</string>
<string name="settings_category_updates_title">Actualizacións</string>
<string name="peertube_instance_add_exists">A instancia xa existe</string>
<string name="peertube_instance_add_fail">Non se puido validar a instancia</string>
@ -542,7 +542,7 @@
<string name="search_showing_result_for">Amosando resultados para: %s</string>
<string name="notification_action_buffering">Procesando</string>
<string name="notification_action_repeat">Repetir</string>
<string name="notification_actions_at_most_three">Podes seleccionar como máximo tres accións para amosar na notificación compacta!</string>
<string name="notification_actions_at_most_three">Pode seleccionar como máximo tres accións para amosar na notificación compacta!</string>
<string name="notification_action_0_title">Primeiro botón de acción</string>
<string name="notification_action_1_title">Segundo botón de acción</string>
<string name="notification_action_2_title">Terceiro botón de acción</string>
@ -566,7 +566,7 @@
<string name="metadata_category">Categoría</string>
<string name="description_select_disable">Deshabilitar a selección do texto da descrición</string>
<string name="description_select_enable">Habilitar a selección do texto na descrición</string>
<string name="description_select_note">Agora podes seleccionar o texto na descrición. Teña en conta que a páxina pode cintilar e as ligazóns poden non ser clicábeis no modo selección.</string>
<string name="description_select_note">Agora pode seleccionar o texto na descrición. Teña en conta que a páxina pode cintilar e as ligazóns poden non ser clicábeis no modo selección.</string>
<string name="auto_device_theme_title">Automático (Tema do dispositivo)</string>
<string name="radio">Radio</string>
<string name="service_provides_reason">%s dá este motivo:</string>
@ -616,7 +616,7 @@
<string name="on">Prendido</string>
<string name="metadata_host">Provedor</string>
<string name="featured">Destacado</string>
<string name="paid_content">Este contido só está dispoñíbel para usuarios que pagaran por el, así que non pode ser transmitido ou decarregado por NewPipe.</string>
<string name="paid_content">Este contido só está dispoñíbel para usuarios que pagaran por el, así que non pode ser transmitido ou descarregado por NewPipe.</string>
<string name="downloads_storage_ask_summary_no_saf_notice">Será preguntado onde desexa gardar cada descarga</string>
<string name="dont_show">Non mostrar</string>
<string name="low_quality_smaller">Baixa calidade (máis pequeno)</string>
@ -655,4 +655,20 @@
<string name="clear_queue_confirmation_summary">Cambiar dun reprodutor a outro pode substituír a súa cola</string>
<string name="notification_action_shuffle">Barallar</string>
<string name="notification_actions_summary">Edite cada acción da notificación premendo nela. Seleccione ata tres delas para seren mostradas na notificación compacta usando as checkboxes da dereita</string>
<string name="enqueue_next_stream">Enfileirar o seguinte vídeo</string>
<string name="start_main_player_fullscreen_title">Inciar reprodutor principal en pantalla completa</string>
<string name="start_main_player_fullscreen_summary">Non iniciar vídeos no reprodutor mini, mais cambiar a pantalla completa directamente, se a rotación estiver bloqueada. Aínda pode acceder o reprodutor mini ao saír da pantalla completa</string>
<string name="main_page_content_swipe_remove">Deslice os elementos para removelos</string>
<string name="no_appropriate_file_manager_message">Non foi atopado ningún xestor de arquivos adecuado para esta acción.
\nPor favor instale un ou tente deshabilitar \'%s\' nas opcións de descarregamento.</string>
<string name="no_appropriate_file_manager_message_android_10">Non foi atopado ningún xestor de arquivos adecuado para esta acción.
\nPor favor instale un compatíbel co Sistema de Acceso ao Almacenamento.</string>
<string name="detail_heart_img_view_description">Valorado polo creador</string>
<string name="error_report_notification_toast">Ocorreu un erro, vexa a notificación</string>
<string name="auto_queue_toggle">Auto-enfileirar</string>
<string name="soundcloud_go_plus_content">Esta é unha pista de SoundCloud Go+, polo menos no seu país, así que non pode ser transmitida ou descarregada por NewPipe.</string>
<string name="error_report_channel_name">Notificación de relatorio de erros</string>
<string name="error_report_channel_description">Notificacións para reportar erros</string>
<string name="error_report_notification_title">NewPipe atopou un erro, presione para reportar</string>
<string name="detail_pinned_comment_view_description">Comentario fixado</string>
</resources>

View File

@ -98,7 +98,7 @@
<string name="undo">ביטול</string>
<string name="play_all">לנגן הכול</string>
<string name="notification_channel_name">התראה מ־NewPipe</string>
<string name="notification_channel_description">התראות עבור נגן הרקע והנגן הצף של NewPipe</string>
<string name="notification_channel_description">התראות עבור הנגן של NewPipe</string>
<string name="unknown_content">[לא ידוע]</string>
<string name="player_stream_failure">נגינת התזרים לא הצליחה</string>
<string name="player_unrecoverable_failure">אירעה תקלה בנגן ממנה לא ניתן להשתקם</string>
@ -144,7 +144,7 @@
<string name="checksum">גיבוב לאימות</string>
<string name="ok">אישור</string>
<string name="msg_name">שם קובץ</string>
<string name="msg_threads">תת־דיונים</string>
<string name="msg_threads">תהליכי משנה</string>
<string name="msg_error">שגיאה</string>
<string name="msg_running">NewPipe בהורדה</string>
<string name="msg_running_detail">יש לגעת לפרטים נוספים</string>
@ -265,8 +265,8 @@
\n3. ללחוץ על „All data included”, ואז על „Deselect all”, לאחר מכן לבחור רק את „subscriptions” וללחוץ על „OK”
\n4. ללחוץ על „Next step” ואז על „Create export”
\n5. ללחוץ על כפתור ה־„Download” כשהוא מופיע
\n6. ללחוץ על „ייבוא קובץ” להלן ולבחור בקובץ ה־zip שהורדת
\n7. (אם ייבוא ה־zip נכשל) יש לחלץ את קובץ ה־‎.csv (בדרך כלל תחת „YouTube and YouTube Music/subscriptions/subscriptions.csv”), ללחוץ על „ייבוא קובץ” להלן וללחוץ על קובץ ה־csv שחולץ</string>
\n6. ללחוץ על „ייבוא קובץ” להלן ולבחור בקובץ ה־.zip שהורדת
\n7. (אם ייבוא ה־.zip נכשל) יש לחלץ את קובץ ה־‎.csv (בדרך כלל תחת „YouTube and YouTube Music/subscriptions/subscriptions.csv”), ללחוץ על „ייבוא קובץ” להלן וללחוץ על קובץ ה־csv שחולץ</string>
<string name="playback_tempo">קצב</string>
<string name="use_inexact_seek_title">שימוש בחיפוש מהיר ולא מדויק</string>
<string name="use_inexact_seek_summary">חיפוש גס מאפשר לנגן לחפש נקודת זמן מהר יותר, ברמת דיוק נמוכה יותר. חיפוש של 5, 15 או 25 שניות לא עובד עם ההגדרה הזאת</string>
@ -336,7 +336,7 @@
<string name="settings_category_updates_title">עדכונים</string>
<string name="file_deleted">קובץ נמחק</string>
<string name="app_update_notification_channel_name">התראת עדכון יישומון</string>
<string name="app_update_notification_channel_description">התראות על גרסה חדשה של NewPipe</string>
<string name="app_update_notification_channel_description">התראות על גרסאות חדשות של NewPipe</string>
<string name="download_to_sdcard_error_title">האחסון החיצוני אינו זמין</string>
<string name="download_to_sdcard_error_message">אין אפשרות להוריד לכרטיס SD. לאפס את מיקום תיקיית ההורדה\?</string>
<string name="saved_tabs_invalid_json">לא ניתן לקרוא לשוניות שמורות, לכן נעשה שימוש באלו של ברירת המחדל</string>
@ -371,7 +371,7 @@
<string name="paused">מושהה</string>
<string name="queued">בתור</string>
<string name="post_processing">עיבוד מאוחר</string>
<string name="enqueue">תור</string>
<string name="enqueue">הוספה לתור</string>
<string name="permission_denied">הפעולה נדחתה על ידי המערכת</string>
<string name="download_failed">ההורדה נכשלה</string>
<string name="generate_unique_name">יצירת שם ייחודי</string>
@ -566,7 +566,7 @@
<string name="autoplay_summary">להתחיל לנגן אוטומטית — %s</string>
<string name="title_activity_play_queue">לנגן את התור</string>
<string name="unsupported_url_dialog_message">לא ניתן לזהות את הכתובת. לפתוח אותה ביישומון אחר\?</string>
<string name="auto_queue_toggle">תור אוטומטי</string>
<string name="auto_queue_toggle">הוספה אוטומטית לתור</string>
<string name="clear_queue_confirmation_description">התור מהנגן הפעיל יוחלף</string>
<string name="clear_queue_confirmation_summary">מעבר מנגן אחד למשנהו עלול להחליף את התור שלך</string>
<string name="clear_queue_confirmation_title">לבקש אישור לפני מחיקת התור</string>
@ -698,7 +698,18 @@
<string name="feed_new_items">פריטים חדשים בהזנה</string>
<string name="crash_the_player">להקריס את הנגן</string>
<string name="show_crash_the_player_title">הצגת „להקריס את הנגן”</string>
<string name="report_player_errors_title">דיווח על שגיאות בנגן</string>
<string name="report_player_errors_summary">מדווח על שגיאות בנגן בפירוט מלא במקום להציג הודעה שקופצת למסך לזמן קצר (יעיל לניתוח תקלות)</string>
<string name="show_crash_the_player_summary">הצגת אפשרות קריסה בעת שימוש בנגן</string>
<string name="error_report_channel_description">התראות לדיווח על שגיאות</string>
<string name="show_error_snackbar">הצגת חלונית בזק עם שגיאה</string>
<string name="create_error_notification">יצירת התראת שגיאה</string>
<string name="error_report_notification_title">NewPipe נתקל בשגיאה, לחיצה תדווח על כך</string>
<string name="error_report_notification_toast">אירעה שגיאה, נא לקרוא את ההתראה</string>
<string name="no_appropriate_file_manager_message">לא נמצא מנהל קבצים מתאים לפעולה זו.
\nנא להתקין מנהל קבצים או לנסות להשבית את %s בהגדרות ההורדה.</string>
<string name="error_report_channel_name">התראת דיווח שגיאה</string>
<string name="no_appropriate_file_manager_message_android_10">לא נמצאו מנהלי קבצים שמתאימים לפעולה הזאת.
\nנא להתקין מנהל קבצים שתומך בתשתית גישה לאחסון.</string>
<string name="background_player_already_playing_toast">כבר מתנגן ברקע</string>
<string name="detail_pinned_comment_view_description">הערה ננעצה</string>
<string name="leak_canary_not_available">LeakCanary אינה זמינה</string>
</resources>

View File

@ -139,7 +139,7 @@
<string name="title_activity_history">Povijest</string>
<string name="action_history">Povijest</string>
<string name="notification_channel_name">NewPipe obavijest</string>
<string name="notification_channel_description">Obavijesti za NewPipe pozadinske i skočne reproduktore</string>
<string name="notification_channel_description">Obavijesti za NewPipe reproduktore</string>
<string name="settings_category_player_title">Reproduktor</string>
<string name="settings_category_player_behavior_title">Ponašanje</string>
<string name="settings_category_history_title">Povijest i predmemorija</string>
@ -280,8 +280,8 @@
\n3. Pritisni „Uključeni svi podaci”, zatim „Poništi odabir svih”, a zatim odaberi samo „pretplate” i pritisni „U redu”
\n4. Pritisni na „Nastavi”, a zatim „Stvori izvoz”
\n5. Pritisni na „Preuzmi”
\n6. Dolje pritisni na UVEZI DATOEKU i odaberi zip datoteku za peuzimanje
\n7. [Ako uvoz zip datoteke ne uspije] Izdvoji .csv datoteku (pod \"YouTube and YouTube Music/subscriptions/subscriptions.json\"). Dolje pritisni UVEZI DATOTEKU i odaberi izdvojenu csv datoteku</string>
\n6. Dolje pritisni na UVEZI DATOEKU i odaberi .zip datoteku za peuzimanje
\n7. [Ako uvoz .zip datoteke ne uspije] Izdvoji .csv datoteku (pod \"YouTube and YouTube Music/subscriptions/subscriptions.json\"). Dolje pritisni UVEZI DATOTEKU i odaberi izdvojenu csv datoteku</string>
<string name="import_soundcloud_instructions_hint">vašID, soundcloud.com/vašID</string>
<string name="import_network_expensive_warning">Uzmite u obzir da ova operacija može uzrokovat veliku potrošnju prometa.
\n
@ -304,7 +304,7 @@
<string name="settings_category_updates_title">Ažuriranja</string>
<string name="events">Događaji</string>
<string name="file_deleted">Datoteka obrisana</string>
<string name="app_update_notification_channel_description">Obavijest za novu verziju NewPipe-a</string>
<string name="app_update_notification_channel_description">Obavijest za nove NewPipe verzije</string>
<string name="clear_search_history_summary">Briše povijest ključnih riječi pretraživanja</string>
<string name="download_to_sdcard_error_title">Vanjska pohrana nije dostupna</string>
<string name="updates_setting_title">Ažuriranja</string>
@ -683,4 +683,11 @@
<string name="local_search_suggestions">Prijedlozi lokalne pretrage</string>
<string name="manual_update_title">Traži nove verzije</string>
<string name="start_main_player_fullscreen_summary">Nemoj pokretati videa u mini reproduktoru, već se izravno pokreni cjeloekranski prikaz, ako je automatsko okretanje zaključano. Mini reproduktoru i dalje možeš pristupiti izlaskom iz cjeloekranskog prikaza</string>
<string name="feed_new_items">Novi feedovi</string>
<string name="error_report_channel_name">Obavijest o prijavi greške</string>
<string name="error_report_channel_description">Obavijesti za prijavu grešaka</string>
<string name="create_error_notification">Stvori obavijest o grešci</string>
<string name="error_report_notification_title">NewPipe je naišao na grešku, dodirni za prijavu</string>
<string name="error_report_notification_toast">Došlo je do greške, pogledaj obavijest</string>
<string name="crash_the_player">Prekini rad playera</string>
</resources>

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="upload_date_text">Közzétéve: %1$s</string>
<string name="no_player_found">Nem megfelelő médialejátszó. Szeretné telepíti a VLC médialejátszót\?</string>
<string name="no_player_found">Nem található megfelelő médialejátszó. Telepíti a VLC-t\?</string>
<string name="install">Telepítés</string>
<string name="cancel">Mégse</string>
<string name="open_in_browser">Megnyitás böngészőben</string>
@ -9,75 +9,75 @@
<string name="download">Letöltés</string>
<string name="search">Keresés</string>
<string name="settings">Beállítások</string>
<string name="did_you_mean">Erre gondoltál: %1$s\?</string>
<string name="did_you_mean">Erre gondolt: %1$s\?</string>
<string name="share_dialog_title">Megosztás ezzel</string>
<string name="download_path_title">Videofájlok letöltési mappája</string>
<string name="download_path_summary">A letöltött videók itt lesznek tárolva</string>
<string name="download_path_summary">A letöltött videófájlok itt lesznek tárolva</string>
<string name="download_path_dialog_title">Válasszon letöltési mappát a videófájloknak</string>
<string name="default_resolution_title">Alapértelmezett felbontás</string>
<string name="play_with_kodi_title">Lejátszás Kodi-val</string>
<string name="kore_not_found">Telepíted a Kore lejátszót\?</string>
<string name="show_play_with_kodi_title">\"Lejátszás Kodi-val\" opció mutatása</string>
<string name="show_play_with_kodi_summary">Opció mutatása a videók Kodi médiaközponttal való lejátszására</string>
<string name="play_with_kodi_title">Lejátszás Kodival</string>
<string name="kore_not_found">Telepíti a hiányzó Kore alkalmazást\?</string>
<string name="show_play_with_kodi_title">A „Lejátszás Kodival” lehetőség megjelenítése</string>
<string name="show_play_with_kodi_summary">A videók Kodi médiaközponttal történő lejátszásának megjelenítése</string>
<string name="play_audio">Hang</string>
<string name="default_audio_format_title">Alapértelmezett hang formátum</string>
<string name="default_audio_format_title">Alapértelmezett hangformátum</string>
<string name="download_dialog_title">Letöltés</string>
<string name="unsupported_url">Nem támogatott webcím</string>
<string name="unsupported_url">Nem támogatott URL</string>
<string name="use_external_video_player_title">Külső videólejátszó használata</string>
<string name="use_external_audio_player_title">Külső hanglejátszó használata</string>
<string name="download_path_audio_dialog_title">Válaszd ki a hangfájlok letöltési helyét</string>
<string name="download_path_audio_dialog_title">Válassza ki a hangfájlok letöltési helyét</string>
<string name="network_error">Hálózati hiba</string>
<string name="background_player_playing_toast">Lejátszás háttérben</string>
<string name="background_player_playing_toast">Lejátszás a háttérben</string>
<string name="settings_category_video_audio_title">Videó és hang</string>
<string name="settings_category_appearance_title">Megjelenés</string>
<string name="content_language_title">Tartalom preferált nyelve</string>
<string name="show_next_and_similar_title">\'Következő\' és \'Hasonló\' videók mutatása</string>
<string name="content_language_title">Tartalom alapértelmezett nyelve</string>
<string name="show_next_and_similar_title">„Következő” és „Hasonló” videók megjelenítése</string>
<string name="dark_theme_title">Sötét</string>
<string name="light_theme_title">Világos</string>
<string name="theme_title">Téma</string>
<string name="download_path_audio_title">Hangfájlok letöltési mappája</string>
<string name="download_path_audio_summary">A letöltött hangfájlok itt találhatóak</string>
<string name="download_path_audio_summary">A letöltött hangfájlok itt lesznek tárolva</string>
<string name="detail_likes_img_view_description">Tetszik</string>
<string name="detail_dislikes_img_view_description">Nem tetszik</string>
<string name="detail_thumbnail_view_description">Videó lejátszása, hossz:</string>
<string name="detail_uploader_thumbnail_view_description">Fetöltő profilképe</string>
<string name="detail_uploader_thumbnail_view_description">Fetöltő profilképének bélyegképe</string>
<string name="content">Tartalom</string>
<string name="show_age_restricted_content_title">Korhatáros tartalom megjelenítése</string>
<string name="general_error">Hiba</string>
<string name="content_not_available">A tartalom nem elérhető</string>
<string name="content_not_available">A tartalom nem érhető el</string>
<string name="duration_live">Élő</string>
<string name="error_snackbar_action">Jelentés</string>
<string name="what_device_headline">Információ:</string>
<string name="what_happened_headline">Ez történt:</string>
<string name="your_comment">Megjegyzésed (angolul):</string>
<string name="your_comment">Az Ön megjegyzése (angolul):</string>
<string name="error_details_headline">Részletek:</string>
<string name="error_snackbar_message">Sajnos hiba történt.</string>
<string name="error_snackbar_message">Elnézet, valami balul sült el.</string>
<string name="sorry_string">Elnézést, ennek nem kellett volna megtörténnie.</string>
<string name="error_report_button_text">Hiba bejelentése e-mailben</string>
<string name="could_not_setup_download_menu">Nem sikerült a letöltés menü beállítása</string>
<string name="youtube_signature_deobfuscation_error">Nem sikerült a videó URL aláírás azonosítása</string>
<string name="could_not_setup_download_menu">Nem sikerült a letöltési menü beállítása</string>
<string name="youtube_signature_deobfuscation_error">Nem sikerült a videó URL aláírásának feloldása</string>
<string name="retry">Újra</string>
<string name="video">Videó</string>
<string name="audio">Audio</string>
<string name="main_bg_subtitle">A kezdéshez koppints a \"Keresés\"-re.</string>
<string name="could_not_load_thumbnails">Nem sikerült az összes előnézeti kép betöltése</string>
<string name="parsing_error">Nem sikerült a weblap betöltése</string>
<string name="audio">Hang</string>
<string name="main_bg_subtitle">A kezdéshez koppintson a nagyítóra.</string>
<string name="could_not_load_thumbnails">Nem sikerült az összes bélyegkép betöltése</string>
<string name="parsing_error">Nem sikerült a weblap feldolgozása</string>
<string name="downloads">Letöltések</string>
<string name="downloads_title">Letöltések</string>
<string name="error_report_title">Hibabejelentés</string>
<string name="start">Indít</string>
<string name="pause">Szünet</string>
<string name="error_report_title">Hibajelentés</string>
<string name="start">Indítás</string>
<string name="pause">Szüneteltetés</string>
<string name="delete">Törlés</string>
<string name="checksum">Ellenőrző összeg</string>
<string name="checksum">Ellenőrzőösszeg</string>
<string name="ok">Rendben</string>
<string name="msg_name">Fájlnév</string>
<string name="msg_threads">Threadek</string>
<string name="msg_threads">Szálak</string>
<string name="msg_error">Hiba</string>
<string name="msg_running">NewPipe letöltés folyamatban</string>
<string name="msg_running_detail">Katt a részletekért</string>
<string name="msg_wait">Kérlek várj</string>
<string name="msg_running_detail">Koppintson a részletekért</string>
<string name="msg_wait">Kis türelmet</string>
<string name="msg_copied">Vágólapra másolva</string>
<string name="no_available_dir">Kérlek, válassz egy létező könyvtárat a letöltésekhez</string>
<string name="no_available_dir">Adjon meg később egy letöltési mappát a beállításokban</string>
<string name="channel_unsubscribed">Csatornáról leiratkozva</string>
<string name="subscription_change_failed">Nem sikerült megváltoztatni a feliratkozást</string>
<string name="subscription_update_failed">Nem sikerült frissíteni a feliratkozást</string>
@ -86,25 +86,25 @@
<string name="fragment_feed_title">Újdonságok</string>
<string name="controls_background_title">Háttér</string>
<string name="controls_popup_title">Felugró ablak</string>
<string name="no_player_found_toast">Nem található stream lejátszó alkalmazás (feltelepítheted a VLC-t a lejátszáshoz).</string>
<string name="no_player_found_toast">Nem található lejátszó a közvetítéshez (feltelepítheti a VLC-t a lejátszáshoz).</string>
<string name="open_in_popup_mode">Megnyitás felugró módban</string>
<string name="use_external_video_player_summary">Néhány felbontásnál eltávolítja a hangot</string>
<string name="subscribe_button_title">Feliratkozás</string>
<string name="subscribed_button_title">Feliratkozva</string>
<string name="show_info">Több infó</string>
<string name="default_popup_resolution_title">Alapértelmezett felugró ablak felbontása</string>
<string name="show_higher_resolutions_title">Mutassa a magasabb felbontásokat</string>
<string name="show_higher_resolutions_summary">Csak néhány eszköz tud lejátszani 2K/4K videókat</string>
<string name="default_video_format_title">Alapértelmezett videó formátum</string>
<string name="show_info">További infó</string>
<string name="default_popup_resolution_title">Felugró ablak alapértelmezett felbontása</string>
<string name="show_higher_resolutions_title">Magasabb felbontások megjelenítése</string>
<string name="show_higher_resolutions_summary">Csak bizonyos eszközök tudnak 2K/4K-s videókat lejátszani</string>
<string name="default_video_format_title">Alapértelmezett videoformátum</string>
<string name="black_theme_title">Fekete</string>
<string name="popup_remember_size_pos_title">Jegyezze meg a felugró ablak helyét és méretét</string>
<string name="popup_remember_size_pos_summary">Jegyezze meg a felugró ablak előző helyét és méretét</string>
<string name="popup_remember_size_pos_title">Felugró ablak tulajdonságainak megjegyzése</string>
<string name="popup_remember_size_pos_summary">A felugró ablak előző helyének és méretének megjegyzése</string>
<string name="show_search_suggestions_title">Keresési javaslatok</string>
<string name="show_search_suggestions_summary">Mutasson javaslatokat keresés közben</string>
<string name="show_search_suggestions_summary">Válassza ki a keresési javaslatokat keresés közben</string>
<string name="enable_search_history_title">Keresési előzmények</string>
<string name="enable_watch_history_title">Előzmények</string>
<string name="enable_watch_history_summary">Megnézett videók nyomon követése</string>
<string name="resume_on_audio_focus_gain_summary">Lejátszás folytatása félbeszakítás után (pl.: telefonhívás)</string>
<string name="enable_watch_history_title">Megtekintési előzmények</string>
<string name="enable_watch_history_summary">Megtekintett videók nyomon követése</string>
<string name="resume_on_audio_focus_gain_summary">Lejátszás folytatása félbeszakítások után (például telefonhívás)</string>
<string name="settings_category_player_title">Lejátszó</string>
<string name="settings_category_player_behavior_title">Működés</string>
<string name="settings_category_history_title">Előzmények és gyorsítótár</string>
@ -119,32 +119,32 @@
<string name="play_all">Összes lejátszása</string>
<string name="always">Mindig</string>
<string name="just_once">Csak egyszer</string>
<string name="notification_channel_name">NewPipe Értesítés</string>
<string name="notification_channel_description">Értesítések a NewPipe háttér- és felugró ablak lejátszójához</string>
<string name="notification_channel_name">NewPipe értesítés</string>
<string name="notification_channel_description">Értesítések a NewPipe lejátszójához</string>
<string name="unknown_content">[Ismeretlen]</string>
<string name="import_data_title">Adatbázis importálása</string>
<string name="export_data_title">Adatbázis exportálása</string>
<string name="import_data_summary">Felülírja a jelenlegi előzményeket, feliratkozásokat, lejátszási listákat és (választható) beállításokat</string>
<string name="import_data_summary">Felülírja a jelenlegi előzményeket, feliratkozásokat, lejátszási listákat és (választhatóan) a beállításokat</string>
<string name="export_data_summary">Előzmények, feliratkozások, lejátszási listák és beállítások exportálása</string>
<string name="app_ui_crash">Alkalmazás/Kezelő felület összeomlott</string>
<string name="player_stream_failure">Videó lejátszása sikertelen</string>
<string name="external_player_unsupported_link_type">A külső lejátszó nem támogatja az ilyen típusú linkeket</string>
<string name="video_streams_empty">Nem található videó formátum</string>
<string name="audio_streams_empty">Nem található hang csatorna</string>
<string name="app_ui_crash">Az alkalmazás/kezelőfelület összeomlott</string>
<string name="player_stream_failure">Nem sikerült a videó lejátszása</string>
<string name="external_player_unsupported_link_type">A külső lejátszó nem támogatja az ilyen típusú hivatkozásokat</string>
<string name="video_streams_empty">Nem található videó adatfolyam</string>
<string name="audio_streams_empty">Nem található hang adatfolyam</string>
<string name="info_labels">Mi:\\nKérés:\\nTartalom nyelve:\\nTartalom származási országa:\\nAlkalmazás nyelve:\\nSzolgáltatás:\\nGMT idő:\\nCsomag:\\nVerzió:\\nOperációs rendszer verzió:</string>
<string name="search_no_results">Nincs találat</string>
<string name="controls_download_desc">Adatfolyam fájl letöltése</string>
<string name="controls_download_desc">Közvetítési fájl letöltése</string>
<string name="controls_add_to_playlist_title">Hozzáadás ehhez</string>
<string name="use_inexact_seek_title">Gyorsabb, de pontatlan tekerés használata</string>
<string name="use_inexact_seek_summary">A pontatlan tekerés lehetővé teszi, hogy gyorsabban ugorjon a pozíciókra, de kevesebb pontossággal. Az 5, 15, vagy 25 másodperces tekerés nem működik ebben a módban.</string>
<string name="use_inexact_seek_summary">A pontatlan tekerés lehetővé teszi, hogy gyorsabban ugorjon a pozíciókra, de kisebb pontossággal. Az 5, 15, vagy 25 másodperces tekerés nem működik ebben a módban.</string>
<string name="download_thumbnail_title">Bélyegképek betöltése</string>
<string name="download_thumbnail_summary">Kapcsold ki, hogy a megelőzzed bélyegképek betöltését, így csökkentve az adat és memória használatot. Ennek az értéknek a megváltoztatása törli a memóriában és a meghajtón lévő bélyegkép gyorsítótárat.</string>
<string name="download_thumbnail_summary">Kapcsolja ki, hogy a megelőzze a bélyegképek betöltését, így csökkentve az adat- és memóriahasználatot. A megváltoztatása törli a memóriában és a meghajtón lévő képgyorsítótárat.</string>
<string name="thumbnail_cache_wipe_complete_notice">A bélyegkép gyorsítótár törölve</string>
<string name="metadata_cache_wipe_title">Gyorsítótárazott metaadat törlése</string>
<string name="metadata_cache_wipe_summary">Minden gyorsítótárazott weboldal adat törlése</string>
<string name="metadata_cache_wipe_complete_notice">A metaadat gyorsítótár törölve lett</string>
<string name="auto_queue_title">Következő videó automatikus lejátszása</string>
<string name="enable_search_history_summary">Keresési előzmények tárolása az eszközön</string>
<string name="metadata_cache_wipe_title">Gyorsítótárazott metaadatok törlése</string>
<string name="metadata_cache_wipe_summary">Minden gyorsítótárazott weboldaladat törlése</string>
<string name="metadata_cache_wipe_complete_notice">A metaadatok gyorsítótára törölve lett</string>
<string name="auto_queue_title">Következő videó automatikus sorba állítása</string>
<string name="enable_search_history_summary">Keresési előzmények helyi tárolása</string>
<string name="channels">Csatornák</string>
<string name="playlists">Lejátszási listák</string>
<string name="tracks">Zeneszámok</string>
@ -153,26 +153,26 @@
<string name="switch_to_background">Folytatás a háttérben</string>
<string name="switch_to_popup">Folytatás felugró ablakban</string>
<string name="clear_views_history_title">Megtekintési előzmények törlése</string>
<string name="clear_views_history_summary">Eltávolítja a megtekintési előzményeket és a lejátszási pozíciókat</string>
<string name="delete_view_history_alert">Törlöd az összes megtekintési előzményt\?</string>
<string name="watch_history_deleted">Megtekintési előzmények törölve.</string>
<string name="clear_views_history_summary">Törli a megtekintési előzményeket és a lejátszási pozíciókat</string>
<string name="delete_view_history_alert">Törli az összes megtekintési előzményt\?</string>
<string name="watch_history_deleted">Megtekintési előzmények törölve</string>
<string name="clear_search_history_title">Keresési előzmények törlése</string>
<string name="clear_search_history_summary">Eltávolítja a kereséshez használt kifejezéseket az előzményekből</string>
<string name="delete_search_history_alert">Törlöd az összes keresési előzményt\?</string>
<string name="search_history_deleted">Keresési előzmények törölve.</string>
<string name="player_unrecoverable_failure">Lejátszási hiba történt</string>
<string name="player_recoverable_failure">Lejátszási hiba helyreállítása</string>
<string name="clear_search_history_summary">Eltávolítja a keresési kulcsszavakat az előzményekből</string>
<string name="delete_search_history_alert">Törli az összes keresési előzményt\?</string>
<string name="search_history_deleted">Keresési előzmények törölve</string>
<string name="player_unrecoverable_failure">Helyreállíthatatlan lejátszóhiba történt</string>
<string name="player_recoverable_failure">Lejátszóhiba helyreállítása</string>
<string name="invalid_directory">Nincs ilyen mappa</string>
<string name="invalid_source">Nincs ilyen fájl vagy tartalom forrás</string>
<string name="invalid_file">A fájl nem létezik vagy jogosultság az olvasáshoz és íráshoz hiányzik</string>
<string name="file_name_empty_error">A fájl neve nem lehet üres</string>
<string name="invalid_source">Nincs ilyen fájl- vagy tartalomforrás</string>
<string name="invalid_file">A fájl nem létezik, vagy hiányzik az olvasási vagy írási jogosultság</string>
<string name="file_name_empty_error">A fájlnév nem lehet üres</string>
<string name="error_occurred_detail">Hiba történt: %1$s</string>
<string name="no_streams_available_download">Nincs letölthető adatforrás</string>
<string name="no_streams_available_download">Nincs letölthető adatfolyam</string>
<string name="empty_subscription_feed_subtitle">Nincs itt semmi pár tücskön kívül</string>
<string name="detail_drag_description">Húzza az átrendezéshez</string>
<string name="short_thousand">e</string>
<string name="short_million">M</string>
<string name="short_billion">Mrd</string>
<string name="short_million">m</string>
<string name="short_billion">M</string>
<string name="no_subscribers">Nincs feliratkozó</string>
<plurals name="subscribers">
<item quantity="one">%s feliratkozó</item>
@ -186,7 +186,7 @@
<string name="no_videos">Nincs videó</string>
<plurals name="videos">
<item quantity="one">%s videó</item>
<item quantity="other">%s videók</item>
<item quantity="other">%s videó</item>
</plurals>
<string name="create">Létrehozás</string>
<string name="rename">Átnevezés</string>
@ -194,107 +194,108 @@
\na felugró ablakban történő megnyitáshoz</string>
<string name="one_item_deleted">1 elem törölve.</string>
<string name="title_activity_recaptcha">reCAPTCHA rejtvény</string>
<string name="recaptcha_request_toast">reCAPTCHA rejtvény igényelve</string>
<string name="recaptcha_request_toast">reCAPTCHA rejtvény kérve</string>
<string name="settings_category_downloads_title">Letöltés</string>
<string name="settings_file_charset_title">Fájlnevekben engedélyezett karakterek</string>
<string name="settings_file_replacement_character_summary">Érvénytelen karakterek ezzel az értékkel kerülnek helyettesítésre</string>
<string name="settings_file_replacement_character_summary">Az érvénytelen karakterek erre az értékre lesznek lecserélve</string>
<string name="settings_file_replacement_character_title">Csere karakter</string>
<string name="charset_letters_and_digits">Betűk és számok</string>
<string name="charset_most_special_characters">Legtöbb speciális karakter</string>
<string name="toast_no_player">Nincs a fájl lejátszásához szükséges alkalmazás telepítve</string>
<string name="title_activity_about">A NewPipe alkalmazásról</string>
<string name="tab_about">Az alkalmazásról</string>
<string name="tab_licenses">Engedélyek</string>
<string name="app_description">Ingyenes, egyszerű streamelés Androidon.</string>
<string name="title_activity_about">A NewPipe névjegye</string>
<string name="tab_about">Névjegy</string>
<string name="tab_licenses">Licencek</string>
<string name="app_description">Szabad, egyszerű közvetítésnézés Androidon.</string>
<string name="contribution_title">Közreműködés</string>
<string name="contribution_encouragement">Legyen ötleted a fordítással, a megjelenéssel, a forrás kód tisztításával vagy komolyabb átszervezésével kapcsolatban, bármilyen segítséget szívesen fogadunk. Járulj hozzá az alkalmazás fejlesztéséhez!</string>
<string name="view_on_github">Megtekintés GitHubon</string>
<string name="contribution_encouragement">Legyen ötleted a fordítással, a dizájnnal, a forráskód tisztításával vagy egy komolyabb átszervezésével kapcsolatban, bármilyen segítséget szívesen fogadunk. Minél több minden készül el, annál jobb lesz!</string>
<string name="view_on_github">Megtekintés a GitHubon</string>
<string name="donation_title">Adományozás</string>
<string name="donation_encouragement">A NewPipe alkalmazást önkéntesek fejlesztik az ő szabadidejükben, hogy a lehető legjobb felhasználói élményt hozzák el neked. Járulj hozzá, hogy segítsd a fejlesztőket amíg ők egy csésze kávét szürcsölnek, hogy még jobbá tehessük a NewPipe-ot.</string>
<string name="donation_encouragement">A NewPipe alkalmazást önkéntesek fejlesztik a szabadidejükben, hogy a lehető legjobb felhasználói élményt nyújtsák. Járuljon hozzá, hogy a fejlesztők még jobbá tegyék alkalmazást, miközben egy csésze kávét szürcsölnek.</string>
<string name="give_back">Hozzájárulás</string>
<string name="website_title">Honlap</string>
<string name="website_encouragement">Látogasd meg a NewPipe honlapját további információkért és hírekért!</string>
<string name="website_encouragement">Látogassa meg a NewPipe honlapját további információkért és hírekért.</string>
<string name="privacy_policy_title">A NewPipe adatvédelmi irányelvei</string>
<string name="privacy_policy_encouragement">A NewPipe projekt komolyan veszi az adataid védelmét. Az alkalmazás nem gyűjt semmilyen adatot a beleegyezésed nélkül.
<string name="privacy_policy_encouragement">A NewPipe projekt komolyan veszi az adatvédelmét. Az alkalmazás nem gyűjt semmilyen adatot a beleegyezése nélkül.
\nA NewPipe adatvédelmi irányelve részletesen elmagyarázza, mely adatok kerülnek elküldésre és tárolásra az alkalmazás összeomlásának jelentésekor.</string>
<string name="read_privacy_policy">Az adatvédelmi irányelvek elolvasása</string>
<string name="read_privacy_policy">Adatvédelmi irányelvek elolvasása</string>
<string name="app_license_title">A NewPipe licence</string>
<string name="read_full_license">Licenc elolvasása</string>
<string name="title_activity_history">Előzmények</string>
<string name="action_history">Előzmények</string>
<string name="delete_item_search_history">Törölni kívánja ezt az elemet a keresési előzmények közül\?</string>
<string name="delete_item_search_history">Törli ezt az elemet a keresési előzmények közül\?</string>
<string name="title_last_played">Utoljára lejátszott</string>
<string name="title_most_played">Legtöbbet lejátszott</string>
<string name="main_page_content">Főoldal tartalma</string>
<string name="blank_page_summary">Üres oldal</string>
<string name="kiosk_page_summary">Újságárus oldal</string>
<string name="channel_page_summary">Csatorna oldal</string>
<string name="select_a_channel">Csatorna választása</string>
<string name="no_channel_subscribed_yet">Még nincs csatorna feliratkozás</string>
<string name="select_a_kiosk">Újságárus választása</string>
<string name="channel_page_summary">Csatornaoldal</string>
<string name="select_a_channel">Válasszon egy csatornát</string>
<string name="no_channel_subscribed_yet">Még nincs csatornafeliratkozás</string>
<string name="select_a_kiosk">Válasszon egy újságárust</string>
<string name="export_complete_toast">Exportálva</string>
<string name="import_complete_toast">Importálva</string>
<string name="no_valid_zip_file">Nem érvényes ZIP fájl</string>
<string name="no_valid_zip_file">Nem érvényes ZIP-fájl</string>
<string name="could_not_import_all_files">Figyelmeztetés: nem sikerült az összes fájl importálása.</string>
<string name="override_current_data">Ez felül fogja írni a jelenlegi beállításokat.</string>
<string name="import_settings">A beállításokat is importálni kívánja\?</string>
<string name="import_settings">A beállításokat is importálja\?</string>
<string name="trending">Felkapott</string>
<string name="top_50">Top 50</string>
<string name="new_and_hot">Új és friss</string>
<string name="new_and_hot">Új és népszerű</string>
<string name="play_queue_remove">Eltávolítás</string>
<string name="play_queue_stream_detail">Részletek</string>
<string name="play_queue_audio_settings">Hang beállítások</string>
<string name="play_queue_audio_settings">Hangbeállítások</string>
<string name="preferred_open_action_settings_summary">Alapértelmezett tevékenység „%s” típusú tartalom megnyitásakor</string>
<string name="video_player">Videólejátszó</string>
<string name="background_player">Lejátszás háttérben</string>
<string name="popup_player">Felugró ablakos lejátszás</string>
<string name="always_ask_open_action">Mindig kérdezz</string>
<string name="always_ask_open_action">Mindig kérdezzen</string>
<string name="preferred_player_fetcher_notification_title">Információk gyűjtése…</string>
<string name="preferred_player_fetcher_notification_message">Kért tartalom betöltése</string>
<string name="create_playlist">Új lejátszási lista</string>
<string name="rename_playlist">Átnevezés</string>
<string name="name">Név</string>
<string name="add_to_playlist">Lejátszási listához adás</string>
<string name="set_as_playlist_thumbnail">Beállítás lejátszási lista indexképeként</string>
<string name="unbookmark_playlist">Könyvjelző törlése</string>
<string name="delete_playlist_prompt">Törlődjön ez a lejátszási lista\?</string>
<string name="playlist_creation_success">Lejátszási listsa létrehozva</string>
<string name="playlist_add_stream_success">Hozzáadva lejátszási listához</string>
<string name="playlist_thumbnail_change_success">Lejátszási lista előképe megváltozott.</string>
<string name="caption_none">Felirat kikapcsolva</string>
<string name="resize_fit">Illeszkedés</string>
<string name="set_as_playlist_thumbnail">Beállítás a lejátszási lista bélyegképeként</string>
<string name="unbookmark_playlist">Könyvjelző eltávolítása</string>
<string name="delete_playlist_prompt">Törli ezt a lejátszási listát\?</string>
<string name="playlist_creation_success">Lejátszási lista létrehozva</string>
<string name="playlist_add_stream_success">Lejátszási listához adva</string>
<string name="playlist_thumbnail_change_success">A lejátszási lista bélyegképe megváltozott.</string>
<string name="caption_none">Nincs felirat</string>
<string name="resize_fit">Igazítás</string>
<string name="resize_fill">Kitöltés</string>
<string name="resize_zoom">Közelítés</string>
<string name="resize_zoom">Nagyítás</string>
<string name="caption_auto_generated">Automatikusan létrehozott</string>
<string name="caption_setting_title">Feliratok</string>
<string name="caption_setting_description">Feliratok méretének és hátterének stílusbeli módosítása. A módosítások életbelépésehez az alkalmazás újraindítása szükséges.</string>
<string name="import_title">Import</string>
<string name="caption_setting_description">Feliratok méretének és hátterének stílusbeli módosítása. A módosítások életbe lépésehez az alkalmazás újraindítása szükséges.</string>
<string name="import_title">Importálás</string>
<string name="import_from">Importálás a következőből</string>
<string name="export_to">Exportálás a következőbe</string>
<string name="import_ongoing">Importálás…</string>
<string name="export_ongoing">Exportálás…</string>
<string name="import_file_title">Fájl importálása</string>
<string name="previous_export">Előző exportálás</string>
<string name="subscriptions_import_unsuccessful">Sikertelen a feliratkozások importálása</string>
<string name="subscriptions_export_unsuccessful">Sikertelen a feliratkozások exportálása</string>
<string name="import_youtube_instructions">YouTube feliratkozások importálása Google takeout-ból:
<string name="subscriptions_import_unsuccessful">A feliratkozások importálása nem sikerült</string>
<string name="subscriptions_export_unsuccessful">A feliratkozások exportálása nem sikerült</string>
<string name="import_youtube_instructions">YouTube feliratkozások importálása a Google Takeoutból:
\n
\n1. Navigálj erre az oldalra: %1$s
\n2. Jelentkezz be
\n3. Kattints a \"All data included/Minden adat\"-ra, majd a \"Deselect all/MInden kijelölés megszüntetése\" gombra, majd válaszd ki a \"subscriptions/feliratkozások\" és kattints az \"OK\"-ra
\n4. Kattints a \"Next step/Következő lépés\", majd az \"Create export/Export létrehozása\" gombra
\n5. Kattints a \"Download/Letöltés\" gombra, mikor megjelenik, majd
\n6. A letöltött zip fájlból csomagold ki a .json fájlt (általában: \"YouTube and YouTube Music/subscriptions/subscriptions.json\"), majd importáld itt.</string>
<string name="import_soundcloud_instructions">Importálja SoundCloud profilját az URL vagy az azonosítójának begépelésével:
\n1. Navigáljon erre az oldalra: %1$s
\n2. Jelentkezzen be, ha kérik
\n3. Kattintson „Az összes adatot tartalmazza” gombra, majd a „Kijelölések megszüntetése” gombra, majd válassza ki a „feliratkozások” lehetőséget és kattintson az „OK” gombra
\n4. Kattintson a „Következő lépés”, majd az \"Exportálás indítása” gombra
\n5. Kattintson a „Letöltés” gombra, amikor megjelenik,
\n6. Kattintson a lenti FÁJL IMPORTÁLÁSA gombra, és válassza ki a letöltött ZIP-fájlt
\n7. [Ha a ZIP-fájl importálása nem sikerül] Bontsa ki a .csv fájlt (általában: „YouTube és YouTube Music/feliratkozások/feliratkozások.csv\"), majd kattintson lent a FÁJL IMPORTÁLÁSA gombra, és válassza az exportált CSV-fájlt</string>
<string name="import_soundcloud_instructions">SoundCloud-profil importálása az URL vagy az azonosítójának begépelésével:
\n
\n1. Az oldal mobileszközökön nem elérhető, így „asztali böngésző mód” szükséges
\n2. Navigáljon erre az oldalra: %1$s
\n3. Jelentkezzen be
\n1. A webböngészőben engedélyezze az „asztali módot” (az oldal nem érhető el mobileszközökön)
\n2. Navigáljon erre az URL-re: %1$s
\n3. Jelentkezzen be, ha kéri
\n4. Másolja ki a profil URL-t, ahova át lett irányítva.</string>
<string name="import_soundcloud_instructions_hint">azonosítód, soundcloud.com/azonosítód</string>
<string name="import_network_expensive_warning">Ez a művelet adatforgalom igényes lehet.
<string name="import_soundcloud_instructions_hint">saját azonosítója, soundcloud.com/azonosító</string>
<string name="import_network_expensive_warning">Ez a művelet adatforgalom-igényes lehet.
\n
\nFolytatni kívánja\?</string>
\nBiztos, hogy folytatja\?</string>
<string name="playback_tempo">Ütem</string>
<string name="playback_pitch">Hangmagasság</string>
<string name="skip_silence_checkbox">Előrepörgetés csend alatt</string>
@ -303,142 +304,143 @@
<string name="accept">Elfogadás</string>
<string name="decline">Elutasítás</string>
<string name="limit_data_usage_none_description">Nincs korlát</string>
<string name="limit_mobile_data_usage_title">Felbontás korlátozása mobilinternet használata esetén</string>
<string name="minimize_on_exit_summary">Művelet alkalmazás váltásakor a fő videólejátszóról — %s</string>
<string name="limit_mobile_data_usage_title">Felbontás korlátozása mobil adatkapcsolat használata esetén</string>
<string name="minimize_on_exit_summary">A fő videólejátszóról más alkalmazásra történő váltáskor teendő művelet — %s</string>
<string name="minimize_on_exit_none_description">Ne tegyen semmit</string>
<string name="minimize_on_exit_background_description">Lejátszás folytatása a háttérben</string>
<string name="minimize_on_exit_popup_description">Lejátszás folytatása felugró ablakban</string>
<string name="resume_on_audio_focus_gain_title">Lejátszás folytatása</string>
<string name="show_hold_to_append_title">Mutassa a \"Tartsa lenyomva a hozzáadáshoz\" tippet</string>
<string name="show_hold_to_append_title">A „Tartsa lenyomva a sorba állításhoz\" tipp megjelenítése</string>
<string name="unsubscribe">Leiratkozás</string>
<string name="tab_choose">Válassz fület</string>
<string name="show_comments_title">Kommentek mutatása</string>
<string name="show_comments_summary">Kapcsold ki a kommentek elrejtéséhez</string>
<string name="default_content_country_title">Alapértelmezett ország tartalom</string>
<string name="tab_choose">Válasszon lapot</string>
<string name="show_comments_title">Megjegyzések megjelenítése</string>
<string name="show_comments_summary">Kapcsolja ki a megjegyzések elrejtéséhez</string>
<string name="default_content_country_title">Tartalom alapértelmezett országa</string>
<string name="switch_to_main">Folytatás főnézetben</string>
<string name="dismiss">Figyelmen kívül hagy</string>
<string name="bookmark_playlist">Lejátszási lista könyvjelzők kö</string>
<string name="auto_queue_summary">Hasonló videó beadása az utolsó videó után egy nem ismétlődő sorban</string>
<string name="dismiss">Eltüntetés</string>
<string name="bookmark_playlist">Lejátszási lista könyvjelzőzése</string>
<string name="auto_queue_summary">Egy hasonló videó hozzáadása a befejeződő (nem ismétlődő) lejátszási sorhoz</string>
<string name="enqueue">Sor</string>
<string name="overwrite_failed">a fájl nem írható felül</string>
<string name="seek_duration_title">Az előre- és visszatekerés időtartama</string>
<string name="enable_playback_resume_summary">Utolsó lejátszási pozíció visszaállítása</string>
<string name="enable_playback_resume_title">Lejátszás folytatása</string>
<string name="app_update_notification_channel_description">Jelentés új NewPipe verzióról</string>
<string name="app_update_notification_channel_name">Alkalmazás-frissítés jelzése</string>
<string name="file_deleted">File törölve</string>
<string name="app_update_notification_channel_description">Értesítések az új NewPipe verziókról</string>
<string name="app_update_notification_channel_name">Alkalmazásfrissítés értesítése</string>
<string name="file_deleted">Fájl törölve</string>
<string name="settings_category_updates_title">Frissítések</string>
<string name="show_hold_to_append_summary">Tipp mutatása háttér vagy felbukkanó gomb megnyomásakor a videó részletei oldalon</string>
<string name="show_hold_to_append_summary">Tipp megjelenítése, ha megnyomja a hátteret vagy a felugró gombot a videó részleteinél</string>
<string name="autoplay_title">Automatikus lejátszás</string>
<string name="settings_category_clear_data_title">Adatok törlése</string>
<string name="enable_playback_state_lists_summary">Lejátszási pozíciók mutatása a listákban</string>
<string name="enable_playback_state_lists_summary">Lejátszási pozíciók megjelenítése a listákban</string>
<string name="enable_playback_state_lists_title">Pozíciók a listákban</string>
<string name="brightness_gesture_control_summary">Gesztusvezérlés használata fényerő szabályzásra</string>
<string name="brightness_gesture_control_summary">Gesztusok használata a fényerő szabályozásához</string>
<string name="brightness_gesture_control_title">Fényerő gesztus</string>
<string name="volume_gesture_control_summary">Gesztusvezérlés használata hangerő szabályzásra</string>
<string name="volume_gesture_control_summary">Gesztusok használata a lejátszó hangerejének szabályzásához</string>
<string name="volume_gesture_control_title">Hangerő gesztus</string>
<string name="downloads_storage_ask_summary">A rendszer megkérdezi, hogy hova mentse el az egyes letöltéseket</string>
<string name="downloads_storage_ask_summary">Meg fogja kérdezni, hogy hova mentse el az egyes letöltéseket.
\nEngedélyezze a rendszermappa-választót (SAF), ha külső SD-kártyára akar letölteni</string>
<string name="downloads_storage_ask_title">Kérdezze meg, hova töltse le</string>
<string name="pause_downloads">Letöltések szüneteltetése</string>
<string name="start_downloads">Letöltések indítása</string>
<string name="enable_queue_limit_desc">Egyszerre egy letöltés fog futni ugyanabban az időben</string>
<string name="enable_queue_limit">Korlátozza a letöltési sort</string>
<string name="close">Bezár</string>
<string name="pause_downloads_on_mobile_desc">Hasznos, amikor átvált a mobil adatokra, bár néhány letöltést nem lehet felfüggeszteni</string>
<string name="pause_downloads_on_mobile">Megszakítás a mért hálózatokon</string>
<string name="max_retry_desc">A letöltés megszakítása előtti kísérletek maximális száma</string>
<string name="max_retry_msg">Maximális próbálkozások</string>
<string name="stop">Állj</string>
<string name="enable_queue_limit_desc">Egyszerre csak egy letöltés fog futni</string>
<string name="enable_queue_limit">Letöltési sor korlátozása</string>
<string name="close">Bezárás</string>
<string name="pause_downloads_on_mobile_desc">Hasznos, ha mobil adatkapcsolatra vált, bár néhány letöltést nem lehet felfüggeszteni</string>
<string name="pause_downloads_on_mobile">Félbehagyás a forgalomkorlátos hálózatokon</string>
<string name="max_retry_desc">A letöltés megszakítása előtti kísérletek legnagyobb száma</string>
<string name="max_retry_msg">Próbálkozások legnagyobb száma</string>
<string name="stop">Leállítás</string>
<string name="delete_downloaded_files">Letöltött fájlok törlése</string>
<string name="confirm_prompt">Törli a letöltési előzményeket, vagy törli az összes letöltött fájlt\?</string>
<string name="clear_download_history">Letöltési előzmények törlése</string>
<string name="error_download_resource_gone">A letöltést nem lehet visszaállítani</string>
<string name="error_timeout">Kapcsolat időtúllépés</string>
<string name="error_progress_lost">A folyamat elveszett, mert a fájlt törölték</string>
<string name="error_download_resource_gone">A letöltést nem lehet helyrehozni</string>
<string name="error_timeout">Kapcsolati időtúllépés</string>
<string name="error_progress_lost">Az előrehaladás elveszett, mert a fájlt törölték</string>
<string name="error_insufficient_storage">Nincs hely az eszközön</string>
<string name="error_postprocessing_stopped">NewPipe leállt a fájl feldolgozása közben</string>
<string name="error_postprocessing_stopped">A NewPipe leállt a fájl feldolgozása közben</string>
<string name="error_postprocessing_failed">Utófeldolgozás sikertelen</string>
<string name="error_http_not_found">Nincs talalat</string>
<string name="error_http_unsupported_range">A szerver nem fogad többszálú letöltést, próbálkozzon újra @ string / msg_threads = 1</string>
<string name="error_http_no_content">A szerver nem küld adatokat</string>
<string name="error_connect_host">Nem lehet csatlakozni a szerverhez</string>
<string name="error_unknown_host">A szerver nem talalható</string>
<string name="error_http_unsupported_range">A kiszolgáló nem fogad többszálú letöltést, próbálkozzon újra ezzel: @string/msg_threads = 1</string>
<string name="error_http_no_content">A kiszolgáló nem küld adatokat</string>
<string name="error_connect_host">Nem lehet csatlakozni a kiszolgálóhoz</string>
<string name="error_unknown_host">A kiszolgáló nem található</string>
<string name="error_ssl_exception">Nem sikerült biztonságos kapcsolatot létesíteni</string>
<string name="error_path_creation">A célmappa nem hozható létre</string>
<string name="error_file_creation">A fájlt nem lehet létrehozni</string>
<string name="show_error">Hiba megjelenítése</string>
<string name="download_already_pending">Ezzel a névvel egy letötés már várakozás alatt áll</string>
<string name="download_already_pending">Ezzel a névvel egy letöltés már várakozik</string>
<string name="download_already_running">Ezzel a névvel egy letöltés már folyamatban van</string>
<string name="overwrite_finished_warning">Az ilyen névvel letöltött fájl már létezik</string>
<string name="overwrite_unrelated_warning">Az ilyen névű fájl már létezik</string>
<string name="overwrite">Átír</string>
<string name="generate_unique_name">Generáljon egyedi nevet</string>
<string name="overwrite_finished_warning">Ilyen névű letöltött fájl már létezik</string>
<string name="overwrite_unrelated_warning">Ilyen névű fájl már létezik</string>
<string name="overwrite">Felülírás</string>
<string name="generate_unique_name">Egyedi név előállítása</string>
<string name="download_failed">Letöltés sikertelen</string>
<string name="recovering">Helyrehozás</string>
<string name="post_processing">Utófeldolgozás</string>
<string name="queued">Sorban álló</string>
<string name="paused">Szünet</string>
<string name="recovering">helyrehozás</string>
<string name="post_processing">utófeldolgozás</string>
<string name="queued">sorba állítva</string>
<string name="paused">szüneteltetve</string>
<string name="missions_header_pending">Függőben lévő</string>
<string name="missions_header_finished">Befejezett</string>
<string name="app_update_notification_content_text">Kattints a letöltéshez</string>
<string name="app_update_notification_content_title">NewPipe frissítés elérhető!</string>
<string name="auto">Auto</string>
<string name="app_update_notification_content_text">Kattintson a letöltéshez</string>
<string name="app_update_notification_content_title">NewPipe frissítés érhető el!</string>
<string name="auto">Automatikus</string>
<string name="grid">Rács</string>
<string name="list">Lista</string>
<string name="list_view_mode">Lista nézet</string>
<string name="missing_file">File áthelyezve vagy törölve</string>
<string name="download_to_sdcard_error_message">Külső SD-kártyára mentés nem lehetséges. Visszaállítsuk a letöltési mappa helyét\?</string>
<string name="download_to_sdcard_error_title">Külső tárhely nem elérhető</string>
<string name="watch_history_states_deleted">Lejátszási pozíciók törölve.</string>
<string name="delete_playback_states_alert">Összes lejátszási pozíció törlése\?</string>
<string name="missing_file">A fájl áthelyezve vagy törölve</string>
<string name="download_to_sdcard_error_message">A külső SD-kártyára történő mentés nem lehetséges. Visszaállítja a letöltési mappa helyét\?</string>
<string name="download_to_sdcard_error_title">A külső tárhely nem érhető el</string>
<string name="watch_history_states_deleted">Lejátszási pozíciók törölve</string>
<string name="delete_playback_states_alert">Törli az összes lejátszási pozíciót\?</string>
<string name="clear_playback_states_summary">Összes lejátszási pozíció törlése</string>
<string name="clear_playback_states_title">Lejátszási pozíciók törlése</string>
<string name="search_showing_result_for">Találatok a következőre: %s</string>
<string name="notification_scale_to_square_image_title">Bélyegkép méretezése 1:1 arányra</string>
<string name="notification_scale_to_square_image_title">Bélyegkép méretezése 1:1-es arányra</string>
<string name="notification_colorize_title">Értesítés színezése</string>
<string name="notification_action_nothing">Semmi</string>
<string name="notification_action_shuffle">Keverés</string>
<string name="notification_action_repeat">Ismétlés</string>
<string name="show_description_title">Leírás megjelenítése</string>
<string name="notification_action_buffering">Bufferelés</string>
<string name="notification_action_buffering">Pufferelés</string>
<string name="open_with">Megnyitás ezzel</string>
<string name="unsupported_url_dialog_message">Az URL-t nem lehetett felismerni. Megnyitás másik alkalmazással\?</string>
<string name="unsupported_url_dialog_message">Az URL-t nem lehetett felismerni. Megnyitja másik alkalmazással\?</string>
<string name="auto_queue_toggle">Automatikus sorba állítás</string>
<string name="show_description_summary">"Kikapcsolása elrejti a videó leírását és a kapcsolódó információt"</string>
<string name="restore_defaults_confirmation">Vissza akarod állítani az alapértelmezéseket\?</string>
<string name="show_description_summary">Kapcsolja ki, hogy elrejtse a videó leírását és a további információkat</string>
<string name="restore_defaults_confirmation">Visszaállítja az alapértelmezéseket\?</string>
<string name="restricted_video_no_stream">Ez a videó korhatáros.
\nÚj, korhatáros videókkal kapcsolatos YouTube irányelvek miatt a NewPipe nem férhet hozzá a videóhoz, így nem tudja lejátszani.</string>
\nAz új, korhatáros videókkal kapcsolatos YouTube irányelvek miatt a NewPipe nem férhet hozzá a videóhoz, így nem tudja lejátszani.</string>
<string name="description_tab_description">Leírás</string>
<string name="comments_tab_description">Megjegyzések</string>
<string name="copy_for_github">Formázott jelentése másolása</string>
<string name="permission_display_over_apps">Adj engedélyt a más alkalmazások feletti megjelenéshez</string>
<string name="no_playlist_bookmarked_yet">Még nincsenek lejátszási lista könyvjelzők</string>
<string name="copy_for_github">Formázott jelentés másolása</string>
<string name="permission_display_over_apps">Adjon engedélyt a más alkalmazások feletti megjelenéshez</string>
<string name="no_playlist_bookmarked_yet">Még nincs könyvjelző lejátszási listához</string>
<string name="unmute">Némítás megszüntetése</string>
<string name="mute">Némítás</string>
<string name="feed_subscription_not_loaded_count">Nincs betöltve: %d</string>
<string name="feed_group_dialog_empty_name">Üres csoportnév</string>
<string name="feed_group_dialog_delete_message">Törölni szeretnéd ezt a csoportot\?</string>
<string name="feed_group_dialog_delete_message">Törli ezt a csoportot\?</string>
<string name="feed_update_threshold_option_always_update">Mindig frissítsen</string>
<string name="channel_created_by">Készítette: %s</string>
<string name="playlist_page_summary">Lejátszási listák oldala</string>
<string name="playlist_page_summary">Lejátszási lista oldal</string>
<string name="show_thumbnail_summary">Bélyegkép használata a zárképernyőn és az értesítéseken is</string>
<string name="radio">Rádió</string>
<string name="night_theme_summary">Válaszd ki kedvenc éjszakai témád — %s</string>
<string name="select_night_theme_toast">Kiválaszthatod a kedvenc éjszakai témádat lentebb</string>
<string name="night_theme_summary">Válassza ki a kedvenc éjszakai témáját — %s</string>
<string name="select_night_theme_toast">Lent kiválaszthatja a kedvenc éjszakai témáját</string>
<string name="recently_added">Nemrég hozzáadott</string>
<string name="new_seek_duration_toast">Az ExoPlayer korlátai miatt az előre- és visszatekerés időtartama %d másodpercre lett állítva</string>
<string name="feed_groups_header_title">Csatorna csoportok</string>
<string name="systems_language">Rendszer által alapértelmezett</string>
<string name="start_accept_privacy_policy">Az Általános adatvédelmi rendeletnek (GDPR) való megfelelés érdekében felhívjuk figyelmed a NewPipe adatvédelmi nyilatkozatára. Kérjük olvasd el figyelmesen.
\nEl kell fogadnod, ha jelenteni szeretnél programhibákat.</string>
<string name="feed_groups_header_title">Csatornacsoportok</string>
<string name="systems_language">Rendszer alapértelmezése</string>
<string name="start_accept_privacy_policy">Az Általános adatvédelmi rendeletnek (GDPR) való megfelelés érdekében felhívjuk figyelmét a NewPipe adatvédelmi nyilatkozatára. Olvassa el figyelmesen.
\nEl kell fogadnia, ha hibajelentést szeretne küldeni.</string>
<string name="crash_the_app">Alkalmazás összeomlasztása</string>
<string name="show_memory_leaks">Memóriaszivárgások mutatása</string>
<string name="enable_leak_canary_summary">A memóriaszivárgás-monitorozás az alkalmazás megállását okozhatja amíg a dinamikus memória mentése folyik</string>
<string name="show_memory_leaks">Memóriaszivárgások megjelenítése</string>
<string name="enable_leak_canary_summary">A memóriaszivárgás-monitorozás az alkalmazás megállását okozhatja, amíg a dinamikus memória mentése folyik</string>
<string name="playlist_no_uploader">Automatikusan létrehozott (feltöltő nem található)</string>
<string name="title_activity_play_queue">Lejátszási sor</string>
<string name="conferences">Konferenciák</string>
<string name="most_liked">Legtöbbet lájkolt</string>
<string name="main_page_content_summary">Mely oldalak kerülnek a főoldalon megjelenítésre</string>
<string name="most_liked">Legkedveltebb</string>
<string name="main_page_content_summary">Mely oldalak jelennek meg a főoldalon</string>
<plurals name="listening">
<item quantity="one">%s hallgató</item>
<item quantity="other">%s hallgató</item>
@ -449,57 +451,56 @@
<item quantity="other">%s néző</item>
</plurals>
<string name="no_one_watching">Senki sem nézi</string>
<string name="subscribers_count_not_available">Feliratkozók száma nem érhető el</string>
<string name="subscribers_count_not_available">A feliratkozók száma nem érhető el</string>
<string name="local">Helyi</string>
<string name="localization_changes_requires_app_restart">A nyelv meg fog változni amint az alkalmazás újra lesz indítva.</string>
<string name="localization_changes_requires_app_restart">A nyelv az alkalmazás újraindításakor fog megváltozni</string>
<string name="error_unable_to_load_comments">Megjegyzések betöltése sikertelen</string>
<string name="select_a_playlist">Lejátszási lista kiválasztása</string>
<string name="select_a_playlist">Válasszon egy lejátszási listát</string>
<string name="autoplay_summary">Lejátszás automatikus indítása — %s</string>
<string name="playback_speed_control">Lejátszás sebességének beállítása</string>
<string name="clear_queue_confirmation_summary">Lejátszó váltása törölheti a lejátszási sort</string>
<string name="clear_queue_confirmation_summary">Az egyik lejátszóról a másikra váltás törölheti a lejátszási sort</string>
<string name="wifi_only">Csak Wi-Fi-hálózaton</string>
<string name="downloads_storage_use_saf_title">SAF használata</string>
<string name="downloads_storage_use_saf_summary">A \'Storage Access Framework\' lehetővé teszi a letöltések külső SD-kártyára történő mentését.
\nBizonyos eszközökön nem támogatott</string>
<string name="permission_denied">A műveletet letiltotta a rendszer</string>
<string name="downloads_storage_use_saf_title">Rendszermappa-választó (SAF) használata</string>
<string name="downloads_storage_use_saf_summary">A „Storage Access Framework” lehetővé teszi a letöltések külső SD-kártyára történő mentését</string>
<string name="permission_denied">A rendszer megtagadta a műveletet</string>
<string name="never">Soha</string>
<string name="feed_group_dialog_select_subscriptions">Feliratkozások kiválasztása</string>
<string name="copyright">© %1$s %2$s, %3$s licenc alatt</string>
<string name="title_licenses">Harmadik féltől származó licencek</string>
<string name="recaptcha_done_button">Kész</string>
<string name="no_comments">Nincsenek megjegyzések</string>
<string name="no_comments">Nincs megjegyzés</string>
<string name="infinite_videos">∞ videó</string>
<string name="more_than_100_videos">100+ videó</string>
<string name="error_report_open_issue_button_text">Jelentés GitHub-on</string>
<string name="restore_defaults">Alapértékek visszaállítása</string>
<string name="help">Segítség</string>
<string name="clear_cookie_summary">Sütik törlése, amelyeket a NewPipe akkor ment, amikor megoldasz egy reCAPTCHA-t</string>
<string name="error_report_open_issue_button_text">Jelentés a GitHubon</string>
<string name="restore_defaults">Alapértelmezések visszaállítása</string>
<string name="help">Súgó</string>
<string name="clear_cookie_summary">Sütik törlése, amelyeket a NewPipe akkor ment, amikor megold egy reCAPTCHA-t</string>
<string name="recaptcha_cookies_cleared">reCAPTCHA sütik törölve</string>
<string name="clear_cookie_title">reCAPTCHA sütik törlése</string>
<string name="artists">Előadók</string>
<string name="albums">Albumok</string>
<string name="songs">Dalok</string>
<string name="songs">Számok</string>
<string name="events">Események</string>
<string name="videos_string">Videók</string>
<string name="restricted_video">Ez a videó korhatáros.
\n
\nEngedélyezd a(z) \"%1$s\" beállítást ha meg szeretnéd tekinteni.</string>
<string name="show_age_restricted_content_summary">Gyermekek számára potenciálisan nem megfelelő, korhatáros tartalom mutatása (pl. 18+)</string>
<string name="peertube_instance_add_https_only">Csak HTTPS URL-ek támogatottak</string>
<string name="show_meta_info_title">Metaadatok mutatása</string>
\nEngedélyezze a(z) „%1$s” beállítást, ha meg szeretné tekinteni.</string>
<string name="show_age_restricted_content_summary">Gyermekek számára esetlegesen nem megfelelő, korhatáros tartalom megjelenítése (például 18+)</string>
<string name="peertube_instance_add_https_only">Csak a HTTPS URL-ek támogatottak</string>
<string name="show_meta_info_title">Metainformációk megjelenítése</string>
<string name="clear_queue_confirmation_description">A jelenleg aktív lejátszási sor le lesz cserélve</string>
<string name="clear_queue_confirmation_title">Kérjen megerősítést a lejátszási sor törlése előtt</string>
<string name="clear_queue_confirmation_title">Megerősítés kérése a lejátszási sor törlése előtt</string>
<string name="night_theme_title">Éjszakai téma</string>
<string name="updates_setting_description">Értesítés az alkalmazás frissítéséhez, amikor egy új verzió érhető el</string>
<string name="updates_setting_description">Frissítési értesítés megjelenítése, amikor egy új verzió érhető el</string>
<string name="updates_setting_title">Frissítések</string>
<string name="notification_colorize_summary">Az Android igazítsa az értesítés színét a bélyegkép meghatározó színéhez (nem minden eszközön elérhető)</string>
<string name="notification_actions_at_most_three">Legfeljebb három választható művelet jeleníthető meg a kompakt értesítésben!</string>
<string name="notification_actions_summary">Szabd személyre, hogy az értesítésben megjelenő akciógombok mit csinálnak. Válassz ki legfeljebb hármat a jobb oldali jelölőnégyzetekkel, amelyek a kompakt értesítésben is megjelennek.</string>
<string name="notification_action_4_title">Ötödik akciógomb</string>
<string name="notification_action_3_title">Negyedik akciógomb</string>
<string name="notification_action_2_title">Harmadik akciógomb</string>
<string name="notification_action_1_title">Második akciógomb</string>
<string name="notification_action_0_title">Első akciógomb</string>
<string name="notification_colorize_summary">Az Android igazítsa az értesítés színét a bélyegkép meghatározó színéhez (nem minden eszközön érhető el)</string>
<string name="notification_actions_at_most_three">Legfeljebb három művelet jeleníthető meg a kompakt értesítésben.</string>
<string name="notification_actions_summary">Koppintással szerkesztheti az egyes értesítéseken megjelenő műveleteket. Válasszon ki legfeljebb hármat a jobb oldali jelölőnégyzetekkel, amelyek a kompakt értesítéseken is megjelennek.</string>
<string name="notification_action_4_title">Ötödik műveletgomb</string>
<string name="notification_action_3_title">Negyedik műveletgomb</string>
<string name="notification_action_2_title">Harmadik műveletgomb</string>
<string name="notification_action_1_title">Második műveletgomb</string>
<string name="notification_action_0_title">Első műveletgomb</string>
<string name="app_language_title">Alkalmazás nyelve</string>
<plurals name="seconds">
<item quantity="one">%d másodperc</item>
@ -523,47 +524,168 @@
<item quantity="other">%d kiválasztva</item>
</plurals>
<string name="feed_create_new_group_button_title">Új</string>
<string name="content_not_supported">Ez a tartalmat még nem támogatja a NewPipe.
<string name="content_not_supported">Ezt a tartalmat még nem támogatja a NewPipe.
\n
\nRemélhetőleg egy következő verzióban már támogatott lesz.</string>
<string name="no_app_to_open_intent">Nincs a készülékeden olyan alkalmazás, amely meg tudja nyitni ezt</string>
<string name="youtube_music_premium_content">Ez a videó csak YouTube Music Prémium előfizetők számára érhető el, így nem megtekinthető és nem letölthető NewPipe segítségével.</string>
<string name="no_app_to_open_intent">Nincs a készülékén olyan alkalmazás, amely meg tudja ezt nyitni</string>
<string name="youtube_music_premium_content">Ez a videó csak YouTube Music Prémium előfizetők számára érhető el, így nem tekinthető meg és nem tölthető le a NewPipe-pal.</string>
<string name="auto_device_theme_title">Automatikus (rendszertéma)</string>
<string name="paid_content">Ez a tartalom csak előfizetőknek érhető el, nem megtekinthető és nem letölthető a NewPipe segítségével.</string>
<string name="georestricted_content">Ez a tartalom nem érhető el az országodban.</string>
<string name="private_content">Ez a tartalom privát, így nem megtekinthető és nem letölthető a NewPipe segítségével.</string>
<string name="paid_content">Ez a tartalom csak előfizetőknek érhető el, nem tekinthető meg és nem tölthető le a NewPipe-pal.</string>
<string name="georestricted_content">Ez a tartalom nem érhető el az országában.</string>
<string name="private_content">Ez a tartalom privát, így nem tekinthető meg és nem tölthető le a NewPipe-pal.</string>
<string name="download_has_started">A letöltés elkezdődött</string>
<string name="notification_scale_to_square_image_summary">Értesítésben megjelenő bélyegkép átméretezése 16:9 helyett 1:1 arányra (torzítással járhat)</string>
<string name="notification_scale_to_square_image_summary">Értesítésben megjelenő bélyegkép átméretezése 16:9-es helyett 1:1-es arányra (torzítással járhat)</string>
<string name="chapters">Fejezetek</string>
<string name="show_thumbnail_title">Bélyegkép mutatása</string>
<string name="start_here_on_popup">Lejátszás felugró ablakban</string>
<string name="start_here_on_background">Lejátszás a háttérben</string>
<string name="enqueued">Sorhoz hozzáadva</string>
<string name="enqueue_stream">Sorhoz adás</string>
<string name="saved_tabs_invalid_json">Mentett fülek olvasása sikertelen, alapértelmezettek használata</string>
<string name="hash_channel_description">Értesítések a videó hashelési folyamathoz</string>
<string name="hash_channel_name">Videó hash értesítés</string>
<string name="youtube_restricted_mode_enabled_summary">YouTube biztosít egy \"Korlátozott Módot\" ami elrejti a lehetséges felnőtteknek szóló tartalmat</string>
<string name="youtube_restricted_mode_enabled_title">YouTube \"Korlátozott Mód\"-jának bekapcsolása</string>
<string name="show_thumbnail_title">Bélyegkép megjelenítése</string>
<string name="start_here_on_popup">Lejátszás indítása felugró ablakban</string>
<string name="start_here_on_background">Lejátszás indítása a háttérben</string>
<string name="enqueued">Sorba állítva</string>
<string name="enqueue_stream">Sorba állítás</string>
<string name="saved_tabs_invalid_json">Nem sikerült a mentett lapok olvasása, alapértelmezettek használata</string>
<string name="hash_channel_description">Értesítések a videók ujjlenyomatkészítési folyamatához</string>
<string name="hash_channel_name">Videó ujjlenyomat-készítési értesítése</string>
<string name="youtube_restricted_mode_enabled_summary">A YouTube biztosít egy „Korlátozott módot”, amely elrejti a lehetséges felnőtteknek szóló tartalmat</string>
<string name="youtube_restricted_mode_enabled_title">A YouTube „Korlátozott módjának” bekapcsolása</string>
<string name="peertube_instance_add_exists">A példány már létezik</string>
<string name="peertube_instance_add_fail">dány érvényesítése nem sikerült</string>
<string name="peertube_instance_add_help">Példány URL megadása</string>
<string name="peertube_instance_add_fail">A példány érvényesítése nem sikerült</string>
<string name="peertube_instance_add_help">Adja meg a példány URL-ét</string>
<string name="peertube_instance_add_title">Példány hozzáadása</string>
<string name="peertube_instance_url_help">A neked tetsző példányokat megtalálhatod itt: %s</string>
<string name="peertube_instance_url_summary">Válaszd ki a kedvenc PeerTube példányaidat</string>
<string name="peertube_instance_url_help">Találjon önnek tetsző példányokat itt: %s</string>
<string name="peertube_instance_url_summary">Válassza ki a kedvenc PeerTube példányait</string>
<string name="peertube_instance_url_title">PeerTube példányok</string>
<string name="enable_disposed_exceptions_title">Életciklusából kifutott hibák jelentése</string>
<string name="preferred_open_action_settings_title">Preferált \'nyitási\' cselekedet</string>
<string name="preferred_open_action_settings_title">Előnyben részesített „megnyitási” művelet</string>
<string name="drawer_close">Fiók bezárása</string>
<string name="drawer_open">Fiók megnyitása</string>
<string name="show_channel_details">Csatorna részleteinek megjelenítése</string>
<string name="hold_to_append">Tartsd hogy sorba állítsd</string>
<string name="default_kiosk_page_summary">Alap Kiosk</string>
<string name="app_license">A NewPipe egy copyleft szabad szoftver: Felhasználhatod, tanulmányozhatod, megoszthatod és fejlesztheted akaratod szerint. Konkrétan továbbadhatod és/vagy módosíthatod a GNU General Public License feltételei alatt ami a Free Software Foundation álltal lett publikálva, vagy a 3. verzióját a licensznek, vagy (a saját opciód szerint), bármelyik későbbi verzióját.</string>
<string name="hold_to_append">Tartsa a sorba állításhoz</string>
<string name="default_kiosk_page_summary">Alapértelmezett újságárus</string>
<string name="app_license">A NewPipe egy copyleft szabad szoftver: tetszése szerint felhasználhatja, tanulmányozhatja, megoszthatja és fejlesztheti. Egész pontosan a Free Software Foundation által kiadott GNU General Public License 3-as, vagy (választható módon) újabb verziójának feltételei szerint módosíthatja vagy adhatja tovább.</string>
<string name="recaptcha_solve">Megoldás</string>
<string name="subtitle_activity_recaptcha">Nyomj a \"Kész\"-re amikor meg van oldva</string>
<string name="msg_calculating_hash">Hash számítása</string>
<string name="related_items_tab_description">Összefüggő elemek</string>
<string name="error_report_open_github_notice">Kérlek ellenőrizd, hogy egy hiba, ami az összeomlásodat írja le, létezik-e már. Ha duplikált jegyet adsz be, időt veszel el tőlünk amit arra tudnánk fordítani, hogy kijavítsuk magát a bugot.</string>
<string name="minimize_on_exit_title">Lekicsinyítés alkalmazás váltáskor</string>
<string name="subtitle_activity_recaptcha">Nyomja meg a „Kész” gombot, ha megoldotta</string>
<string name="msg_calculating_hash">Ujjlenyomat számítása</string>
<string name="related_items_tab_description">Kapcsolódó elemek</string>
<string name="error_report_open_github_notice">Ellenőrizze, hogy létezik-e már olyan jegy, amely az összeomlásával foglalkozik. Ha duplikált jegyet ad fel, akkor olyan időt vesz el tőlünk, amelyet a hiba javítására tudnánk fordítani.</string>
<string name="minimize_on_exit_title">Minimalizálás alkalmazásváltáskor</string>
<string name="service_provides_reason">A(z) %s ezt az okot adta meg:</string>
<string name="local_search_suggestions">Helyi keresési javaslatok</string>
<string name="remote_search_suggestions">Távoli keresési javaslatok</string>
<string name="start_main_player_fullscreen_title">A fő lejátszó teljes képernyős indítása</string>
<string name="start_main_player_fullscreen_summary">A videókat ne a kis lejátszóban indítsa el, hanem kapcsolja be a teljes képernyős módot, ha az automatikus forgatás zárolva van. Továbbra is elérheti a kis lejátszót, ha kilép a teljes képernyőből.</string>
<string name="drawer_header_description">Szolgáltatás be/ki, jelenleg kiválasztott:</string>
<string name="comments_are_disabled">A megjegyzések ki vannak kapcsolva</string>
<string name="main_page_content_swipe_remove">Húzza oldalra az elemeket az eltávolításukhoz</string>
<string name="enqueue_next_stream">A következő sorba állítása</string>
<string name="enqueued_next">A következő sorba állítva</string>
<string name="processing_may_take_a_moment">Feldolgozás… Ez eltarthat egy ideig.</string>
<string name="enable_disposed_exceptions_summary">Az eltávolítás utáni, fragment vagy activity életcikluson kívüli, nem kézbesíthető Rx kivételek jelentésének kényszerítése</string>
<string name="show_original_time_ago_title">Eredeti „ennyi ideje” megjelenítése az elemeken</string>
<string name="disable_media_tunneling_summary">Tiltsa le a médiacsatornázást, ha fekete képernyőt vagy akadozást tapasztal videólejátszáskor</string>
<string name="show_image_indicators_summary">Picasso színes szalagok megjelenítése a képek fölött, megjelölve a forrásukat: piros a hálózathoz, kék a lemezhez, zöld a memóriához</string>
<string name="downloads_storage_ask_summary_no_saf_notice">Minden letöltésnél meg fogja kérdezni, hogy hova mentse el</string>
<string name="downloads_storage_use_saf_summary_api_19">A „Storage Access Framework” nem támogatott Android KitKaten vagy régebbin</string>
<string name="choose_instance_prompt">Válasszon egy példányt</string>
<string name="feed_oldest_subscription_update">Lista legutóbbi frissítése: %s</string>
<string name="feed_notification_loading">Lista betöltése…</string>
<string name="feed_group_show_only_ungrouped_subscriptions">Csak a nem csoportosított feliratkozások megjelenítése</string>
<string name="settings_category_feed_title">Lista</string>
<string name="feed_update_threshold_title">Lista frissítési küszöb</string>
<string name="feed_update_threshold_summary">A legutóbbi frissítés óta eltelt idő, ami után a feliratkozás elavultnak számít %s</string>
<string name="feed_load_error_terminated">A szerző fiókját eltávolították.
\nA NewPipe nem fogja tudni betölteni ezt a listát a jövőben.
\nLeiratkozik erről a csatornáról\?</string>
<string name="feed_load_error_fast_unknown">A gyors listamód nem ad ennél több információt.</string>
<string name="feed_use_dedicated_fetch_method_title">Lekérés egy dedikált listából, ha lehetséges</string>
<string name="feed_use_dedicated_fetch_method_enable_button">Gyors mód engedélyezése</string>
<string name="feed_use_dedicated_fetch_method_help_text">Úgy gondolja, hogy a lista betöltése lassú\? Ha így van, akkor próbálja engedélyezni a gyors betöltést (ezt a beállításokban változtathatja meg, vagy a lenti gomb megnyomásával).
\n
\nA NewPipe két listabetöltési stratégiát kínál:
\n• A teljes feliratkozott csatorna lekérése, amely lassú, de teljes.
\n• Egy dedikált szolgáltatási végpont, amely gyors, de általában nem teljes.
\n
\nA különbség a kettő között az, hogy a gyorsból általában hiányoznak egyes információk, mint az elem hossza vagy a típusa (nem lehet megkülönböztetni az élő videókat a normálaktól), valamint kevesebb elemet adhat vissza.
\n
\nA YouTube például egy olyan szolgáltatás, amely ezt a gyors módot RSS hírcsatornával kínálja.
\n
\nÍgy a választása azon múlik, hogy melyiket tartja fontosabbnak: a sebességet vagy a pontos információkat.</string>
<string name="detail_sub_channel_thumbnail_view_description">Csatorna profilképének bélyegképe</string>
<string name="recent">Legutóbbi</string>
<string name="featured">Kiemelt</string>
<string name="description_select_note">Most már kijelölheti a leírásban lévő szöveg. Vegye figyelembe, hogy kijelölési módban az oldal villoghat, és a hivatkozások nem biztos, hogy kattinthatók lesznek.</string>
<string name="description_select_disable">Szöveg kijelölésének letiltása a leírásban</string>
<string name="metadata_licence">Licenc</string>
<string name="metadata_age_limit">Korhatár</string>
<string name="metadata_host">Kiszolgáló</string>
<string name="metadata_thumbnail_url">Bélyegkép URL</string>
<string name="metadata_privacy_public">Nyilvános</string>
<string name="metadata_privacy_unlisted">Nem listázott</string>
<string name="off">Ki</string>
<string name="loading_channel_details">Csatornarészletek betöltése…</string>
<string name="no_appropriate_file_manager_message">Nem található megfelelő fájlkezelő ehhez a művelethez.
\nTelepítsen egy fájlkezelőt, vagy próbálja meg letiltani a következőt a letöltési beállításokban: „%s”.</string>
<plurals name="download_finished_notification">
<item quantity="one">Letöltés befejezve</item>
<item quantity="other">%s letöltés befejezve</item>
</plurals>
<string name="feed_processing_message">Lista feldolgozása…</string>
<string name="feed_use_dedicated_fetch_method_summary">Egyes szolgáltatásoknál érhető el, általában sokkal gyorsabb, és korlátozott számú elemet adhat vissza, gyakran hiányos információkkal (például nincs hossz, elemtípus, vagy élő videó állapot)</string>
<string name="account_terminated">Fiók eltávolítva</string>
<string name="mark_as_watched">Megjelölés megtekintettként</string>
<string name="no_dir_yet">Még nincs letöltési mappa beállítva, válassza ki az alapértelmezett letöltési mappát most</string>
<string name="seekbar_preview_thumbnail_title">Tekerősáv bélyegkép-előnézete</string>
<string name="high_quality_larger">Magas minőségű (nagyobb)</string>
<string name="feed_load_error">Hiba a lista betöltésekor</string>
<string name="feed_toggle_show_played_items">Megnézett elemek megjelenítése</string>
<string name="metadata_language">Nyelv</string>
<string name="metadata_support">Támogatás</string>
<string name="open_website_license">Weboldal megnyitása</string>
<string name="tablet_mode_title">Táblagép mód</string>
<string name="downloads_storage_use_saf_summary_api_29">Az Android 10-től kezdve, csak a „Storage Access Framework” támogatott</string>
<string name="feed_new_items">Új listaelemek</string>
<string name="metadata_privacy_private">Privát</string>
<string name="metadata_privacy_internal">Belső</string>
<string name="detail_heart_img_view_description">Készítő által szívecskézve</string>
<string name="on">Be</string>
<string name="feed_load_error_account_info">A(z) „%s” listája nem tölthető be.</string>
<string name="soundcloud_go_plus_content">Ez egy SoundCloud Go+ szám, legalábbis az Ön országában, így nem játszható le vagy tölthető le a NewPipe-pal.</string>
<string name="show_meta_info_summary">Kapcsolja ki, hogy elrejtse a metainformációs dobozokat, melyek további információkat tartalmaznak a közvetítés létrehozójáról, annak tartalmáról vagy egy keresési kérésről</string>
<string name="error_report_channel_name">Hibajelentési értesítés</string>
<string name="error_report_channel_description">Értesítések a hibák jelentéséhez</string>
<string name="error_report_notification_title">A NewPipe hibát észlelt, koppintson a jelentéséhez</string>
<string name="error_report_notification_toast">Hiba történt, lásd az értesítést</string>
<string name="disable_media_tunneling_title">Médiacsatornázás letiltása</string>
<string name="show_error_snackbar">Hiba üzenetsávjának megjelenítése</string>
<string name="create_error_notification">Hibaértesítés létrehozása</string>
<string name="manual_update_description">Új verziók kézi keresése</string>
<string name="low_quality_smaller">Alacsony minőségű (kisebb)</string>
<string name="checking_updates_toast">Frissítések keresése…</string>
<string name="video_detail_by">Készítette: %s</string>
<string name="no_appropriate_file_manager_message_android_10">Nem található megfelelő fájlkezelő ehhez a művelethez.
\nTelepítsen egy olyan fájlkezelőt, amely kompatibilis a Storage Access Frameworkkel.</string>
<string name="description_select_enable">Szöveg kijelölésének engedélyezése a leírásban</string>
<string name="metadata_category">Kategória</string>
<string name="metadata_tags">Címkék</string>
<string name="metadata_privacy">Adatvédelem</string>
<string name="error_show_channel_details">Hiba a csatornarészletek megjelenítésekor</string>
<string name="feed_use_dedicated_fetch_method_disable_button">Gyors mód letiltása</string>
<string name="remove_watched_popup_yes_and_partially_watched_videos">Igen, és távolítsa el a részben megnézett videókat is</string>
<string name="remove_watched_popup_warning">A videók, melyeket már megnézett miután a lejátszási listához adta őket, el lesznek távolítva.
\nBiztos benne\? Ez nem vonható vissza.</string>
<string name="show_original_time_ago_summary">A szolgáltatásokból származó eredeti szövegek láthatók lesznek a közvetítési elemeken</string>
<string name="crash_the_player">Lejátszó összeomlasztása</string>
<string name="show_image_indicators_title">Képjelölők megjelenítése</string>
<string name="show_crash_the_player_title">A „lejátszó összeomlasztása” lehetőség megjelenítése</string>
<string name="show_crash_the_player_summary">Megjeleníti az összeomlasztási lehetőséget a lejátszó használatakor</string>
<string name="unhook_checkbox">Hangmagasság megtartása (torzítást okozhat)</string>
<string name="manual_update_title">Frissítések keresése</string>
<string name="dont_show">Ne jelenítse meg</string>
<string name="remove_watched">Megnézettek eltávolítása</string>
<string name="remove_watched_popup_title">Eltávolítja a megnézett videókat\?</string>
<plurals name="deleted_downloads_toast">
<item quantity="one">%1$s letöltés törölve</item>
<item quantity="other">%1$s letöltés törölve</item>
</plurals>
<string name="detail_pinned_comment_view_description">Rögzített megjegyzés</string>
<string name="background_player_already_playing_toast">Már megy a lejátszás a háttérben</string>
<string name="leak_canary_not_available">LeakCanary nem elérhető</string>
</resources>

View File

@ -21,7 +21,7 @@
<string name="clear">Մաքրել</string>
<string name="upload_date_text">Հրապարակվել է %1$s</string>
<string name="install">Տեղադրել</string>
<string name="cancel">Վերացնել</string>
<string name="cancel">Չեղարկել</string>
<string name="open_in_browser">Բացել բրաուզերում</string>
<string name="download_path_audio_title">Ձայնային բեռնման պանակ</string>
<string name="download_path_dialog_title">Ընտրեք ներբեռնման թղթապանակը տեսաֆայլերի համար</string>
@ -130,4 +130,17 @@
<string name="always">Միշտ</string>
<string name="download_dialog_title">Բեռնել</string>
<string name="enable_playback_state_lists_title">Ցանկերում դիրքերը</string>
<string name="auto_queue_toggle">Ինքնանվագարկում</string>
<string name="clear_views_history_title">Մաքրել դիտման պատմությունը</string>
<string name="clear_download_history">Մաքրել ներբեռնման պատմությունը</string>
<string name="play_audio">Աուդիո</string>
<string name="mark_as_watched">Նշել որպես դիտված</string>
<string name="notification_action_repeat">Կրկնել</string>
<string name="settings_category_player_title">Նվագարկիչ</string>
<string name="settings_category_history_title">Պատմություն և քեշ</string>
<string name="night_theme_title">Գիշերային ոճ</string>
<string name="stop">Կանգ</string>
<string name="title_activity_history">Պատմություն</string>
<string name="action_history">Պատմություն</string>
<string name="trending">Թրենդային</string>
</resources>

View File

@ -227,4 +227,12 @@
<string name="metadata_support">Supporto</string>
<string name="recent">Recente</string>
<string name="metadata_privacy_internal">Interne</string>
<string name="open_with">Aperir con</string>
<string name="remote_search_suggestions">Suggestiones de recerca remote</string>
<string name="download_thumbnail_title">Cargar miniaturas</string>
<string name="settings_category_notification_title">Notification</string>
<string name="search_showing_result_for">Monstrante resultatos pro: %s</string>
<string name="show_higher_resolutions_summary">Solmente alicun apparatos pote reproducer videos 2K/4K</string>
<string name="start_main_player_fullscreen_title">Initiar le reproductor principal in schermo plen</string>
<string name="peertube_instance_add_https_only">Solmente le URLs HTTPS es supportate</string>
</resources>

View File

@ -153,7 +153,7 @@
<string name="always">Selalu</string>
<string name="just_once">Hanya Sekali</string>
<string name="file">Berkas</string>
<string name="notification_channel_description">Notifikasi untuk pemutar latar belakang dan popup NewPipe</string>
<string name="notification_channel_description">Notifikasi untuk pemutar NewPipe</string>
<string name="unknown_content">[Tidak diketahui]</string>
<string name="switch_to_background">Alihkan ke Latar Belakang</string>
<string name="switch_to_popup">Alihkan ke Popup</string>
@ -285,11 +285,12 @@
<string name="import_youtube_instructions">Impor langganan YouTube dari Google takeout:
\n
\n1. Kunjungi URL ini: %1$s
\n2. Masuk ketika ditanya
\n2. Masuk ketika ditanyakan
\n3. Klik \"Semua data disertakan\", lalu \"Batalkan semua pilihan\", lalu hanya pilih \"langganan\" dan klik \"OKE\"
\n4. Klik \"Langkah berikutnya\" dan kemudian \"Buat ekspor\"
\n5. Klik tombol \"Unduh\" dan
\n6. Dari unduhan zip takeout ekstrak berkas .json (biasanya di bawah \"YouTube and YouTube Music/subscriptions/subscriptions.json\") dan impor di sini</string>
\n5. Klik tombol \"Unduh\"
\n6. Klik IMPOR FILE di bawah dan pilih file .zip yang terunduh
\n7. [Jika impor .zip gagal] Ekstrak file .csv (biasanya di \"YouTube dan YouTube Music/langganan/langganan.csv\"), klik IMPOR FILE di bawah dan pilih file csv yang diekstrak</string>
<string name="import_soundcloud_instructions">Impor profil SoundCloud dengan mengetik URL atau ID Anda:
\n
\n1. Aktifkan \"mode desktop\" di peramban web (situs tidak tersedia untuk perangkat seluler)
@ -336,8 +337,8 @@
<string name="settings_category_updates_title">Pembaruan</string>
<string name="events">Acara</string>
<string name="file_deleted">Berkas dihapus</string>
<string name="app_update_notification_channel_name">Notifikasi Pembaruan Apl</string>
<string name="app_update_notification_channel_description">Notifikasi untuk versi NewPipe baru</string>
<string name="app_update_notification_channel_name">Notifikasi pembaruan apl</string>
<string name="app_update_notification_channel_description">Notifikasi untuk versi-versi NewPipe baru</string>
<string name="download_to_sdcard_error_title">Penyimpanan eksternal tidak tersedia</string>
<string name="download_to_sdcard_error_message">Tidak bisa mengunduh ke kartu SD eksternal. Atur ulang lokasi folder unduhan\?</string>
<string name="saved_tabs_invalid_json">Tidak bisa membaca tab yang disimpan, beralih menggunakan tab bawaan</string>
@ -569,7 +570,7 @@
<string name="show_meta_info_summary">Nonaktifkan untuk menyembunyikan kotak info dengan informasi tambahan tentang kreator, konten stream atau pencarian</string>
<string name="show_meta_info_title">Tampilkan info meta</string>
<string name="hash_channel_description">Notifikasi untuk laju pemrosesan hash video</string>
<string name="hash_channel_name">Notifikasi Hash Video</string>
<string name="hash_channel_name">Notifikasi hash video</string>
<string name="no_app_to_open_intent">Tidak ada apl di perangkat Anda yang bisa membuka ini</string>
<string name="chapters">Chapter</string>
<string name="description_tab_description">Deskripsi</string>
@ -579,8 +580,8 @@
<string name="show_description_title">Tampilkan deskripsi</string>
<string name="open_with">Buka dengan</string>
<string name="paid_content">Konten ini hanya tersedia untuk pengguna yang telah membayar, sehingga tidak bisa diputar atau diunduh oleh NewPipe.</string>
<string name="youtube_music_premium_content">Video ini hanya tersedia untuk anggota Premium YouTube Music, sehingga tidak bisa diputar atau diunduh oleh NewPipe.</string>
<string name="private_content">Konten ini bersifat pribadi, jadi tidak bisa diputar ataupun diunduh oleh NewPipe.</string>
<string name="youtube_music_premium_content">Video ini hanya tersedia untuk anggota YouTube Music Premium, sehingga tidak bisa diputar atau diunduh oleh NewPipe.</string>
<string name="private_content">Konten ini privat, sehingga tidak bisa diputar atau diunduh oleh NewPipe.</string>
<string name="soundcloud_go_plus_content">Ini adalah sebuah trek SoundCloud Go +, setidaknya di negara Anda, sehingga tidak bisa diputar atau diunduh oleh NewPipe.</string>
<string name="georestricted_content">Konten ini tidak tersedia di negara Anda.</string>
<string name="crash_the_app">Hentikan aplikasi</string>
@ -661,7 +662,18 @@
<string name="feed_new_items">Item feed baru</string>
<string name="show_crash_the_player_title">Tampilkan \"hentikan pemain video\"</string>
<string name="show_crash_the_player_summary">Menampilkan opsi penghentian ketika menggunakan pemain video</string>
<string name="report_player_errors_summary">Melaporkan kesalahan pemain video dalam detail yang penuh daripada menampilkan pesan toast yang muncul sebentar (berguna untuk memeriksa masalah)</string>
<string name="report_player_errors_title">Laporkan kesalahan pemain video</string>
<string name="crash_the_player">Hentikan pemain video</string>
<string name="error_report_channel_description">Notifikasi untuk melaporkan kegalatan</string>
<string name="error_report_channel_name">Notifikasi laporan kegalatan</string>
<string name="error_report_notification_toast">Sebuah kegalatan terjadi, lihat notifikasinya</string>
<string name="show_error_snackbar">Menampilkan sebuah snackbar kegalatan</string>
<string name="create_error_notification">Buat sebuah notifikasi kegalatan</string>
<string name="no_appropriate_file_manager_message">Tidak ada manajer file yang ditemukan untuk tindakan ini.
\nMohon instal sebuah manajer file atau coba menonaktifkan \'%s\' di pengaturan unduhan.</string>
<string name="error_report_notification_title">NewPipe mengalami sebuah kegalatan, ketuk untuk melaporkan</string>
<string name="no_appropriate_file_manager_message_android_10">Tidak ada manajer file yang ditemukan untuk tindakan ini.
\nMohon instal sebuah manajer file yang kompatibel dengan Storage Access Framework.</string>
<string name="detail_pinned_comment_view_description">Komentar dipin</string>
<string name="background_player_already_playing_toast">Sudah diputar di latar belakang</string>
<string name="leak_canary_not_available">LeakCanary tidak tersedia</string>
</resources>

View File

@ -142,8 +142,8 @@
<string name="settings_category_player_behavior_title">Comportamento</string>
<string name="settings_category_history_title">Cronologia e cache</string>
<string name="undo">Annulla</string>
<string name="notification_channel_name">Notifiche NewPipe</string>
<string name="notification_channel_description">Notifiche per lettore in sottofondo e popup</string>
<string name="notification_channel_name">Notifica NewPipe</string>
<string name="notification_channel_description">Notifiche per il lettore multimediale di NewPipe</string>
<string name="search_no_results">Nessun risultato</string>
<string name="no_subscribers">Nessun iscritto</string>
<plurals name="subscribers">
@ -342,8 +342,8 @@
<string name="brightness_gesture_control_summary">Utilizza i gesti per controllare la luminosità del lettore multimediale</string>
<string name="settings_category_updates_title">Aggiornamenti</string>
<string name="file_deleted">File eliminato</string>
<string name="app_update_notification_channel_name">Notifiche di aggiornamenti dell\'applicazione</string>
<string name="app_update_notification_channel_description">Notifiche per una nuova versione di NewPipe</string>
<string name="app_update_notification_channel_name">Notifiche per aggiornamenti dell\'app</string>
<string name="app_update_notification_channel_description">Notifiche per le nuove versioni di NewPipe</string>
<string name="download_to_sdcard_error_title">Archiviazione esterna non disponibile</string>
<string name="download_to_sdcard_error_message">Impossibile scaricare sulla scheda SD esterna. Ripristinare la posizione della cartella dei download\?</string>
<string name="saved_tabs_invalid_json">Impossibile leggere le schede salvate, verranno usate quelle predefinite</string>
@ -576,7 +576,7 @@
<string name="show_thumbnail_summary">Utilizza le copertine come sfondo della schermata di blocco e per le notifiche</string>
<string name="show_thumbnail_title">Mostra copertina</string>
<string name="msg_calculating_hash">Calcolo dell\'hash</string>
<string name="hash_channel_name">Notifica Hash Video</string>
<string name="hash_channel_name">Notifica hash video</string>
<string name="hash_channel_description">Notifiche per lo stato di avanzamento dell\'hashing video</string>
<string name="recent">Recente</string>
<string name="show_meta_info_summary">Disattiva per nascondere i riquadri con informazioni aggiuntive sul contenuto, sul suo autore o su una richiesta di ricerca</string>
@ -672,9 +672,20 @@
<string name="manual_update_description">Verifica manualmente la presenza di nuove versioni</string>
<string name="checking_updates_toast">Controllo aggiornamenti…</string>
<string name="feed_new_items">Nuovi elementi feed</string>
<string name="report_player_errors_title">Segnala errori del lettore multimediale</string>
<string name="show_crash_the_player_summary">Quando il lettore multimediale è in uso, mostra un\'opzione per farlo crashare</string>
<string name="report_player_errors_summary">Invece di mostrare un messaggio popup di breve durata, gli errori del lettore multimediale saranno visualizzati in modo dettagliato (utile per diagnosticare i problemi)</string>
<string name="show_crash_the_player_title">Mostra \"Fai crashare il lettore\"</string>
<string name="crash_the_player">Fai crashare il lettore</string>
<string name="error_report_notification_title">NewPipe ha riscontrato un errore, tocca per segnalarlo</string>
<string name="show_error_snackbar">Mostra un messaggio di errore</string>
<string name="no_appropriate_file_manager_message">Non è stato trovato alcun gestore di file appropriato per questa azione.
\nInstallane uno prova a disattivare \"%s\" nelle impostazioni di download.</string>
<string name="error_report_channel_name">Notifica per segnalazione errori</string>
<string name="error_report_channel_description">Notifiche per segnalare errori</string>
<string name="error_report_notification_toast">Si è verificato un errore, vedi la notifica</string>
<string name="create_error_notification">Crea una notifica di errore</string>
<string name="no_appropriate_file_manager_message_android_10">Non è stato trovato alcun gestore di file appropriato per questa azione.
\nInstallane uno compatibile con Storage Access Framework.</string>
<string name="detail_pinned_comment_view_description">Commento in primo piano</string>
<string name="background_player_already_playing_toast">Già in riproduzione in sottofondo</string>
<string name="leak_canary_not_available">LeakCanary non è disponibile</string>
</resources>

View File

@ -272,14 +272,14 @@
<string name="give_back">支援する</string>
<string name="privacy_policy_encouragement">NewPipe プロジェクトはあなたのプライバシーを非常に大切にしています。あなたの同意がない限り、アプリはいかなるデータも収集しません。
\nNewPipe のプライバシー・ポリシーでは、クラッシュリポート送信時にどのような種類のデータが送信・記録されるかを詳細に説明しています。</string>
<string name="app_license">NewPipe はコピーレフトなソフトウェアです。あなたは自由にそれを使用し、研究し、そして改善することができます。あなたは、GNU フリーソフトウェア財団が公開する GNU General Public ライセンス バージョン3以降の下に、自由に再配布・修正を行うことができます。</string>
<string name="app_license">NewPipe はコピーレフトなソフトウェアです。あなたは自由にそれを使用し、研究し、共有し、そして改善することができます。あなたは、GNU フリーソフトウェア財団が公開する GNU General Public ライセンス バージョン3以降の下に、自由に再配布・修正を行うことができます。</string>
<string name="title_last_played">最終再生日時</string>
<string name="title_most_played">最も再生された動画</string>
<string name="resize_zoom">拡大</string>
<string name="controls_add_to_playlist_title">プレイリスト</string>
<string name="show_hold_to_append_title">「長押しして追加」のヒントを表示</string>
<string name="show_hold_to_append_title">「長押ししてキュー」のヒントを表示</string>
<string name="tracks">トラック</string>
<string name="notification_channel_description">NewPipe のバックグラウンドおよびポップアッププレイヤーの通知</string>
<string name="notification_channel_description">NewPipe のプレイヤーの通知</string>
<string name="new_and_hot">新着と人気</string>
<string name="hold_to_append">長押ししてキューに追加</string>
<string name="start_here_on_popup">ポップアップで連続再生を開始</string>
@ -659,8 +659,21 @@
<string name="enqueue_next_stream">次をキューに追加</string>
<string name="enqueued_next">次をキューに追加しました</string>
<string name="detail_heart_img_view_description">クリエイターの心をこめて</string>
<string name="report_player_errors_summary">プレーヤーのエラーを、短時間のトーストメッセージではなく、詳細に報告する(問題の診断に役立ちます)</string>
<string name="report_player_errors_title">プレイヤーのエラーを報告</string>
<string name="show_crash_the_player_title">\"プレイヤーがクラッシュ\"を表示</string>
<string name="crash_the_player">プレイヤーがクラッシュ</string>
<string name="feed_new_items">新しいフィードアイテム</string>
<string name="error_report_channel_name">エラー報告通知</string>
<string name="error_report_notification_toast">エラーが発生しました。通知をご覧ください</string>
<string name="error_report_notification_title">NewPipe はエラーに遭遇しました。タップして報告</string>
<string name="show_error_snackbar">スナックバーにエラーを表示</string>
<string name="background_player_already_playing_toast">既にバックグラウンドで再生されています</string>
<string name="detail_pinned_comment_view_description">固定されたコメント</string>
<string name="no_appropriate_file_manager_message_android_10">この動作に適切なファイルマネージャが見つかりませんでした。
\nStorage Access Frameworkと互換性のあるファイルマネージャをインストールしてください。</string>
<string name="no_appropriate_file_manager_message">この動作に適切なファイルマネージャが見つかりませんでした。
\nファイルマネージャをインストールするか、ダウンロード設定で\'%s\'を無効にすることをお試しください。</string>
<string name="show_crash_the_player_summary">プレイヤー使用時にクラッシュオプションを表示</string>
<string name="create_error_notification">エラー通知を作成</string>
<string name="error_report_channel_description">エラーを報告する通知</string>
<string name="leak_canary_not_available">LeakCanaryが利用不可能です</string>
</resources>

View File

@ -72,5 +72,5 @@
<string name="no_player_found_toast">Ra ono pamuter (Sampeyan iso masang VLC kanggo muter iku).</string>
<string name="no_player_found">Pamuter ora ditemokke. Pasang VLC\?</string>
<string name="upload_date_text">Diterbitake ing %1$s</string>
<string name="main_bg_subtitle">Pencet suryakanta kanggo nglekasi</string>
<string name="main_bg_subtitle">Pencet lup kanggo nglekasi</string>
</resources>

View File

@ -134,7 +134,7 @@
<string name="undo">Atgal</string>
<string name="play_all">Groti viską</string>
<string name="notification_channel_name">NewPipe pranešimai</string>
<string name="notification_channel_description">Foninio ir langelio rėžimo grotuvų pranešimai</string>
<string name="notification_channel_description">NewPipe grotuvo pranešimai</string>
<string name="unknown_content">[Nežinoma]</string>
<string name="player_stream_failure">Srauto atkurti nepavyko</string>
<string name="player_unrecoverable_failure">Įvyko nepataisoma grotuvo klaida</string>
@ -310,7 +310,7 @@
<string name="clear_cookie_title">Išvalyti reCAPTCHA slapukus</string>
<string name="hash_channel_description">Pranešimas apie video maišos progresą</string>
<string name="hash_channel_name">Video maišos pranešimas</string>
<string name="app_update_notification_channel_description">Pranešimas apie naują NewPipe versija</string>
<string name="app_update_notification_channel_description">Pranešimas apie naują NewPipe versiją</string>
<string name="app_update_notification_channel_name">Programos atnaujinimo pranešimas</string>
<string name="file">Failą</string>
<string name="file_deleted">Failas pašalintas</string>
@ -469,7 +469,7 @@
<string name="close">Užverti</string>
<string name="stop">Sustabdyti</string>
<string name="overwrite">Perrašyti</string>
<string name="enqueue">Eilė</string>
<string name="enqueue">Į eilę</string>
<string name="post_processing">apdorojama</string>
<string name="queued">eilėje</string>
<string name="paused">sustabdyta</string>
@ -684,4 +684,19 @@
<string name="manual_update_description">Tikrinti ar yra atnaujinimų rankiniu būdu</string>
<string name="checking_updates_toast">Tikrinti ar yra atnaujinimų…</string>
<string name="feed_new_items">Nauji sklaidos kanalo elementai</string>
<string name="leak_canary_not_available">LeakCanary neprieinama</string>
<string name="show_crash_the_player_summary">Naudojant grotuvą rodo lūžio parinkty</string>
<string name="show_error_snackbar">Rodyti klaidos juostą</string>
<string name="detail_pinned_comment_view_description">Prisegtas komentaras</string>
<string name="no_appropriate_file_manager_message_android_10">Nerasta tinkama failų tvarkyklė.
\nĮdiekite „Storage Access Framework“ suderinamą su šia failų tvarkykle.</string>
<string name="error_report_channel_description">Pranešimai pranešimui apie klaidas</string>
<string name="show_crash_the_player_title">Rodyti „grotuvas užlūžo“</string>
<string name="create_error_notification">Sukurti klaidos pranešimą</string>
<string name="error_report_notification_title">NewPipe susidūrė su klaida, paspauskite norėdami pranešti</string>
<string name="no_appropriate_file_manager_message">Šiam veiksmui nerastas tinkama failų tvarkyklė.
\nĮdiekite failų tvarkyklę arba pabandykite išjungti „%s“ parsiuntimo nustatymuose.</string>
<string name="crash_the_player">Užlūžo</string>
<string name="error_report_channel_name">Klaidos pranešimo pranešimas</string>
<string name="error_report_notification_toast">Įvyko klaida, peržiūrėti pranešimą</string>
</resources>

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="main_bg_subtitle">Tekan \"Cari\" untuk bermula</string>
<string name="main_bg_subtitle">Tekan kanta kaca \"Cari\" untuk bermula</string>
<string name="upload_date_text">Diterbitkan pada %1$s</string>
<string name="no_player_found">Tiada pemain strim ditemui. Muat turun VLC\?</string>
<string name="no_player_found_toast">Tiada pemain strim yang ditemui (anda boleh memasang VLC untuk memainkan).</string>
@ -43,7 +43,7 @@
<string name="show_higher_resolutions_title">Papar resolusi yang lebih tinggi</string>
<string name="show_higher_resolutions_summary">Hanya peranti tertentu yang boleh bermain video 2K/4K</string>
<string name="play_with_kodi_title">Main dengan Kodi</string>
<string name="kore_not_found">App Kore tidak dijumpai. Pasangkan\?</string>
<string name="kore_not_found">Pasangkan aplikasi Kore yang tidak dijumpai\?</string>
<string name="show_play_with_kodi_title">Paparkan opsyen \"Main dengan Kodi\"</string>
<string name="show_play_with_kodi_summary">Paparkan opsyen untuk memain video dengan Kodi</string>
<string name="play_audio">Audio</string>
@ -441,4 +441,6 @@
<string name="overwrite_failed">tidak boleh tulis ganti fail</string>
<string name="overwrite_unrelated_warning">Fail dengan nama yang sama sudah ada</string>
<string name="dont_show">Jangan tunjuk</string>
<string name="unmute">Nyahbisu</string>
<string name="notification_colorize_summary">Minta Android menyesuaikan warna pemberitahuan sesuai dengan warna utama di thumbnail (perhatikan bahawa ini tidak tersedia dalam semua perangkat)</string>
</resources>

Some files were not shown because too many files have changed in this diff Show More