Merge pull request #6432 from TeamNewPipe/release_0.21.4
Release 0.21.4
This commit is contained in:
commit
70b9330b61
|
@ -41,6 +41,6 @@ You'll see exactly what is sent, be able to add your comments, and then send it.
|
|||
|
||||
## Communication
|
||||
|
||||
* The [#newpipe](irc:irc.freenode.net/newpipe) channel on freenode has the core team and other developers in it. [Click here for webchat](https://webchat.freenode.net/?channels=newpipe)!
|
||||
* You can also use a Matrix account to join the Newpipe channel at [#freenode_#newpipe:matrix.org](https://matrix.to/#/#freenode_#newpipe:matrix.org).
|
||||
* The #newpipe channel on Libera Chat (`ircs://irc.libera.chat:6697/newpipe`) has the core team and other developers in it. [Click here for webchat](https://web.libera.chat/#newpipe)!
|
||||
* You can also use a Matrix account to join the NewPipe channel at [#newpipe:libera.chat](https://matrix.to/#/#newpipe:libera.chat).
|
||||
* Post suggestions, changes, ideas etc. on GitHub or IRC.
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: 💬 IRC
|
||||
url: https://webchat.freenode.net/#newpipe
|
||||
url: https://web.libera.chat/#newpipe
|
||||
about: Chat with us via IRC for quick Q/A
|
||||
- name: 💬 Matrix
|
||||
url: https://matrix.to/#/#freenode_#newpipe:matrix.org
|
||||
url: https://matrix.to/#/#newpipe:libera.chat
|
||||
about: Chat with us via Matrix for quick Q/A
|
||||
|
|
|
@ -4,6 +4,7 @@ on:
|
|||
pull_request:
|
||||
branches:
|
||||
- dev
|
||||
- master
|
||||
push:
|
||||
branches:
|
||||
- dev
|
||||
|
@ -25,7 +26,7 @@ jobs:
|
|||
uses: actions/setup-java@v2
|
||||
with:
|
||||
java-version: 8
|
||||
distribution: "zulu"
|
||||
distribution: "adopt"
|
||||
|
||||
- name: Cache Gradle dependencies
|
||||
uses: actions/cache@v2
|
||||
|
@ -54,7 +55,7 @@ jobs:
|
|||
uses: actions/setup-java@v2
|
||||
with:
|
||||
java-version: 8
|
||||
distribution: "zulu"
|
||||
distribution: "adopt"
|
||||
|
||||
- name: Cache Gradle dependencies
|
||||
uses: actions/cache@v2
|
||||
|
@ -79,7 +80,7 @@ jobs:
|
|||
# uses: actions/setup-java@v2
|
||||
# with:
|
||||
# java-version: 11 # Sonar requires JDK 11
|
||||
# distribution: "zulu"
|
||||
# distribution: "adopt"
|
||||
|
||||
# - name: Cache SonarCloud packages
|
||||
# uses: actions/cache@v2
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
<a href="https://www.gnu.org/licenses/gpl-3.0" alt="License: GPLv3"><img src="https://img.shields.io/badge/Licencia-GPL%20v3-blue.svg"></a>
|
||||
<a href="https://github.com/TeamNewPipe/NewPipe/actions" alt="Build Status"><img src="https://github.com/TeamNewPipe/NewPipe/workflows/CI/badge.svg?branch=dev&event=push"></a>
|
||||
<a href="https://hosted.weblate.org/engage/newpipe/es/" alt="Estado de la traducción"><img src="https://hosted.weblate.org/widgets/newpipe/es/svg-badge.svg"></a>
|
||||
<a href="https://webchat.freenode.net/#newpipe" alt="IRC channel: #newpipe"><img src="https://img.shields.io/badge/Canal%20de%20IRC%20-%23newpipe-brightgreen.svg"></a>
|
||||
<a href="https://web.libera.chat/#newpipe" alt="IRC channel: #newpipe"><img src="https://img.shields.io/badge/Canal%20de%20IRC%20-%23newpipe-brightgreen.svg"></a>
|
||||
<a href="https://www.bountysource.com/teams/newpipe" alt="Bountysource bounties"><img src="https://img.shields.io/bountysource/team/newpipe/activity.svg?colorB=cd201f"></a>
|
||||
</p>
|
||||
<hr>
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
<a href="https://www.gnu.org/licenses/gpl-3.0" alt="ライセンス: GPLv3"><img src="https://img.shields.io/badge/License-GPL%20v3-blue.svg"></a>
|
||||
<a href="https://github.com/TeamNewPipe/NewPipe/actions" alt="ビルド状態"><img src="https://github.com/TeamNewPipe/NewPipe/workflows/CI/badge.svg?branch=dev&event=push"></a>
|
||||
<a href="https://hosted.weblate.org/engage/newpipe/" alt="翻訳状態"><img src="https://hosted.weblate.org/widgets/newpipe/-/svg-badge.svg"></a>
|
||||
<a href="https://webchat.freenode.net/#newpipe" alt="IRC チャンネル: #newpipe"><img src="https://img.shields.io/badge/IRC%20chat-%23newpipe-brightgreen.svg"></a>
|
||||
<a href="https://web.libera.chat/#newpipe" alt="IRC チャンネル: #newpipe"><img src="https://img.shields.io/badge/IRC%20chat-%23newpipe-brightgreen.svg"></a>
|
||||
<a href="https://www.bountysource.com/teams/newpipe" alt="Bountysource 寄付"><img src="https://img.shields.io/bountysource/team/newpipe/activity.svg?colorB=cd201f"></a>
|
||||
</p>
|
||||
<hr>
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
<a href="https://www.gnu.org/licenses/gpl-3.0" alt="License: GPLv3"><img src="https://img.shields.io/badge/License-GPL%20v3-blue.svg"></a>
|
||||
<a href="https://github.com/TeamNewPipe/NewPipe/actions" alt="Build Status"><img src="https://github.com/TeamNewPipe/NewPipe/workflows/CI/badge.svg?branch=dev&event=push"></a>
|
||||
<a href="https://hosted.weblate.org/engage/newpipe/" alt="Translation Status"><img src="https://hosted.weblate.org/widgets/newpipe/-/svg-badge.svg"></a>
|
||||
<a href="https://webchat.freenode.net/#newpipe" alt="IRC channel: #newpipe"><img src="https://img.shields.io/badge/IRC%20chat-%23newpipe-brightgreen.svg"></a>
|
||||
<a href="https://web.libera.chat/#newpipe" alt="IRC channel: #newpipe"><img src="https://img.shields.io/badge/IRC%20chat-%23newpipe-brightgreen.svg"></a>
|
||||
<a href="https://www.bountysource.com/teams/newpipe" alt="Bountysource bounties"><img src="https://img.shields.io/bountysource/team/newpipe/activity.svg?colorB=cd201f"></a>
|
||||
</p>
|
||||
<hr>
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
<a href="https://www.gnu.org/licenses/gpl-3.0" alt="License: GPLv3"><img src="https://img.shields.io/badge/License-GPL%20v3-blue.svg"></a>
|
||||
<a href="https://github.com/TeamNewPipe/NewPipe/actions" alt="Build Status"><img src="https://github.com/TeamNewPipe/NewPipe/workflows/CI/badge.svg?branch=dev&event=push"></a>
|
||||
<a href="https://hosted.weblate.org/engage/newpipe/" alt="Translation Status"><img src="https://hosted.weblate.org/widgets/newpipe/-/svg-badge.svg"></a>
|
||||
<a href="https://webchat.freenode.net/#newpipe" alt="IRC channel: #newpipe"><img src="https://img.shields.io/badge/IRC%20chat-%23newpipe-brightgreen.svg"></a>
|
||||
<a href="https://web.libera.chat/#newpipe" alt="IRC channel: #newpipe"><img src="https://img.shields.io/badge/IRC%20chat-%23newpipe-brightgreen.svg"></a>
|
||||
<a href="https://www.bountysource.com/teams/newpipe" alt="Bountysource bounties"><img src="https://img.shields.io/bountysource/team/newpipe/activity.svg?colorB=cd201f"></a>
|
||||
</p>
|
||||
<hr>
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
<a href="https://www.gnu.org/licenses/gpl-3.0" alt="License: GPLv3"><img src="https://img.shields.io/badge/License-GPL%20v3-blue.svg"></a>
|
||||
<a href="https://github.com/TeamNewPipe/NewPipe/actions" alt="Build Status"><img src="https://github.com/TeamNewPipe/NewPipe/workflows/CI/badge.svg?branch=dev&event=push"></a>
|
||||
<a href="https://hosted.weblate.org/engage/newpipe/" alt="Translation Status"><img src="https://hosted.weblate.org/widgets/newpipe/-/svg-badge.svg"></a>
|
||||
<a href="https://webchat.freenode.net/#newpipe" alt="IRC channel: #newpipe"><img src="https://img.shields.io/badge/IRC%20chat-%23newpipe-brightgreen.svg"></a>
|
||||
<a href="https://web.libera.chat/#newpipe" alt="IRC channel: #newpipe"><img src="https://img.shields.io/badge/IRC%20chat-%23newpipe-brightgreen.svg"></a>
|
||||
<a href="https://www.bountysource.com/teams/newpipe" alt="Bountysource bounties"><img src="https://img.shields.io/bountysource/team/newpipe/activity.svg?colorB=cd201f"></a>
|
||||
</p>
|
||||
<hr>
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
<a href="https://www.gnu.org/licenses/gpl-3.0" alt="License: GPLv3"><img src="https://img.shields.io/badge/License-GPL%20v3-blue.svg"></a>
|
||||
<a href="https://github.com/TeamNewPipe/NewPipe/actions" alt="Build Status"><img src="https://github.com/TeamNewPipe/NewPipe/workflows/CI/badge.svg?branch=dev&event=push"></a>
|
||||
<a href="https://hosted.weblate.org/engage/newpipe/" alt="Translation Status"><img src="https://hosted.weblate.org/widgets/newpipe/-/svg-badge.svg"></a>
|
||||
<a href="https://webchat.freenode.net/#newpipe" alt="IRC channel: #newpipe"><img src="https://img.shields.io/badge/IRC%20chat-%23newpipe-brightgreen.svg"></a>
|
||||
<a href="https://web.libera.chat/#newpipe" alt="IRC channel: #newpipe"><img src="https://img.shields.io/badge/IRC%20chat-%23newpipe-brightgreen.svg"></a>
|
||||
<a href="https://www.bountysource.com/teams/newpipe" alt="Bountysource bounties"><img src="https://img.shields.io/bountysource/team/newpipe/activity.svg?colorB=cd201f"></a>
|
||||
</p>
|
||||
<hr>
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
<a href="https://www.gnu.org/licenses/gpl-3.0" alt="Laysinka: GPLv3"><img src="https://img.shields.io/badge/License-GPL%20v3-blue.svg"></a>
|
||||
<a href="https://github.com/TeamNewPipe/NewPipe/actions" alt="Darajada Dhismaha"><img src="https://github.com/TeamNewPipe/NewPipe/workflows/CI/badge.svg?branch=dev&event=push"></a>
|
||||
<a href="https://hosted.weblate.org/engage/newpipe/" alt="Heerka Turjimaada"><img src="https://hosted.weblate.org/widgets/newpipe/-/svg-badge.svg"></a>
|
||||
<a href="https://webchat.freenode.net/#newpipe" alt="Kanaalka IRC: #newpipe"><img src="https://img.shields.io/badge/IRC%20chat-%23newpipe-brightgreen.svg"></a>
|
||||
<a href="https://web.libera.chat/#newpipe" alt="Kanaalka IRC: #newpipe"><img src="https://img.shields.io/badge/IRC%20chat-%23newpipe-brightgreen.svg"></a>
|
||||
<a href="https://www.bountysource.com/teams/newpipe" alt="Kuwa Bountysource "><img src="https://img.shields.io/bountysource/team/newpipe/activity.svg?colorB=cd201f"></a>
|
||||
</p>
|
||||
<hr>
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
<a href="https://www.gnu.org/licenses/gpl-3.0" alt="Lisans: GPLv3"><img src="https://img.shields.io/badge/License-GPL%20v3-blue.svg"></a>
|
||||
<a href="https://github.com/TeamNewPipe/NewPipe/actions" alt="Derleme Durumu"><img src="https://github.com/TeamNewPipe/NewPipe/workflows/CI/badge.svg?branch=dev&event=push"></a>
|
||||
<a href="https://hosted.weblate.org/engage/newpipe/" alt="Çeviri Durumu"><img src="https://hosted.weblate.org/widgets/newpipe/-/svg-badge.svg"></a>
|
||||
<a href="https://webchat.freenode.net/#newpipe" alt="IRC kanalı: #newpipe"><img src="https://img.shields.io/badge/IRC%20chat-%23newpipe-brightgreen.svg"></a>
|
||||
<a href="https://web.libera.chat/#newpipe" alt="IRC kanalı: #newpipe"><img src="https://img.shields.io/badge/IRC%20chat-%23newpipe-brightgreen.svg"></a>
|
||||
<a href="https://www.bountysource.com/teams/newpipe" alt="Bountysource ödülleri"><img src="https://img.shields.io/bountysource/team/newpipe/activity.svg?colorB=cd201f"></a>
|
||||
</p>
|
||||
<hr>
|
||||
|
|
|
@ -17,8 +17,8 @@ android {
|
|||
resValue "string", "app_name", "NewPipe"
|
||||
minSdkVersion 19
|
||||
targetSdkVersion 29
|
||||
versionCode 969
|
||||
versionName "0.21.3"
|
||||
versionCode 970
|
||||
versionName "0.21.4"
|
||||
|
||||
multiDexEnabled true
|
||||
|
||||
|
@ -178,12 +178,12 @@ sonarqube {
|
|||
|
||||
dependencies {
|
||||
/** Desugaring **/
|
||||
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.1'
|
||||
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
|
||||
|
||||
/** NewPipe libraries **/
|
||||
// You can use a local version by uncommenting a few lines in settings.gradle
|
||||
implementation 'com.github.TeamNewPipe:nanojson:1d9e1aea9049fc9f85e68b43ba39fe7be1c1f751'
|
||||
implementation 'com.github.TeamNewPipe:NewPipeExtractor:v0.21.3'
|
||||
implementation 'com.github.TeamNewPipe:NewPipeExtractor:v0.21.4'
|
||||
|
||||
/** Checkstyle **/
|
||||
checkstyle "com.puppycrawl.tools:checkstyle:${checkstyleVersion}"
|
||||
|
@ -258,7 +258,7 @@ dependencies {
|
|||
implementation "com.jakewharton.rxbinding4:rxbinding:4.0.0"
|
||||
|
||||
// Date and time formatting
|
||||
implementation "org.ocpsoft.prettytime:prettytime:5.0.0.Final"
|
||||
implementation "org.ocpsoft.prettytime:prettytime:5.0.1.Final"
|
||||
|
||||
/** Debugging **/
|
||||
// Memory leak detection
|
||||
|
@ -270,7 +270,7 @@ dependencies {
|
|||
debugImplementation "com.facebook.stetho:stetho-okhttp3:${stethoVersion}"
|
||||
|
||||
/** Testing **/
|
||||
testImplementation 'junit:junit:4.13.1'
|
||||
testImplementation 'junit:junit:4.13.2'
|
||||
testImplementation "org.mockito:mockito-core:${mockitoVersion}"
|
||||
testImplementation "org.mockito:mockito-inline:${mockitoVersion}"
|
||||
|
||||
|
|
|
@ -319,7 +319,7 @@
|
|||
<data android:pathPrefix="/video-channels/" />
|
||||
</intent-filter>
|
||||
|
||||
<!-- Bandcamp filter -->
|
||||
<!-- Bandcamp filter for tracks, albums and playlists -->
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW"/>
|
||||
<action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH"/>
|
||||
|
@ -330,10 +330,23 @@
|
|||
|
||||
<data android:scheme="http"/>
|
||||
<data android:scheme="https"/>
|
||||
<data android:host="bandcamp.com"/>
|
||||
<data android:host="*.bandcamp.com"/>
|
||||
<data android:pathPrefix="/"/>
|
||||
</intent-filter>
|
||||
|
||||
<!-- Bandcamp filter for radio -->
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW"/>
|
||||
<action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH"/>
|
||||
<action android:name="android.nfc.action.NDEF_DISCOVERED"/>
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT"/>
|
||||
<category android:name="android.intent.category.BROWSABLE"/>
|
||||
|
||||
<data android:scheme="http"/>
|
||||
<data android:scheme="https"/>
|
||||
<data android:sspPattern="bandcamp.com/?show=*"/>
|
||||
</intent-filter>
|
||||
|
||||
</activity>
|
||||
<service
|
||||
android:name=".RouterActivity$FetcherService"
|
||||
|
|
|
@ -95,6 +95,7 @@ import static org.schabi.newpipe.util.Localization.assureCorrectAppLanguage;
|
|||
|
||||
public class MainActivity extends AppCompatActivity {
|
||||
private static final String TAG = "MainActivity";
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
public static final boolean DEBUG = !BuildConfig.BUILD_TYPE.equals("release");
|
||||
|
||||
private ActivityMainBinding mainBinding;
|
||||
|
|
|
@ -466,6 +466,11 @@ public class RouterActivity extends AppCompatActivity {
|
|||
if (capabilities.contains(AUDIO)) {
|
||||
returnList.add(backgroundPlayer);
|
||||
}
|
||||
// download is redundant for linkType CHANNEL AND PLAYLIST (till playlist downloading is
|
||||
// not supported )
|
||||
returnList.add(new AdapterChoiceItem(getString(R.string.download_key),
|
||||
getString(R.string.download),
|
||||
R.drawable.ic_file_download));
|
||||
|
||||
} else {
|
||||
returnList.add(showInfo);
|
||||
|
@ -478,10 +483,6 @@ public class RouterActivity extends AppCompatActivity {
|
|||
}
|
||||
}
|
||||
|
||||
returnList.add(new AdapterChoiceItem(getString(R.string.download_key),
|
||||
getString(R.string.download),
|
||||
R.drawable.ic_file_download));
|
||||
|
||||
return returnList;
|
||||
}
|
||||
|
||||
|
|
|
@ -312,25 +312,36 @@ public class DownloadDialog extends DialogFragment
|
|||
|
||||
private void fetchStreamsSize() {
|
||||
disposables.clear();
|
||||
|
||||
disposables.add(StreamSizeWrapper.fetchSizeForWrapper(wrappedVideoStreams)
|
||||
.subscribe(result -> {
|
||||
if (dialogBinding.videoAudioGroup.getCheckedRadioButtonId() == R.id.video_button) {
|
||||
setupVideoSpinner();
|
||||
}
|
||||
}));
|
||||
if (dialogBinding.videoAudioGroup.getCheckedRadioButtonId()
|
||||
== R.id.video_button) {
|
||||
setupVideoSpinner();
|
||||
}
|
||||
}, throwable -> ErrorActivity.reportErrorInSnackbar(context,
|
||||
new ErrorInfo(throwable, UserAction.DOWNLOAD_OPEN_DIALOG,
|
||||
"Downloading video stream size",
|
||||
currentInfo.getServiceId()))));
|
||||
disposables.add(StreamSizeWrapper.fetchSizeForWrapper(wrappedAudioStreams)
|
||||
.subscribe(result -> {
|
||||
if (dialogBinding.videoAudioGroup.getCheckedRadioButtonId() == R.id.audio_button) {
|
||||
setupAudioSpinner();
|
||||
}
|
||||
}));
|
||||
if (dialogBinding.videoAudioGroup.getCheckedRadioButtonId()
|
||||
== R.id.audio_button) {
|
||||
setupAudioSpinner();
|
||||
}
|
||||
}, throwable -> ErrorActivity.reportErrorInSnackbar(context,
|
||||
new ErrorInfo(throwable, UserAction.DOWNLOAD_OPEN_DIALOG,
|
||||
"Downloading audio stream size",
|
||||
currentInfo.getServiceId()))));
|
||||
disposables.add(StreamSizeWrapper.fetchSizeForWrapper(wrappedSubtitleStreams)
|
||||
.subscribe(result -> {
|
||||
if (dialogBinding.videoAudioGroup.getCheckedRadioButtonId() == R.id.subtitle_button) {
|
||||
setupSubtitleSpinner();
|
||||
}
|
||||
}));
|
||||
if (dialogBinding.videoAudioGroup.getCheckedRadioButtonId()
|
||||
== R.id.subtitle_button) {
|
||||
setupSubtitleSpinner();
|
||||
}
|
||||
}, throwable -> ErrorActivity.reportErrorInSnackbar(context,
|
||||
new ErrorInfo(throwable, UserAction.DOWNLOAD_OPEN_DIALOG,
|
||||
"Downloading subtitle stream size",
|
||||
currentInfo.getServiceId()))));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -11,15 +11,20 @@ import org.schabi.newpipe.BaseFragment;
|
|||
import org.schabi.newpipe.R;
|
||||
|
||||
public class EmptyFragment extends BaseFragment {
|
||||
final boolean showMessage;
|
||||
private static final String SHOW_MESSAGE = "SHOW_MESSAGE";
|
||||
|
||||
public EmptyFragment(final boolean showMessage) {
|
||||
this.showMessage = showMessage;
|
||||
public static final EmptyFragment newInstance(final boolean showMessage) {
|
||||
final EmptyFragment emptyFragment = new EmptyFragment();
|
||||
final Bundle bundle = new Bundle(1);
|
||||
bundle.putBoolean(SHOW_MESSAGE, showMessage);
|
||||
emptyFragment.setArguments(bundle);
|
||||
return emptyFragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(final LayoutInflater inflater, @Nullable final ViewGroup container,
|
||||
final Bundle savedInstanceState) {
|
||||
final boolean showMessage = getArguments().getBoolean(SHOW_MESSAGE);
|
||||
final View view = inflater.inflate(R.layout.fragment_empty, container, false);
|
||||
view.findViewById(R.id.empty_state_view).setVisibility(
|
||||
showMessage ? View.VISIBLE : View.GONE);
|
||||
|
|
|
@ -4,23 +4,38 @@ import android.os.Bundle;
|
|||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.StringRes;
|
||||
import androidx.appcompat.widget.TooltipCompat;
|
||||
import androidx.core.text.HtmlCompat;
|
||||
|
||||
import com.google.android.material.chip.Chip;
|
||||
|
||||
import org.schabi.newpipe.BaseFragment;
|
||||
import org.schabi.newpipe.R;
|
||||
import org.schabi.newpipe.databinding.FragmentDescriptionBinding;
|
||||
import org.schabi.newpipe.databinding.ItemMetadataBinding;
|
||||
import org.schabi.newpipe.databinding.ItemMetadataTagsBinding;
|
||||
import org.schabi.newpipe.extractor.stream.Description;
|
||||
import org.schabi.newpipe.extractor.stream.StreamInfo;
|
||||
import org.schabi.newpipe.util.Localization;
|
||||
import org.schabi.newpipe.util.NavigationHelper;
|
||||
import org.schabi.newpipe.util.ShareUtils;
|
||||
import org.schabi.newpipe.util.TextLinkifier;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import icepick.State;
|
||||
import io.reactivex.rxjava3.disposables.Disposable;
|
||||
|
||||
import static android.text.TextUtils.isEmpty;
|
||||
import static org.schabi.newpipe.extractor.stream.StreamExtractor.NO_AGE_LIMIT;
|
||||
import static org.schabi.newpipe.extractor.utils.Utils.isBlank;
|
||||
|
||||
public class DescriptionFragment extends BaseFragment {
|
||||
|
||||
|
@ -28,6 +43,7 @@ public class DescriptionFragment extends BaseFragment {
|
|||
StreamInfo streamInfo = null;
|
||||
@Nullable
|
||||
Disposable descriptionDisposable = null;
|
||||
FragmentDescriptionBinding binding;
|
||||
|
||||
public DescriptionFragment() {
|
||||
}
|
||||
|
@ -40,11 +56,11 @@ public class DescriptionFragment extends BaseFragment {
|
|||
public View onCreateView(@NonNull final LayoutInflater inflater,
|
||||
@Nullable final ViewGroup container,
|
||||
@Nullable final Bundle savedInstanceState) {
|
||||
final FragmentDescriptionBinding binding =
|
||||
FragmentDescriptionBinding.inflate(inflater, container, false);
|
||||
binding = FragmentDescriptionBinding.inflate(inflater, container, false);
|
||||
if (streamInfo != null) {
|
||||
setupUploadDate(binding.detailUploadDateView);
|
||||
setupDescription(binding.detailDescriptionView);
|
||||
setupUploadDate();
|
||||
setupDescription();
|
||||
setupMetadata(inflater, binding.detailMetadataLayout);
|
||||
}
|
||||
return binding.getRoot();
|
||||
}
|
||||
|
@ -57,37 +73,197 @@ public class DescriptionFragment extends BaseFragment {
|
|||
}
|
||||
}
|
||||
|
||||
private void setupUploadDate(final TextView uploadDateTextView) {
|
||||
|
||||
private void setupUploadDate() {
|
||||
if (streamInfo.getUploadDate() != null) {
|
||||
uploadDateTextView.setText(Localization
|
||||
binding.detailUploadDateView.setText(Localization
|
||||
.localizeUploadDate(activity, streamInfo.getUploadDate().offsetDateTime()));
|
||||
} else {
|
||||
uploadDateTextView.setVisibility(View.GONE);
|
||||
binding.detailUploadDateView.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
private void setupDescription(final TextView descriptionTextView) {
|
||||
|
||||
private void setupDescription() {
|
||||
final Description description = streamInfo.getDescription();
|
||||
if (description == null || isEmpty(description.getContent())
|
||||
|| description == Description.emptyDescription) {
|
||||
descriptionTextView.setText("");
|
||||
binding.detailDescriptionView.setVisibility(View.GONE);
|
||||
binding.detailSelectDescriptionButton.setVisibility(View.GONE);
|
||||
return;
|
||||
}
|
||||
|
||||
// start with disabled state. This also loads description content (!)
|
||||
disableDescriptionSelection();
|
||||
|
||||
binding.detailSelectDescriptionButton.setOnClickListener(v -> {
|
||||
if (binding.detailDescriptionNoteView.getVisibility() == View.VISIBLE) {
|
||||
disableDescriptionSelection();
|
||||
} else {
|
||||
// enable selection only when button is clicked to prevent flickering
|
||||
enableDescriptionSelection();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void enableDescriptionSelection() {
|
||||
binding.detailDescriptionNoteView.setVisibility(View.VISIBLE);
|
||||
binding.detailDescriptionView.setTextIsSelectable(true);
|
||||
|
||||
final String buttonLabel = getString(R.string.description_select_disable);
|
||||
binding.detailSelectDescriptionButton.setContentDescription(buttonLabel);
|
||||
TooltipCompat.setTooltipText(binding.detailSelectDescriptionButton, buttonLabel);
|
||||
binding.detailSelectDescriptionButton.setImageResource(R.drawable.ic_close);
|
||||
}
|
||||
|
||||
private void disableDescriptionSelection() {
|
||||
// show description content again, otherwise some links are not clickable
|
||||
loadDescriptionContent();
|
||||
|
||||
binding.detailDescriptionNoteView.setVisibility(View.GONE);
|
||||
binding.detailDescriptionView.setTextIsSelectable(false);
|
||||
|
||||
final String buttonLabel = getString(R.string.description_select_enable);
|
||||
binding.detailSelectDescriptionButton.setContentDescription(buttonLabel);
|
||||
TooltipCompat.setTooltipText(binding.detailSelectDescriptionButton, buttonLabel);
|
||||
binding.detailSelectDescriptionButton.setImageResource(R.drawable.ic_select_all);
|
||||
}
|
||||
|
||||
private void loadDescriptionContent() {
|
||||
final Description description = streamInfo.getDescription();
|
||||
switch (description.getType()) {
|
||||
case Description.HTML:
|
||||
descriptionDisposable = TextLinkifier.createLinksFromHtmlBlock(requireContext(),
|
||||
description.getContent(), descriptionTextView,
|
||||
description.getContent(), binding.detailDescriptionView,
|
||||
HtmlCompat.FROM_HTML_MODE_LEGACY);
|
||||
break;
|
||||
case Description.MARKDOWN:
|
||||
descriptionDisposable = TextLinkifier.createLinksFromMarkdownText(requireContext(),
|
||||
description.getContent(), descriptionTextView);
|
||||
description.getContent(), binding.detailDescriptionView);
|
||||
break;
|
||||
case Description.PLAIN_TEXT: default:
|
||||
descriptionDisposable = TextLinkifier.createLinksFromPlainText(requireContext(),
|
||||
description.getContent(), descriptionTextView);
|
||||
description.getContent(), binding.detailDescriptionView);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void setupMetadata(final LayoutInflater inflater,
|
||||
final LinearLayout layout) {
|
||||
addMetadataItem(inflater, layout, false,
|
||||
R.string.metadata_category, streamInfo.getCategory());
|
||||
|
||||
addTagsMetadataItem(inflater, layout);
|
||||
|
||||
addMetadataItem(inflater, layout, false,
|
||||
R.string.metadata_licence, streamInfo.getLicence());
|
||||
|
||||
addPrivacyMetadataItem(inflater, layout);
|
||||
|
||||
if (streamInfo.getAgeLimit() != NO_AGE_LIMIT) {
|
||||
addMetadataItem(inflater, layout, false,
|
||||
R.string.metadata_age_limit, String.valueOf(streamInfo.getAgeLimit()));
|
||||
}
|
||||
|
||||
if (streamInfo.getLanguageInfo() != null) {
|
||||
addMetadataItem(inflater, layout, false,
|
||||
R.string.metadata_language, streamInfo.getLanguageInfo().getDisplayLanguage());
|
||||
}
|
||||
|
||||
addMetadataItem(inflater, layout, true,
|
||||
R.string.metadata_support, streamInfo.getSupportInfo());
|
||||
addMetadataItem(inflater, layout, true,
|
||||
R.string.metadata_host, streamInfo.getHost());
|
||||
addMetadataItem(inflater, layout, true,
|
||||
R.string.metadata_thumbnail_url, streamInfo.getThumbnailUrl());
|
||||
}
|
||||
|
||||
private void addMetadataItem(final LayoutInflater inflater,
|
||||
final LinearLayout layout,
|
||||
final boolean linkifyContent,
|
||||
@StringRes final int type,
|
||||
@Nullable final String content) {
|
||||
if (isBlank(content)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final ItemMetadataBinding itemBinding
|
||||
= ItemMetadataBinding.inflate(inflater, layout, false);
|
||||
|
||||
itemBinding.metadataTypeView.setText(type);
|
||||
itemBinding.metadataTypeView.setOnLongClickListener(v -> {
|
||||
ShareUtils.copyToClipboard(requireContext(), content);
|
||||
return true;
|
||||
});
|
||||
|
||||
if (linkifyContent) {
|
||||
TextLinkifier.createLinksFromPlainText(requireContext(),
|
||||
content, itemBinding.metadataContentView);
|
||||
} else {
|
||||
itemBinding.metadataContentView.setText(content);
|
||||
}
|
||||
|
||||
layout.addView(itemBinding.getRoot());
|
||||
}
|
||||
|
||||
private void addTagsMetadataItem(final LayoutInflater inflater, final LinearLayout layout) {
|
||||
if (streamInfo.getTags() != null && !streamInfo.getTags().isEmpty()) {
|
||||
final ItemMetadataTagsBinding itemBinding
|
||||
= ItemMetadataTagsBinding.inflate(inflater, layout, false);
|
||||
|
||||
final List<String> tags = new ArrayList<>(streamInfo.getTags());
|
||||
Collections.sort(tags);
|
||||
for (final String tag : tags) {
|
||||
final Chip chip = (Chip) inflater.inflate(R.layout.chip,
|
||||
itemBinding.metadataTagsChips, false);
|
||||
chip.setText(tag);
|
||||
chip.setOnClickListener(this::onTagClick);
|
||||
chip.setOnLongClickListener(this::onTagLongClick);
|
||||
itemBinding.metadataTagsChips.addView(chip);
|
||||
}
|
||||
|
||||
layout.addView(itemBinding.getRoot());
|
||||
}
|
||||
}
|
||||
|
||||
private void onTagClick(final View chip) {
|
||||
if (getParentFragment() != null) {
|
||||
NavigationHelper.openSearchFragment(getParentFragment().getParentFragmentManager(),
|
||||
streamInfo.getServiceId(), ((Chip) chip).getText().toString());
|
||||
}
|
||||
}
|
||||
|
||||
private boolean onTagLongClick(final View chip) {
|
||||
ShareUtils.copyToClipboard(requireContext(), ((Chip) chip).getText().toString());
|
||||
return true;
|
||||
}
|
||||
|
||||
private void addPrivacyMetadataItem(final LayoutInflater inflater, final LinearLayout layout) {
|
||||
if (streamInfo.getPrivacy() != null) {
|
||||
@StringRes final int contentRes;
|
||||
switch (streamInfo.getPrivacy()) {
|
||||
case PUBLIC:
|
||||
contentRes = R.string.metadata_privacy_public;
|
||||
break;
|
||||
case UNLISTED:
|
||||
contentRes = R.string.metadata_privacy_unlisted;
|
||||
break;
|
||||
case PRIVATE:
|
||||
contentRes = R.string.metadata_privacy_private;
|
||||
break;
|
||||
case INTERNAL:
|
||||
contentRes = R.string.metadata_privacy_internal;
|
||||
break;
|
||||
case OTHER: default:
|
||||
contentRes = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (contentRes != 0) {
|
||||
addMetadataItem(inflater, layout, false,
|
||||
R.string.metadata_privacy, getString(contentRes));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -929,20 +929,20 @@ public final class VideoDetailFragment
|
|||
|
||||
if (showRelatedItems && binding.relatedItemsLayout == null) {
|
||||
// temp empty fragment. will be updated in handleResult
|
||||
pageAdapter.addFragment(new EmptyFragment(false), RELATED_TAB_TAG);
|
||||
pageAdapter.addFragment(EmptyFragment.newInstance(false), RELATED_TAB_TAG);
|
||||
tabIcons.add(R.drawable.ic_art_track);
|
||||
tabContentDescriptions.add(R.string.related_items_tab_description);
|
||||
}
|
||||
|
||||
if (showDescription) {
|
||||
// temp empty fragment. will be updated in handleResult
|
||||
pageAdapter.addFragment(new EmptyFragment(false), DESCRIPTION_TAB_TAG);
|
||||
pageAdapter.addFragment(EmptyFragment.newInstance(false), DESCRIPTION_TAB_TAG);
|
||||
tabIcons.add(R.drawable.ic_description);
|
||||
tabContentDescriptions.add(R.string.description_tab_description);
|
||||
}
|
||||
|
||||
if (pageAdapter.getCount() == 0) {
|
||||
pageAdapter.addFragment(new EmptyFragment(true), EMPTY_TAB_TAG);
|
||||
pageAdapter.addFragment(EmptyFragment.newInstance(true), EMPTY_TAB_TAG);
|
||||
}
|
||||
pageAdapter.notifyDataSetUpdate();
|
||||
|
||||
|
|
|
@ -370,10 +370,10 @@ public abstract class BaseListFragment<I, N> extends BaseStateFragment<I>
|
|||
StreamDialogEntry.share
|
||||
));
|
||||
}
|
||||
entries.add(StreamDialogEntry.open_in_browser);
|
||||
if (KoreUtil.shouldShowPlayWithKodi(context, item.getServiceId())) {
|
||||
entries.add(StreamDialogEntry.play_with_kodi);
|
||||
}
|
||||
|
||||
if (!isNullOrEmpty(item.getUploaderUrl())) {
|
||||
entries.add(StreamDialogEntry.show_channel_details);
|
||||
}
|
||||
|
|
|
@ -59,6 +59,7 @@ import io.reactivex.rxjava3.core.Single;
|
|||
import io.reactivex.rxjava3.disposables.CompositeDisposable;
|
||||
import io.reactivex.rxjava3.disposables.Disposable;
|
||||
|
||||
import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty;
|
||||
import static org.schabi.newpipe.ktx.ViewUtils.animate;
|
||||
import static org.schabi.newpipe.ktx.ViewUtils.animateHideRecyclerViewAllowingScrolling;
|
||||
|
||||
|
@ -160,9 +161,15 @@ public class PlaylistFragment extends BaseListInfoFragment<PlaylistInfo> {
|
|||
StreamDialogEntry.share
|
||||
));
|
||||
}
|
||||
entries.add(StreamDialogEntry.open_in_browser);
|
||||
if (KoreUtil.shouldShowPlayWithKodi(context, item.getServiceId())) {
|
||||
entries.add(StreamDialogEntry.play_with_kodi);
|
||||
}
|
||||
|
||||
if (!isNullOrEmpty(item.getUploaderUrl())) {
|
||||
entries.add(StreamDialogEntry.show_channel_details);
|
||||
}
|
||||
|
||||
StreamDialogEntry.setEnabledEntries(entries);
|
||||
|
||||
StreamDialogEntry.start_here_on_background.setCustomAction((fragment, infoItem) ->
|
||||
|
|
|
@ -9,6 +9,7 @@ import android.text.Editable;
|
|||
import android.text.Html;
|
||||
import android.text.TextUtils;
|
||||
import android.text.TextWatcher;
|
||||
import android.text.style.CharacterStyle;
|
||||
import android.util.Log;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
|
@ -588,6 +589,11 @@ public class SearchFragment extends BaseListFragment<SearchInfo, ListExtractor.I
|
|||
|
||||
@Override
|
||||
public void afterTextChanged(final Editable s) {
|
||||
// Remove rich text formatting
|
||||
for (final CharacterStyle span : s.getSpans(0, s.length(), CharacterStyle.class)) {
|
||||
s.removeSpan(span);
|
||||
}
|
||||
|
||||
final String newText = searchEditText.getText().toString();
|
||||
suggestionPublisher.onNext(newText);
|
||||
}
|
||||
|
|
|
@ -137,7 +137,10 @@ public class CommentsMiniInfoItemHolder extends InfoItemHolder {
|
|||
}
|
||||
|
||||
if (item.getLikeCount() >= 0) {
|
||||
itemLikesCountView.setText(String.valueOf(item.getLikeCount()));
|
||||
itemLikesCountView.setText(
|
||||
Localization.shortCount(
|
||||
itemBuilder.getContext(),
|
||||
item.getLikeCount()));
|
||||
} else {
|
||||
itemLikesCountView.setText("-");
|
||||
}
|
||||
|
|
|
@ -53,6 +53,8 @@ import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
|
|||
import io.reactivex.rxjava3.disposables.CompositeDisposable;
|
||||
import io.reactivex.rxjava3.disposables.Disposable;
|
||||
|
||||
import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty;
|
||||
|
||||
public class StatisticsPlaylistFragment
|
||||
extends BaseLocalListFragment<List<StreamStatisticsEntry>, Void> {
|
||||
private final CompositeDisposable disposables = new CompositeDisposable();
|
||||
|
@ -356,9 +358,15 @@ public class StatisticsPlaylistFragment
|
|||
StreamDialogEntry.share
|
||||
));
|
||||
}
|
||||
entries.add(StreamDialogEntry.open_in_browser);
|
||||
if (KoreUtil.shouldShowPlayWithKodi(context, infoItem.getServiceId())) {
|
||||
entries.add(StreamDialogEntry.play_with_kodi);
|
||||
}
|
||||
|
||||
if (!isNullOrEmpty(infoItem.getUploaderUrl())) {
|
||||
entries.add(StreamDialogEntry.show_channel_details);
|
||||
}
|
||||
|
||||
StreamDialogEntry.setEnabledEntries(entries);
|
||||
|
||||
StreamDialogEntry.start_here_on_background.setCustomAction((fragment, infoItemDuplicate) ->
|
||||
|
|
|
@ -66,6 +66,7 @@ import io.reactivex.rxjava3.disposables.Disposable;
|
|||
import io.reactivex.rxjava3.schedulers.Schedulers;
|
||||
import io.reactivex.rxjava3.subjects.PublishSubject;
|
||||
|
||||
import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty;
|
||||
import static org.schabi.newpipe.ktx.ViewUtils.animate;
|
||||
|
||||
public class LocalPlaylistFragment extends BaseLocalListFragment<List<PlaylistStreamEntry>, Void> {
|
||||
|
@ -768,9 +769,15 @@ public class LocalPlaylistFragment extends BaseLocalListFragment<List<PlaylistSt
|
|||
StreamDialogEntry.share
|
||||
));
|
||||
}
|
||||
entries.add(StreamDialogEntry.open_in_browser);
|
||||
if (KoreUtil.shouldShowPlayWithKodi(context, infoItem.getServiceId())) {
|
||||
entries.add(StreamDialogEntry.play_with_kodi);
|
||||
}
|
||||
|
||||
if (!isNullOrEmpty(infoItem.getUploaderUrl())) {
|
||||
entries.add(StreamDialogEntry.show_channel_details);
|
||||
}
|
||||
|
||||
StreamDialogEntry.setEnabledEntries(entries);
|
||||
|
||||
StreamDialogEntry.start_here_on_background.setCustomAction((fragment, infoItemDuplicate) ->
|
||||
|
|
|
@ -40,7 +40,7 @@ public class ImportConfirmationDialog extends DialogFragment {
|
|||
@Override
|
||||
public Dialog onCreateDialog(@Nullable final Bundle savedInstanceState) {
|
||||
assureCorrectAppLanguage(getContext());
|
||||
return new AlertDialog.Builder(getContext())
|
||||
return new AlertDialog.Builder(requireContext())
|
||||
.setMessage(R.string.import_network_expensive_warning)
|
||||
.setCancelable(true)
|
||||
.setNegativeButton(R.string.cancel, null)
|
||||
|
|
|
@ -294,12 +294,16 @@ class SubscriptionFragment : BaseStateFragment<SubscriptionState>() {
|
|||
}
|
||||
|
||||
private fun showLongTapDialog(selectedItem: ChannelInfoItem) {
|
||||
val commands = arrayOf(getString(R.string.share), getString(R.string.unsubscribe))
|
||||
val commands = arrayOf(
|
||||
getString(R.string.share), getString(R.string.open_in_browser),
|
||||
getString(R.string.unsubscribe)
|
||||
)
|
||||
|
||||
val actions = DialogInterface.OnClickListener { _, i ->
|
||||
when (i) {
|
||||
0 -> ShareUtils.shareText(requireContext(), selectedItem.name, selectedItem.url)
|
||||
1 -> deleteChannel(selectedItem)
|
||||
1 -> ShareUtils.openUrlInBrowser(requireContext(), selectedItem.url)
|
||||
2 -> deleteChannel(selectedItem)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ import android.view.ViewGroup;
|
|||
import android.widget.PopupMenu;
|
||||
import android.widget.SeekBar;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.recyclerview.widget.ItemTouchHelper;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
|
@ -456,6 +457,7 @@ public final class PlayQueueActivity extends AppCompatActivity
|
|||
final boolean playbackSkipSilence) {
|
||||
if (player != null) {
|
||||
player.setPlaybackParameters(playbackTempo, playbackPitch, playbackSkipSilence);
|
||||
onPlaybackParameterChanged(player.getPlaybackParameters());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -639,7 +641,7 @@ public final class PlayQueueActivity extends AppCompatActivity
|
|||
queueControlBinding.controlShuffle.setImageAlpha(shuffleAlpha);
|
||||
}
|
||||
|
||||
private void onPlaybackParameterChanged(final PlaybackParameters parameters) {
|
||||
private void onPlaybackParameterChanged(@Nullable final PlaybackParameters parameters) {
|
||||
if (parameters != null) {
|
||||
if (menu != null && player != null) {
|
||||
final MenuItem item = menu.findItem(R.id.action_playback_speed);
|
||||
|
|
|
@ -3029,6 +3029,7 @@ public final class Player implements
|
|||
buildSegments();
|
||||
|
||||
binding.itemsListHeaderTitle.setVisibility(View.VISIBLE);
|
||||
binding.itemsListHeaderDuration.setVisibility(View.GONE);
|
||||
binding.shuffleButton.setVisibility(View.GONE);
|
||||
binding.repeatButton.setVisibility(View.GONE);
|
||||
|
||||
|
|
|
@ -40,29 +40,25 @@ import io.reactivex.rxjava3.subjects.BehaviorSubject;
|
|||
*/
|
||||
public abstract class PlayQueue implements Serializable {
|
||||
public static final boolean DEBUG = MainActivity.DEBUG;
|
||||
|
||||
private ArrayList<PlayQueueItem> backup;
|
||||
private ArrayList<PlayQueueItem> streams;
|
||||
|
||||
@NonNull
|
||||
private final AtomicInteger queueIndex;
|
||||
private final ArrayList<PlayQueueItem> history;
|
||||
private final List<PlayQueueItem> history = new ArrayList<>();
|
||||
|
||||
private List<PlayQueueItem> backup;
|
||||
private List<PlayQueueItem> streams;
|
||||
|
||||
private transient BehaviorSubject<PlayQueueEvent> eventBroadcast;
|
||||
private transient Flowable<PlayQueueEvent> broadcastReceiver;
|
||||
|
||||
private transient boolean disposed;
|
||||
private transient boolean disposed = false;
|
||||
|
||||
PlayQueue(final int index, final List<PlayQueueItem> startWith) {
|
||||
streams = new ArrayList<>();
|
||||
streams.addAll(startWith);
|
||||
history = new ArrayList<>();
|
||||
streams = new ArrayList<>(startWith);
|
||||
|
||||
if (streams.size() > index) {
|
||||
history.add(streams.get(index));
|
||||
}
|
||||
|
||||
queueIndex = new AtomicInteger(index);
|
||||
disposed = false;
|
||||
}
|
||||
|
||||
/*//////////////////////////////////////////////////////////////////////////
|
||||
|
@ -137,18 +133,36 @@ public abstract class PlayQueue implements Serializable {
|
|||
public synchronized void setIndex(final int index) {
|
||||
final int oldIndex = getIndex();
|
||||
|
||||
int newIndex = index;
|
||||
final int newIndex;
|
||||
|
||||
if (index < 0) {
|
||||
newIndex = 0;
|
||||
} else if (index < streams.size()) {
|
||||
// Regular assignment for index in bounds
|
||||
newIndex = index;
|
||||
} else if (streams.isEmpty()) {
|
||||
// Out of bounds from here on
|
||||
// Need to check if stream is empty to prevent arithmetic error and negative index
|
||||
newIndex = 0;
|
||||
} else if (isComplete()) {
|
||||
// Circular indexing
|
||||
newIndex = index % streams.size();
|
||||
} else {
|
||||
// Index of last element
|
||||
newIndex = streams.size() - 1;
|
||||
}
|
||||
if (index >= streams.size()) {
|
||||
newIndex = isComplete() ? index % streams.size() : streams.size() - 1;
|
||||
}
|
||||
|
||||
queueIndex.set(newIndex);
|
||||
|
||||
if (oldIndex != newIndex) {
|
||||
history.add(streams.get(newIndex));
|
||||
}
|
||||
|
||||
queueIndex.set(newIndex);
|
||||
/*
|
||||
TODO: Documentation states that a SelectEvent will only be emitted if the new index is...
|
||||
different from the old one but this is emitted regardless? Not sure what this what it does
|
||||
exactly so I won't touch it
|
||||
*/
|
||||
broadcast(new SelectEvent(oldIndex, newIndex));
|
||||
}
|
||||
|
||||
|
@ -180,8 +194,6 @@ public abstract class PlayQueue implements Serializable {
|
|||
* @return the index of the given item
|
||||
*/
|
||||
public int indexOf(@NonNull final PlayQueueItem item) {
|
||||
// referential equality, can't think of a better way to do this
|
||||
// todo: better than this
|
||||
return streams.indexOf(item);
|
||||
}
|
||||
|
||||
|
@ -410,34 +422,42 @@ public abstract class PlayQueue implements Serializable {
|
|||
}
|
||||
|
||||
/**
|
||||
* Shuffles the current play queue.
|
||||
* Shuffles the current play queue
|
||||
* <p>
|
||||
* This method first backs up the existing play queue and item being played.
|
||||
* Then a newly shuffled play queue will be generated along with currently
|
||||
* playing item placed at the beginning of the queue.
|
||||
* This method first backs up the existing play queue and item being played. Then a newly
|
||||
* shuffled play queue will be generated along with currently playing item placed at the
|
||||
* beginning of the queue. This item will also be added to the history.
|
||||
* </p>
|
||||
* <p>
|
||||
* Will emit a {@link ReorderEvent} in any context.
|
||||
* Will emit a {@link ReorderEvent} if shuffled.
|
||||
* </p>
|
||||
*
|
||||
* @implNote Does nothing if the queue has a size <= 2 (the currently playing video must stay on
|
||||
* top, so shuffling a size-2 list does nothing)
|
||||
*/
|
||||
public synchronized void shuffle() {
|
||||
// Can't shuffle an list that's empty or only has one element
|
||||
if (size() <= 2) {
|
||||
return;
|
||||
}
|
||||
// Create a backup if it doesn't already exist
|
||||
if (backup == null) {
|
||||
backup = new ArrayList<>(streams);
|
||||
}
|
||||
final int originIndex = getIndex();
|
||||
final PlayQueueItem current = getItem();
|
||||
|
||||
final int originalIndex = getIndex();
|
||||
final PlayQueueItem currentItem = getItem();
|
||||
|
||||
Collections.shuffle(streams);
|
||||
|
||||
final int newIndex = streams.indexOf(current);
|
||||
if (newIndex != -1) {
|
||||
streams.add(0, streams.remove(newIndex));
|
||||
}
|
||||
// Move currentItem to the head of the queue
|
||||
streams.remove(currentItem);
|
||||
streams.add(0, currentItem);
|
||||
queueIndex.set(0);
|
||||
if (streams.size() > 0) {
|
||||
history.add(streams.get(0));
|
||||
}
|
||||
|
||||
broadcast(new ReorderEvent(originIndex, queueIndex.get()));
|
||||
history.add(currentItem);
|
||||
|
||||
broadcast(new ReorderEvent(originalIndex, 0));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -457,7 +477,6 @@ public abstract class PlayQueue implements Serializable {
|
|||
final int originIndex = getIndex();
|
||||
final PlayQueueItem current = getItem();
|
||||
|
||||
streams.clear();
|
||||
streams = backup;
|
||||
backup = null;
|
||||
|
||||
|
@ -500,22 +519,19 @@ public abstract class PlayQueue implements Serializable {
|
|||
* we don't have to do anything with new queue.
|
||||
* This method also gives a chance to track history of items in a queue in
|
||||
* VideoDetailFragment without duplicating items from two identical queues
|
||||
* */
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(@Nullable final Object obj) {
|
||||
if (!(obj instanceof PlayQueue)
|
||||
|| getStreams().size() != ((PlayQueue) obj).getStreams().size()) {
|
||||
if (!(obj instanceof PlayQueue)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final PlayQueue other = (PlayQueue) obj;
|
||||
for (int i = 0; i < getStreams().size(); i++) {
|
||||
if (!getItem(i).getUrl().equals(other.getItem(i).getUrl())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return streams.equals(other.streams);
|
||||
}
|
||||
|
||||
return true;
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return streams.hashCode();
|
||||
}
|
||||
|
||||
public boolean isDisposed() {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package org.schabi.newpipe.settings;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
@ -25,8 +26,8 @@ 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;
|
||||
import org.schabi.newpipe.util.FilePickerActivityHelper;
|
||||
import org.schabi.newpipe.util.FilePathUtils;
|
||||
import org.schabi.newpipe.util.FilePickerActivityHelper;
|
||||
import org.schabi.newpipe.util.ZipHelper;
|
||||
|
||||
import java.io.File;
|
||||
|
@ -177,17 +178,14 @@ public class ContentSettingsFragment extends BasePreferenceFragment {
|
|||
if ((requestCode == REQUEST_IMPORT_PATH || requestCode == REQUEST_EXPORT_PATH)
|
||||
&& resultCode == Activity.RESULT_OK && data.getData() != null) {
|
||||
final File file = Utils.getFileForUri(data.getData());
|
||||
final String path = file.getAbsolutePath();
|
||||
setImportExportDataPath(file);
|
||||
|
||||
if (requestCode == REQUEST_EXPORT_PATH) {
|
||||
final SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US);
|
||||
exportDatabase(path + "/NewPipeData-" + sdf.format(new Date()) + ".zip");
|
||||
exportDatabase(file);
|
||||
} else {
|
||||
final AlertDialog.Builder builder = new AlertDialog.Builder(requireActivity());
|
||||
builder.setMessage(R.string.override_current_data)
|
||||
.setPositiveButton(getString(R.string.finish),
|
||||
(d, id) -> importDatabase(path))
|
||||
(d, id) -> importDatabase(file))
|
||||
.setNegativeButton(android.R.string.cancel,
|
||||
(d, id) -> d.cancel());
|
||||
builder.create().show();
|
||||
|
@ -195,26 +193,34 @@ public class ContentSettingsFragment extends BasePreferenceFragment {
|
|||
}
|
||||
}
|
||||
|
||||
private void exportDatabase(final String path) {
|
||||
private void exportDatabase(@NonNull final File folder) {
|
||||
try {
|
||||
final SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US);
|
||||
final String path = folder.getAbsolutePath() + "/NewPipeData-"
|
||||
+ sdf.format(new Date()) + ".zip";
|
||||
|
||||
//checkpoint before export
|
||||
NewPipeDatabase.checkpoint();
|
||||
|
||||
final SharedPreferences preferences = PreferenceManager
|
||||
.getDefaultSharedPreferences(requireContext());
|
||||
.getDefaultSharedPreferences(requireContext());
|
||||
manager.exportDatabase(preferences, path);
|
||||
|
||||
setImportExportDataPath(folder, false);
|
||||
|
||||
Toast.makeText(getContext(), R.string.export_complete_toast, Toast.LENGTH_SHORT).show();
|
||||
} catch (final Exception e) {
|
||||
ErrorActivity.reportUiErrorInSnackbar(this, "Exporting database", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void importDatabase(final String filePath) {
|
||||
private void importDatabase(@NonNull final File file) {
|
||||
final String filePath = file.getAbsolutePath();
|
||||
|
||||
// check if file is supported
|
||||
if (!ZipHelper.isValidZipFile(filePath)) {
|
||||
Toast.makeText(getContext(), R.string.no_valid_zip_file, Toast.LENGTH_SHORT)
|
||||
.show();
|
||||
.show();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -225,7 +231,7 @@ public class ContentSettingsFragment extends BasePreferenceFragment {
|
|||
|
||||
if (!manager.extractDb(filePath)) {
|
||||
Toast.makeText(getContext(), R.string.could_not_import_all_files, Toast.LENGTH_LONG)
|
||||
.show();
|
||||
.show();
|
||||
}
|
||||
|
||||
//If settings file exist, ask if it should be imported.
|
||||
|
@ -235,27 +241,40 @@ public class ContentSettingsFragment extends BasePreferenceFragment {
|
|||
|
||||
alert.setNegativeButton(android.R.string.no, (dialog, which) -> {
|
||||
dialog.dismiss();
|
||||
// restart app to properly load db
|
||||
System.exit(0);
|
||||
finishImport(file);
|
||||
});
|
||||
alert.setPositiveButton(getString(R.string.finish), (dialog, which) -> {
|
||||
dialog.dismiss();
|
||||
manager.loadSharedPreferences(PreferenceManager
|
||||
.getDefaultSharedPreferences(requireContext()));
|
||||
// restart app to properly load db
|
||||
System.exit(0);
|
||||
.getDefaultSharedPreferences(requireContext()));
|
||||
finishImport(file);
|
||||
});
|
||||
alert.show();
|
||||
} else {
|
||||
// restart app to properly load db
|
||||
System.exit(0);
|
||||
finishImport(file);
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
ErrorActivity.reportUiErrorInSnackbar(this, "Importing database", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void setImportExportDataPath(final File file) {
|
||||
/**
|
||||
* Save import path and restart system.
|
||||
*
|
||||
* @param file The file of the created backup
|
||||
*/
|
||||
private void finishImport(@NonNull final File file) {
|
||||
if (file.getParentFile() != null) {
|
||||
//immediately because app is about to exit
|
||||
setImportExportDataPath(file.getParentFile(), true);
|
||||
}
|
||||
|
||||
// restart app to properly load db
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
@SuppressLint("ApplySharedPref")
|
||||
private void setImportExportDataPath(@NonNull final File file, final boolean immediately) {
|
||||
final String directoryPath;
|
||||
if (file.isDirectory()) {
|
||||
directoryPath = file.getAbsolutePath();
|
||||
|
@ -267,6 +286,13 @@ public class ContentSettingsFragment extends BasePreferenceFragment {
|
|||
directoryPath = "";
|
||||
}
|
||||
}
|
||||
defaultPreferences.edit().putString(importExportDataPathKey, directoryPath).apply();
|
||||
final SharedPreferences.Editor editor = defaultPreferences
|
||||
.edit()
|
||||
.putString(importExportDataPathKey, directoryPath);
|
||||
if (immediately) {
|
||||
editor.commit();
|
||||
} else {
|
||||
editor.apply();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -596,6 +596,7 @@ public final class NavigationHelper {
|
|||
final Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||
intent.setPackage(context.getString(R.string.kore_package));
|
||||
intent.setData(videoURL);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
context.startActivity(intent);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,8 @@ public enum StreamDialogEntry {
|
|||
|
||||
show_channel_details(R.string.show_channel_details, (fragment, item) ->
|
||||
// For some reason `getParentFragmentManager()` doesn't work, but this does.
|
||||
NavigationHelper.openChannelFragment(fragment.getActivity().getSupportFragmentManager(),
|
||||
NavigationHelper.openChannelFragment(
|
||||
fragment.requireActivity().getSupportFragmentManager(),
|
||||
item.getServiceId(), item.getUploaderUrl(), item.getUploaderName())
|
||||
),
|
||||
|
||||
|
@ -80,14 +81,17 @@ public enum StreamDialogEntry {
|
|||
play_with_kodi(R.string.play_with_kodi_title, (fragment, item) -> {
|
||||
final Uri videoUrl = Uri.parse(item.getUrl());
|
||||
try {
|
||||
NavigationHelper.playWithKore(fragment.getContext(), videoUrl);
|
||||
NavigationHelper.playWithKore(fragment.requireContext(), videoUrl);
|
||||
} catch (final Exception e) {
|
||||
KoreUtil.showInstallKoreDialog(fragment.getActivity());
|
||||
}
|
||||
}),
|
||||
|
||||
share(R.string.share, (fragment, item) ->
|
||||
ShareUtils.shareText(fragment.getContext(), item.getName(), item.getUrl()));
|
||||
ShareUtils.shareText(fragment.getContext(), item.getName(), item.getUrl())),
|
||||
|
||||
open_in_browser(R.string.open_in_browser, (fragment, item) ->
|
||||
ShareUtils.openUrlInBrowser(fragment.getContext(), item.getUrl()));
|
||||
|
||||
|
||||
///////////////
|
||||
|
|
|
@ -275,7 +275,7 @@ public class StoredFileHelper implements Serializable {
|
|||
if (!docTree.canRead() || !docTree.canWrite()) return false;
|
||||
try {
|
||||
docFile = createSAF(context, srcType, srcName);
|
||||
if (docFile == null || docFile.getName() == null) return false;
|
||||
if (docFile.getName() == null) return false;
|
||||
result = true;
|
||||
} catch (IOException e) {
|
||||
return false;
|
||||
|
@ -354,7 +354,9 @@ public class StoredFileHelper implements Serializable {
|
|||
}
|
||||
}
|
||||
|
||||
private DocumentFile createSAF(@Nullable Context context, String mime, String filename) throws IOException {
|
||||
@NonNull
|
||||
private DocumentFile createSAF(@Nullable Context context, String mime, String filename)
|
||||
throws IOException {
|
||||
DocumentFile res = StoredDirectoryHelper.findFileSAFHelper(context, docTree, filename);
|
||||
|
||||
if (res != null && res.exists() && res.isDirectory()) {
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="#ffffff">
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M3,5h2L5,3c-1.1,0 -2,0.9 -2,2zM3,13h2v-2L3,11v2zM7,21h2v-2L7,19v2zM3,9h2L5,7L3,7v2zM13,3h-2v2h2L13,3zM19,3v2h2c0,-1.1 -0.9,-2 -2,-2zM5,21v-2L3,19c0,1.1 0.9,2 2,2zM3,17h2v-2L3,15v2zM9,3L7,3v2h2L9,3zM11,21h2v-2h-2v2zM19,13h2v-2h-2v2zM19,21c1.1,0 2,-0.9 2,-2h-2v2zM19,9h2L21,7h-2v2zM19,17h2v-2h-2v2zM15,21h2v-2h-2v2zM15,5h2L17,3h-2v2zM7,17h10L17,7L7,7v10zM9,9h6v6L9,15L9,9z"/>
|
||||
</vector>
|
|
@ -0,0 +1,10 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="#000000">
|
||||
<path
|
||||
android:fillColor="#000000"
|
||||
android:pathData="M3,5h2L5,3c-1.1,0 -2,0.9 -2,2zM3,13h2v-2L3,11v2zM7,21h2v-2L7,19v2zM3,9h2L5,7L3,7v2zM13,3h-2v2h2L13,3zM19,3v2h2c0,-1.1 -0.9,-2 -2,-2zM5,21v-2L3,19c0,1.1 0.9,2 2,2zM3,17h2v-2L3,15v2zM9,3L7,3v2h2L9,3zM11,21h2v-2h-2v2zM19,13h2v-2h-2v2zM19,21c1.1,0 2,-0.9 2,-2h-2v2zM19,9h2L21,7h-2v2zM19,17h2v-2h-2v2zM15,21h2v-2h-2v2zM15,5h2L17,3h-2v2zM7,17h10L17,7L7,7v10zM9,9h6v6L9,15L9,9z"/>
|
||||
</vector>
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- This is used to inflate a chip with a Material theme, otherwise it would crash -->
|
||||
<!-- Theme.MaterialComponents.DayNight is used to guarantee auto day/night switching -->
|
||||
<com.google.android.material.chip.Chip xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:theme="@style/Theme.MaterialComponents.DayNight.Bridge"
|
||||
tools:text="I'm a correctly themed chip!" />
|
|
@ -2,14 +2,15 @@
|
|||
<androidx.core.widget.NestedScrollView 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"
|
||||
android:orientation="vertical"
|
||||
android:scrollbars="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:scrollbars="vertical">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
android:layout_height="wrap_content"
|
||||
android:animateLayoutChanges="true">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/detail_upload_date_view"
|
||||
|
@ -17,32 +18,83 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="6dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
android:textSize="@dimen/video_item_detail_upload_date_text_size"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.0"
|
||||
app:layout_constraintEnd_toStartOf="@+id/detail_select_description_button"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="Published on Oct 2, 2009" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/detail_select_description_button"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginBottom="2dp"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:clickable="true"
|
||||
android:contentDescription="@string/description_select_enable"
|
||||
android:focusable="true"
|
||||
android:padding="5dp"
|
||||
app:layout_constraintBottom_toTopOf="@+id/barrier"
|
||||
app:layout_constraintDimensionRatio="1"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:srcCompat="@drawable/ic_select_all" />
|
||||
|
||||
<androidx.constraintlayout.widget.Barrier
|
||||
android:id="@+id/barrier"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:barrierAllowsGoneWidgets="false"
|
||||
app:barrierDirection="top"
|
||||
app:constraint_referenced_ids="detail_description_note_view,detail_description_view" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/detail_description_view"
|
||||
android:layout_width="match_parent"
|
||||
android:id="@+id/detail_description_note_view"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
android:textIsSelectable="true"
|
||||
android:textSize="@dimen/video_item_detail_description_text_size"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
android:gravity="center"
|
||||
android:text="@string/description_select_note"
|
||||
android:textSize="12sp"
|
||||
android:textStyle="italic"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/detail_upload_date_view"
|
||||
app:layout_constraintVertical_bias="0.0"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/detail_description_view"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
android:textSize="@dimen/video_item_detail_description_text_size"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/detail_description_note_view"
|
||||
tools:text="Description Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed a ultricies ex. Integer sit amet sodales risus. Duis non mi et urna pretium bibendum." />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/detail_metadata_layout"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/detail_description_view" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
<?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"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="6dp"
|
||||
android:paddingBottom="6dp">
|
||||
|
||||
<androidx.constraintlayout.widget.Guideline
|
||||
android:id="@+id/guideline"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintGuide_percent="0.30" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/metadata_type_view"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical|end"
|
||||
android:textAllCaps="true"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/guideline"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="Licence" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/metadata_content_view"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="@+id/guideline"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="Description Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed a ultricies ex. Integer sit amet sodales risus. Duis non mi et urna pretium bibendum." />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -0,0 +1,46 @@
|
|||
<?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:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<androidx.constraintlayout.widget.Guideline
|
||||
android:id="@+id/guideline"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintGuide_percent="0.30" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical|end"
|
||||
android:text="@string/metadata_tags"
|
||||
android:textAllCaps="true"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/guideline"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<HorizontalScrollView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="-8dp"
|
||||
android:layout_marginBottom="-8dp"
|
||||
android:fadeScrollbars="false"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="@+id/guideline"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<com.google.android.material.chip.ChipGroup
|
||||
android:id="@+id/metadata_tags_chips"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Chip"
|
||||
app:singleLine="true" />
|
||||
</HorizontalScrollView>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -34,11 +34,12 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/channel_item_description_to_details_margin"
|
||||
android:ellipsize="end"
|
||||
android:lines="2"
|
||||
android:maxLines="2"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:textSize="@dimen/video_item_search_uploader_text_size"
|
||||
app:layout_constraintBottom_toTopOf="@+id/itemAdditionalDetails"
|
||||
app:layout_constraintLeft_toLeftOf="@+id/itemTitleView"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="@+id/itemTitleView"
|
||||
app:layout_constraintTop_toBottomOf="@+id/itemTitleView"
|
||||
tools:text="Channel description, Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc tristique vitae sem vitae blanditLorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc tristique vitae sem vitae blanditLorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc tristique vitae sem vitae blandit" />
|
||||
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:paddingStart="@dimen/activity_horizontal_margin"
|
||||
android:paddingEnd="@dimen/activity_horizontal_margin"
|
||||
tools:context=".fragments.detail.VideoDetailFragment">
|
||||
|
||||
<TextView
|
||||
|
@ -13,6 +15,7 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginTop="30dp"
|
||||
android:layout_marginBottom="20dp"
|
||||
android:fontFamily="sans-serif-condensed"
|
||||
android:text="@string/app_name"
|
||||
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||
|
@ -20,9 +23,10 @@
|
|||
|
||||
<TextView
|
||||
android:id="@+id/mainBGSubtitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:gravity="center"
|
||||
android:text="@string/main_bg_subtitle"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium" />
|
||||
|
||||
|
|
|
@ -720,4 +720,20 @@
|
|||
<string name="show_channel_details">إظهار تفاصيل القناة</string>
|
||||
<string name="disable_media_tunneling_summary">تعطيل نفق الوسائط إذا واجهت شاشة سوداء أو التقطيع في تشغيل الفيديو</string>
|
||||
<string name="disable_media_tunneling_title">تعطيل نفق الوسائط</string>
|
||||
<string name="metadata_privacy_internal">داخلي</string>
|
||||
<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_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_category">الصنف</string>
|
||||
<string name="description_select_disable">تعطيل تحديد النص في الوصف</string>
|
||||
<string name="description_select_enable">تمكين تحديد نص في الوصف</string>
|
||||
<string name="description_select_note">يمكنك الآن تحديد نص داخل الوصف. لاحظ أن الصفحة قد تومض وقد لا تكون الروابط قابلة للنقر أثناء وضع التحديد.</string>
|
||||
</resources>
|
|
@ -30,7 +30,7 @@
|
|||
<string name="parsing_error">Nun pudo analizase\'l sitiu web</string>
|
||||
<string name="live_streams_not_supported">Los fluxos en direuto entá nun se sofiten</string>
|
||||
<string name="could_not_get_stream">Nun pudo consiguise nengún fluxu</string>
|
||||
<string name="sorry_string">Buff... Esto nun debió asoceder.</string>
|
||||
<string name="sorry_string">Buff… Esto nun debió asoceder.</string>
|
||||
<string name="error_snackbar_message">Perdona mas asocedió daqué malo.</string>
|
||||
<string name="what_device_headline">Información:</string>
|
||||
<string name="error_details_headline">Detalles:</string>
|
||||
|
@ -107,7 +107,7 @@
|
|||
<string name="tab_licenses">Llicencies</string>
|
||||
<string name="view_on_github">Ver en GitHub</string>
|
||||
<string name="app_license_title">Llicencia de NewPipe</string>
|
||||
<string name="contribution_encouragement">Si tienes idees, quies traducir, facer dalgún cambéu nel diseñu, acuriosar poco o muncho\'l códigu... Agradecemos l\'ayuda. ¡Cuanto más se faiga, meyor!</string>
|
||||
<string name="contribution_encouragement">Si tienes idees, quies traducir, facer dalgún cambéu nel diseñu, acuriosar poco o muncho\'l códigu… Agradecemos l\'ayuda. ¡Cuanto más se faiga, meyor!</string>
|
||||
<string name="read_full_license">Lleer</string>
|
||||
<string name="contribution_title">Collaboración</string>
|
||||
<string name="title_activity_history">Historial</string>
|
||||
|
|
|
@ -387,7 +387,7 @@
|
|||
<string name="playback_pitch">音调</string>
|
||||
<string name="unhook_checkbox">解除音视挂钩(可能导致失真)</string>
|
||||
<string name="preferred_open_action_settings_title">首选“打开”操作</string>
|
||||
<string name="preferred_open_action_settings_summary">打开内容时的默认操作 - %s</string>
|
||||
<string name="preferred_open_action_settings_summary">打开内容时的默认操作 — %s</string>
|
||||
<string name="no_streams_available_download">没有可下载的串流</string>
|
||||
<string name="caption_setting_title">字幕</string>
|
||||
<string name="caption_setting_description">修改播放器字幕比例和背景样式。重启应用生效。</string>
|
||||
|
@ -678,4 +678,20 @@
|
|||
<string name="show_channel_details">显示频道详情</string>
|
||||
<string name="disable_media_tunneling_summary">如果遇到黑屏或视频播放卡顿的情况,请禁用媒体隧道</string>
|
||||
<string name="disable_media_tunneling_title">禁用媒体隧道</string>
|
||||
<string name="description_select_disable">关闭简介中的文本选择功能</string>
|
||||
<string name="metadata_privacy_internal">内部</string>
|
||||
<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_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_category">类别</string>
|
||||
<string name="description_select_enable">开启简介中的文本选择功能</string>
|
||||
<string name="description_select_note">你现在可以选择简介中的文本,注意,在选择模式下,页面可能会闪烁,链接可能无法点击。</string>
|
||||
</resources>
|
|
@ -346,7 +346,7 @@
|
|||
<string name="share">শেয়ার</string>
|
||||
<string name="open_in_popup_mode">পপ-আপ মোডে ওপেন করো</string>
|
||||
<string name="open_in_browser">ব্রাউজারে ওপেন করো</string>
|
||||
<string name="cancel">বাদ দিন</string>
|
||||
<string name="cancel">বাতিল</string>
|
||||
<string name="install">ইনস্টল</string>
|
||||
<string name="no_player_found_toast">কোন স্ট্রিম প্লেয়ার পাওয়া যায়নি (প্লে করতে VLC ইন্সটল করতে পারেন).</string>
|
||||
<string name="no_player_found">কোন স্ট্রিম প্লেয়ার পাওয়া যায়নি। VLC ইনস্টল করতে চাও\?</string>
|
||||
|
|
|
@ -553,7 +553,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>
|
||||
|
|
|
@ -251,7 +251,7 @@
|
|||
<string name="switch_to_background">In den Hintergrund wechseln</string>
|
||||
<string name="switch_to_popup">Zum Pop-up wechseln</string>
|
||||
<string name="switch_to_main">Zur normalen Wiedergabe wechseln</string>
|
||||
<string name="external_player_unsupported_link_type">Externe Abspielprogramme unterstützen diese Art von Links nicht</string>
|
||||
<string name="external_player_unsupported_link_type">Externe Player unterstützen diese Art von Links nicht</string>
|
||||
<string name="invalid_url_toast">Ungültige URL</string>
|
||||
<string name="video_streams_empty">Keine Video-Streams gefunden</string>
|
||||
<string name="audio_streams_empty">Keine Audio-Streams gefunden</string>
|
||||
|
@ -632,7 +632,7 @@
|
|||
<string name="notification_action_nothing">Nichts</string>
|
||||
<string name="title_activity_play_queue">Warteschlange abspielen</string>
|
||||
<string name="auto_queue_toggle">Automatische Warteschlange</string>
|
||||
<string name="clear_queue_confirmation_summary">Der Wechsel von einem Abspielprogramm zu einem anderen kann Ihre Warteschlange überschreiben</string>
|
||||
<string name="clear_queue_confirmation_summary">Der Wechsel von einem Player zu einem anderen kann deine Warteschlange überschreiben</string>
|
||||
<string name="clear_queue_confirmation_title">Überschreiben der Warteschlange bestätigen</string>
|
||||
<string name="clear_queue_confirmation_description">Die aktive Player-Warteschlange wird ersetzt</string>
|
||||
<string name="enqueued">Eingereiht</string>
|
||||
|
@ -680,4 +680,20 @@
|
|||
<string name="show_channel_details">Kanal-Details anzeigen</string>
|
||||
<string name="disable_media_tunneling_summary">Deaktiviere das Media-Tunneling, wenn bei der Videowiedergabe ein schwarzer Bildschirm oder Stottern auftritt</string>
|
||||
<string name="disable_media_tunneling_title">Media-Tunneling deaktivieren</string>
|
||||
<string name="metadata_privacy_internal">Intern</string>
|
||||
<string name="metadata_privacy_private">Privat</string>
|
||||
<string name="metadata_privacy_public">Öffentlich</string>
|
||||
<string name="metadata_language">Sprache</string>
|
||||
<string name="metadata_age_limit">Altersbeschränkung</string>
|
||||
<string name="metadata_privacy">Sichtbarkeit</string>
|
||||
<string name="metadata_licence">Lizenz</string>
|
||||
<string name="metadata_tags">Tags</string>
|
||||
<string name="metadata_category">Kategorie</string>
|
||||
<string name="metadata_privacy_unlisted">Nicht gelistet</string>
|
||||
<string name="metadata_thumbnail_url">Vorschaubild-URL</string>
|
||||
<string name="metadata_host">Server</string>
|
||||
<string name="metadata_support">Unterstützung</string>
|
||||
<string name="description_select_disable">Auswählen von Text in der Beschreibung deaktivieren</string>
|
||||
<string name="description_select_enable">Auswählen von Text in der Beschreibung aktivieren</string>
|
||||
<string name="description_select_note">Du kannst nun Text innerhalb der Beschreibung auswählen. Beachte, dass die Seite flackern kann und Links im Auswahlmodus möglicherweise nicht anklickbar sind.</string>
|
||||
</resources>
|
|
@ -645,7 +645,7 @@
|
|||
<string name="peertube_instance_url_title">Στιγμιότυπα PeerTube</string>
|
||||
<string name="notification_colorize_title">Χρωματισμός ειδοποιήσεων</string>
|
||||
<string name="notification_colorize_summary">Επιτρέπει στο Android να τροποποιήσει το χρώμα της ειδοποίησης, σύμφωνα με το κύριο χρώμα του εικονιδίου (δεν διατίθεται σε όλες τις συσκευές)</string>
|
||||
<string name="show_thumbnail_summary">Χρήση των εικονιδίων στην οθόνη κλειδώματοςως φόντο και στις ειδοποιήσεις</string>
|
||||
<string name="show_thumbnail_summary">Χρήση των εικονιδίων ως φόντο στην οθόνη κλειδώματος και στις ειδοποιήσεις</string>
|
||||
<string name="show_thumbnail_title">Εμφάνιση</string>
|
||||
<string name="msg_calculating_hash">Υπολογισμός hash</string>
|
||||
<string name="hash_channel_description">Ειδοποιήσεις για πρόοδο βίντεο hashing</string>
|
||||
|
@ -680,4 +680,19 @@
|
|||
<string name="show_channel_details">Εμφάνιση λεπτομερειών καναλιού</string>
|
||||
<string name="disable_media_tunneling_summary">Απενεργοποιήστε το media tunneling, αν εμφανίζεται μαύρη οθόνη ή διακοπτόμενος ήχος κατά την αναπαραγωγή βίντεο</string>
|
||||
<string name="disable_media_tunneling_title">Απενεργοποίηση media tunneling</string>
|
||||
<string name="metadata_privacy_internal">Εσωτερικό</string>
|
||||
<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_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_category">Κατηγορία</string>
|
||||
<string name="description_select_disable">Απενεργοποίηση επιλογής κειμένου στην περιγραφή</string>
|
||||
<string name="description_select_enable">Ενεργοποίηση επιλογής κειμένου στην περιγραφή</string>
|
||||
<string name="description_select_note">Τώρα μπορείτε να επιλέξετε κείμενο εντός της περιγραφής. Σημειώστε ότι, η σελίδα μπορεί να παρουσιάζει αστάθεια κατά τη διάρκεια της κατάστασης επιλογής κειμένου.</string>
|
||||
</resources>
|
|
@ -660,7 +660,7 @@
|
|||
<string name="comments_tab_description">Iruzkinak</string>
|
||||
<string name="show_description_summary">Desaktibatu bideoaren deskribapena eta informazio gehigarria ezkutatzeko</string>
|
||||
<string name="show_description_title">Erakutsi deskribapena</string>
|
||||
<string name="open_with">Ireki honekin...</string>
|
||||
<string name="open_with">Ireki honekin…</string>
|
||||
<string name="radio">Irratia</string>
|
||||
<string name="featured">Nabarmenduak</string>
|
||||
<string name="paid_content">Eduki hau ordaindu duten erabiltzaileentzat soilik dago eskuragarri, eta NewPipe-k ezin du tramsmititu edo deskargatu.</string>
|
||||
|
|
|
@ -97,7 +97,7 @@
|
|||
<string name="msg_server_unsupported">Serveur non pris en charge</string>
|
||||
<string name="msg_exists">Fichier déjà existant</string>
|
||||
<string name="msg_url_malform">Lien malformé ou accès à Internet indisponible</string>
|
||||
<string name="msg_running">NewPipe télécharge...</string>
|
||||
<string name="msg_running">NewPipe télécharge…</string>
|
||||
<string name="msg_running_detail">Appuyer pour plus de détails</string>
|
||||
<string name="msg_wait">Veuillez patienter…</string>
|
||||
<string name="msg_copied">Copié dans le presse-papiers</string>
|
||||
|
@ -682,4 +682,20 @@
|
|||
<string name="show_channel_details">Afficher les détails de la chaîne</string>
|
||||
<string name="disable_media_tunneling_summary">Désactivez le tunnelage multimédia si vous constatez un écran noir ou un bégaiement lors de la lecture d\'une vidéo</string>
|
||||
<string name="disable_media_tunneling_title">Désactiver le tunnelage média</string>
|
||||
<string name="description_select_disable">Désactiver la sélection de texte dans la description</string>
|
||||
<string name="description_select_enable">Permettre la sélection de texte dans la description</string>
|
||||
<string name="metadata_privacy_internal">Interne</string>
|
||||
<string name="metadata_privacy_private">Privé</string>
|
||||
<string name="metadata_privacy_unlisted">Non répertorié</string>
|
||||
<string name="metadata_privacy_public">Public</string>
|
||||
<string name="metadata_thumbnail_url">URL de la miniature</string>
|
||||
<string name="metadata_host">Hôte</string>
|
||||
<string name="metadata_support">Support</string>
|
||||
<string name="metadata_language">Langue</string>
|
||||
<string name="metadata_age_limit">Limite d\'âge</string>
|
||||
<string name="metadata_privacy">Confidentialité</string>
|
||||
<string name="metadata_licence">Licence</string>
|
||||
<string name="metadata_tags">Étiquettes</string>
|
||||
<string name="metadata_category">Catégorie</string>
|
||||
<string name="description_select_note">Vous pouvez maintenant sélectionner du texte à l\'intérieur de la description. Notez que la page peut scintiller et que les liens peuvent ne pas être cliquables en mode sélection.</string>
|
||||
</resources>
|
|
@ -700,4 +700,20 @@
|
|||
<string name="show_channel_details">להציג את פרטי הערוץ</string>
|
||||
<string name="disable_media_tunneling_summary">כדאי להשבית תיעול מדיה אם הופיעה תופעה של מסך שחור או גמגום בנגינת וידאו</string>
|
||||
<string name="disable_media_tunneling_title">השבתת תיעול מדיה</string>
|
||||
<string name="metadata_privacy_internal">פנימי</string>
|
||||
<string name="metadata_privacy_private">פרטי</string>
|
||||
<string name="metadata_privacy_unlisted">לא מופיע ברשימות</string>
|
||||
<string name="metadata_privacy_public">ציבורי</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_category">קטגוריה</string>
|
||||
<string name="description_select_disable">השבתת בחירת טקסט בתיאור</string>
|
||||
<string name="description_select_enable">הפעלת בחירת טקסט בתיאור</string>
|
||||
<string name="description_select_note">מעתה ניתן לבחור טקסט בתוך התיאור. נא לשים לב שהעמוד עשוי להבהב והקישורים לא יהיו לחיצים בזמן מצב הבחירה.</string>
|
||||
</resources>
|
|
@ -54,7 +54,7 @@
|
|||
<string name="enable_search_history_title">Chronologia de cerca</string>
|
||||
<string name="enable_search_history_summary">Immagazinar le cercas localmente</string>
|
||||
<string name="enable_watch_history_title">Chronologia de reproductiones</string>
|
||||
<string name="enable_playback_resume_title">We</string>
|
||||
<string name="enable_playback_resume_title">Resumer le reproduction</string>
|
||||
<string name="enable_playback_resume_summary">Restaurar le ultime position del reproduction</string>
|
||||
<string name="enable_playback_state_lists_title">Positiones in le listas</string>
|
||||
<string name="enable_playback_state_lists_summary">Monstrar le indicatores de position in listas</string>
|
||||
|
@ -151,7 +151,7 @@
|
|||
<string name="action_settings">Configurationes</string>
|
||||
<string name="action_about">A proposito de</string>
|
||||
<string name="copyright" formatted="true">© %1$s per %2$s sub %3$s</string>
|
||||
<string name="action_open_website">Aperir sito web</string>
|
||||
<string name="action_open_website">Aperir le sito web</string>
|
||||
<string name="tab_about">A proposito de</string>
|
||||
<string name="tab_licenses">Licentias</string>
|
||||
<string name="contribution_title">Contribuer</string>
|
||||
|
@ -207,4 +207,54 @@
|
|||
<string name="no_one_watching">Nemo is observante</string>
|
||||
<string name="watch_history_deleted">Chronologia de reproductiones vacuate.</string>
|
||||
<string name="delete_view_history_alert">Deler omne chronologia de reproductiones\?</string>
|
||||
<string name="error_snackbar_message">Pardono, qualcosa vadeva incorrecte.</string>
|
||||
<string name="sorry_string">Pardono, illo non deberea haber ocurrite.</string>
|
||||
<string name="clear_playback_states_title">Deler le positiones de reproduction</string>
|
||||
<string name="songs">Cantos</string>
|
||||
<string name="playlists">Listas de reproduction</string>
|
||||
<string name="playlist">Lista de reproduction</string>
|
||||
<string name="error_report_title">Reporto de error</string>
|
||||
<string name="youtube_restricted_mode_enabled_title">Activar el \"Modo restricte\" de YouTube</string>
|
||||
<string name="more_than_100_videos">Plus de 100 videos</string>
|
||||
<string name="no_one_listening">Nemo es ascoltante</string>
|
||||
<plurals name="views">
|
||||
<item quantity="one">%s reproduction</item>
|
||||
<item quantity="other">%s reproductiones</item>
|
||||
</plurals>
|
||||
<string name="subscribers_count_not_available">Le numero de subscriptores non es disponibile</string>
|
||||
<plurals name="subscribers">
|
||||
<item quantity="one">%s subscriptor</item>
|
||||
<item quantity="other">%s subscriptores</item>
|
||||
</plurals>
|
||||
<string name="no_subscribers">Nulle subscriptores</string>
|
||||
<string name="audio">Audio</string>
|
||||
<string name="video">Video</string>
|
||||
<string name="empty_subscription_feed_subtitle">Nihil contentos ci</string>
|
||||
<string name="search_no_results">Nulle resultatos</string>
|
||||
<string name="user_report">Reporto de usator</string>
|
||||
<string name="report_error">Reportar un error</string>
|
||||
<string name="description_tab_description">Description</string>
|
||||
<string name="related_items_tab_description">Fluxos associate</string>
|
||||
<string name="detail_dislikes_img_view_description">Non me place</string>
|
||||
<string name="comments_tab_description">Commentos</string>
|
||||
<string name="detail_likes_img_view_description">Me place</string>
|
||||
<string name="error_snackbar_action">Reportar</string>
|
||||
<string name="error_report_open_issue_button_text">Reportar in GitHub</string>
|
||||
<string name="permission_display_over_apps">Permitter monstrar supra altere applicationes</string>
|
||||
<string name="restore_defaults_confirmation">Esque tu vole reinitialisar le valores predefinite\?</string>
|
||||
<string name="restore_defaults">Reinitialisar le valores predefinite</string>
|
||||
<string name="no_streams_available_download">Nulle fluxos disponibile pro discargar</string>
|
||||
<string name="error_occurred_detail">Ocurreva un error: %1$s</string>
|
||||
<string name="missing_file">File displaciate o delite</string>
|
||||
<string name="app_ui_crash">Falleva le interfacie del application</string>
|
||||
<string name="download_to_sdcard_error_message">Le discarga al carta SD non es possibile. Reinitialisar le location del dossier de discargas\?</string>
|
||||
<string name="download_to_sdcard_error_title">Immagazinage externe non disponibile</string>
|
||||
<string name="general_error">Error</string>
|
||||
<string name="help">Adjuta</string>
|
||||
<string name="delete_playback_states_alert">Esque tu vole deler tote le positiones de reproduction\?</string>
|
||||
<string name="clear_playback_states_summary">Dele tote le positiones de reproduction</string>
|
||||
<string name="use_inexact_seek_title">Usar le recerca rapide e inexacte</string>
|
||||
<string name="night_theme_title">Thema nocturne</string>
|
||||
<string name="notification_action_nothing">Nihil</string>
|
||||
<string name="show_description_title">Monstrar le description</string>
|
||||
</resources>
|
|
@ -656,7 +656,7 @@
|
|||
<string name="private_content">Konten ini bersifat pribadi, jadi tidak dapat di stream ataupun diunduh oleh NewPipe.</string>
|
||||
<string name="soundcloud_go_plus_content">Ini adalah sebuah trek SoundCloud Go +, setidaknya di negara Anda, sehingga tidak dapat di stream atau diunduh oleh Newpipe.</string>
|
||||
<string name="georestricted_content">Konten ini tidak tersedia di negara Anda.</string>
|
||||
<string name="crash_the_app">Aplikasi crash</string>
|
||||
<string name="crash_the_app">Hentikan aplikasi</string>
|
||||
<string name="restricted_video_no_stream">Video ini dibatasi usia.
|
||||
\nKarena kebijakan YouTube yang baru dengan video yang dibatasi usia, Newpipe tidak dapat mengakses aliran video dan karenanya tidak dapat memainkannya.</string>
|
||||
<string name="select_night_theme_toast">Kamu bisa pilih tema malam favoritmu dibawah</string>
|
||||
|
@ -670,4 +670,20 @@
|
|||
<string name="show_channel_details">Tampilkan rincian channel</string>
|
||||
<string name="disable_media_tunneling_summary">Nonaktifkan terowongan media (tunnel) jiaka anda mengalami sebuah layar hitam atau kerusakan dalam memutar video</string>
|
||||
<string name="disable_media_tunneling_title">Nonaktifkan terowongan media (tunnel)</string>
|
||||
<string name="metadata_privacy_internal">Internal</string>
|
||||
<string name="metadata_privacy_private">Privasi</string>
|
||||
<string name="metadata_privacy_unlisted">Tidak didaftar</string>
|
||||
<string name="metadata_privacy_public">Publik</string>
|
||||
<string name="metadata_thumbnail_url">Alamat URL gambar mini/thumbnail</string>
|
||||
<string name="metadata_host">Host</string>
|
||||
<string name="metadata_support">Dukungan</string>
|
||||
<string name="metadata_language">Bahasa</string>
|
||||
<string name="metadata_age_limit">Batas umur</string>
|
||||
<string name="metadata_privacy">Privasi</string>
|
||||
<string name="metadata_licence">Lisensi</string>
|
||||
<string name="metadata_tags">Tag</string>
|
||||
<string name="metadata_category">Kategori</string>
|
||||
<string name="description_select_disable">Nonaktifkan dapat memilih teks pada deskripsi</string>
|
||||
<string name="description_select_enable">Aktifkan dapat memilih teks pada deskripsi</string>
|
||||
<string name="description_select_note">Anda sekarang dapat memilih teks di dalam deskripsi. Perhatikan bahwa halaman mungkin berkedip dan tautan tidak dapat diklik saat dalam mode pemilihan.</string>
|
||||
</resources>
|
|
@ -680,4 +680,20 @@
|
|||
<string name="show_channel_details">Mostra dettagli canale</string>
|
||||
<string name="disable_media_tunneling_summary">Disattiva il tunneling multimediale se durante la riproduzione dei video si verificano schermate nere o irregolarità nell\'audio</string>
|
||||
<string name="disable_media_tunneling_title">Disattiva tunneling multimediale</string>
|
||||
<string name="metadata_privacy_internal">Interno</string>
|
||||
<string name="metadata_privacy_private">Privato</string>
|
||||
<string name="metadata_privacy_unlisted">Non elencato</string>
|
||||
<string name="metadata_privacy_public">Pubblico</string>
|
||||
<string name="metadata_thumbnail_url">URL miniatura</string>
|
||||
<string name="metadata_host">Host</string>
|
||||
<string name="metadata_support">Supporto</string>
|
||||
<string name="metadata_language">Lingua</string>
|
||||
<string name="metadata_age_limit">Limite di età</string>
|
||||
<string name="metadata_privacy">Privacy</string>
|
||||
<string name="metadata_licence">Licenza</string>
|
||||
<string name="metadata_tags">Etichette</string>
|
||||
<string name="metadata_category">Categoria</string>
|
||||
<string name="description_select_disable">Disattiva la selezione del testo nella descrizione</string>
|
||||
<string name="description_select_enable">Attiva la selezione del testo nella descrizione</string>
|
||||
<string name="description_select_note">Ora puoi selezionare il testo all\'interno della descrizione. Nota che la pagina potrebbe sfarfallare e i collegamenti potrebbero non essere cliccabili mentre sei in modalità di selezione.</string>
|
||||
</resources>
|
|
@ -665,4 +665,19 @@
|
|||
<string name="show_description_title">Toon beschrijving</string>
|
||||
<string name="night_theme_title">Nacht Thema</string>
|
||||
<string name="open_with">Open met</string>
|
||||
<string name="featured">Featured</string>
|
||||
<string name="private_content">Deze inhoud is privé, waardoor het niet kan worden gestreamd of gedownload door NewPipe.</string>
|
||||
<string name="crash_the_app">Laat de app crashen</string>
|
||||
<string name="disable_media_tunneling_summary">Schakel media tunneling uit indien u een zwart scherm of haperingen vaststelt bij het afspelen van video\'s</string>
|
||||
<string name="download_has_started">De download is begonnen</string>
|
||||
<string name="select_night_theme_toast">U kunt uw favoriete nachtthema hieronder kiezen</string>
|
||||
<string name="night_theme_summary">Kies uw favoriete nachtthema - %s</string>
|
||||
<string name="auto_device_theme_title">Automatisch (thema van de telefoon)</string>
|
||||
<string name="radio">Radio</string>
|
||||
<string name="paid_content">Deze inhoud is enkel toegankelijk voor betalende gebruikers, waardoor het niet kan worden gestreamd of gedownload door NewPipe.</string>
|
||||
<string name="youtube_music_premium_content">Deze video is enkel toegankelijk voor YouTube Music Premium leden, waardoor het niet kan worden gestreamd of gedownload door NewPipe.</string>
|
||||
<string name="soundcloud_go_plus_content">Dit is (tenminste in uw land) een SoundCloud Go+ titel, waardoor het niet kan worden gestreamd of gedownload door NewPipe.</string>
|
||||
<string name="georestricted_content">Deze inhoud is niet toegankelijk in uw land.</string>
|
||||
<string name="no_app_to_open_intent">Geen app beschikbaar om dit te openen</string>
|
||||
<string name="chapters">Hoofdstukken</string>
|
||||
</resources>
|
|
@ -72,7 +72,7 @@
|
|||
<string name="video">Video</string>
|
||||
<string name="audio">Geluid</string>
|
||||
<string name="retry">Opnieuw proberen</string>
|
||||
<string name="main_bg_subtitle">Druk op \"zoeken\" om te beginnen.</string>
|
||||
<string name="main_bg_subtitle">Druk op \"Zoeken\" om te beginnen.</string>
|
||||
<string name="autoplay_by_calling_app_title">Automatisch afspelen</string>
|
||||
<string name="autoplay_by_calling_app_summary">Speelt video’s af als NewPipe vanuit een andere app wordt geopend</string>
|
||||
<string name="duration_live">Live</string>
|
||||
|
@ -262,8 +262,8 @@
|
|||
<string name="preferred_player_fetcher_notification_message">Bezig met laden van gevraagde inhoud</string>
|
||||
<string name="import_data_title">Databank importeren</string>
|
||||
<string name="export_data_title">Databank exporteren</string>
|
||||
<string name="import_data_summary">Dit overschrijft je huidige geschiedenis, abonnementen, playlists en instellingen</string>
|
||||
<string name="export_data_summary">Exporteer geschiedenis, abonnementen, playlists en instellingen</string>
|
||||
<string name="import_data_summary">Dit overschrijft je huidige geschiedenis, abonnementen, afspeellijsten en instellingen</string>
|
||||
<string name="export_data_summary">Exporteer geschiedenis, abonnementen, afspeellijsten en instellingen</string>
|
||||
<string name="export_complete_toast">Geëxporteerd</string>
|
||||
<string name="import_complete_toast">Geïmporteerd</string>
|
||||
<string name="no_valid_zip_file">Geen geldig ZIP-bestand</string>
|
||||
|
@ -599,7 +599,7 @@
|
|||
\nSchakel \"%1$s\" in bij de instellingen als u die wilt zien.</string>
|
||||
<string name="remove_watched">Verwijder bekeken</string>
|
||||
<string name="show_original_time_ago_summary">Originele teksten van services zijn zichtbaar in stream-items</string>
|
||||
<string name="youtube_restricted_mode_enabled_title">YouTube \"beperkte modus\" aanzetten</string>
|
||||
<string name="youtube_restricted_mode_enabled_title">YouTube \"Beperkte modus\" aanzetten</string>
|
||||
<string name="show_original_time_ago_title">Laat originele tijd geleden zien</string>
|
||||
<string name="detail_sub_channel_thumbnail_view_description">Kanaal avatar afbeelding</string>
|
||||
<string name="video_detail_by">Door %s</string>
|
||||
|
@ -641,7 +641,7 @@
|
|||
<string name="clear_cookie_summary">Verwijder cookies die NewPipe opslaat wanneer u een reCAPTCHA oplost</string>
|
||||
<string name="recaptcha_cookies_cleared">reCAPTCHA cookies zijn verwijderd</string>
|
||||
<string name="clear_cookie_title">Verwijder reCAPTCHA cookies</string>
|
||||
<string name="youtube_restricted_mode_enabled_summary">YouTube biedt een \"beperkte modus\" aan; dit verbergt mogelijk materiaal voor volwassenen</string>
|
||||
<string name="youtube_restricted_mode_enabled_summary">YouTube biedt een \"Beperkte modus\" aan, dit verbergt mogelijk materiaal voor volwassenen</string>
|
||||
<string name="show_age_restricted_content_summary">Toon inhoud die mogelijk niet geschikt is voor kinderen omwille van een leeftijdslimiet (zoals 18+)</string>
|
||||
<string name="notification_colorize_summary">Laat Android de kleur van de notificatie aanpassen, op basis van de meest voorkomende kleur in de thumbnail (let op: niet beschikbaar op elk apparaat)</string>
|
||||
<string name="notification_colorize_title">Notificatie kleur aanpassen</string>
|
||||
|
@ -675,7 +675,25 @@
|
|||
<string name="download_has_started">Downloaden is gestart</string>
|
||||
<string name="select_night_theme_toast">Je kan je favoriete nacht thema hier beneden selecteren</string>
|
||||
<string name="night_theme_summary">Selecteer uw favoriete nacht thema — %s</string>
|
||||
<string name="auto_device_theme_title">Automatisch (apparaat thema)</string>
|
||||
<string name="auto_device_theme_title">Automatisch (toestel thema)</string>
|
||||
<string name="show_channel_details">Toon details van kanaal</string>
|
||||
<string name="night_theme_title">Nachtmodus</string>
|
||||
<string name="metadata_privacy_internal">Intern</string>
|
||||
<string name="metadata_privacy_private">Privé</string>
|
||||
<string name="metadata_privacy_unlisted">Niet vermeld</string>
|
||||
<string name="metadata_privacy_public">Openbaar</string>
|
||||
<string name="metadata_thumbnail_url">Miniatuur-URL</string>
|
||||
<string name="metadata_host">Host</string>
|
||||
<string name="metadata_support">Ondersteuning</string>
|
||||
<string name="metadata_language">Taal</string>
|
||||
<string name="metadata_age_limit">Leeftijdslimiet</string>
|
||||
<string name="metadata_privacy">Privacy</string>
|
||||
<string name="metadata_licence">Licentie</string>
|
||||
<string name="metadata_tags">Tags</string>
|
||||
<string name="metadata_category">Categorie</string>
|
||||
<string name="description_select_disable">Tekst selecteren in de beschrijving uitschakelen</string>
|
||||
<string name="description_select_enable">Tekst selecteren in de beschrijving inschakelen</string>
|
||||
<string name="description_select_note">U kunt nu tekst in de beschrijving selecteren. Houd er rekening mee dat de pagina kan flikkeren en dat links mogelijk niet klikbaar zijn in de selectiemodus.</string>
|
||||
<string name="disable_media_tunneling_summary">Media tunneling uitschakelen als u een zwart scherm ervaart of video hapert bij het afspelen</string>
|
||||
<string name="disable_media_tunneling_title">Media tunneling uitschakelen</string>
|
||||
</resources>
|
|
@ -1,2 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources></resources>
|
||||
<resources>
|
||||
<string name="view_count_text">%1$s ଭିଉଜ、</string>
|
||||
<string name="main_bg_subtitle">ଆରମ୍ଭ କରିବା ପାଇଁ \"ସର୍ଚ୍ଚ\" ବଟନ କୁ ଦବାନ୍ତୁ</string>
|
||||
</resources>
|
|
@ -690,4 +690,18 @@
|
|||
<string name="show_channel_details">Pokaż szczegóły kanału</string>
|
||||
<string name="disable_media_tunneling_summary">Wyłącz tunelowanie multimediów jeśli zaobserwowałeś czarny ekran bądź brak płynności odtwarzania wideo</string>
|
||||
<string name="disable_media_tunneling_title">Wyłącz tunelowanie multimediów</string>
|
||||
<string name="metadata_age_limit">Ograniczenie wieku</string>
|
||||
<string name="description_select_disable">Wyłącz zaznaczanie tekstu w opisie</string>
|
||||
<string name="description_select_enable">Włącz zaznaczanie tekstu w opisie</string>
|
||||
<string name="metadata_privacy_internal">Wewnętrzny</string>
|
||||
<string name="metadata_privacy_private">Prywatny</string>
|
||||
<string name="metadata_privacy_public">Publiczny</string>
|
||||
<string name="metadata_thumbnail_url">Adres URL miniatury</string>
|
||||
<string name="metadata_host">Host</string>
|
||||
<string name="metadata_support">Wsparcie</string>
|
||||
<string name="metadata_language">Język</string>
|
||||
<string name="metadata_privacy">Prywatność</string>
|
||||
<string name="metadata_licence">Licencja</string>
|
||||
<string name="metadata_tags">Tagi</string>
|
||||
<string name="metadata_category">Kategoria</string>
|
||||
</resources>
|
|
@ -680,4 +680,20 @@
|
|||
<string name="show_channel_details">Mostrar detalhes do canal</string>
|
||||
<string name="disable_media_tunneling_summary">Desative o túnel de mídia se você tiver uma tela preta ou a reprodução do vídeo estiver engasgando</string>
|
||||
<string name="disable_media_tunneling_title">Desativar túnel de mídia</string>
|
||||
<string name="metadata_privacy_internal">Interno</string>
|
||||
<string name="metadata_privacy_private">Privado</string>
|
||||
<string name="metadata_privacy_unlisted">Não Listado</string>
|
||||
<string name="metadata_privacy_public">Público</string>
|
||||
<string name="metadata_age_limit">Limite de Idade</string>
|
||||
<string name="metadata_thumbnail_url">URL da Capa</string>
|
||||
<string name="metadata_host">Hospedado em</string>
|
||||
<string name="metadata_support">Suporte</string>
|
||||
<string name="metadata_language">Idioma</string>
|
||||
<string name="metadata_privacy">Privacidade</string>
|
||||
<string name="metadata_licence">Licença</string>
|
||||
<string name="metadata_tags">Tags</string>
|
||||
<string name="metadata_category">Categoria</string>
|
||||
<string name="description_select_disable">Desativar seleção de texto na descrição</string>
|
||||
<string name="description_select_enable">Ativar seleção de texto na descrição</string>
|
||||
<string name="description_select_note">Agora você pode selecionar o texto dentro da descrição. Observe que a página pode piscar e os links podem não ser clicáveis no modo de seleção.</string>
|
||||
</resources>
|
|
@ -623,7 +623,7 @@
|
|||
<string name="clear_queue_confirmation_title">Pedir confirmação antes de limpar uma fila</string>
|
||||
<string name="popup_remember_size_pos_summary">Lembrar do último tamanho e posição do popup</string>
|
||||
<string name="notification_action_nothing">Nada</string>
|
||||
<string name="notification_action_buffering">Processamento...</string>
|
||||
<string name="notification_action_buffering">Processamento…</string>
|
||||
<string name="notification_action_shuffle">Baralhar</string>
|
||||
<string name="notification_action_repeat">Repetir</string>
|
||||
<string name="notification_actions_at_most_three">Pode selecionar, no máximo, três ações para mostrar na notificação compacta!</string>
|
||||
|
|
|
@ -621,7 +621,7 @@
|
|||
<string name="autoplay_summary">Iniciar reprodução automaticamente — %s</string>
|
||||
<string name="title_activity_play_queue">Reproduzir fila</string>
|
||||
<string name="never">Nunca</string>
|
||||
<string name="notification_action_buffering">Processamento...</string>
|
||||
<string name="notification_action_buffering">Processamento…</string>
|
||||
<string name="clear_queue_confirmation_description">A fila do reprodutor ativo será substituída</string>
|
||||
<string name="unsupported_url_dialog_message">URL não reconhecido. Abrir com outra aplicação\?</string>
|
||||
<string name="auto_queue_toggle">Colocar na fila automaticamente</string>
|
||||
|
|
|
@ -691,4 +691,20 @@
|
|||
<string name="show_channel_details">Подробно о канале</string>
|
||||
<string name="disable_media_tunneling_summary">Отключите туннелирование медиа, если вы видите черный экран или подёргивание при воспроизведении видео</string>
|
||||
<string name="disable_media_tunneling_title">Отключить туннелирование медиа</string>
|
||||
<string name="description_select_note">Теперь вы можете выделить текст внутри описания. Заметьте, что страница может мигать и ссылки могут быть некликабельны в режиме выделения.</string>
|
||||
<string name="metadata_support">Поддержка</string>
|
||||
<string name="metadata_language">Язык</string>
|
||||
<string name="metadata_age_limit">Возрастное ограничение</string>
|
||||
<string name="metadata_licence">Лицензия</string>
|
||||
<string name="metadata_tags">Тэги</string>
|
||||
<string name="metadata_category">Категория</string>
|
||||
<string name="description_select_disable">Отключить выделение текста в описании</string>
|
||||
<string name="description_select_enable">Включить выделение текста в описании</string>
|
||||
<string name="metadata_privacy_internal">Внутренняя</string>
|
||||
<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_host">Сервер</string>
|
||||
<string name="metadata_privacy">Доступность</string>
|
||||
</resources>
|
|
@ -680,4 +680,20 @@
|
|||
<string name="show_channel_details">Ammustra sos detàllios de su canale</string>
|
||||
<string name="disable_media_tunneling_summary">Disabìlita sa tunnellizatzione de sos elementos multimediales si durante sa riprodutzione bi sunt ischermadas nieddas o su flussu de su vìdeu no est regulare</string>
|
||||
<string name="disable_media_tunneling_title">Disabìlita sa tunnellizatzione de sos mèdios</string>
|
||||
<string name="metadata_privacy_internal">Internu</string>
|
||||
<string name="metadata_privacy_unlisted">No elencadu</string>
|
||||
<string name="metadata_privacy_private">Privadu</string>
|
||||
<string name="metadata_privacy_public">Pùblicu</string>
|
||||
<string name="metadata_thumbnail_url">URL de sa miniadura</string>
|
||||
<string name="metadata_host">Istrangiadore</string>
|
||||
<string name="metadata_support">Suportu</string>
|
||||
<string name="metadata_language">Limba</string>
|
||||
<string name="metadata_age_limit">Lìmite de edade</string>
|
||||
<string name="metadata_privacy">Riservadesa</string>
|
||||
<string name="metadata_licence">Litzèntzia</string>
|
||||
<string name="metadata_tags">Etichetas</string>
|
||||
<string name="metadata_category">Categoria</string>
|
||||
<string name="description_select_disable">Disabìlita s\'ischerta de su testu in sa descritzione</string>
|
||||
<string name="description_select_enable">Abìlita s\'ischerta de su testu in sa descritzione</string>
|
||||
<string name="description_select_note">Como podes ischertare su testu in intro de sa descritzione. Ammenta·ti chi sa pàgina diat pòdere trèmere e sos ligàmenes si diant pòdere no abèrrere cando ses in modalidade de ischerta.</string>
|
||||
</resources>
|
|
@ -26,7 +26,7 @@
|
|||
<string name="play_with_kodi_title">Prehrať cez Kodi</string>
|
||||
<string name="kore_not_found">Nainštalovať chýbajúcu aplikáciu Kore\?</string>
|
||||
<string name="show_play_with_kodi_title">Zobraziť možnosť \"Prehrať cez Kodi\"</string>
|
||||
<string name="show_play_with_kodi_summary">Zobraziť možnosť \"Prehraj cez Kodi\"</string>
|
||||
<string name="show_play_with_kodi_summary">Zobraziť možnosť \"Prehrať cez Kodi\"</string>
|
||||
<string name="play_audio">Zvuk</string>
|
||||
<string name="default_audio_format_title">Predvolený zvukový formát</string>
|
||||
<string name="theme_title">Téma</string>
|
||||
|
@ -128,7 +128,7 @@
|
|||
<string name="filter">Filter</string>
|
||||
<string name="refresh">Obnoviť</string>
|
||||
<string name="clear">Vyčistiť</string>
|
||||
<string name="use_external_video_player_summary">Neprehrá audio pri niektorých rozlíšeniach</string>
|
||||
<string name="use_external_video_player_summary">Odstráni audio pri niektorých rozlíšeniach</string>
|
||||
<string name="popup_remember_size_pos_title">Zapamätať si parametre mini okna</string>
|
||||
<string name="popup_remember_size_pos_summary">Zapamätať si posledné nastavenie veľkosti a pozície mini okna</string>
|
||||
<string name="player_gesture_controls_title">Ovládanie prehrávača gestami</string>
|
||||
|
@ -313,7 +313,7 @@
|
|||
<string name="metadata_cache_wipe_summary">Odstrániť všetky údaje webových stránok vo vyrovnávacej pamäti</string>
|
||||
<string name="metadata_cache_wipe_complete_notice">Vyrovnávacia pamäť metadát bola vymazaná</string>
|
||||
<string name="auto_queue_title">Automaticky zaradiť daľší stream</string>
|
||||
<string name="auto_queue_summary">Končiaci neopakujúci sa zoznam prehrávania bude pokračovať súvisiacim streamom</string>
|
||||
<string name="auto_queue_summary">Končiaci (neopakujúci sa) zoznam prehrávania bude pokračovať súvisiacim streamom</string>
|
||||
<string name="settings_category_debug_title">Ladenie</string>
|
||||
<string name="file">Súbor</string>
|
||||
<string name="invalid_directory">Neplatný adresár</string>
|
||||
|
@ -690,4 +690,20 @@
|
|||
<string name="night_theme_title">Nočná Téma</string>
|
||||
<string name="disable_media_tunneling_summary">Ak vám video pri prehrávaní seká alebo sa zobrazuje čierna obrazovka zakážte tunelovanie médií</string>
|
||||
<string name="disable_media_tunneling_title">Zakázať tunelovanie médií</string>
|
||||
<string name="metadata_privacy_internal">Interné</string>
|
||||
<string name="metadata_privacy_private">Súkromné</string>
|
||||
<string name="metadata_privacy_unlisted">Nezaradené</string>
|
||||
<string name="metadata_thumbnail_url">URL miniatúry</string>
|
||||
<string name="metadata_privacy_public">Verejné</string>
|
||||
<string name="metadata_host">Hostiteľ</string>
|
||||
<string name="metadata_support">Podpora</string>
|
||||
<string name="metadata_language">Jazyk</string>
|
||||
<string name="metadata_age_limit">Vekový limit</string>
|
||||
<string name="metadata_privacy">Ochrana osobných údajov</string>
|
||||
<string name="metadata_licence">Licencia</string>
|
||||
<string name="metadata_tags">Tagy</string>
|
||||
<string name="metadata_category">Kategória</string>
|
||||
<string name="description_select_disable">Zakázať výber textu v popise</string>
|
||||
<string name="description_select_enable">Povolenie výberu textu v popise</string>
|
||||
<string name="description_select_note">Teraz môžete vybrať text vo vnútri popisu. Upozorňujeme, že stránka môže blikať a odkazy nemusia byť klikateľné, keď je v režime výberu.</string>
|
||||
</resources>
|
|
@ -319,7 +319,7 @@
|
|||
<string name="permission_display_over_apps">U ogolow app-ka inuu dul fuulo applicationada kale</string>
|
||||
<string name="restore_defaults_confirmation">Ma rabtaa inaad sidii hore kuceliso\?</string>
|
||||
<string name="restore_defaults">Dib ugu celi sidii hore</string>
|
||||
<string name="saved_tabs_invalid_json">Lama akhrin karo daaqadihii la kaydiyay, ...isticmaalaya kuwii app-ku kusoo baxay</string>
|
||||
<string name="saved_tabs_invalid_json">Lama akhrin karo daaqadihii la kaydiyay, …isticmaalaya kuwii app-ku kusoo baxay</string>
|
||||
<string name="no_streams_available_download">Wax la dajiyo lama heli karo</string>
|
||||
<string name="error_occurred_detail">Khalad ayaa ka dhacay: %1$s</string>
|
||||
<string name="file_name_empty_error">Magaca shayga ma madhnaan karo</string>
|
||||
|
|
|
@ -76,7 +76,7 @@
|
|||
<string name="report_error">Пријавите грешку</string>
|
||||
<string name="user_report">Извештај корисника</string>
|
||||
<string name="duration_live">Уживо</string>
|
||||
<string name="main_bg_subtitle">тапните на лупу да започнете</string>
|
||||
<string name="main_bg_subtitle">Тапните на лупу да започнете.</string>
|
||||
<string name="autoplay_by_calling_app_title">Аутопуштање</string>
|
||||
<string name="autoplay_by_calling_app_summary">Пушта видео по позиву из друге апликације</string>
|
||||
<string name="start">Почни</string>
|
||||
|
@ -139,10 +139,10 @@
|
|||
<string name="subscribed_button_title">Прати се</string>
|
||||
<string name="subscribe_button_title">Прати</string>
|
||||
<string name="tab_main">Главно</string>
|
||||
<string name="tab_subscriptions">Претплате</string>
|
||||
<string name="tab_subscriptions">Праћења</string>
|
||||
<string name="fragment_feed_title">Шта је ново</string>
|
||||
<string name="enable_search_history_title">Историјат претраге</string>
|
||||
<string name="enable_search_history_summary">Уписуј појмове претраге локално</string>
|
||||
<string name="enable_search_history_summary">Појмове претраге складишти локално</string>
|
||||
<string name="enable_watch_history_title">Историја гледања</string>
|
||||
<string name="enable_watch_history_summary">Чувај историјат гледања</string>
|
||||
<string name="resume_on_audio_focus_gain_title">Настави са репродукцијом</string>
|
||||
|
@ -166,9 +166,9 @@
|
|||
<string name="action_history">Историјат</string>
|
||||
<string name="history_empty">Историјат је празан</string>
|
||||
<string name="history_cleared">Историјат очишћен</string>
|
||||
<string name="resume_on_audio_focus_gain_summary">Настави репродукцију након прекида (нпр. позива)</string>
|
||||
<string name="resume_on_audio_focus_gain_summary">Настави пуштање након прекида (нпр. позива)</string>
|
||||
<string name="settings_file_charset_title">Дозвољени знакови у називима</string>
|
||||
<string name="charset_letters_and_digits">Слова и бројке</string>
|
||||
<string name="charset_letters_and_digits">слова и бројке</string>
|
||||
<string name="copyright" formatted="true">© %1$s од %2$s под %3$s</string>
|
||||
<string name="error_unable_to_load_license">Не могу да учитам лиценцу</string>
|
||||
<string name="channel_unsubscribed">Одјављен са канала</string>
|
||||
|
@ -183,11 +183,11 @@
|
|||
<string name="notification_channel_description">Обавештења за Њупајп плејере у позадини и искачућем прозору</string>
|
||||
<string name="search_no_results">Нема резултата</string>
|
||||
<string name="empty_subscription_feed_subtitle">Нема ничега овде осим цврчака</string>
|
||||
<string name="no_subscribers">Нема претплатника</string>
|
||||
<string name="no_subscribers">Нема пратилаца</string>
|
||||
<plurals name="subscribers">
|
||||
<item quantity="one">%s претплатник</item>
|
||||
<item quantity="few">%s претплатника</item>
|
||||
<item quantity="other">%s претплатника</item>
|
||||
<item quantity="one">%s пратилац</item>
|
||||
<item quantity="few">%s пратилаца</item>
|
||||
<item quantity="other">%s пратилаца</item>
|
||||
</plurals>
|
||||
<string name="no_views">Нема прегледа</string>
|
||||
<plurals name="views">
|
||||
|
@ -203,7 +203,7 @@
|
|||
</plurals>
|
||||
<string name="settings_file_replacement_character_summary">Неисправни знакови биће замењени овим</string>
|
||||
<string name="settings_file_replacement_character_title">Знак за замену</string>
|
||||
<string name="charset_most_special_characters">Посебни знакови</string>
|
||||
<string name="charset_most_special_characters">и посебни знакови</string>
|
||||
<string name="title_licenses">Лиценце треће стране</string>
|
||||
<string name="app_license_title">Лиценца Њупајпа</string>
|
||||
<string name="contribution_encouragement">Помоћ је увек добро дошла, било да имате идеју за превод, дизајн, козметичке или озбиљне измене кôда. Што се више уради, боље је!</string>
|
||||
|
@ -331,23 +331,23 @@
|
|||
<string name="app_update_notification_content_text">Тапните за преузимање</string>
|
||||
<string name="app_update_notification_content_title">Доступно је ажурирање за ЊуПајп!</string>
|
||||
<string name="switch_view">Промени приказ</string>
|
||||
<string name="auto">Аутоматски</string>
|
||||
<string name="grid">Мрежа</string>
|
||||
<string name="list">Листа</string>
|
||||
<string name="auto">аутоматски</string>
|
||||
<string name="grid">мрежа</string>
|
||||
<string name="list">листа</string>
|
||||
<string name="list_view_mode">Режим приказа листе</string>
|
||||
<string name="never">Никад</string>
|
||||
<string name="wifi_only">Само на бежичној</string>
|
||||
<string name="autoplay_summary">Покрени пуштање аутоматски — %s</string>
|
||||
<string name="minimize_on_exit_popup_description">Умањи на искачући плејер</string>
|
||||
<string name="minimize_on_exit_background_description">Умањи на позадински плејер</string>
|
||||
<string name="never">никад</string>
|
||||
<string name="wifi_only">само на бежичној</string>
|
||||
<string name="autoplay_summary">Покрени аутоматски — %s</string>
|
||||
<string name="minimize_on_exit_popup_description">умањи на искачући плејер</string>
|
||||
<string name="minimize_on_exit_background_description">умањи на позадински плејер</string>
|
||||
<string name="minimize_on_exit_none_description">ништа</string>
|
||||
<string name="minimize_on_exit_summary">Радња при преласку на другу апликацију са главног видео плејера — %s</string>
|
||||
<string name="minimize_on_exit_title">Умањи при мењању апликације</string>
|
||||
<string name="updates_setting_description">Прикажи обавештење када постоји нова верзија апликације</string>
|
||||
<string name="updates_setting_title">Ажурирања</string>
|
||||
<string name="limit_mobile_data_usage_title">Ограничи резолуцију када користим мобилне податке</string>
|
||||
<string name="limit_mobile_data_usage_title">Ограничити резолуцију на мобилној мрежи</string>
|
||||
<string name="decline">Одбиј</string>
|
||||
<string name="limit_data_usage_none_description">Без органичења</string>
|
||||
<string name="limit_data_usage_none_description">без ограничења</string>
|
||||
<string name="accept">Прихвати</string>
|
||||
<string name="start_accept_privacy_policy">Да бисмо били у складу са Европском општом уредбом о заштити података („GDPR“), скрећемо вам пажњу на политику приватности апликације ЊуПајпа. Пажљиво је прочитајте.
|
||||
\nМорате је прихватити да бисте нам послали извештај о грешци.</string>
|
||||
|
@ -484,7 +484,7 @@
|
|||
<item quantity="other">%s гледалаца</item>
|
||||
</plurals>
|
||||
<string name="no_one_watching">Нико не гледа</string>
|
||||
<string name="subscribers_count_not_available">Број претплатника није доступан</string>
|
||||
<string name="subscribers_count_not_available">Број пратилаца није доступан</string>
|
||||
<string name="drawer_header_description">Мењај услугу, тренутно изабрана:</string>
|
||||
<string name="detail_drag_description">Превуците за преуређивање</string>
|
||||
<string name="description_tab_description">Опис</string>
|
||||
|
@ -554,7 +554,7 @@
|
|||
\n
|
||||
\nУкључите „%1$s“ у поставкама ако желите да га видите.</string>
|
||||
<string name="youtube_restricted_mode_enabled_summary">Јутјуб омогућава „Ограничени режим“ који скрива потенцијални садржај за одрасле</string>
|
||||
<string name="youtube_restricted_mode_enabled_title">Укључите Јутјубов „Ограничени режим“</string>
|
||||
<string name="youtube_restricted_mode_enabled_title">Укључити Јутјубов „Ограничени режим“</string>
|
||||
<string name="show_age_restricted_content_summary">Приказ садржаја који можда није прикладан за децу јер има старосну границу (попут 18+)</string>
|
||||
<string name="settings_category_notification_title">Обавештење</string>
|
||||
<string name="settings_category_updates_title">Ажурирања</string>
|
||||
|
@ -611,7 +611,7 @@
|
|||
<string name="download_has_started">Преузимање је започело</string>
|
||||
<string name="select_night_theme_toast">Испод можете одабрати своју омиљену ноћну тему</string>
|
||||
<string name="night_theme_summary">Изаберите своју омиљену ноћну тему — %s</string>
|
||||
<string name="auto_device_theme_title">Аутоматски (тема уређаја)</string>
|
||||
<string name="auto_device_theme_title">аутоматски (тема уређаја)</string>
|
||||
<string name="radio">Радио</string>
|
||||
<string name="featured">Истакнуто</string>
|
||||
<string name="paid_content">Овај садржај је доступан само корисницима који су платили, тако да га ЊуПајп не може стримовати или преузимати.</string>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="main_bg_subtitle">Tryck på \"Sök\" för att komma igång</string>
|
||||
<string name="main_bg_subtitle">Tryck på förstoringsglaset för att komma igång</string>
|
||||
<string name="upload_date_text">Publicerad den %1$s</string>
|
||||
<string name="no_player_found">Ingen strömspelare hittades. Vill du installera VLC?</string>
|
||||
<string name="install">Installera</string>
|
||||
|
|
|
@ -670,4 +670,20 @@
|
|||
<string name="show_channel_details">顯示頻道詳細資訊</string>
|
||||
<string name="disable_media_tunneling_summary">如果您遇到黑畫面或影片播放停頓的現象,請停用媒體隧道</string>
|
||||
<string name="disable_media_tunneling_title">停用媒體隧道</string>
|
||||
<string name="metadata_privacy_internal">內部</string>
|
||||
<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_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_category">分類</string>
|
||||
<string name="description_select_disable">停用選取描述中的文字</string>
|
||||
<string name="description_select_enable">啟用選取描述中的文字</string>
|
||||
<string name="description_select_note">您現在可以選取描述中的文字了。請注意,在選取模式下,頁面可能會閃爍,連結也可能無法點擊。</string>
|
||||
</resources>
|
|
@ -716,4 +716,20 @@
|
|||
<string name="night_theme_summary">Select your favorite night theme — %s</string>
|
||||
<string name="select_night_theme_toast">You can select your favorite night theme below</string>
|
||||
<string name="download_has_started">Download has started</string>
|
||||
<string name="description_select_note">You can now select text inside the description. Note that the page may flicker and links may not be clickable while in selection mode.</string>
|
||||
<string name="description_select_enable">Enable selecting text in the description</string>
|
||||
<string name="description_select_disable">Disable selecting text in the description</string>
|
||||
<string name="metadata_category">Category</string>
|
||||
<string name="metadata_tags">Tags</string>
|
||||
<string name="metadata_licence">Licence</string>
|
||||
<string name="metadata_privacy">Privacy</string>
|
||||
<string name="metadata_age_limit">Age limit</string>
|
||||
<string name="metadata_language">Language</string>
|
||||
<string name="metadata_support">Support</string>
|
||||
<string name="metadata_host">Host</string>
|
||||
<string name="metadata_thumbnail_url">Thumbnail URL</string>
|
||||
<string name="metadata_privacy_public">Public</string>
|
||||
<string name="metadata_privacy_unlisted">Unlisted</string>
|
||||
<string name="metadata_privacy_private">Private</string>
|
||||
<string name="metadata_privacy_internal">Internal</string>
|
||||
</resources>
|
|
@ -91,7 +91,7 @@ public class ImportExportJsonHelperTest {
|
|||
final List<SubscriptionItem> itemsFromFile = ImportExportJsonHelper.readFrom(
|
||||
inputStream, null);
|
||||
|
||||
if (itemsFromFile == null || itemsFromFile.isEmpty()) {
|
||||
if (itemsFromFile.isEmpty()) {
|
||||
fail("ImportExportJsonHelper.readFrom(input) returned a null or empty list");
|
||||
}
|
||||
|
||||
|
@ -116,7 +116,7 @@ public class ImportExportJsonHelperTest {
|
|||
final List<SubscriptionItem> secondReadItems = ImportExportJsonHelper.readFrom(
|
||||
inputStream, null);
|
||||
|
||||
if (secondReadItems == null || secondReadItems.isEmpty()) {
|
||||
if (secondReadItems.isEmpty()) {
|
||||
fail("second call to readFrom returned an empty list");
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,183 @@
|
|||
package org.schabi.newpipe.player.playqueue;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
|
||||
import org.schabi.newpipe.extractor.stream.StreamType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.spy;
|
||||
|
||||
@SuppressWarnings("checkstyle:HideUtilityClassConstructor")
|
||||
public class PlayQueueTest {
|
||||
static PlayQueue makePlayQueue(final int index, final List<PlayQueueItem> streams) {
|
||||
// I tried using Mockito, but it didn't work for some reason
|
||||
return new PlayQueue(index, streams) {
|
||||
@Override
|
||||
public boolean isComplete() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fetch() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
static PlayQueueItem makeItemWithUrl(final String url) {
|
||||
final StreamInfoItem infoItem = new StreamInfoItem(
|
||||
0, url, "", StreamType.VIDEO_STREAM
|
||||
);
|
||||
return new PlayQueueItem(infoItem);
|
||||
}
|
||||
|
||||
public static class SetIndexTests {
|
||||
private static final int SIZE = 5;
|
||||
private PlayQueue nonEmptyQueue;
|
||||
private PlayQueue emptyQueue;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
final List<PlayQueueItem> streams = new ArrayList<>(5);
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
streams.add(makeItemWithUrl("URL_" + i));
|
||||
}
|
||||
nonEmptyQueue = spy(makePlayQueue(0, streams));
|
||||
emptyQueue = spy(makePlayQueue(0, new ArrayList<>()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void negative() {
|
||||
nonEmptyQueue.setIndex(-5);
|
||||
assertEquals(0, nonEmptyQueue.getIndex());
|
||||
|
||||
emptyQueue.setIndex(-5);
|
||||
assertEquals(0, nonEmptyQueue.getIndex());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void inBounds() {
|
||||
nonEmptyQueue.setIndex(2);
|
||||
assertEquals(2, nonEmptyQueue.getIndex());
|
||||
|
||||
// emptyQueue not tested because 0 isn't technically inBounds
|
||||
}
|
||||
|
||||
@Test
|
||||
public void outOfBoundIsComplete() {
|
||||
doReturn(true).when(nonEmptyQueue).isComplete();
|
||||
nonEmptyQueue.setIndex(7);
|
||||
assertEquals(2, nonEmptyQueue.getIndex());
|
||||
|
||||
doReturn(true).when(emptyQueue).isComplete();
|
||||
emptyQueue.setIndex(2);
|
||||
assertEquals(0, emptyQueue.getIndex());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void outOfBoundsNotComplete() {
|
||||
doReturn(false).when(nonEmptyQueue).isComplete();
|
||||
nonEmptyQueue.setIndex(7);
|
||||
assertEquals(SIZE - 1, nonEmptyQueue.getIndex());
|
||||
|
||||
doReturn(false).when(emptyQueue).isComplete();
|
||||
emptyQueue.setIndex(2);
|
||||
assertEquals(0, emptyQueue.getIndex());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void indexZero() {
|
||||
nonEmptyQueue.setIndex(0);
|
||||
assertEquals(0, nonEmptyQueue.getIndex());
|
||||
|
||||
doReturn(true).when(emptyQueue).isComplete();
|
||||
emptyQueue.setIndex(0);
|
||||
assertEquals(0, emptyQueue.getIndex());
|
||||
|
||||
doReturn(false).when(emptyQueue).isComplete();
|
||||
emptyQueue.setIndex(0);
|
||||
assertEquals(0, emptyQueue.getIndex());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addToHistory() {
|
||||
nonEmptyQueue.setIndex(0);
|
||||
assertFalse(nonEmptyQueue.previous());
|
||||
|
||||
nonEmptyQueue.setIndex(3);
|
||||
assertTrue(nonEmptyQueue.previous());
|
||||
assertEquals("URL_0", Objects.requireNonNull(nonEmptyQueue.getItem()).getUrl());
|
||||
}
|
||||
}
|
||||
|
||||
public static class GetItemTests {
|
||||
private static List<PlayQueueItem> streams;
|
||||
private PlayQueue queue;
|
||||
|
||||
@BeforeClass
|
||||
public static void init() {
|
||||
streams = new ArrayList<>(Collections.nCopies(5, makeItemWithUrl("OTHER_URL")));
|
||||
streams.set(3, makeItemWithUrl("TARGET_URL"));
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
queue = makePlayQueue(0, streams);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void inBounds() {
|
||||
assertEquals("TARGET_URL", Objects.requireNonNull(queue.getItem(3)).getUrl());
|
||||
assertEquals("OTHER_URL", Objects.requireNonNull(queue.getItem(1)).getUrl());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void outOfBounds() {
|
||||
assertNull(queue.getItem(-1));
|
||||
assertNull(queue.getItem(5));
|
||||
}
|
||||
}
|
||||
|
||||
public static class EqualsTests {
|
||||
private final PlayQueueItem item1 = makeItemWithUrl("URL_1");
|
||||
private final PlayQueueItem item2 = makeItemWithUrl("URL_2");
|
||||
|
||||
@Test
|
||||
public void sameStreams() {
|
||||
final List<PlayQueueItem> streams = Collections.nCopies(5, item1);
|
||||
final PlayQueue queue1 = makePlayQueue(0, streams);
|
||||
final PlayQueue queue2 = makePlayQueue(0, streams);
|
||||
assertEquals(queue1, queue2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sameSizeDifferentItems() {
|
||||
final List<PlayQueueItem> streams1 = Collections.nCopies(5, item1);
|
||||
final List<PlayQueueItem> streams2 = Collections.nCopies(5, item2);
|
||||
final PlayQueue queue1 = makePlayQueue(0, streams1);
|
||||
final PlayQueue queue2 = makePlayQueue(0, streams2);
|
||||
assertNotEquals(queue1, queue2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void differentSizeStreams() {
|
||||
final List<PlayQueueItem> streams1 = Collections.nCopies(5, item1);
|
||||
final List<PlayQueueItem> streams2 = Collections.nCopies(6, item2);
|
||||
final PlayQueue queue1 = makePlayQueue(0, streams1);
|
||||
final PlayQueue queue2 = makePlayQueue(0, streams2);
|
||||
assertNotEquals(queue1, queue2);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
Option "Kanaldetails" wurde zum Langdruckmenü hinzugefügt.
|
||||
Funktion zum Umbenennen des Playlist-Namens von der Playlist-Oberfläche zugefügt.
|
||||
Benutzer kann nun pausieren, während ein Video gepuffert wird.
|
||||
Weiße Thema wurde aufpoliert.
|
||||
Überlappende Schriftarten bei Verwendung einer größeren Schriftgröße behoben.
|
||||
Kein Video auf Formuler- und Zephier-Geräten behoben.
|
||||
Verschiedene Abstürze behoben.
|
|
@ -0,0 +1,8 @@
|
|||
• Installation auf externen Speicher möglich
|
||||
• [Bandcamp] Unterstützung für die Anzeige der ersten drei Kommentare in einem Stream
|
||||
• Nur Hinweisanzeige "Download gestartet", wenn der Download gestartet wird
|
||||
• Setzt kein reCaptcha-Cookie, wenn kein Cookie gespeichert wird
|
||||
• Cache-Leistung verbessert
|
||||
• Problem behoben, dass die Wiedergabe nicht automatisch abspielt wird
|
||||
• Verwerfen früherer Snackbars beim Löschen von Downloads
|
||||
• Fehler beim Löschen des Objekts, das nicht in der Liste enthalten ist
|
|
@ -0,0 +1,11 @@
|
|||
Neu
|
||||
• Inhaltsmetadaten (Tags, Kategorien, Lizenz, ...) unter der Beschreibung anzeigen
|
||||
• Option "Kanaldetails anzeigen" in remote (nicht lokalen) Wiedergabelisten hinzugefügt
|
||||
• Option "Im Browser öffnen" zum Langdruck-Menü hinzugefügt
|
||||
|
||||
Behoben
|
||||
• Rotationsabsturz auf der Videodetailseite
|
||||
• "Mit Kodi spielen"-Button im Player fordert immer auf, Kore zu installieren
|
||||
• Setzen von Import- und Exportpfaden wurde behoben und verbessert
|
||||
• [YouTube] Anzahl Kommentar-Likes korrigiert
|
||||
Und vieles mehr
|
|
@ -0,0 +1,11 @@
|
|||
New
|
||||
• Show content metadata (tags, categories, license, ...) below the description
|
||||
• Added "Show channel details" option in remote (non-local) playlists
|
||||
• Added "Open in browser" option to long-press menu
|
||||
|
||||
Fixed
|
||||
• Fixed rotation crash on video detail page
|
||||
• Fixed "Play with Kodi" button in player always prompts to install Kore
|
||||
• Fixed and improved setting import and export paths
|
||||
• [YouTube] Fixed comment like count
|
||||
And much more
|
|
@ -0,0 +1 @@
|
|||
• [YouTube] rétablissement des flux
|
|
@ -0,0 +1 @@
|
|||
La réparation du flux YouTube ne fonctionnait pas correctement dans l'UE. Cela était dû à un nouveau système de cookies et de consentement à la confidentialité qui exige que NewPipe définisse un cookie CONSENT.
|
|
@ -0,0 +1,6 @@
|
|||
Ajout d'une option de détails sur les chaînes dans le menu de pression longue.
|
||||
Ajout d'une fonctionnalité permettant de renommer le nom de la liste de lecture à partir de l'interface de la liste de lecture.
|
||||
Permet à l'utilisateur de faire une pause pendant la mise en mémoire tampon d'une vidéo.
|
||||
Le thème blanc a été amélioré.
|
||||
Correction du chevauchement des polices lors de l'utilisation d'une taille de police plus grande.
|
||||
Correction de l'absence de vidéo sur les appareils Formuler et Zephier.
|
|
@ -0,0 +1,8 @@
|
|||
• Izinkan instalasi pada penyimpanan eksternal
|
||||
• [Bandcamp] Penambahan dukungan untuk menampilkan tiga komentar pertama pada stream
|
||||
• Hanya Tampilkan toast 'Unduh telah dimulai' saat mengunduh dimulai
|
||||
• Jangan mengatur cookie reCaptcha ketika tidak ada cookie yang disimpan
|
||||
• [Pemutar] Peningkatan kinerja cache
|
||||
• [Pemutar] Tidak memutar secara otomatis
|
||||
• Abaikan Snackbars sebelumnya saat menghapus unduhan
|
||||
• Perbaikan mencoba menghapus objek tidak dalam daftar
|
|
@ -1 +1 @@
|
|||
NewPipe nenaudoja jokių Google paslaugų ar Youtube API. Jisai tiktai nuskanuoja svetaine dėl reikemos informacijos. Dėlto NewPipe nereikia įdiegtų Google paslaugų. Ir jums nereikia Youtube paskyros norint naudoti NewPipe taip pat yra FLOSS.
|
||||
NewPipe nenaudoja jokių Google paslaugų ar Youtube API. Programa tik paima informaciją kurios jai reikia. Dėlto NewPipe nereikia įdiegtų Google paslaugų. Taipogi jums nereikia Youtube paskyros norint naudoti NewPipe, tai yra FLOSS.
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Nemokama ir lengva "YouTube" sąsaja skirta "Android".
|
|
@ -1 +1 @@
|
|||
ଏକ ମାଗଣା ହାଲୁକା Youtube ସେବା Android ପାଇଁ |
|
||||
ଏକ ମାଗଣା ହାଲୁକା Youtube ସେବା Android ପାଇଁ
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
• Povoliť inštaláciu na externom úložisku
|
||||
• [Bandcamp] Pridaná podpora pre zobrazovanie prvých troch komentárov v streame
|
||||
• Zobraziť „sťahovanie začalo“ sa zobrazí až pri začatí sťahovania
|
||||
• Nenastavovať súbor cookie reCaptcha, ak nie je uložený žiadny súbor cookie
|
||||
• [Player] Zlepšenie výkonu medzipamäte
|
||||
• [Prehrávač] Opravené automatické prehrávanie
|
||||
• Zavrieť predchádzajúce Snackbary pri odstraňovaní sťahovaní
|
||||
• Opravený pokus o odstránenie objektu, ktorý nie je na zozname
|
|
@ -1 +1 @@
|
|||
ЊуПајп не користи ниједну библиотеку Гугл оквира нити Јутјуб АПИ. Само скида са Јутјуба оно што му је потребно. Стога се ова апликација може користити на уређајима без инсталираних Гугл услуга. Такође, није вам потребан Јутјуб налог да бисте користили ЊуПајп, и још је ФЛОСС.
|
||||
ЊуПајп не користи ниједну библиотеку Гугл оквира нити Јутјуб АПИ. Само скида са Јутјуба оно што му је потребно. Стога се ова апликација може користити на уређајима без инсталираних Гугл услуга. Такође, није вам потребан Јутјуб налог да бисте користили ЊуПајп, и још је слободан, бесплатан и отвореног кода.
|
||||
|
|
|
@ -1 +1 @@
|
|||
Безкоштовний та легкий YouTube інткрфейс для Android
|
||||
Безкоштовний та легкий YouTube-інтерфейс для Android.
|
||||
|
|
|
@ -1,2 +1,22 @@
|
|||
v0.13.7
|
||||
修复排序异常
|
||||
v0.13.6
|
||||
##改进
|
||||
禁用汉堡菜单图标动画
|
||||
刚删除的下载文件可恢复
|
||||
添加分享菜单中的下载选项
|
||||
添加分享选项至长按菜单
|
||||
退出时最小化主播放器
|
||||
库版本更新和数据库备份修复
|
||||
更新 ExoPlayer 至 2.8.2
|
||||
重新设计播放速度控制对话框,可支持不同的步长加快速度
|
||||
播放速度控制中增加沉默期间快进开关,给某些有声读物和音乐类型带来真正的无缝体验
|
||||
重构媒体源解析,允许在播放器内部将元数据与媒体一起传递,而非手动进行,因此成为单一元数据来源,在开始播放时直接可用
|
||||
修正在打开播放列表碎片且新的元数据可用时远程播放列表元数据未更新
|
||||
各种UI修复:后台播放器通知控件现在为白色,更容易通过滑动关闭悬浮窗播放器
|
||||
使用新的提取器,重构了多服务架构
|
||||
##修复
|
||||
修复异常视频信息页布局
|
||||
修复历史记录视图异常(更新元数据(缩略图,标题和数量)时恰访问播放列表;当从详情页从外部播放器上播放视频时,在数据库中注册一个视图)
|
||||
修复悬浮窗下视频超时
|
||||
修复主视频播放器(修正当播放器活动处于后台时收到新意图后重复模式导致NPE;修正当未获得悬浮窗权限,切换悬浮窗时播放器异常)
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
新增
|
||||
• 在音视频简介下方显示元数据 (标签、类别、发行许可证...)
|
||||
• 在远程(非本地)播放列表中添加"显示频道详情"选项
|
||||
• 在长按菜单中添加"在浏览器中打开"选项
|
||||
修复
|
||||
• 修复 视频详情页面旋转屏幕时崩溃
|
||||
• 修复 在播放器内"使用Kodi播放"按钮总是提示安装Kore
|
||||
• 修复和改进了设置导出导入路径
|
||||
• [YouTube]修复 评论点赞计数
|
||||
• 以及修复其他细小问题
|
Loading…
Reference in New Issue