From bc4f0c699fba3265cfb4aaef3370ebc81d36249b Mon Sep 17 00:00:00 2001 From: TobiGr Date: Wed, 2 Aug 2023 20:43:01 +0200 Subject: [PATCH 001/172] Ignore false positive inspection --- .../java/org/schabi/newpipe/player/playqueue/PlayQueue.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueue.java b/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueue.java index 4c6230964..cfa2ab316 100644 --- a/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueue.java +++ b/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueue.java @@ -539,7 +539,8 @@ public abstract class PlayQueue implements Serializable { public boolean equalStreamsAndIndex(@Nullable final PlayQueue other) { if (equalStreams(other)) { - return other.getIndex() == getIndex(); + //noinspection ConstantConditions + return other.getIndex() == getIndex(); //NOSONAR: other is not null } return false; } From c06d61a83c5ab999a583c13ef0124bae03167abb Mon Sep 17 00:00:00 2001 From: J-Stutzmann <18075488+J-Stutzmann@users.noreply.github.com> Date: Mon, 31 Jul 2023 06:09:07 -0400 Subject: [PATCH 002/172] Made audio-focus calls respect mute state. --- .../main/java/org/schabi/newpipe/player/Player.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/player/Player.java b/app/src/main/java/org/schabi/newpipe/player/Player.java index 1a8283590..1a323176c 100644 --- a/app/src/main/java/org/schabi/newpipe/player/Player.java +++ b/app/src/main/java/org/schabi/newpipe/player/Player.java @@ -1082,7 +1082,7 @@ public final class Player implements PlaybackListener, Listener { UIs.call(PlayerUi::onPrepared); - if (playWhenReady) { + if (playWhenReady && !isMuted()) { audioReactor.requestAudioFocus(); } } @@ -1223,6 +1223,11 @@ public final class Player implements PlaybackListener, Listener { public void toggleMute() { final boolean wasMuted = isMuted(); simpleExoPlayer.setVolume(wasMuted ? 1 : 0); + if (wasMuted) { + audioReactor.requestAudioFocus(); + } else { + audioReactor.abandonAudioFocus(); + } UIs.call(playerUi -> playerUi.onMuteUnmuteChanged(!wasMuted)); notifyPlaybackUpdateToListeners(); } @@ -1620,7 +1625,9 @@ public final class Player implements PlaybackListener, Listener { return; } - audioReactor.requestAudioFocus(); + if (!isMuted()) { + audioReactor.requestAudioFocus(); + } if (currentState == STATE_COMPLETED) { if (playQueue.getIndex() == 0) { From c69bcaafbb80ddc736e0bf14e1fb01e592d7d464 Mon Sep 17 00:00:00 2001 From: TobiGr Date: Thu, 3 Aug 2023 11:55:18 +0200 Subject: [PATCH 003/172] Fixed some Sonar warnings --- .../newpipe/settings/ContentSettingsManager.kt | 13 ++++++++++--- .../newpipe/views/player/PlayerFastSeekOverlay.kt | 2 -- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsManager.kt b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsManager.kt index 92be93a29..df56de516 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsManager.kt +++ b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsManager.kt @@ -2,6 +2,7 @@ package org.schabi.newpipe.settings import android.content.SharedPreferences import android.util.Log +import org.schabi.newpipe.MainActivity.DEBUG import org.schabi.newpipe.streams.io.SharpOutputStream import org.schabi.newpipe.streams.io.StoredFileHelper import org.schabi.newpipe.util.ZipHelper @@ -32,7 +33,9 @@ class ContentSettingsManager(private val fileLocator: NewPipeFileLocator) { output.flush() } } catch (e: IOException) { - Log.e(TAG, "Unable to exportDatabase", e) + if (DEBUG) { + Log.e(TAG, "Unable to exportDatabase", e) + } } ZipHelper.addFileToZip(outZip, fileLocator.settings.path, "newpipe.settings") @@ -105,9 +108,13 @@ class ContentSettingsManager(private val fileLocator: NewPipeFileLocator) { preferenceEditor.commit() } } catch (e: IOException) { - Log.e(TAG, "Unable to loadSharedPreferences", e) + if (DEBUG) { + Log.e(TAG, "Unable to loadSharedPreferences", e) + } } catch (e: ClassNotFoundException) { - Log.e(TAG, "Unable to loadSharedPreferences", e) + if (DEBUG) { + Log.e(TAG, "Unable to loadSharedPreferences", e) + } } } } diff --git a/app/src/main/java/org/schabi/newpipe/views/player/PlayerFastSeekOverlay.kt b/app/src/main/java/org/schabi/newpipe/views/player/PlayerFastSeekOverlay.kt index d0782e1a1..877070a91 100644 --- a/app/src/main/java/org/schabi/newpipe/views/player/PlayerFastSeekOverlay.kt +++ b/app/src/main/java/org/schabi/newpipe/views/player/PlayerFastSeekOverlay.kt @@ -4,7 +4,6 @@ import android.content.Context import android.util.AttributeSet import android.util.Log import android.view.LayoutInflater -import androidx.annotation.NonNull import androidx.constraintlayout.widget.ConstraintLayout import androidx.constraintlayout.widget.ConstraintLayout.LayoutParams.END import androidx.constraintlayout.widget.ConstraintLayout.LayoutParams.PARENT_ID @@ -127,7 +126,6 @@ class PlayerFastSeekOverlay(context: Context, attrs: AttributeSet?) : /** * Determines if the playback should forward/rewind or do nothing. */ - @NonNull fun getFastSeekDirection(portion: DisplayPortion): FastSeekDirection fun seek(forward: Boolean) From 32f74273f07bf3b764565feca02c8cadb0e425ef Mon Sep 17 00:00:00 2001 From: TobiGr Date: Sat, 5 Aug 2023 03:50:28 +0200 Subject: [PATCH 004/172] Adjust empty state message for ListInfoFragments depending on Info stream type Show "no streams" for SoundClound. Show "no live streams" for MeidaCCCLiveStreamKiosk. Otherwise show "no videos" --- app/build.gradle | 2 +- .../newpipe/fragments/BaseStateFragment.java | 17 ++++++++++++++--- .../fragments/list/BaseListInfoFragment.java | 16 ++++++++++++++++ .../fragments/list/channel/ChannelFragment.java | 2 +- .../fragments/list/kiosk/KioskFragment.java | 12 ++++++++++++ app/src/main/res/layout/fragment_channel.xml | 2 +- app/src/main/res/layout/fragment_kiosk.xml | 1 + app/src/main/res/layout/fragment_playlist.xml | 1 + app/src/main/res/values/strings.xml | 2 ++ 9 files changed, 49 insertions(+), 6 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 1a0af662b..e48f6e907 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -200,7 +200,7 @@ dependencies { // name and the commit hash with the commit hash of the (pushed) commit you want to test // This works thanks to JitPack: https://jitpack.io/ implementation 'com.github.TeamNewPipe:nanojson:1d9e1aea9049fc9f85e68b43ba39fe7be1c1f751' - implementation 'com.github.TeamNewPipe:NewPipeExtractor:v0.22.7' + implementation 'com.github.TeamNewPipe:NewPipeExtractor:340095515d45ecbee576872c7198992ebd8e4f08' implementation 'com.github.TeamNewPipe:NoNonsense-FilePicker:5.0.0' /** Checkstyle **/ diff --git a/app/src/main/java/org/schabi/newpipe/fragments/BaseStateFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/BaseStateFragment.java index 9b4bf8377..85603d337 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/BaseStateFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/BaseStateFragment.java @@ -1,12 +1,16 @@ package org.schabi.newpipe.fragments; +import static org.schabi.newpipe.ktx.ViewUtils.animate; + import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.ProgressBar; +import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.annotation.StringRes; import androidx.fragment.app.Fragment; import org.schabi.newpipe.BaseFragment; @@ -20,15 +24,15 @@ import java.util.concurrent.atomic.AtomicBoolean; import icepick.State; -import static org.schabi.newpipe.ktx.ViewUtils.animate; - public abstract class BaseStateFragment extends BaseFragment implements ViewContract { @State protected AtomicBoolean wasLoading = new AtomicBoolean(); protected AtomicBoolean isLoading = new AtomicBoolean(); @Nullable - private View emptyStateView; + protected View emptyStateView; + @Nullable + protected TextView emptyStateMessageView; @Nullable private ProgressBar loadingProgressBar; @@ -65,6 +69,7 @@ public abstract class BaseStateFragment extends BaseFragment implements ViewC protected void initViews(final View rootView, final Bundle savedInstanceState) { super.initViews(rootView, savedInstanceState); emptyStateView = rootView.findViewById(R.id.empty_state_view); + emptyStateMessageView = rootView.findViewById(R.id.empty_state_message); loadingProgressBar = rootView.findViewById(R.id.loading_progress_bar); errorPanelHelper = new ErrorPanelHelper(this, rootView, this::onRetryButtonClicked); } @@ -189,6 +194,12 @@ public abstract class BaseStateFragment extends BaseFragment implements ViewC errorPanelHelper.showTextError(errorString); } + protected void setEmptyStateMessage(@StringRes final int text) { + if (emptyStateMessageView != null) { + emptyStateMessageView.setText(text); + } + } + public final void hideErrorPanel() { errorPanelHelper.hide(); lastPanelError = null; diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListInfoFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListInfoFragment.java index 35424437d..d4d31a110 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListInfoFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListInfoFragment.java @@ -1,5 +1,7 @@ package org.schabi.newpipe.fragments.list; +import static org.schabi.newpipe.extractor.ServiceList.SoundCloud; + import android.os.Bundle; import android.text.TextUtils; import android.util.Log; @@ -7,6 +9,7 @@ import android.view.View; import androidx.annotation.NonNull; +import org.schabi.newpipe.R; import org.schabi.newpipe.error.ErrorInfo; import org.schabi.newpipe.error.UserAction; import org.schabi.newpipe.extractor.InfoItem; @@ -252,6 +255,19 @@ public abstract class BaseListInfoFragment No comments Comments are disabled + No streams + No live streams %s new stream %s new streams From bef79e77aa753caa4b4e7a10f84ee984dbdb3b0c Mon Sep 17 00:00:00 2001 From: Stypox Date: Sun, 6 Aug 2023 10:07:13 +0200 Subject: [PATCH 005/172] Update app/src/main/java/org/schabi/newpipe/fragments/list/BaseListInfoFragment.java --- .../schabi/newpipe/fragments/list/BaseListInfoFragment.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListInfoFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListInfoFragment.java index d4d31a110..c73ae8be0 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListInfoFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListInfoFragment.java @@ -257,7 +257,8 @@ public abstract class BaseListInfoFragment Date: Mon, 7 Aug 2023 20:40:33 +0100 Subject: [PATCH 006/172] Make capitalization of "Night theme" setting consistent with others Been a pet peeve of mine for some time. --- app/src/main/res/values/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 5f96e4041..472d1ea43 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -69,7 +69,7 @@ Default audio format Default video format Theme - Night Theme + Night theme Light Dark Black From 4a0ff3f7efab4fa1da5d4634150239181eebfdf7 Mon Sep 17 00:00:00 2001 From: opusforlife2 <53176348+opusforlife2@users.noreply.github.com> Date: Sat, 12 Aug 2023 15:08:03 +0000 Subject: [PATCH 007/172] Make latest release link more obvious to bug reporters --- .github/ISSUE_TEMPLATE/bug_report.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index d3befbc81..52897f1ac 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -14,7 +14,7 @@ body: attributes: label: "Checklist" options: - - label: "I am able to reproduce the bug with the [latest version](https://github.com/TeamNewPipe/NewPipe/releases/latest)." + - label: "I am able to reproduce the bug with the latest version given here: [CLICK THIS LINK](https://github.com/TeamNewPipe/NewPipe/releases/latest)." required: true - label: "I made sure that there are *no existing issues* - [open](https://github.com/TeamNewPipe/NewPipe/issues) or [closed](https://github.com/TeamNewPipe/NewPipe/issues?q=is%3Aissue+is%3Aclosed) - which I could contribute my information to." required: true From 0db12e5561f66eb9a717998910c9cb064768af99 Mon Sep 17 00:00:00 2001 From: TobiGr Date: Thu, 15 Jun 2023 12:38:39 +0200 Subject: [PATCH 008/172] Rename StreamSizeWrapper to StreamInfoWrapper --- .../newpipe/util/StreamItemAdapterTest.kt | 8 +++---- .../newpipe/download/DownloadDialog.java | 24 +++++++++---------- .../newpipe/util/AudioTrackAdapter.java | 8 +++---- .../newpipe/util/SecondaryStreamHelper.java | 6 ++--- .../newpipe/util/StreamItemAdapter.java | 22 ++++++++--------- 5 files changed, 34 insertions(+), 34 deletions(-) diff --git a/app/src/androidTest/java/org/schabi/newpipe/util/StreamItemAdapterTest.kt b/app/src/androidTest/java/org/schabi/newpipe/util/StreamItemAdapterTest.kt index 0fe251c16..c67564232 100644 --- a/app/src/androidTest/java/org/schabi/newpipe/util/StreamItemAdapterTest.kt +++ b/app/src/androidTest/java/org/schabi/newpipe/util/StreamItemAdapterTest.kt @@ -84,7 +84,7 @@ class StreamItemAdapterTest { @Test fun subtitleStreams_noIcon() { val adapter = StreamItemAdapter( - StreamItemAdapter.StreamSizeWrapper( + StreamItemAdapter.StreamInfoWrapper( (0 until 5).map { SubtitlesStream.Builder() .setContent("https://example.com", true) @@ -105,7 +105,7 @@ class StreamItemAdapterTest { @Test fun audioStreams_noIcon() { val adapter = StreamItemAdapter( - StreamItemAdapter.StreamSizeWrapper( + StreamItemAdapter.StreamInfoWrapper( (0 until 5).map { AudioStream.Builder() .setId(Stream.ID_UNKNOWN) @@ -128,7 +128,7 @@ class StreamItemAdapterTest { * [videoOnly] vararg. */ private fun getVideoStreams(vararg videoOnly: Boolean) = - StreamItemAdapter.StreamSizeWrapper( + StreamItemAdapter.StreamInfoWrapper( videoOnly.map { VideoStream.Builder() .setId(Stream.ID_UNKNOWN) @@ -196,7 +196,7 @@ class StreamItemAdapterTest { streams.forEachIndexed { index, stream -> val secondaryStreamHelper: SecondaryStreamHelper? = stream?.let { SecondaryStreamHelper( - StreamItemAdapter.StreamSizeWrapper(streams, context), + StreamItemAdapter.StreamInfoWrapper(streams, context), it ) } diff --git a/app/src/main/java/org/schabi/newpipe/download/DownloadDialog.java b/app/src/main/java/org/schabi/newpipe/download/DownloadDialog.java index 9e05584da..e5bb7a7e1 100644 --- a/app/src/main/java/org/schabi/newpipe/download/DownloadDialog.java +++ b/app/src/main/java/org/schabi/newpipe/download/DownloadDialog.java @@ -67,7 +67,7 @@ import org.schabi.newpipe.util.PermissionHelper; import org.schabi.newpipe.util.SecondaryStreamHelper; import org.schabi.newpipe.util.SimpleOnSeekBarChangeListener; import org.schabi.newpipe.util.StreamItemAdapter; -import org.schabi.newpipe.util.StreamItemAdapter.StreamSizeWrapper; +import org.schabi.newpipe.util.StreamItemAdapter.StreamInfoWrapper; import org.schabi.newpipe.util.AudioTrackAdapter; import org.schabi.newpipe.util.AudioTrackAdapter.AudioTracksWrapper; import org.schabi.newpipe.util.ThemeHelper; @@ -97,9 +97,9 @@ public class DownloadDialog extends DialogFragment @State StreamInfo currentInfo; @State - StreamSizeWrapper wrappedVideoStreams; + StreamInfoWrapper wrappedVideoStreams; @State - StreamSizeWrapper wrappedSubtitleStreams; + StreamInfoWrapper wrappedSubtitleStreams; @State AudioTracksWrapper wrappedAudioTracks; @State @@ -187,8 +187,8 @@ public class DownloadDialog extends DialogFragment wrappedAudioTracks.size() > 1 ); - this.wrappedVideoStreams = new StreamSizeWrapper<>(videoStreams, context); - this.wrappedSubtitleStreams = new StreamSizeWrapper<>( + this.wrappedVideoStreams = new StreamInfoWrapper<>(videoStreams, context); + this.wrappedSubtitleStreams = new StreamInfoWrapper<>( getStreamsOfSpecifiedDelivery(info.getSubtitles(), PROGRESSIVE_HTTP), context); this.selectedVideoIndex = ListHelper.getDefaultResolutionIndex(context, videoStreams); @@ -258,10 +258,10 @@ public class DownloadDialog extends DialogFragment * Update the displayed video streams based on the selected audio track. */ private void updateSecondaryStreams() { - final StreamSizeWrapper audioStreams = getWrappedAudioStreams(); + final StreamInfoWrapper audioStreams = getWrappedAudioStreams(); final var secondaryStreams = new SparseArrayCompat>(4); final List videoStreams = wrappedVideoStreams.getStreamsList(); - wrappedVideoStreams.resetSizes(); + wrappedVideoStreams.resetInfo(); for (int i = 0; i < videoStreams.size(); i++) { if (!videoStreams.get(i).isVideoOnly()) { @@ -396,7 +396,7 @@ public class DownloadDialog extends DialogFragment private void fetchStreamsSize() { disposables.clear(); - disposables.add(StreamSizeWrapper.fetchSizeForWrapper(wrappedVideoStreams) + disposables.add(StreamInfoWrapper.fetchMoreInfoForWrapper(wrappedVideoStreams) .subscribe(result -> { if (dialogBinding.videoAudioGroup.getCheckedRadioButtonId() == R.id.video_button) { @@ -406,7 +406,7 @@ public class DownloadDialog extends DialogFragment new ErrorInfo(throwable, UserAction.DOWNLOAD_OPEN_DIALOG, "Downloading video stream size", currentInfo.getServiceId())))); - disposables.add(StreamSizeWrapper.fetchSizeForWrapper(getWrappedAudioStreams()) + disposables.add(StreamInfoWrapper.fetchMoreInfoForWrapper(getWrappedAudioStreams()) .subscribe(result -> { if (dialogBinding.videoAudioGroup.getCheckedRadioButtonId() == R.id.audio_button) { @@ -416,7 +416,7 @@ public class DownloadDialog extends DialogFragment new ErrorInfo(throwable, UserAction.DOWNLOAD_OPEN_DIALOG, "Downloading audio stream size", currentInfo.getServiceId())))); - disposables.add(StreamSizeWrapper.fetchSizeForWrapper(wrappedSubtitleStreams) + disposables.add(StreamInfoWrapper.fetchMoreInfoForWrapper(wrappedSubtitleStreams) .subscribe(result -> { if (dialogBinding.videoAudioGroup.getCheckedRadioButtonId() == R.id.subtitle_button) { @@ -724,9 +724,9 @@ public class DownloadDialog extends DialogFragment dialogBinding.subtitleButton.setEnabled(enabled); } - private StreamSizeWrapper getWrappedAudioStreams() { + private StreamInfoWrapper getWrappedAudioStreams() { if (selectedAudioTrackIndex < 0 || selectedAudioTrackIndex > wrappedAudioTracks.size()) { - return StreamSizeWrapper.empty(); + return StreamInfoWrapper.empty(); } return wrappedAudioTracks.getTracksList().get(selectedAudioTrackIndex); } diff --git a/app/src/main/java/org/schabi/newpipe/util/AudioTrackAdapter.java b/app/src/main/java/org/schabi/newpipe/util/AudioTrackAdapter.java index 39a05acb3..90689052e 100644 --- a/app/src/main/java/org/schabi/newpipe/util/AudioTrackAdapter.java +++ b/app/src/main/java/org/schabi/newpipe/util/AudioTrackAdapter.java @@ -13,7 +13,7 @@ import androidx.annotation.Nullable; import org.schabi.newpipe.R; import org.schabi.newpipe.extractor.stream.AudioStream; -import org.schabi.newpipe.util.StreamItemAdapter.StreamSizeWrapper; +import org.schabi.newpipe.util.StreamItemAdapter.StreamInfoWrapper; import java.io.Serializable; import java.util.List; @@ -75,15 +75,15 @@ public class AudioTrackAdapter extends BaseAdapter { } public static class AudioTracksWrapper implements Serializable { - private final List> tracksList; + private final List> tracksList; public AudioTracksWrapper(@NonNull final List> groupedAudioStreams, @Nullable final Context context) { this.tracksList = groupedAudioStreams.stream().map(streams -> - new StreamSizeWrapper<>(streams, context)).collect(Collectors.toList()); + new StreamInfoWrapper<>(streams, context)).collect(Collectors.toList()); } - public List> getTracksList() { + public List> getTracksList() { return tracksList; } diff --git a/app/src/main/java/org/schabi/newpipe/util/SecondaryStreamHelper.java b/app/src/main/java/org/schabi/newpipe/util/SecondaryStreamHelper.java index e7fd2d4a4..9415135cf 100644 --- a/app/src/main/java/org/schabi/newpipe/util/SecondaryStreamHelper.java +++ b/app/src/main/java/org/schabi/newpipe/util/SecondaryStreamHelper.java @@ -7,15 +7,15 @@ import org.schabi.newpipe.extractor.MediaFormat; import org.schabi.newpipe.extractor.stream.AudioStream; import org.schabi.newpipe.extractor.stream.Stream; import org.schabi.newpipe.extractor.stream.VideoStream; -import org.schabi.newpipe.util.StreamItemAdapter.StreamSizeWrapper; +import org.schabi.newpipe.util.StreamItemAdapter.StreamInfoWrapper; import java.util.List; public class SecondaryStreamHelper { private final int position; - private final StreamSizeWrapper streams; + private final StreamInfoWrapper streams; - public SecondaryStreamHelper(@NonNull final StreamSizeWrapper streams, + public SecondaryStreamHelper(@NonNull final StreamInfoWrapper streams, final T selectedStream) { this.streams = streams; this.position = streams.getStreamsList().indexOf(selectedStream); diff --git a/app/src/main/java/org/schabi/newpipe/util/StreamItemAdapter.java b/app/src/main/java/org/schabi/newpipe/util/StreamItemAdapter.java index 2eb63ff41..48fb81c99 100644 --- a/app/src/main/java/org/schabi/newpipe/util/StreamItemAdapter.java +++ b/app/src/main/java/org/schabi/newpipe/util/StreamItemAdapter.java @@ -41,7 +41,7 @@ import us.shandian.giga.util.Utility; */ public class StreamItemAdapter extends BaseAdapter { @NonNull - private final StreamSizeWrapper streamsWrapper; + private final StreamInfoWrapper streamsWrapper; @NonNull private final SparseArrayCompat> secondaryStreams; @@ -53,7 +53,7 @@ public class StreamItemAdapter extends BaseA private final boolean hasAnyVideoOnlyStreamWithNoSecondaryStream; public StreamItemAdapter( - @NonNull final StreamSizeWrapper streamsWrapper, + @NonNull final StreamInfoWrapper streamsWrapper, @NonNull final SparseArrayCompat> secondaryStreams ) { this.streamsWrapper = streamsWrapper; @@ -63,7 +63,7 @@ public class StreamItemAdapter extends BaseA checkHasAnyVideoOnlyStreamWithNoSecondaryStream(); } - public StreamItemAdapter(final StreamSizeWrapper streamsWrapper) { + public StreamItemAdapter(final StreamInfoWrapper streamsWrapper) { this(streamsWrapper, new SparseArrayCompat<>(0)); } @@ -121,7 +121,7 @@ public class StreamItemAdapter extends BaseA final TextView sizeView = convertView.findViewById(R.id.stream_size); final T stream = getItem(position); - final MediaFormat mediaFormat = stream.getFormat(); + final MediaFormat mediaFormat = streamsWrapper.getFormat(position); int woSoundIconVisibility = View.GONE; String qualityString; @@ -221,16 +221,16 @@ public class StreamItemAdapter extends BaseA * * @param the stream type's class extending {@link Stream} */ - public static class StreamSizeWrapper implements Serializable { - private static final StreamSizeWrapper EMPTY = - new StreamSizeWrapper<>(Collections.emptyList(), null); + public static class StreamInfoWrapper implements Serializable { + private static final StreamInfoWrapper EMPTY = + new StreamInfoWrapper<>(Collections.emptyList(), null); private static final int SIZE_UNSET = -2; private final List streamsList; private final long[] streamSizes; private final String unknownSize; - public StreamSizeWrapper(@NonNull final List streamList, + public StreamInfoWrapper(@NonNull final List streamList, @Nullable final Context context) { this.streamsList = streamList; this.streamSizes = new long[streamsList.size()]; @@ -249,7 +249,7 @@ public class StreamItemAdapter extends BaseA */ @NonNull public static Single fetchSizeForWrapper( - final StreamSizeWrapper streamsWrapper) { + final StreamInfoWrapper streamsWrapper) { final Callable fetchAndSet = () -> { boolean hasChanged = false; for (final X stream : streamsWrapper.getStreamsList()) { @@ -275,9 +275,9 @@ public class StreamItemAdapter extends BaseA Arrays.fill(streamSizes, SIZE_UNSET); } - public static StreamSizeWrapper empty() { + public static StreamInfoWrapper empty() { //noinspection unchecked - return (StreamSizeWrapper) EMPTY; + return (StreamInfoWrapper) EMPTY; } public List getStreamsList() { From f3859ed710887d9549d7f6c35f214416f055fbdf Mon Sep 17 00:00:00 2001 From: TobiGr Date: Mon, 14 Aug 2023 23:05:30 +0200 Subject: [PATCH 009/172] Retrieve MediaFormat for streams that could not be extracted by the extractor --- .../newpipe/download/DownloadDialog.java | 10 +- .../newpipe/util/StreamItemAdapter.java | 175 ++++++++++++++++-- 2 files changed, 169 insertions(+), 16 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/download/DownloadDialog.java b/app/src/main/java/org/schabi/newpipe/download/DownloadDialog.java index e5bb7a7e1..9e9909e85 100644 --- a/app/src/main/java/org/schabi/newpipe/download/DownloadDialog.java +++ b/app/src/main/java/org/schabi/newpipe/download/DownloadDialog.java @@ -766,7 +766,7 @@ public class DownloadDialog extends DialogFragment } private void showFailedDialog(@StringRes final int msg) { - assureCorrectAppLanguage(getContext()); + assureCorrectAppLanguage(requireContext()); new AlertDialog.Builder(context) .setTitle(R.string.general_error) .setMessage(msg) @@ -799,7 +799,7 @@ public class DownloadDialog extends DialogFragment filenameTmp += "opus"; } else if (format != null) { mimeTmp = format.mimeType; - filenameTmp += format.suffix; + filenameTmp += format.getSuffix(); } break; case R.id.video_button: @@ -808,7 +808,7 @@ public class DownloadDialog extends DialogFragment format = videoStreamsAdapter.getItem(selectedVideoIndex).getFormat(); if (format != null) { mimeTmp = format.mimeType; - filenameTmp += format.suffix; + filenameTmp += format.getSuffix(); } break; case R.id.subtitle_button: @@ -820,9 +820,9 @@ public class DownloadDialog extends DialogFragment } if (format == MediaFormat.TTML) { - filenameTmp += MediaFormat.SRT.suffix; + filenameTmp += MediaFormat.SRT.getSuffix(); } else if (format != null) { - filenameTmp += format.suffix; + filenameTmp += format.getSuffix(); } break; default: diff --git a/app/src/main/java/org/schabi/newpipe/util/StreamItemAdapter.java b/app/src/main/java/org/schabi/newpipe/util/StreamItemAdapter.java index 48fb81c99..04cd737b6 100644 --- a/app/src/main/java/org/schabi/newpipe/util/StreamItemAdapter.java +++ b/app/src/main/java/org/schabi/newpipe/util/StreamItemAdapter.java @@ -1,5 +1,7 @@ package org.schabi.newpipe.util; +import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty; + import android.content.Context; import android.view.LayoutInflater; import android.view.View; @@ -16,16 +18,20 @@ import androidx.collection.SparseArrayCompat; import org.schabi.newpipe.DownloaderImpl; import org.schabi.newpipe.R; import org.schabi.newpipe.extractor.MediaFormat; +import org.schabi.newpipe.extractor.downloader.Response; import org.schabi.newpipe.extractor.stream.AudioStream; import org.schabi.newpipe.extractor.stream.Stream; import org.schabi.newpipe.extractor.stream.SubtitlesStream; import org.schabi.newpipe.extractor.stream.VideoStream; +import org.schabi.newpipe.extractor.utils.Utils; import java.io.Serializable; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.concurrent.Callable; +import java.util.stream.Collectors; import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; import io.reactivex.rxjava3.core.Single; @@ -228,6 +234,7 @@ public class StreamItemAdapter extends BaseA private final List streamsList; private final long[] streamSizes; + private final MediaFormat[] streamFormats; private final String unknownSize; public StreamInfoWrapper(@NonNull final List streamList, @@ -236,31 +243,42 @@ public class StreamItemAdapter extends BaseA this.streamSizes = new long[streamsList.size()]; this.unknownSize = context == null ? "--.-" : context.getString(R.string.unknown_content); - - resetSizes(); + this.streamFormats = new MediaFormat[streamsList.size()]; + resetInfo(); } /** - * Helper method to fetch the sizes of all the streams in a wrapper. + * Helper method to fetch the sizes and missing media formats + * of all the streams in a wrapper. * * @param the stream type's class extending {@link Stream} * @param streamsWrapper the wrapper * @return a {@link Single} that returns a boolean indicating if any elements were changed */ @NonNull - public static Single fetchSizeForWrapper( + public static Single fetchMoreInfoForWrapper( final StreamInfoWrapper streamsWrapper) { final Callable fetchAndSet = () -> { boolean hasChanged = false; for (final X stream : streamsWrapper.getStreamsList()) { - if (streamsWrapper.getSizeInBytes(stream) > SIZE_UNSET) { + final boolean changeSize = streamsWrapper.getSizeInBytes(stream) <= SIZE_UNSET; + final boolean changeFormat = stream.getFormat() == null; + if (!changeSize && !changeFormat) { continue; } - - final long contentLength = DownloaderImpl.getInstance().getContentLength( - stream.getContent()); - streamsWrapper.setSize(stream, contentLength); - hasChanged = true; + final Response response = DownloaderImpl.getInstance() + .head(stream.getContent()); + if (changeSize) { + final String contentLength = response.getHeader("Content-Length"); + if (!isNullOrEmpty(contentLength)) { + streamsWrapper.setSize(stream, Long.parseLong(contentLength)); + hasChanged = true; + } + } + if (changeFormat) { + hasChanged = retrieveMediaFormat(stream, streamsWrapper, response) + || hasChanged; + } } return hasChanged; }; @@ -271,8 +289,135 @@ public class StreamItemAdapter extends BaseA .onErrorReturnItem(true); } - public void resetSizes() { + /** + * Try to retrieve the {@link MediaFormat} for a stream from the request headers. + * + * @param the stream type to get the {@link MediaFormat} for + * @param stream the stream to find the {@link MediaFormat} for + * @param streamsWrapper the wrapper to store the found {@link MediaFormat} in + * @param response the response of the head request for the given stream + * @return {@code true} if the media format could be retrieved; {@code false} otherwise + */ + private static boolean retrieveMediaFormat( + @NonNull final X stream, + @NonNull final StreamInfoWrapper streamsWrapper, + @NonNull final Response response) { + return retrieveMediaFormatFromFileTypeHeaders(stream, streamsWrapper, response) + || retrieveMediaFormatFromContentDispositionHeader( + stream, streamsWrapper, response) + || retrieveMediaFormatFromContentTypeHeader(stream, streamsWrapper, response); + } + + private static boolean retrieveMediaFormatFromFileTypeHeaders( + @NonNull final X stream, + @NonNull final StreamInfoWrapper streamsWrapper, + @NonNull final Response response) { + // try to use additional headers from CDNs or servers, + // e.g. x-amz-meta-file-type (e.g. for SoundCloud) + final List keys = response.responseHeaders().keySet().stream() + .filter(k -> k.endsWith("file-type")).collect(Collectors.toList()); + if (!keys.isEmpty()) { + for (final String key : keys) { + final String suffix = response.getHeader(key); + final MediaFormat format = MediaFormat.getFromSuffix(suffix); + if (format != null) { + streamsWrapper.setFormat(stream, format); + return true; + } + } + } + return false; + } + + /** + *

Retrieve a {@link MediaFormat} from a HTTP Content-Disposition header + * for a stream and store the info in a wrapper.

+ * @see + * + * mdn Web Docs for the HTTP Content-Disposition Header + * @param stream the stream to get the {@link MediaFormat} for + * @param streamsWrapper the wrapper to store the {@link MediaFormat} in + * @param response the response to get the Content-Disposition header from + * @return {@code true} if the {@link MediaFormat} could be retrieved from the response; + * otherwise {@code false} + * @param + */ + public static boolean retrieveMediaFormatFromContentDispositionHeader( + @NonNull final X stream, + @NonNull final StreamInfoWrapper streamsWrapper, + @NonNull final Response response) { + // parse the Content-Disposition header, + // see + // there can be two filename directives + String contentDisposition = response.getHeader("Content-Disposition"); + if (contentDisposition == null) { + return false; + } + try { + contentDisposition = Utils.decodeUrlUtf8(contentDisposition); + final String[] parts = contentDisposition.split(";"); + for (String part : parts) { + final String fileName; + part = part.trim(); + + // extract the filename + if (part.startsWith("filename=")) { + // remove directive and decode + fileName = Utils.decodeUrlUtf8(part.substring(9)); + } else if (part.startsWith("filename*=")) { + fileName = Utils.decodeUrlUtf8(part.substring(10)); + } else { + continue; + } + + // extract the file extension / suffix + final String[] p = fileName.split("\\."); + String suffix = p[p.length - 1]; + if (suffix.endsWith("\"") || suffix.endsWith("'")) { + // remove trailing quotes if present, end index is exclusive + suffix = suffix.substring(0, suffix.length() - 1); + } + + // get the corresponding media format + final MediaFormat format = MediaFormat.getFromSuffix(suffix); + if (format != null) { + streamsWrapper.setFormat(stream, format); + return true; + } + } + } catch (final Exception ignored) { + // fail silently + } + return false; + } + + private static boolean retrieveMediaFormatFromContentTypeHeader( + @NonNull final X stream, + @NonNull final StreamInfoWrapper streamsWrapper, + @NonNull final Response response) { + // try to get the format by content type + // some mime types are not unique for every format, those are omitted + final List formats = MediaFormat.getAllFromMimeType( + response.getHeader("Content-Type")); + final List uniqueFormats = new ArrayList<>(formats.size()); + for (int i = 0; i < formats.size(); i++) { + final MediaFormat format = formats.get(i); + if (uniqueFormats.stream().filter(f -> f.id == format.id).count() == 0) { + uniqueFormats.add(format); + } + } + if (uniqueFormats.size() == 1) { + streamsWrapper.setFormat(stream, uniqueFormats.get(0)); + return true; + } + return false; + } + + public void resetInfo() { Arrays.fill(streamSizes, SIZE_UNSET); + for (int i = 0; i < streamsList.size(); i++) { + streamFormats[i] = streamsList.get(i).getFormat(); + } } public static StreamInfoWrapper empty() { @@ -306,5 +451,13 @@ public class StreamItemAdapter extends BaseA public void setSize(final T stream, final long sizeInBytes) { streamSizes[streamsList.indexOf(stream)] = sizeInBytes; } + + public MediaFormat getFormat(final int streamIndex) { + return streamFormats[streamIndex]; + } + + public void setFormat(final T stream, final MediaFormat format) { + streamFormats[streamsList.indexOf(stream)] = format; + } } } From e51067177edf0ad4034c330f69c2dc7c92a4df15 Mon Sep 17 00:00:00 2001 From: TobiGr Date: Mon, 14 Aug 2023 23:05:38 +0200 Subject: [PATCH 010/172] Add tests for new methods retrieving MediaFormats Fix failing tests --- .../newpipe/util/StreamItemAdapterTest.kt | 159 ++++++++++++++++++ .../newpipe/util/StreamItemAdapter.java | 14 +- 2 files changed, 169 insertions(+), 4 deletions(-) diff --git a/app/src/androidTest/java/org/schabi/newpipe/util/StreamItemAdapterTest.kt b/app/src/androidTest/java/org/schabi/newpipe/util/StreamItemAdapterTest.kt index c67564232..13c27aec9 100644 --- a/app/src/androidTest/java/org/schabi/newpipe/util/StreamItemAdapterTest.kt +++ b/app/src/androidTest/java/org/schabi/newpipe/util/StreamItemAdapterTest.kt @@ -12,15 +12,21 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.MediumTest import androidx.test.internal.runner.junit4.statement.UiThreadStatement import org.junit.Assert +import org.junit.Assert.assertEquals +import org.junit.Assert.assertFalse +import org.junit.Assert.assertNull +import org.junit.Assert.assertTrue import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.schabi.newpipe.R import org.schabi.newpipe.extractor.MediaFormat +import org.schabi.newpipe.extractor.downloader.Response import org.schabi.newpipe.extractor.stream.AudioStream import org.schabi.newpipe.extractor.stream.Stream import org.schabi.newpipe.extractor.stream.SubtitlesStream import org.schabi.newpipe.extractor.stream.VideoStream +import org.schabi.newpipe.util.StreamItemAdapter.StreamInfoWrapper @MediumTest @RunWith(AndroidJUnit4::class) @@ -123,6 +129,101 @@ class StreamItemAdapterTest { } } + @Test + fun retrieveMediaFormatFromFileTypeHeaders() { + val streams = getIncompleteAudioStreams(5) + val wrapper = StreamInfoWrapper(streams, context) + val retrieveMediaFormat = { stream: AudioStream, response: Response -> + StreamInfoWrapper.retrieveMediaFormatFromFileTypeHeaders(stream, wrapper, response) + } + val helper = AssertionHelper(streams, wrapper, retrieveMediaFormat) + + helper.assertInvalidResponse(getResponse(mapOf(Pair("content-length", "mp3"))), 0) + helper.assertInvalidResponse(getResponse(mapOf(Pair("file-type", "mp0"))), 1) + + helper.assertValidResponse(getResponse(mapOf(Pair("x-amz-meta-file-type", "aiff"))), 2, MediaFormat.AIFF) + helper.assertValidResponse(getResponse(mapOf(Pair("file-type", "mp3"))), 3, MediaFormat.MP3) + } + + @Test + fun retrieveMediaFormatFromContentDispositionHeader() { + val streams = getIncompleteAudioStreams(11) + val wrapper = StreamInfoWrapper(streams, context) + val retrieveMediaFormat = { stream: AudioStream, response: Response -> + StreamInfoWrapper.retrieveMediaFormatFromContentDispositionHeader(stream, wrapper, response) + } + val helper = AssertionHelper(streams, wrapper, retrieveMediaFormat) + + helper.assertInvalidResponse(getResponse(mapOf(Pair("content-length", "mp3"))), 0) + helper.assertInvalidResponse( + getResponse(mapOf(Pair("Content-Disposition", "filename=\"train.png\""))), 1 + ) + helper.assertInvalidResponse( + getResponse(mapOf(Pair("Content-Disposition", "form-data; name=\"data.csv\""))), 2 + ) + helper.assertInvalidResponse( + getResponse(mapOf(Pair("Content-Disposition", "form-data; filename=\"data.csv\""))), 3 + ) + helper.assertInvalidResponse( + getResponse(mapOf(Pair("Content-Disposition", "form-data; name=\"fieldName\"; filename*=\"filename.jpg\""))), 4 + ) + + helper.assertValidResponse( + getResponse(mapOf(Pair("Content-Disposition", "filename=\"train.ogg\""))), + 5, MediaFormat.OGG + ) + helper.assertValidResponse( + getResponse(mapOf(Pair("Content-Disposition", "some-form-data; filename=\"audio.flac\""))), + 6, MediaFormat.FLAC + ) + helper.assertValidResponse( + getResponse(mapOf(Pair("Content-Disposition", "form-data; name=\"audio.aiff\"; filename=\"audio.aiff\""))), + 7, MediaFormat.AIFF + ) + helper.assertValidResponse( + getResponse(mapOf(Pair("Content-Disposition", "form-data; name=\"alien?\"; filename*=UTF-8''%CE%B1%CE%BB%CE%B9%CF%B5%CE%BD.m4a"))), + 8, MediaFormat.M4A + ) + helper.assertValidResponse( + getResponse(mapOf(Pair("Content-Disposition", "form-data; name=\"audio.mp3\"; filename=\"audio.opus\"; filename*=UTF-8''alien.opus"))), + 9, MediaFormat.OPUS + ) + helper.assertValidResponse( + getResponse(mapOf(Pair("Content-Disposition", "form-data; name=\"audio.mp3\"; filename=\"audio.opus\"; filename*=\"UTF-8''alien.opus\""))), + 10, MediaFormat.OPUS + ) + } + + @Test + fun retrieveMediaFormatFromContentTypeHeader() { + val streams = getIncompleteAudioStreams(10) + val wrapper = StreamInfoWrapper(streams, context) + val retrieveMediaFormat = { stream: AudioStream, response: Response -> + StreamInfoWrapper.retrieveMediaFormatFromContentTypeHeader(stream, wrapper, response) + } + val helper = AssertionHelper(streams, wrapper, retrieveMediaFormat) + + helper.assertInvalidResponse(getResponse(mapOf(Pair("content-length", "984501"))), 0) + helper.assertInvalidResponse(getResponse(mapOf(Pair("Content-Type", "audio/xyz"))), 1) + helper.assertInvalidResponse(getResponse(mapOf(Pair("Content-Type", "mp3"))), 2) + helper.assertInvalidResponse(getResponse(mapOf(Pair("Content-Type", "mp3"))), 3) + helper.assertInvalidResponse(getResponse(mapOf(Pair("Content-Type", "audio/mpeg"))), 4) + helper.assertInvalidResponse(getResponse(mapOf(Pair("Content-Type", "audio/aif"))), 5) + + helper.assertValidResponse( + getResponse(mapOf(Pair("Content-Type", "audio/flac"))), 6, MediaFormat.FLAC + ) + helper.assertValidResponse( + getResponse(mapOf(Pair("Content-Type", "audio/wav"))), 7, MediaFormat.WAV + ) + helper.assertValidResponse( + getResponse(mapOf(Pair("Content-Type", "audio/opus"))), 8, MediaFormat.OPUS + ) + helper.assertValidResponse( + getResponse(mapOf(Pair("Content-Type", "audio/aiff"))), 9, MediaFormat.AIFF + ) + } + /** * @return a list of video streams, in which their video only property mirrors the provided * [videoOnly] vararg. @@ -161,6 +262,19 @@ class StreamItemAdapterTest { } ) + private fun getIncompleteAudioStreams(size: Int): List { + val list = ArrayList(size) + for (i in 1..size) { + list.add( + AudioStream.Builder() + .setId(Stream.ID_UNKNOWN) + .setContent("https://example.com/$i", true) + .build() + ) + } + return list + } + /** * Checks whether the item at [position] in the [spinner] has the correct icon visibility when * it is shown in normal mode (selected) and in dropdown mode (user is choosing one of a list). @@ -203,4 +317,49 @@ class StreamItemAdapterTest { put(index, secondaryStreamHelper) } } + + private fun getResponse(headers: Map): Response { + val listHeaders = HashMap>() + headers.forEach { entry -> + listHeaders[entry.key] = listOf(entry.value) + } + return Response(200, null, listHeaders, "", "") + } + + /** + * Helper class for assertion related to extractions of [MediaFormat]s. + */ + class AssertionHelper( + private val streams: List, + private val wrapper: StreamInfoWrapper, + private val retrieveMediaFormat: (stream: T, response: Response) -> Boolean + ) { + + /** + * Assert that an invalid response does not result in wrongly extracted [MediaFormat]. + */ + fun assertInvalidResponse( + response: Response, + index: Int + ) { + assertFalse( + "invalid header returns valid value", retrieveMediaFormat(streams[index], response) + ) + assertNull("Media format extracted although stated otherwise", wrapper.getFormat(index)) + } + + /** + * Assert that a valid response results in correctly extracted and handled [MediaFormat]. + */ + fun assertValidResponse( + response: Response, + index: Int, + format: MediaFormat + ) { + assertTrue( + "header was not recognized", retrieveMediaFormat(streams[index], response) + ) + assertEquals("Wrong media format extracted", format, wrapper.getFormat(index)) + } + } } diff --git a/app/src/main/java/org/schabi/newpipe/util/StreamItemAdapter.java b/app/src/main/java/org/schabi/newpipe/util/StreamItemAdapter.java index 04cd737b6..691b39403 100644 --- a/app/src/main/java/org/schabi/newpipe/util/StreamItemAdapter.java +++ b/app/src/main/java/org/schabi/newpipe/util/StreamItemAdapter.java @@ -13,6 +13,7 @@ import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.annotation.VisibleForTesting; import androidx.collection.SparseArrayCompat; import org.schabi.newpipe.DownloaderImpl; @@ -298,7 +299,8 @@ public class StreamItemAdapter extends BaseA * @param response the response of the head request for the given stream * @return {@code true} if the media format could be retrieved; {@code false} otherwise */ - private static boolean retrieveMediaFormat( + @VisibleForTesting + public static boolean retrieveMediaFormat( @NonNull final X stream, @NonNull final StreamInfoWrapper streamsWrapper, @NonNull final Response response) { @@ -308,7 +310,8 @@ public class StreamItemAdapter extends BaseA || retrieveMediaFormatFromContentTypeHeader(stream, streamsWrapper, response); } - private static boolean retrieveMediaFormatFromFileTypeHeaders( + @VisibleForTesting + public static boolean retrieveMediaFormatFromFileTypeHeaders( @NonNull final X stream, @NonNull final StreamInfoWrapper streamsWrapper, @NonNull final Response response) { @@ -342,6 +345,7 @@ public class StreamItemAdapter extends BaseA * otherwise {@code false} * @param */ + @VisibleForTesting public static boolean retrieveMediaFormatFromContentDispositionHeader( @NonNull final X stream, @NonNull final StreamInfoWrapper streamsWrapper, @@ -391,7 +395,8 @@ public class StreamItemAdapter extends BaseA return false; } - private static boolean retrieveMediaFormatFromContentTypeHeader( + @VisibleForTesting + public static boolean retrieveMediaFormatFromContentTypeHeader( @NonNull final X stream, @NonNull final StreamInfoWrapper streamsWrapper, @NonNull final Response response) { @@ -416,7 +421,8 @@ public class StreamItemAdapter extends BaseA public void resetInfo() { Arrays.fill(streamSizes, SIZE_UNSET); for (int i = 0; i < streamsList.size(); i++) { - streamFormats[i] = streamsList.get(i).getFormat(); + streamFormats[i] = streamsList.get(i) == null // test for invalid streams + ? null : streamsList.get(i).getFormat(); } } From ba84e7eeadafcbdd97c8a0cbd1dd52a1e2b2dc68 Mon Sep 17 00:00:00 2001 From: TobiGr Date: Wed, 19 Jul 2023 23:36:38 +0200 Subject: [PATCH 011/172] Display "Unknown quality" if quality is unknown and not MediaFormat name --- .../main/java/org/schabi/newpipe/util/StreamItemAdapter.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/util/StreamItemAdapter.java b/app/src/main/java/org/schabi/newpipe/util/StreamItemAdapter.java index 691b39403..d5b73d0b6 100644 --- a/app/src/main/java/org/schabi/newpipe/util/StreamItemAdapter.java +++ b/app/src/main/java/org/schabi/newpipe/util/StreamItemAdapter.java @@ -154,8 +154,6 @@ public class StreamItemAdapter extends BaseA final AudioStream audioStream = ((AudioStream) stream); if (audioStream.getAverageBitrate() > 0) { qualityString = audioStream.getAverageBitrate() + "kbps"; - } else if (mediaFormat != null) { - qualityString = mediaFormat.getName(); } else { qualityString = context.getString(R.string.unknown_quality); } From db5ed48dbb529c8bd0b0871724c821b666157aba Mon Sep 17 00:00:00 2001 From: TobiGr Date: Fri, 11 Aug 2023 23:12:47 +0200 Subject: [PATCH 012/172] Fix some sonar warnings and make some smaller improvements --- .../java/org/schabi/newpipe/player/PlayQueueActivity.java | 8 +++----- .../org/schabi/newpipe/settings/tabs/TabsManager.java | 6 ++---- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/player/PlayQueueActivity.java b/app/src/main/java/org/schabi/newpipe/player/PlayQueueActivity.java index cd71c64e9..4baadf69f 100644 --- a/app/src/main/java/org/schabi/newpipe/player/PlayQueueActivity.java +++ b/app/src/main/java/org/schabi/newpipe/player/PlayQueueActivity.java @@ -585,11 +585,9 @@ public final class PlayQueueActivity extends AppCompatActivity } 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); - item.setTitle(formatSpeed(parameters.speed)); - } + if (parameters != null && menu != null && player != null) { + final MenuItem item = menu.findItem(R.id.action_playback_speed); + item.setTitle(formatSpeed(parameters.speed)); } } diff --git a/app/src/main/java/org/schabi/newpipe/settings/tabs/TabsManager.java b/app/src/main/java/org/schabi/newpipe/settings/tabs/TabsManager.java index c885b803c..7dcbee56f 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/tabs/TabsManager.java +++ b/app/src/main/java/org/schabi/newpipe/settings/tabs/TabsManager.java @@ -73,10 +73,8 @@ public final class TabsManager { private SharedPreferences.OnSharedPreferenceChangeListener getPreferenceChangeListener() { return (sp, key) -> { - if (savedTabsKey.equals(key)) { - if (savedTabsChangeListener != null) { - savedTabsChangeListener.onTabsChanged(); - } + if (savedTabsKey.equals(key) && savedTabsChangeListener != null) { + savedTabsChangeListener.onTabsChanged(); } }; } From 62f0abee473735d9c6e2f83874bc2241ef0ceaa8 Mon Sep 17 00:00:00 2001 From: TobiGr Date: Sat, 19 Aug 2023 21:57:15 +0200 Subject: [PATCH 013/172] Simplify MainActivity.tabSelected(MenuItem) Rename variables and skip iterations if kiosk was found. --- .../java/org/schabi/newpipe/MainActivity.java | 26 ++++++++----------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/MainActivity.java b/app/src/main/java/org/schabi/newpipe/MainActivity.java index ee2bb3f05..ea047ce61 100644 --- a/app/src/main/java/org/schabi/newpipe/MainActivity.java +++ b/app/src/main/java/org/schabi/newpipe/MainActivity.java @@ -219,14 +219,14 @@ public class MainActivity extends AppCompatActivity { final int currentServiceId = ServiceHelper.getSelectedServiceId(this); final StreamingService service = NewPipe.getService(currentServiceId); - int kioskId = 0; + int kioskMenuItemId = 0; for (final String ks : service.getKioskList().getAvailableKiosks()) { drawerLayoutBinding.navigation.getMenu() - .add(R.id.menu_tabs_group, kioskId, 0, KioskTranslator + .add(R.id.menu_tabs_group, kioskMenuItemId, 0, KioskTranslator .getTranslatedKioskName(ks, this)) .setIcon(KioskTranslator.getKioskIcon(ks)); - kioskId++; + kioskMenuItemId++; } drawerLayoutBinding.navigation.getMenu() @@ -306,20 +306,16 @@ public class MainActivity extends AppCompatActivity { NavigationHelper.openStatisticFragment(getSupportFragmentManager()); break; default: - final int currentServiceId = ServiceHelper.getSelectedServiceId(this); - final StreamingService service = NewPipe.getService(currentServiceId); - String serviceName = ""; - - int kioskId = 0; - for (final String ks : service.getKioskList().getAvailableKiosks()) { - if (kioskId == item.getItemId()) { - serviceName = ks; + final StreamingService currentService = ServiceHelper.getSelectedService(this); + int kioskMenuItemId = 0; + for (final String kioskId : currentService.getKioskList().getAvailableKiosks()) { + if (kioskMenuItemId == item.getItemId()) { + NavigationHelper.openKioskFragment(getSupportFragmentManager(), + currentService.getServiceId(), kioskId); + break; } - kioskId++; + kioskMenuItemId++; } - - NavigationHelper.openKioskFragment(getSupportFragmentManager(), currentServiceId, - serviceName); break; } } From 68957d3880e95ac864cf93f30f2b23786fc67eb1 Mon Sep 17 00:00:00 2001 From: TobiGr Date: Tue, 22 Aug 2023 13:51:31 +0200 Subject: [PATCH 014/172] Fix grammar in JDoc --- app/src/main/java/org/schabi/newpipe/util/StateSaver.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/org/schabi/newpipe/util/StateSaver.java b/app/src/main/java/org/schabi/newpipe/util/StateSaver.java index 3c901aacb..91dc5f35b 100644 --- a/app/src/main/java/org/schabi/newpipe/util/StateSaver.java +++ b/app/src/main/java/org/schabi/newpipe/util/StateSaver.java @@ -309,7 +309,7 @@ public final class StateSaver { } /** - * Used for describe how to save/read the objects. + * Used for describing how to save/read the objects. *

* Queue was chosen by its FIFO property. */ From e4003c842bd45e937b73abf45b201ecf1992109e Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Wed, 23 Aug 2023 21:29:25 +0200 Subject: [PATCH 015/172] Translated using Weblate (Arabic) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 100.0% (686 of 686 strings) Translated using Weblate (Odia) Currently translated at 100.0% (686 of 686 strings) Translated using Weblate (Malayalam) Currently translated at 6.6% (5 of 75 strings) Translated using Weblate (Punjabi) Currently translated at 100.0% (686 of 686 strings) Translated using Weblate (Swedish) Currently translated at 100.0% (686 of 686 strings) Translated using Weblate (Russian) Currently translated at 100.0% (686 of 686 strings) Translated using Weblate (German) Currently translated at 100.0% (686 of 686 strings) Translated using Weblate (German) Currently translated at 100.0% (686 of 686 strings) Translated using Weblate (Punjabi) Currently translated at 100.0% (686 of 686 strings) Translated using Weblate (Swedish) Currently translated at 99.7% (684 of 686 strings) Translated using Weblate (Dutch) Currently translated at 100.0% (686 of 686 strings) Translated using Weblate (Estonian) Currently translated at 100.0% (686 of 686 strings) Translated using Weblate (Albanian) Currently translated at 82.7% (568 of 686 strings) Translated using Weblate (Portuguese) Currently translated at 100.0% (686 of 686 strings) Translated using Weblate (Dutch) Currently translated at 100.0% (686 of 686 strings) Translated using Weblate (French) Currently translated at 100.0% (686 of 686 strings) Translated using Weblate (Punjabi) Currently translated at 100.0% (686 of 686 strings) Translated using Weblate (Hindi) Currently translated at 100.0% (686 of 686 strings) Added translation using Weblate (Burmese) Translated using Weblate (ryu (generated) (ryu)) Currently translated at 100.0% (686 of 686 strings) Translated using Weblate (Hebrew) Currently translated at 100.0% (686 of 686 strings) Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (686 of 686 strings) Translated using Weblate (Chinese (Simplified)) Currently translated at 100.0% (686 of 686 strings) Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (686 of 686 strings) Translated using Weblate (Polish) Currently translated at 100.0% (686 of 686 strings) Translated using Weblate (Ukrainian) Currently translated at 100.0% (686 of 686 strings) Translated using Weblate (Arabic) Currently translated at 100.0% (686 of 686 strings) Translated using Weblate (Czech) Currently translated at 100.0% (686 of 686 strings) Translated using Weblate (Slovak) Currently translated at 98.9% (679 of 686 strings) Translated using Weblate (Greek) Currently translated at 100.0% (686 of 686 strings) Translated using Weblate (Italian) Currently translated at 100.0% (686 of 686 strings) Translated using Weblate (Japanese) Currently translated at 100.0% (686 of 686 strings) Translated using Weblate (Dutch) Currently translated at 100.0% (686 of 686 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (686 of 686 strings) Translated using Weblate (German) Currently translated at 100.0% (686 of 686 strings) Translated using Weblate (ryu (generated) (ryu)) Currently translated at 100.0% (684 of 684 strings) Translated using Weblate (Czech) Currently translated at 100.0% (75 of 75 strings) Translated using Weblate (Croatian) Currently translated at 91.8% (628 of 684 strings) Translated using Weblate (Indonesian) Currently translated at 100.0% (684 of 684 strings) Translated using Weblate (Czech) Currently translated at 100.0% (684 of 684 strings) Translated using Weblate (French) Currently translated at 100.0% (684 of 684 strings) Translated using Weblate (ryu (generated) (ryu)) Currently translated at 98.6% (675 of 684 strings) Translated using Weblate (Japanese) Currently translated at 100.0% (684 of 684 strings) Translated using Weblate (Odia) Currently translated at 100.0% (684 of 684 strings) Translated using Weblate (Urdu) Currently translated at 74.2% (508 of 684 strings) Translated using Weblate (Vietnamese) Currently translated at 99.2% (679 of 684 strings) Translated using Weblate (Portuguese) Currently translated at 100.0% (684 of 684 strings) Translated using Weblate (Korean) Currently translated at 100.0% (684 of 684 strings) Translated using Weblate (Japanese) Currently translated at 100.0% (684 of 684 strings) Translated using Weblate (Portuguese (Portugal)) Currently translated at 100.0% (75 of 75 strings) Translated using Weblate (Portuguese) Currently translated at 100.0% (75 of 75 strings) Translated using Weblate (Ukrainian) Currently translated at 100.0% (75 of 75 strings) Translated using Weblate (Portuguese (Portugal)) Currently translated at 100.0% (684 of 684 strings) Translated using Weblate (Galician) Currently translated at 99.5% (681 of 684 strings) Translated using Weblate (Finnish) Currently translated at 89.9% (615 of 684 strings) Translated using Weblate (Portuguese) Currently translated at 100.0% (684 of 684 strings) Co-authored-by: Agnieszka C Co-authored-by: Alex25820 Co-authored-by: Alexthegib Co-authored-by: AudricV Co-authored-by: C. Rüdinger Co-authored-by: Eric Co-authored-by: Fjuro Co-authored-by: GET100PERCENT Co-authored-by: Hoseok Seo Co-authored-by: Hosted Weblate Co-authored-by: Igor Rückert Co-authored-by: Ihor Hordiichuk Co-authored-by: J. Lavoie Co-authored-by: Jani Kinnunen Co-authored-by: Jeff Huang Co-authored-by: Joel A Co-authored-by: Jorge Pelaez Co-authored-by: Linerly Co-authored-by: Milan Šalka Co-authored-by: Milo Ivir Co-authored-by: Philip Goto Co-authored-by: Priit Jõerüüt Co-authored-by: Rex_sa Co-authored-by: Sergio Marques Co-authored-by: ShareASmile Co-authored-by: Shifa Graphics Co-authored-by: TXRdev Archive Co-authored-by: Vasilis K Co-authored-by: VfBFan Co-authored-by: W L Co-authored-by: WB Co-authored-by: Weblate Co-authored-by: Yaron Shahrabani Co-authored-by: gallegonovato Co-authored-by: kuragehime Co-authored-by: nautilusx Co-authored-by: random r Co-authored-by: ssantos Co-authored-by: tellmeY18 Co-authored-by: thami simo Co-authored-by: Макар Разин Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/cs/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/ml/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/pt/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/pt_PT/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/uk/ Translation: NewPipe/Metadata --- app/src/main/res/values-ar/strings.xml | 36 +++--- app/src/main/res/values-cs/strings.xml | 5 +- app/src/main/res/values-de/strings.xml | 22 ++-- app/src/main/res/values-el/strings.xml | 2 + app/src/main/res/values-es/strings.xml | 4 +- app/src/main/res/values-et/strings.xml | 2 + app/src/main/res/values-fi/strings.xml | 24 +++- app/src/main/res/values-fr/strings.xml | 5 +- app/src/main/res/values-gl/strings.xml | 3 + app/src/main/res/values-he/strings.xml | 2 + app/src/main/res/values-hi/strings.xml | 2 + app/src/main/res/values-hr/strings.xml | 2 +- app/src/main/res/values-in/strings.xml | 3 +- app/src/main/res/values-it/strings.xml | 2 + app/src/main/res/values-ja/strings.xml | 5 +- app/src/main/res/values-ko/strings.xml | 8 +- app/src/main/res/values-my/strings.xml | 2 + app/src/main/res/values-nl/strings.xml | 119 +++++++++--------- app/src/main/res/values-or/strings.xml | 30 ++++- app/src/main/res/values-pa/strings.xml | 40 +++--- app/src/main/res/values-pl/strings.xml | 2 + app/src/main/res/values-pt-rBR/strings.xml | 7 +- app/src/main/res/values-pt-rPT/strings.xml | 3 +- app/src/main/res/values-pt/strings.xml | 19 +-- app/src/main/res/values-ru/strings.xml | 13 +- app/src/main/res/values-ryu/strings.xml | 32 ++++- app/src/main/res/values-sk/strings.xml | 2 +- app/src/main/res/values-sq/strings.xml | 18 +++ app/src/main/res/values-sv/strings.xml | 5 +- app/src/main/res/values-uk/strings.xml | 2 + app/src/main/res/values-ur/strings.xml | 11 +- app/src/main/res/values-vi/strings.xml | 2 +- app/src/main/res/values-zh-rCN/strings.xml | 2 + app/src/main/res/values-zh-rTW/strings.xml | 2 + .../metadata/android/cs/changelogs/994.txt | 15 +++ .../metadata/android/ml/changelogs/64.txt | 8 ++ .../metadata/android/pt-PT/changelogs/994.txt | 15 +++ .../metadata/android/pt/changelogs/994.txt | 15 +++ .../metadata/android/uk/changelogs/994.txt | 15 +++ 39 files changed, 367 insertions(+), 139 deletions(-) create mode 100644 app/src/main/res/values-my/strings.xml create mode 100644 fastlane/metadata/android/cs/changelogs/994.txt create mode 100644 fastlane/metadata/android/ml/changelogs/64.txt create mode 100644 fastlane/metadata/android/pt-PT/changelogs/994.txt create mode 100644 fastlane/metadata/android/pt/changelogs/994.txt create mode 100644 fastlane/metadata/android/uk/changelogs/994.txt diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index a4c2953d1..595a3182f 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -18,12 +18,12 @@ اختر مجلد التنزيل لملفات الفيديو يتم تخزين ملفات الفيديو التي تم تنزيلها هنا مجلد تحميل الفيديو - تثبيت + ثبت تطبيق Kore غير موجود. هل تريد تثبيته؟ فاتح خطأ في الشبكة لم يتم العثور على مشغل بث. تثبيت VLC؟ - فتح في المتصفح + فتح في متصفح الويب الصوت تشغيل بواسطة كودي البحث @@ -37,7 +37,7 @@ اعرض خيار لتشغيل الفيديو عبر مركز وسائط Kodi عرض خيار التشغيل بواسطة كودي السمة - تم النشر بتاريخ %1$s + تم النشر في %1$s رابط غير مدعوم استخدام مشغل صوت خارجي استخدام مشغل فيديو خارجي @@ -46,7 +46,7 @@ خطأ تعذر تحليل الموقع تعذر فك تشفير توقيع رابط الفيديو - اضغط على \"العدسة المكبرة\" للبدء. + اضغط على عدسة المكبرة للبدء. اشتراك مشترك الاشتراكات @@ -64,7 +64,7 @@ حول التطبيق & الأسئلة الشائعة التاريخ التاريخ - فتح في وضع منبثق + فتح في الوضع المنبثق يزيل الصوت في بعض الجودات تم إلغاء الاشتراك في القناة تعذر تغيير حالة الاشتراك @@ -122,12 +122,12 @@ بليون ليس هناك مشترِكون - %s مشترك - %s l مشاركين - %s مشتركين - %s مشتركين - %s مشتركين - %s مشتركين + %s مشارك + %s مشارك + %s مشاركين + %s مشترك + %s مشترك + %s مشترك دون مشاهدات لاتوجد فيديوهات @@ -135,7 +135,7 @@ إيقاف مؤقت احذف التوقيع - حسناً + موافق اسم الملف التقسيم الخطأ @@ -182,7 +182,7 @@ ضغط مطول للإدراج الى قائمة الانتظار %s مشاهد - %s مشاهدة + %s مشاهد %s مشاهدة %s مشاهدة %s مشاهدة @@ -541,7 +541,7 @@ %d دقيقة نظرا لقيود مشغل ExoPlayer مدة التقديم تم ضبطها الى %d ثانية - إلغاء كتم الصوت + غير صامت كتم الصوت هذا المحتوى ليس مدعومًا من قبل NewPipe. \n @@ -620,7 +620,7 @@ تعليقات قم بإيقاف التشغيل لإخفاء وصف الفيديو والمعلومات الإضافية إظهار الوصف - فتح مع + افتح باستخدام يتوفر هذا المحتوى فقط للمستخدمين الذين قاموا بالدفع، لذلك لا يمكن بثه أو تنزيله عبر NewPipe. يتوفر هذا الفيديو فقط لأعضاء YouTube Music Premium، لذلك لا يمكن بثه أو تنزيله من قبل NewPipe. هذا المحتوى خاص، لذلك لا يمكن دفقه أو تنزيله بواسطة NewPipe. @@ -628,7 +628,7 @@ هذا المحتوى غير متوفر في بلدك. اغلق التطبيق قسريا هذا الفيديو مقيد بالفئة العمرية. -\nنظرًا لسياسات YouTube الجديدة المتعلقة بمقاطع الفيديو المقيدة بالفئة العمرية، لا يمكن لـNewPipe الوصول إلى أي من مقاطع الفيديو الخاصة بها وبالتالي لا يمكن تشغيلها. +\nنظرًا لسياسات YouTube الجديدة المتعلقة بمقاطع الفيديو المقيدة بالفئة العمرية، لا يمكن لـ NewPipe الوصول إلى أي من تدفقات الفيديو الخاصة به، وبالتالي لا يتمكن من تشغيلها. إذاعة المميزة حل @@ -676,7 +676,7 @@ جودة منخفضة (أصغر) جودة عالية (أكبر) معاينة مصغرة على شريط التمرير - تعليم كفيديو تمت مشاهدته + وضع علامة على تمت مشاهدته أُعجب بها منشئ المحتوى أظهر أشرطة ملونة لبيكاسو أعلى الصور تشير إلى مصدرها: الأحمر للشبكة والأزرق للقرص والأخضر للذاكرة إظهار مؤشرات الصور @@ -816,4 +816,6 @@ انقل محدد علامة التبويب الرئيسي إلى الأسفل موضع علامات التبويب الرئيسية تم تعطيل نفق وسائل الإعلام عن طريق التقصير على جهازك لأن نموذج جهازك معروف بأنه لا يدعمه. + لاتوجد بثوث + لاتوجد بثوث مباشرة \ No newline at end of file diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index 742d4da54..f7214176f 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -608,7 +608,7 @@ Toto video je věkově omezeno. \nKvůli novým pravidlům YouTube ohledně věkově omezených videí nemůže NewPipe získat přístup na streamy videa, a tak je nemůže přehrát. Noční motiv - Vypněte media-tunelling, pokud zaznamenáte temnou obrazovku nebo zadrhávání během playbacku + Vypněte media-tunelling, pokud během přehrávání zaznamenáte temnou obrazovku nebo zadrhávání. Vypnout media-tunelling Přejít na website Interní @@ -776,4 +776,7 @@ Zvuk: %s Pozice hlavních karet Přesunout výběr hlavní karty dolů + Na vašem zařízení byl zakázán media tunelling, protože model vašeho zařízení jej nepodporuje. + Žádná videa + Žádné živé přenosy \ No newline at end of file diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 2fee618fd..ed02258b8 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -104,7 +104,7 @@ Entfernt Tonspur bei manchen Auflösungen Letzte Größe und Position des Pop-ups merken Suchvorschläge - Wähle die Vorschläge aus, die bei der Suche angezeigt werden sollen + Vorschläge auswählen, die bei der Suche angezeigt werden sollen Löschen Beste Auflösung Über NewPipe @@ -270,7 +270,7 @@ Geschwindigkeit Tonhöhe Entkoppeln (kann zu Verzerrungen führen) - Deaktiviere diese Option, um das Laden von Vorschaubildern zu verhindern, was Daten- und Speicherverbrauch spart. Änderungen löschen den Bildzwischenspeicher sowohl im Arbeitsspeicher als auch auf dem internen Speicher + Ausschalten, um das Laden von Vorschaubildern zu verhindern, was Daten- und Speicherverbrauch spart. Änderungen löschen den Bildzwischenspeicher sowohl im Arbeitsspeicher als auch auf dem internen Speicher Nächsten Stream automatisch einreihen Wiedergabe durch Anhängen eines verwandten Streams an die Warteschlange (ohne Wiederholungsschleife) fortsetzen Wiedergabeliste mit Lesezeichen versehen @@ -579,7 +579,7 @@ Video-Hash Benachrichtigung Letzte Metadaten anzeigen - Deaktiviere diese Option, um Meta-Infofelder mit zusätzlichen Informationen zum Stream-Ersteller, zum Stream-Inhalt oder zu einer Suchanforderung auszublenden + Ausschalten, um Metadaten-Felder mit zusätzlichen Informationen zu Stream-Ersteller, -Inhalten oder einer Suchanfrage auszublenden Kapitel Beschreibung Verwandte Elemente @@ -739,16 +739,16 @@ Linke Gestenaktion Helligkeit Lautstärke - Ändere die Größe des Ladeintervalls für progressive Inhalte (derzeit %s). Ein niedrigerer Wert kann das anfängliche Laden der Inhalte beschleunigen. + Ändere die Größe des Ladeintervalls für progressive Inhalte (derzeit %s). Ein niedrigerer Wert kann das anfängliche Laden der Inhalte beschleunigen Originalton bevorzugen - Wähle die Originaltonspur unabhängig von der Sprache + Originaltonspur unabhängig von der Sprache wählen Beschreibendes Audio bevorzugen - Wähle eine Audiospur mit Beschreibungen für sehbehinderte Menschen, falls verfügbar + Wenn möglich Audiospur mit Beschreibungen für sehbehinderte Menschen wählen Audio: %s Audiospur - Verwalte einige ExoPlayer-Einstellungen. Diese Änderungen erfordern einen Neustart des Players, um wirksam zu werden - Verwende die Decoder-Fallback-Funktion von ExoPlayer - Verwende immer die ExoPlayer-Einstellung für die Videoausgangsoberfläche als Umgehung + Einige ExoPlayer-Einstellungen steuern. Diese Änderungen erfordern einen Neustart des Players, um wirksam zu werden + Die Decoder-Fallback-Funktion von ExoPlayer verwenden + Immer die ExoPlayer-Einstellung für die Videoausgangsoberfläche als Umgehung verwenden Dieser Workaround gibt die Video-Codecs frei und instanziiert sie neu, wenn sich die Oberfläche ändert, anstatt die Oberfläche direkt auf den Codec zu setzen. Diese Einstellung wird bereits von ExoPlayer auf einigen Geräten mit diesem Problem verwendet und hat nur Auswirkungen auf Android 6 und höher \n \nDas Aktivieren dieser Option kann Wiedergabefehler beim Wechsel des aktuellen Videoplayers oder beim Wechsel zum Vollbildmodus verhindern @@ -757,11 +757,13 @@ Beschreibend Audiospur für externe Player auswählen In diesem Stream sollte bereits eine Audiospur vorhanden sein - Aktiviere diese Option, wenn du Probleme mit der Decoderinitialisierung hast, die auf Decoder mit niedrigerer Priorität zurückgreift, wenn die Initialisierung des primären Decoders fehlschlägt. Dies kann zu einer schlechteren Wiedergabeleistung führen als bei der Verwendung von Primärdecodern + Einschalten, wenn es Probleme mit der Decoderinitialisierung gibt, die auf Decoder mit niedrigerer Priorität zurückgreift, wenn die Initialisierung des primären Decoders fehlschlägt. Dies kann zu einer schlechteren Wiedergabeleistung führen als bei der Verwendung von Primärdecodern Unbekannt ExoPlayer-Einstellungen %1s %2s Hauptauswahltab nach unten verschieben Position des Haupttabs Das Media-Tunneling wurde auf dem Gerät standardmäßig deaktiviert, da das Gerätemodell diese Funktion bekanntermaßen nicht unterstützt. + Keine Live-Streams + Keine Streams \ No newline at end of file diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index 113f4f3da..9b746067d 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -764,4 +764,6 @@ Μετακινήστε τον επιλογέα κύριας καρτέλας στο κάτω μέρος Θέση κύριων καρτελών Το media tunneling απενεργοποιήθηκε από προεπιλογή στη συσκευή σας, επειδή το μοντέλο της συσκευής σας είναι γνωστό ότι δεν το υποστηρίζει. + Καμία ζωντανή ροή + Καμία ροή \ No newline at end of file diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index bb2b336c9..676fe2434 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -606,7 +606,7 @@ La descarga ha comenzado Solucionar Puedes seleccionar tu tema nocturno favorito a continuación - Modo oscuro + tema para la noche Selecciona tu tema nocturno favorito — %s Automático (tema del dispositivo) Mostrar detalles del canal @@ -780,4 +780,6 @@ Posición de las pestañas principales Mover el selector de la pestaña principal a la parte inferior Como se sabe que este dispositivo no es compatible con la tunelización de medios, esta función está desactivada de forma predeterminada. + Sin retransmisiones + Sin transmisiones en directo \ No newline at end of file diff --git a/app/src/main/res/values-et/strings.xml b/app/src/main/res/values-et/strings.xml index dc2f70158..e534c6569 100644 --- a/app/src/main/res/values-et/strings.xml +++ b/app/src/main/res/values-et/strings.xml @@ -764,4 +764,6 @@ Tõsta põhiline vahekaartide valija alla äärde Vahekaartide põhiline asukoht Kuna on teada, et see seade ei toeta meedia tunneldamist, siis on see funktsionaalsus vaikimisi välja lülitatud. + Meediavoogusid ei leidu + Otseeetris meediavoogusid ei leidu \ No newline at end of file diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml index ef84871e2..7832e3dae 100644 --- a/app/src/main/res/values-fi/strings.xml +++ b/app/src/main/res/values-fi/strings.xml @@ -36,7 +36,7 @@ Näytä korkeammat resoluutiot Vain jotkin laitteet voivat toistaa 2K/4K-videota Toista Kodissa - Asennetaanko puuttuva Kode-sovellus\? + Asennetaanko puuttuva Kore-sovellus\? Näytä ”Toista Kodissa”-vaihtoehto Näyttää vaihtoehdon videon toistamiseen Kodi-mediasoittimessa Ääni @@ -553,8 +553,8 @@ Kolmas toimintopainike Toinen toimintopainike Ensimmäinen toimintopainike - Skaalaa ilmoituksessa näytettävä videon esikatselukuva kuvasuhteesta 16:9 kuvasuhteeseen 1:1 (saattaa aiheuttaa vääristymiä) - Skaalaa esikatselukuva 1:1-kuvasuhteeseen + Rajaa ilmoituksessa näytettävä videon esikatselukuva kuvasuhteesta 16:9 kuvasuhteeseen 1:1 + Rajaa esikatselukuva 1:1-kuvasuhteeseen Näytä muistivuodot Lisätty jonoon Lisää jonoon @@ -681,4 +681,22 @@ dubattu %1s %2s alkuperäinen + Soittimen ilmoitus + Määritä toistettavan lähetysvirran ilmoitus + Vasemman eleen toiminto + Valitse soitinnäytön oikean puoliskon ele + Oikean eleen toiminto + Kirkkaus + Äänenvoimakkuus + Ei mitään + Toiston latausvälin koko + Ohita laitteiston mediapainikkeiden tapahtumat + Suosi alkuperäistä ääntä + Valitse alkuperäinen ääniraita kielestä riippumatta + Suosi kuvailutulkkausta + Valitse näkövammaisille tarkoitetun kuvailutulkkauksen sisältävä ääniraita, mikäli saatavilla + Valitse soitinnäytön vasemman puoliskon ele + Uusia lähetysvirtoja + Muuta progressiivisen sisällön latausvälin kokoa (tällä hetkellä %s). Pienempi arvo saattaa nopeuttaa ensimmäistä latausta. + Tästä on hyötyä esim. silloin, jos käyttämiesi kuulokkeiden fyysiset painikkeet eivät toimi. \ No newline at end of file diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 6a129cc98..258b44809 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -610,7 +610,7 @@ Vous pouvez sélectionner votre thème de nuit favori ci-dessous Le téléchargement a démarré Afficher les détails de la chaîne - Désactivez la tunnelisation multimédia si vous constatez un écran noir ou un bégaiement lors de la lecture d’une vidéo + Désactivez la tunnelisation multimédia si vous constatez un écran noir ou un bégaiement lors de la lecture d’une vidéo. Désactiver la tunnelisation média Désactiver la sélection de texte dans la description Permettre la sélection de texte dans la description @@ -778,4 +778,7 @@ Activez cette option si vous rencontrez des problèmes d\'initialisation des décodeurs, ce qui permet de revenir à des décodeurs moins prioritaires si l\'initialisation des décodeurs primaires échoue. Les performances de lecture peuvent être moins bonnes que lors de l\'utilisation des décodeurs primaires Déplacer le sélecteur d\'onglet principal en bas Position des onglets principaux + La tunnelisation multimédia a été désactivée par défaut sur votre appareil car votre modèle d\'appareil est connu pour ne pas la supporter. + Aucun flux + Aucun direct \ No newline at end of file diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml index e2ab9596b..fdc74a7d8 100644 --- a/app/src/main/res/values-gl/strings.xml +++ b/app/src/main/res/values-gl/strings.xml @@ -758,4 +758,7 @@ Seleciona o audio con descrición para persoas con dificuldades de visión, se estar dispoñíbel Prefirir o audio descritivo Escolla o xesto para a metade esquerda da pantalla do reprodutor + Mova o selector da lapela principal para a parte inferior + Posición prinicipal das lapelas + A tunelización da multimedia foi deshabilitada por defecto, porque o seu modelo de dispositivo carece de soporte. \ No newline at end of file diff --git a/app/src/main/res/values-he/strings.xml b/app/src/main/res/values-he/strings.xml index 89b2fe484..91287e7d0 100644 --- a/app/src/main/res/values-he/strings.xml +++ b/app/src/main/res/values-he/strings.xml @@ -790,4 +790,6 @@ להעביר את בורר הלשוניות הראשי לתחתית %1s %2s תיעול מדיה הושבת כברירת מחדל במכשיר שלך כיוון שדגם המכשיר ידוע בכך שאינו תומך בזה. + אין תזרימים חיים + אין תזרימים \ No newline at end of file diff --git a/app/src/main/res/values-hi/strings.xml b/app/src/main/res/values-hi/strings.xml index 230c730d8..726a0e107 100644 --- a/app/src/main/res/values-hi/strings.xml +++ b/app/src/main/res/values-hi/strings.xml @@ -764,4 +764,6 @@ मुख्य टैब सिलेक्टर को नीचे ले जाएँ %1s %2s आपके डिवाइस पर मीडिया टनलिंग डिफ़ॉल्ट रूप से अक्षम कर दी गई थी क्योंकि यह ज्ञात है कि आपका डिवाइस मॉडल इसका समर्थन नहीं करता। + कोई स्ट्रीम नहीं + कोई लाइव स्ट्रीम नहीं \ No newline at end of file diff --git a/app/src/main/res/values-hr/strings.xml b/app/src/main/res/values-hr/strings.xml index 11ad99b93..80b734fcd 100644 --- a/app/src/main/res/values-hr/strings.xml +++ b/app/src/main/res/values-hr/strings.xml @@ -608,7 +608,7 @@ Riješi Noćna tema Prikaži detalje kanala - Isključi tuneliranje medija ako doživiš crni ekran ili isprekidanu reprodukciju videa + Isključi tuneliranje medija ako doživiš crni ekran ili isprekidanu reprodukciju videa. Iskljuci medija tuneling Isklj. Uklj. diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index f4e708abc..04880fc73 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -588,7 +588,7 @@ Tema malam Pengunduhan dimulai Tampilkan detail channel - Nonaktifkan terowongan media (tunnel) jiaka anda mengalami sebuah layar hitam atau kerusakan dalam memutar video + Nonaktifkan terowongan media (tunnel) jiaka anda mengalami sebuah layar hitam atau kerusakan dalam memutar video. Nonaktifkan terowongan media (tunnel) Internal Privasi @@ -750,4 +750,5 @@ Pindahkan pemilih tab utama ke bawah Posisi tab utama %1s %2s + Terowongan media dinonaktifkan secara bawaan di perangkat Anda karena model perangkat Anda tidak mendukungnya. \ No newline at end of file diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index e8dcda8bc..0e307a3be 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -777,4 +777,6 @@ Posizione delle schede principali Sposta in fondo il selettore della scheda principale Il tunneling multimediale è stato disabilitato per impostazione predefinita sul dispositivo in uso, poiché è noto che il modello del dispositivo non lo supporta. + Nessuna trasmissione + Nessuna trasmissione in diretta \ No newline at end of file diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 66dc541f7..dedb5763e 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -588,7 +588,7 @@ チャンネルの詳細を表示 ラジオ おすすめ - ビデオ再生が止まったり出ない場合はメディアトンネリングを無効にしてください + 動画の再生が止まったり動画が出ない場合はメディアトンネリングを無効にしてください。 マルチメディアトンネリングを無効にする 公開 限定公開 @@ -750,4 +750,7 @@ メインタブの場所 メインタブセレクタを下に移動 %1s %2s + お使いのデバイスのモデルではメディアトンネリングがサポートされていないため、このデバイスではメディアトンネリングがデフォルトで無効になっています。 + ストリームはありません + ライブ配信はありません \ No newline at end of file diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index 9ec68a23c..f0640b56b 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -73,7 +73,7 @@ 구독 구독중 구독 취소됨 - 구독상태를 변경할 수 없었습니다. + 구독을 변경할 수 없음 구독을 업데이트할 수 없음 구독목록 새로운 영상 @@ -547,7 +547,7 @@ 스트림 세부정보 불러오는 중… 미디어 터널링 비활성화 서비스의 원본 텍스트가 스트림 항목에 표시됩니다 - 비디오 재생 시 검은색 화면이나 끊김 현상이 발생하는 경우 미디어 터널링을 비활성화합니다 + 동영상 재생 시 검은 화면이 나타나거나 끊김 현상이 발생하면 미디어 터널링을 비활성화하세요. 이미지 표시기 표시 원본을 나타내는 이미지 위에 피카소 컬러 리본 표시: 네트워크는 빨간색, 디스크는 파란색, 메모리는 녹색 \"플레이어 충돌\" 표시 @@ -747,4 +747,8 @@ 이 해결 방법은 인터페이스가 변경될 때 인터페이스를 코덱으로 직접 설정하는 대신 비디오 코덱을 해제하고 다시 인스턴스화합니다. 이 문제가 있는 일부 기기에서 ExoPlayer가 이미 사용 중인 이 설정은 안드로이드 6 이상에서만 적용 \n \n이 옵션을 활성화하면 현재 동영상 플레이어를 전환하거나 전체 화면으로 전환할 때 재생 오류를 방지할 수 있음 + 메인 탭 선택기를 하단으로 이동 + %1s %2s + 메인 탭 위치 + 장치 모델에서 미디어 터널링을 지원하지 않는 것으로 알려져 있기 때문에 장치에서 기본적으로 미디어 터널링이 비활성화되었습니다. \ No newline at end of file diff --git a/app/src/main/res/values-my/strings.xml b/app/src/main/res/values-my/strings.xml new file mode 100644 index 000000000..a6b3daec9 --- /dev/null +++ b/app/src/main/res/values-my/strings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 5f111973b..3530071fb 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -17,13 +17,13 @@ Standaardresolutie Afspelen met Kodi Ontbrekende Kore-app installeren\? - \"Afspelen met Kodi\"-optie tonen - Toon een optie om een video af te spelen via Kodi media center + Optie ‘Afspelen met Kodi’ tonen + Toont een optie om een video af te spelen via Kodi media center Audio Standaardaudioformaat Downloaden URL wordt niet ondersteund - Toon ‘volgende’ en ‘vergelijkbare’ video’s + ‘Volgende’ en ‘Vergelijkbare’ video\'s tonen Standaardtaal voor inhoud Externe videospeler gebruiken Externe audiospeler gebruiken @@ -31,7 +31,7 @@ Speel video, tijd: Gebruikersafbeelding van uploader Vind-ik-niet-leuks - Downloadfolder voor audio + Download­map voor audio Gedownloade muziek wordt hier opgeslagen Voer de downloadlocatie in voor audiobestanden Thema @@ -40,7 +40,7 @@ Uiterlijk Speelt af op achtergrond Inhoud - Toon inhoud met leeftijdsbeperking + Inhoud met leeftijdsbeperking tonen Fout Netwerkfout Kan niet alle miniatuurvoorbeelden laden @@ -60,7 +60,7 @@ Video Geluid Opnieuw proberen - Tik op het vergrootglas om te beginnen. + Druk op het vergrootglas om te beginnen. Live Downloads Downloads @@ -91,7 +91,7 @@ Deze machtiging is vereist om te \nopenen in pop-upmodus Speelt af in pop-upmodus - Standaard videoformaat + Standaard­videoformaat Uitgeschakeld Standaardresolutie van pop-up Hogere resoluties tonen @@ -161,7 +161,7 @@ %s video’s Wil je dit item verwijderen uit je zoekgeschiedenis? - Toon tip \"Ingedrukt houden om toe te voegen\" + Tip ‘Ingedrukt houden om toe te voegen’ tonen Toon tip als de achtergrond- of pop-upknop wordt ingedrukt op de videogegevenspagina Alles afspelen Deze stream kan niet worden afgespeeld @@ -180,7 +180,7 @@ Verwijderen Details Audio-instellingen - Houd ingedrukt om toe te voegen aan wachtrij + Houd ingedrukt om toe te voegen aan de wachtrij [onbekend] Begin hier met afspelen in de achtergrond Begin met afspelen in pop-up @@ -189,7 +189,7 @@ Teruggeven Website Bezoek de website van NewPipe voor meer informatie en het laatste nieuws. - Standaard inhoudsland + Standaard­land voor inhoud Verplaatsen naar achtergrond Verplaatsen naar pop-up Verplaatsen naar hoofdvenster @@ -269,11 +269,11 @@ \n \n1. Ga naar dit adres: %1$s \n2. Log in op je account -\n3. Klik op \"Alle YouTube-gegevens inbegrepen\", dan op \"Selectie van alle items ongedaan maken\", dan selecteer alleen \"abonnementen\" en klik op \"OK\" -\n4. Klik op \"Volgende stap\", dan op \"Export maken\" -\n5. Klik op de knop \"Downloaden\" nadat deze verschijnt -\n6. Klik onder op \"Bestand importeren\" en selecteer de gedownloade zip file -\n7. [Als de zip import faalt] Uit de zip file, pak de .csv uit (gebruikelijk in de folder \"YouTube en YouTube Music/abonnementen/abonnementen.csv\"), klik onder op \"Bestand importeren\" en selecteer de uitgepakte zip file +\n3. Druk op ‘Alle YouTube-gegevens inbegrepen’, dan op ‘Selectie van alle items ongedaan maken’, dan selecteer alleen ‘abonnementen’ en druk op ‘OK’ +\n4. Druk op ‘Volgende stap’, dan op ‘Export maken’ +\n5. Druk op de knop ‘Downloaden’ nadat deze verschijnt +\n6. Druk onder op ‘Bestand importeren’ en selecteer de gedownloade zip file +\n7. [Als de zip-import faalt] Uit het zip-bestand, pak de .csv uit (normaal in de map ‘YouTube en YouTube Music/abonnementen/abonnementen.csv’), druk onder op ‘Bestand importeren’ en selecteer het uitgepakte zip-bestand Importeer een SoundCloud-profiel door de URL of het ID ervan in te voeren: \n \n1. Kies een webbrowser en schakel bureaubladmodus in (de website is niet beschikbaar voor mobiele apparaten) @@ -340,13 +340,13 @@ Meldingen voor nieuwe New Pipe versies Externe opslag niet beschikbaar Downloaden naar externe SD-kaart is niet mogelijk. Download map opnieuw instellen\? - Fout bij het lezen van de opgeslagen tabbladen, waardoor standaardtabbladen worden gebruikt + Fout bij lezen van opgeslagen tabbladen, standaard­tabbladen worden gebruikt Standaardinstellingen herstellen Wil je de standaardinstellingen herstellen\? Aantal abonnees niet beschikbaar Welke tabbladen worden weergegeven op de hoofdpagina Bijwerken - Toon een melding om de applicatie te updaten wanneer er een nieuwe versie beschikbaar is + Toon een melding om de app bij te werken wanneer een nieuwe versie beschikbaar is Lijstweergavemodus Lijst Raster @@ -357,14 +357,14 @@ gepauzeerd aan de wachtrij toegevoegd nabewerking - Wachtrij + In wachtrij plaatsen Actie door het systeem geweigerd Downloaden mislukt Genereer een unieke naam Overschrijven Er bestaat al een gedownload bestand met deze naam Er is een download aan de gang met deze naam - Toon foutmelding + Foutmelding tonen Het bestand kan niet worden gemaakt De doelmap kan niet worden gemaakt Kon geen beveiligde verbinding opzetten @@ -402,7 +402,7 @@ Geen vrije ruimte meer op het apparaat Voortgang verloren, omdat bestand was verwijderd Wilt u de downloadgeschiedenis of alle gedownloade bestanden verwijderen\? - Limiteer de download wachtrij + Download­wachtrij limiteren Er zal maximaal 1 bestand tegelijk worden gedownload Downloads starten Downloads pauzeren @@ -410,7 +410,7 @@ U wordt gevraagd waar elk bestand wordt opgeslagen. \nSchakel de systeem map kiezer (SAF) in als u naar een externe SD-kaart wilt downloaden Mapkiezer van systeem gebruiken (SAF) - Verwijder afspeelposities + Afspeelposities verwijderen Verwijdert alle afspeelposities Alle afspeelposities verwijderen\? Niemand is aan het kijken @@ -426,14 +426,14 @@ De taal zal veranderen zodra de app opnieuw is opgestart Standaard kiosk Duur voor-/achteruit spoelen - PeerTube kanaal - Selecteer je favorite PeerTube kanaal - Vind het kanaal dat je leuk vindt op %s - Kanaal toevoegen - Kanaal URL invoeren - Kon kanaal niet valideren - Alleen HTTPS URL\'s worden ondersteund - Kanaal bestaat al + PeerTube-instanties + Selecteer je favorite PeerTube-instanties + Vind de instanties die je leuk vindt op %s + Instantie toevoegen + Instantie-URL invoeren + Kon instantie niet valideren + Alleen HTTPS-URL\'s worden ondersteund + Instantie bestaat al Lokaal Recentelijk toegevoegd Automatisch gegenereerd (geen uploader gevonden) @@ -445,7 +445,7 @@ Geef toestemming voor weergave over andere apps App-taal Systeemtaal gebruiken - Druk op \"Klaar\" zodra opgelost + Druk op ‘Klaar’ als u dit heeft opgelost Klaar Video\'s Door beperkingen van ExoPlayer is de zoekduur ingesteld op %d seconden @@ -517,17 +517,17 @@ 100+ video\'s Deze video heeft een leeftijdsbeperking. \n -\nSchakel \"%1$s\" in bij de instellingen als u die wilt zien. +\nSchakel ‘%1$s’ in onder instellingen als u het wilt zien. Bekeken verwijderen Originele teksten van services zijn zichtbaar in stream-items - YouTube \"Beperkte modus\" aanzetten + YouTube\'s ‘Beperkte modus’ inschakelen Laat originele tijd geleden zien Avatarminiatuur van kanaal Door %s Gemaakt door %s - Afspeellijst pagina - Toon enkel ongegroepeerde abonnementen - Geen afspeellijst bookmarks + Afspeellijst­pagina + Enkel ongegroepeerde abonnementen tonen + Nog geen afspeellijst­bladwijzers Selecteer een afspeellijst Controleer of er al een probleem bestaat dat uw crash beschrijft. Wanneer u dubbele tickets aanmaakt, neemt dit tijd van ons in beslag die we beter kunnen besteden aan het oplossen van het daadwerkelijke probleem. In GitHub rapporteren @@ -536,9 +536,9 @@ Nooit Enkel via Wi-Fi Start automatisch met afspelen — %s - Speel wachtrij af + Wachtrij afspelen Kon de URL niet herkennen. In een andere app openen\? - De actieve spelerswachtrij wordt vervangen + De actieve speler­wachtrij zal worden vervangen Veranderen van één speler naar een andere kan jouw wachtrij vervangen Vraag bevestiging alvorens de wachtrij te wissen Niets @@ -546,27 +546,27 @@ Willekeurig afspelen Herhaal Je kan maximaal drie acties selecteren om te tonen in de compacte notificatie! - Pas elke notificatieactie hieronder aan door er op te tikken. Selecteer tot drie acties die getoond worden in de compacte notificatie door gebruik te maken van de selectievakjes aan de rechterkant + Pas elke meldings­actie hieronder aan door er op te tikken. Selecteer tot drie acties die getoond worden in de compacte melding door gebruik te maken van de selectievakjes aan de rechterkant Vijfde actieknop Vierde actieknop Derde actieknop Tweede actieknop Eerste actieknop - Schaal de miniatuurafbeelding van de video die getoond wordt in de notificatie van verhouding 16:9 naar 1:1 + Schaalt de miniatuurafbeelding van de video die getoond wordt in de melding van verhouding 16:9 naar 1:1 Schaal de miniatuurafbeelding tot verhouding 1:1 - Automatisch in de wachtrij plaatsen - Toon memory leaks + Automatisch in wachtrij plaatsen + Geheugen­lekken tonen In de wachtrij geplaatst In de wachtrij plaatsen Verwijder cookies die NewPipe opslaat wanneer u een reCAPTCHA oplost - reCAPTCHA cookies zijn verwijderd - Verwijder reCAPTCHA cookies - YouTube biedt een \"Beperkte modes\" aan, dit verbergt mogelijk materiaal voor volwassenen + reCAPTCHA-cookies zijn gewist + reCAPTCHA-cookies wissen + YouTube biedt een ‘Beperkte modus’ aan, dit verbergt materiaal voor volwassenen Toon inhoud die mogelijk niet geschikt is voor kinderen omwille van een leeftijdslimiet (zoals 18+) 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) Meldingkleur aanpassen - Toon miniatuurafbeelding op het vergrendelscherm als achtergrond en in de notificaties - Toon miniatuurafbeelding + Toon miniatuurafbeelding op het vergrendelscherm als achtergrond en in de meldingen + Miniatuur tonen Recente Hash berekenen Meldingen over de voortgang van video-hashing @@ -588,7 +588,7 @@ Deze inhoud is privé en kan dus niet worden gestreamd of gedownload door NewPipe. Dit is een SoundCloud Go + -track, althans in jouw land, dus het kan niet worden gestreamd of gedownload door NewPipe. Deze inhoud is niet beschikbaar in uw land. - De app laten crashen + App laten crashen Oplossen Deze video heeft een leeftijdsbeperking. \nVanwege nieuw YouTube-beleid over video\'s met leeftijdsbeperking, heeft NewPipe geen toegang tot zijn videostreams en kan deze dus niet afspelen. @@ -596,7 +596,7 @@ U kunt uw favoriete nachtthema hieronder selecteren Selecteer uw favoriete nachtthema — %s Automatisch (systeemthema) - Toon details van kanaal + Kanaal­details tonen Nachtthema Intern Privé @@ -614,7 +614,7 @@ Tekst selecteren in de beschrijving uitschakelen Tekst selecteren in de beschrijving inschakelen 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. - Media tunneling uitschakelen als u een zwart scherm ervaart of video hapert bij het afspelen + Schakel media-tunneling uit als u een zwart scherm ervaart of de video hapert bij het afspelen. Media tunneling uitschakelen Uit Aan @@ -630,14 +630,14 @@ Error bij het inladen van de feed Vanaf Android 10 is enkel \'Storage Access Framework\' ondersteund U wordt gevraagd waar elk bestand wordt opgeslagen - Nog geen downloadfolder gekozen, kies de standaard downloadfolder + Nog geen download­map gekozen, kies nu de standaard­download­map Geliefd door de maker Niet laten zien Lage kwaliteit (kleiner) Hoge kwaliteit (groter) Zoekbalk miniatuurafbeelding voorbeeld Toon Picasso-gekleurde linten bovenop afbeeldingen die hun bron aangeven: rood voor netwerk, blauw voor schijf en groen voor geheugen - Toon afbeeldingsindicatoren + Afbeeldings­indicatoren tonen Reacties zijn uitgeschakeld Zoeksuggesties op afstand Lokale zoeksuggesties @@ -651,14 +651,14 @@ %s downloads voltooid Volgende item in de wachtrij geplaatst - Plaats volgende item in de wachtrij + Volgende item in de wachtrij plaatsen Veeg items om ze te verwijderen Start geen video\'s in de minispeler, maar ga direct naar de volledige schermmodus, als automatisch draaien is vergrendeld. Je hebt nog steeds toegang tot de minispeler door de volledige schermmodus af te sluiten Start hoofdspeler als volledig scherm Verwerken... Dit kan even duren - Crash de speler - Toon \"crash de speler\" - Toon een crash overzicht bij gebruik van de speler + Speler crashen + ‘Speler crashen’ tonen + Toont een crash-optie bij gebruik van de speler Controleer handmatig op nieuwe versies Controleren op updates Bezig met controleren op updates… @@ -686,7 +686,7 @@ Meldingen over nieuwe streams Melding over nieuwe streams van abonnementen Frequentie van controleren - Vereiste netwerk connectie + Vereiste netwerk­verbinding Elk netwerk Meldingen zijn uitgeschakeld Meldingen @@ -715,7 +715,7 @@ Snelle modus Importeer of exporteer abonnementen vanuit het 3-punten menu U heeft de laatste versie van NewPipe - Klik om %s te downloaden + Druk om %s te downloaden Kon niet naar klembord kopiëren Deze instelling is alleen beschikbaar als %s als thema ingesteld is Kaart @@ -761,4 +761,9 @@ origineel nagesynchroniseerd beschrijvend + Secties onderaan weergeven + Positie van sectie-tabbladen + Geen streams + Geen live-streams + Media-tunneling is standaard uitgeschakeld op uw apparaat omdat uw apparaatmodel dit niet ondersteunt. \ No newline at end of file diff --git a/app/src/main/res/values-or/strings.xml b/app/src/main/res/values-or/strings.xml index f329fc44e..f01ca2843 100644 --- a/app/src/main/res/values-or/strings.xml +++ b/app/src/main/res/values-or/strings.xml @@ -181,7 +181,7 @@ ଏହି କାର୍ଯ୍ୟ ପାଇଁ କୌଣସି ଉପଯୁକ୍ତ ଫାଇଲ ପରିଚାଳକ ମିଳିଲା ନାହିଁ । \nଦୟାକରି ଏକ ଫାଇଲ୍ ମ୍ୟାନେଜର୍ ସଂସ୍ଥାପନ କରନ୍ତୁ କିମ୍ବା ଡାଉନଲୋଡ୍ ସେଟିଂସମୂହରେ \'%s\' ଅକ୍ଷମ କରିବାକୁ ଚେଷ୍ଟା କରନ୍ତୁ ଏହି ଭିଡିଓ କେବଳ ୟୁଟ୍ୟୁବ୍ ମ୍ୟୁଜିକ୍ ପ୍ରିମିୟମ୍ ସଦସ୍ୟଙ୍କ ପାଇଁ ଉପଲବ୍ଧ, ତେଣୁ ଏହାକୁ ନ୍ୟୁପାଇପ୍ ଦ୍ୱାରା ଷ୍ଟ୍ରିମ୍ କିମ୍ବା ଡାଉନଲୋଡ୍ କରାଯାଇପାରିବ ନାହିଁ । - ଲୋଡ୍ ବ୍ୟବଧାନ ଆକାର ପରିବର୍ତ୍ତନ କରନ୍ତୁ (currently %s)। ଏକ କମ୍ ମୂଲ୍ୟ ପ୍ରାରମ୍ଭିକ ଭିଡିଓ ଲୋଡିଂକୁ ତ୍ୱରାନ୍ୱିତ କରିପାରେ । ପରିବର୍ତ୍ତନଗୁଡିକ ଏକ ପ୍ଲେୟାର ପୁନଃଆରମ୍ଭ ଆବଶ୍ୟକ କରେ + ଧାରଣ ଅନ୍ତରାଳର ଆକାରକୁ ପ୍ରଗତିଶୀଳ ବିଷୟବସ୍ତୁ (ବର୍ତ୍ତମାନ %s) ରେ ପରିବର୍ତ୍ତନ କରନ୍ତୁ । ଗୋଟିଏ ନିମ୍ନମାନ ସେମାନଙ୍କର ପ୍ରାରମ୍ଭିକ ଧାରଣକୁ ତ୍ୱରାନ୍ୱିତ କରିପାରେ ଏହି କାର୍ଯ୍ୟ ପାଇଁ କୌଣସି ଉପଯୁକ୍ତ ଫାଇଲ ପରିଚାଳକ ମିଳିଲା ନାହିଁ । \nଦୟାକରି ଏକ ଷ୍ଟୋରେଜ୍ ଆକ୍ସେସ୍ ଫ୍ରେମୱାର୍କ ସୁସଙ୍ଗତ ଫାଇଲ୍ ମ୍ୟାନେଜର୍ ସଂସ୍ଥାପନ କରନ୍ତୁ ଅନ୍ତତଃ ପକ୍ଷେ ଆପଣଙ୍କ ଦେଶରେ ଏହା ଏକ ସାଉଣ୍ଡକ୍ଲାଉଡ୍ ଗୋ + ଟ୍ରାକ୍, ତେଣୁ ଏହାକୁ ନ୍ୟୁପାଇପ୍ ଦ୍ୱାରା ଷ୍ଟ୍ରିମ୍ କିମ୍ବା ଡାଉନଲୋଡ୍ କରାଯାଇପାରିବ ନାହିଁ । @@ -343,7 +343,7 @@ ମେମୋରୀ ଲିକ୍ ମନିଟରିଂ ହିପ୍ ଡମ୍ପିଂ କରିବା ସମୟରେ ଆପ୍ ପ୍ରତିକ୍ରିୟାଶୀଳ ହୋଇପାରେ ସେବାଗୁଡିକରୁ ମୂଳ ଲେଖା ଷ୍ଟ୍ରିମ୍ ଆଇଟମ୍ ଗୁଡିକରେ ଦୃଶ୍ୟମାନ ହେବ ମିଡିଆ ଟନେଲିଂକୁ ଅକ୍ଷମ କରନ୍ତୁ - ଯଦି ଆପଣ ଏକ କଳା ପରଦା ଅନୁଭବ କରନ୍ତି କିମ୍ବା ଭିଡିଓ ପ୍ଲେବେକ୍ ଉପରେ ଝୁଣ୍ଟି ପଡ଼ନ୍ତି ତେବେ ମିଡିଆ ଟନେଲିଂକୁ ଅକ୍ଷମ କରନ୍ତୁ + ଯଦି ଆପଣ ଏକ କଳା ପରଦା ଅନୁଭବ କରନ୍ତି କିମ୍ବା ଭିଡିଓ ପ୍ଲେବେକ୍ ଉପରେ ଝୁଣ୍ଟି ପଡ଼ନ୍ତି ତେବେ ମିଡିଆ ଟନେଲିଂକୁ ଅକ୍ଷମ କରନ୍ତୁ । ଚିତ୍ରଗୁଡ଼ିକର ଉପରେ ପିକାସୋ ରଙ୍ଗୀନ ଫିତା ଦେଖାନ୍ତୁ: ସେମାନଙ୍କର ଉତ୍ସକୁ ସୂଚାଇଥାଏ: ନେଟୱାର୍କ ପାଇଁ ନାଲି, ଡିସ୍କ ପାଇଁ ନୀଳ ଏବଂ ସ୍ମୃତି ପାଇଁ ସବୁଜ ଆମଦାନି କରନ୍ତୁ ଠାରୁ ଆମଦାନୀ କରନ୍ତୁ @@ -740,4 +740,30 @@ ଉଜ୍ଜ୍ୱଳତା ଭଲ୍ୟୁମ୍ କିଛି ନୁହେଁ + ମୂଖ୍ୟ ଟ୍ୟାବ ଚୟନକର୍ତ୍ତାଙ୍କୁ ତଳ ଭାଗକୁ ଘୁଞ୍ଚାନ୍ତୁ + ମୂଖ୍ଯ ଟ୍ୟାବ ଅବସ୍ଥାନ + କିଛି ExoPlayer ବିନ୍ୟାସକୁ ପରିଚାଳନା କରନ୍ତୁ । ଏହି ପରିବର୍ତ୍ତନଗୁଡ଼ିକୁ ପ୍ରଭାବୀ ହେବା ପାଇଁ ଗୋଟିଏ ଚାଳକକୁ ପୁନଃଚାଳନ କରିବା ଆବଶ୍ୟକ + ExoPlayer ର ଡିକୋଡର୍ ଫଲବ୍ୟାକ୍ ବୈଶିଷ୍ଟ୍ୟକୁ ବ୍ୟବହାର କରନ୍ତୁ + ଯଦି ଆପଣଙ୍କର ଡିକୋଡର ପ୍ରାରମ୍ଭିକ ସମସ୍ୟା ଅଛି ତେବେ ଏହି ବିକଳ୍ପକୁ ସକ୍ରିୟ କରନ୍ତୁ, ଯାହା ପ୍ରାଥମିକ ଡିକୋଡର ପ୍ରାରମ୍ଭିକତା ବିଫଳ ହେଲେ ନିମ୍ନ ପ୍ରାଥମିକତା ଡିକୋଡରକୁ ଫେରିଥାଏ । ପ୍ରାଥମିକ ଡିକୋଡର ବ୍ୟବହାର କରିବା ସମୟରେ ଏହା ଖରାପ ପ୍ଲେବ୍ୟାକ ପ୍ରଦର୍ଶନର କାରଣ ହୋଇପାରେ + %1s ଓ %2s + ବର୍ଣ୍ଣନାତ୍ମକ + ମୂଳ + ଡବିଙ୍ଗ୍ ହୋଇଛି + ମୂଳ ଧ୍ୱନିକୁ ପସନ୍ଦ କରନ୍ତୁ + ଭାଷା ନିର୍ବିଶେଷରେ ମୂଳ ଧ୍ୱନି ଟ୍ରାକକୁ ବାଛନ୍ତୁ + ବର୍ଣ୍ଣନାମୂଳକ ଧ୍ୱନିକୁ ପସନ୍ଦ କରନ୍ତୁ + ଧ୍ୱନି: %s + ଧ୍ୱନି ଟ୍ରାକ୍ + ଏହି ଧାରାରେ ଗୋଟିଏ ଧ୍ୱନୀ ଟ୍ରାକ ପୂର୍ବରୁ ଉପସ୍ଥିତ ହେବା ଉଚିତ + ବାହ୍ୟ ଚାଳକମାନଙ୍କ ପାଇଁ ଧ୍ୱନୀ ଟ୍ରାକ ବାଛନ୍ତୁ + ଅଜଣା + ଉପଲବ୍ଧ ହେଲେ ଦୃଷ୍ଟିହୀନ ବ୍ୟକ୍ତିଙ୍କ ପାଇଁ ବର୍ଣ୍ଣନା ସହିତ ଗୋଟିଏ ଧ୍ୱନି ଟ୍ରାକ ଚୟନ କରନ୍ତୁ + ସର୍ବଦା ExoPlayer ର ଭିଡ଼ିଓ ଆଉଟପୁଟ୍ ପୃଷ୍ଠ ବିନ୍ୟାସ କାର୍ଯ୍ଯକ୍ଷେତ୍ରକୁ ବ୍ୟବହାର କରନ୍ତୁ + ଆପଣଙ୍କର ଡିଭାଇସରେ ଡିଫଲ୍ଟ ଭାବରେ ମିଡିଆ ସୁଡଙ୍ଗକୁ ନିଷ୍କ୍ରିୟ କରାଯାଇଛି କାରଣ ଆପଣଙ୍କର ଡିଭାଇସ ମଡେଲ ଏହାକୁ ସମର୍ଥନ କରୁନାହିଁ ବୋଲି ଜଣାଅଛି । + ExoPlayer ବିନ୍ୟାସଗୁଡ଼ିକ + ଏହି ୱାର୍କଆରାଉଣ୍ଡ ଭିଡିଓ କୋଡେକଗୁଡ଼ିକୁ ରିଲିଜ କରିଥାଏ ଏବଂ ପୁନଃସ୍ଥାପନ କରିଥାଏ ଯେତେବେଳେ ଗୋଟିଏ ପୃଷ୍ଠ ପରିବର୍ତ୍ତନ ହୋଇଥାଏ, ଭୂପୃଷ୍ଠକୁ ସିଧାସଳଖ କୋଡେକରେ ସେଟ କରିବା ପରିବର୍ତ୍ତେ । ଏହି ସମସ୍ୟା ସହିତ କିଛି ଉପକରଣରେ ExoPlayer ଦ୍ୱାରା ପୂର୍ବରୁ ବ୍ୟବହୃତ, ଏହି ସଂରଚନା କେବଳ ଆଣ୍ଡ୍ରଏଡ 6 ଏବଂ ଉଚ୍ଚତର ଉପରେ ପ୍ରଭାବ ପକାଇଥାଏ +\n +\nଏହି ବିକଳ୍ପକୁ ସକ୍ରିୟ କରିବା ସାମ୍ପ୍ରତିକ ଭିଡିଓ ପ୍ଲେୟାରକୁ ବଦଳାଇବା କିମ୍ବା ସମ୍ପୂର୍ଣ୍ଣ ପରଦାକୁ ପରିବର୍ତ୍ତନ କରିବା ସମୟରେ ପ୍ଲେବ୍ୟାକ ତ୍ରୁଟିକୁ ପ୍ରତିରୋଧ କରିପାରେ + କୌଣସି ସ୍ରୋତ ନାହିଁ + କୌଣସି ଲାଇଭ ଷ୍ଟ୍ରିମ୍ ନାହିଁ \ No newline at end of file diff --git a/app/src/main/res/values-pa/strings.xml b/app/src/main/res/values-pa/strings.xml index 4e67a98ae..3142f3cc5 100644 --- a/app/src/main/res/values-pa/strings.xml +++ b/app/src/main/res/values-pa/strings.xml @@ -38,7 +38,7 @@ ਆਡੀਓ ਫ਼ਾਈਲਾਂ ਲਈ ਡਾਊਨਲੋਡ ਫ਼ੋਲਡਰ ਚੁਣੋ ਡਿਫ਼ਾਲਟ ਰੈਜ਼ੋਲਿਊਸ਼ਨ ਪੌਪ-ਅਪ ਲਈ ਡਿਫ਼ਾਲਟ ਰੈਜ਼ੋਲਿਊਸ਼ਨ - ਵੱਡੀਆਂ ਰੈਜ਼ੋਲਿਊਸ਼ਨਜ਼ ਦਿਖਾਓ + ਉੱਚੀਆਂ ਰੈਜ਼ੋਲਿਊਸ਼ਨਾਂ ਵਿਖਾਓ ਸਿਰਫ਼ ਕੁਝ ਹੀ ਡਿਵਾਈਸ 2K/4K ਵੀਡੀਓ ਨੂੰ ਚਲਾ ਸਕਦੇ ਹਨ Kodi ਵਿੱਚ ਚਲਾਓ Kodi ਐਪ ਇੰਸਟਾਲ ਨਹੀਂ ਹੈ\? @@ -271,7 +271,7 @@ ਜ਼ੂਮ ਆਪਣੇ-ਆਪ ਬਣੀ ਸਿਰਲੇਖ - ਪਲੇਅਰ ਕੈਪਸ਼ਨ, ਟੈਕਸਟ ਸਕੇਲ ਅਤੇ ਬੈਕਗ੍ਰਾਊਂਡ ਸਟਾਈਲ ਨੂੰ ਬਦਲੋ। ਪ੍ਰਭਾਵ ਨੂੰ ਲਾਗੂ ਕਰਨ ਲਈ ਐਪ ਨੂੰ ਮੁੜ ਚਾਲੂ ਕਰਨ ਦੀ ਜ਼ਰੂਰਤ ਹੈ + ਪਲੇਅਰ ਕੈਪਸ਼ਨ, ਟੈਕਸਟ ਸਕੇਲ ਅਤੇ ਬੈਕਗ੍ਰਾਊਂਡ ਸਟਾਈਲ ਨੂੰ ਬਦਲੋ। ਪ੍ਰਭਾਵੀ ਕਰਨ ਲਈ ਐਪ ਨੂੰ ਮੁੜ ਚਾਲੂ ਕਰਨ ਦੀ ਜ਼ਰੂਰਤ ਹੈ ਮੈਮੋਰੀ ਲੀਕ ਨਿਗਰਾਨੀ, ਐਪ ਨੂੰ ਆਕ੍ਰਿਆਸ਼ੀਲ ਬਣਾ ਸਕਦੀ ਹੈ ਜਦੋਂ ਹੀਪ ਡੰਪਿੰਗ ਹੁੰਦੀ ਹੈ ਚੱਕਰ ਤੋਂ ਬਾਹਰ ਤਰੁੱਟੀਆਂ ਰਿਪੋਰਟ ਕਰੋ ਨਿਪਟਾਰੇ ਦੇ ਬਾਅਦ ਫਰੈਗਮੈਂਟ ਜਾਂ ਐਕਟੀਵਿਟੀ ਦੇ ਚੱਕਰ ਤੋਂ ਬਾਹਰ ਨਾ ਪਹੁੰਚਾਉਣ ਯੋਗ ਆਰ-ਐਕਸ ਅਪਵਾਦਾਂ ਬਾਰੇ ਜ਼ਬਰੀ ਰਿਪੋਰਟ ਕਰਨਾ @@ -345,7 +345,7 @@ ਸਬਸਕ੍ਰਾਈਬਰਾਂ ਦੀ ਗਿਣਤੀ ਅਣ-ਉਪਲਬਧ ਮੁੱਖ ਪੰਨੇ ਤੇ ਕਿਹੜੇ ਟੈਬ ਵਿਖਾਏ ਜਾਣਗੇ ਅਪਡੇਟਾਂ - ਜਦੋਂ ਨਵਾਂ ਸੰਸਕਰਣ ਉਪਲਬਧ ਹੁੰਦਾ ਹੈ ਤਾਂ ਐਪ ਅਪਡੇਟ ਨੂੰ ਪੁੱਛਣ ਲਈ ਇੱਕ ਨੋਟੀਫਿਕੇਸ਼ਨ ਦਿਖਾਓ + ਜਦੋਂ ਨਵਾਂ ਸੰਸਕਰਣ ਉਪਲਬਧ ਹੁੰਦਾ ਹੈ ਤਾਂ ਐਪ ਅੱਪਡੇਟ ਕਰਨ ਨੂੰ ਪੁੱਛਣ ਲਈ ਇੱਕ ਨੋਟੀਫਿਕੇਸ਼ਨ ਵਿਖਾਓ ਲਿਸਟ ਵਿਊ ਮੋਡ ਲਿਸਟ ਗਰਿੱਡ @@ -379,7 +379,7 @@ ਮੋਬਾਈਲ ਡਾਟਾ ਤੇ ਸਵਿੱਚ ਕਰਨ ਵੇਲੇ ਲਾਭਦਾਇਕ ਹੈ, ਹਾਲਾਂਕਿ ਕੁਝ ਡਾਉਨਲੋਡਾਂ ਨੂੰ ਮੁਅੱਤਲ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ ਇਵੇੰਟਸ ਕਾਨਫਰੰਸਾਂ - ਟਿੱਪਣੀਆਂ ਦਿਖਾਓ + ਟਿੱਪਣੀਆਂ ਵਿਖਾਓ ਟਿੱਪਣੀਆਂ ਲੁਕਾਉਣ ਲਈ ਇਸਨੂੰ ਬੰਦ ਕਰੋ ਆਟੋ-ਪਲੇਅ ਕੋਈ ਟਿੱਪਣੀ ਨਹੀਂ ਕੀਤੀ ਗਈ @@ -388,7 +388,7 @@ ਪਲੇਅਬੈਕ ਫਿਰ ਚਾਲੂ ਕਰੋ ਪਿਛਲੀ ਪਲੇਅਬੈਕ ਸਥਿਤੀ ਤੋਂ ਮੁੜ ਚਲਾਓ ਸੂਚੀਆਂ ਦੀ ਸਥਿਤੀ - ਸੂਚੀਆਂ ਵਿੱਚ ਪਲੇਅਬੈਕ ਸਥਿਤੀ ਸੂਚਕ ਦਿਖਾਓ + ਸੂਚੀਆਂ ਵਿੱਚ ਪਲੇਅਬੈਕ ਸਥਿਤੀ ਸੂਚਕ ਵਿਖਾਓ ਡਾਟਾ ਮਿਟਾਓ ਵੇਖੀਆਂ ਸਟ੍ਰੀਮਾਂ ਦੀ ਇਤਿਹਾਸ ਸੂਚੀ ਨੂੰ ਮਿਟਾ ਦਿੱਤਾ ਗਿਆ ਪਲੇਬੈਕ ਸਥਿਤੀਆਂ ਨੂੰ ਮਿਟਾ ਦਿੱਤਾ ਗਿਆ ਹੈ @@ -454,7 +454,7 @@ ਵਰਗ ਵੇਰਵੇ \'ਚੋਂ ਲਿਖਤ ਚੁਣਨਾ ਬੰਦ ਕਰੋ ਵੇਰਵੇ \'ਚੋਂ ਲਿਖਤ ਚੁਣਨਾ ਚਾਲੂ ਕਰੋ - ਤੁਸੀਂ ਹੁਣ ਵੇਰਵੇ \'ਚੋਂ ਲਿਖਤ ਨੂੰ ਚੁਣ ਸਕਦੇ ਹੋ। ਧਿਆਦੇ ਦਿਓ ਕਿ ਲਿਖਤ ਸਲੈਕਟ ਮੋਡ ਵਿੱਚ ਪੰਨਾ ਜਗ-ਬੁੱਝ ਸਕਦਾ ਹੈ ਅਤੇ ਲਿੰਕ ਵੀ ਕਲਿਕ ਕਰਨ ਯੋਗ ਨਹੀਂ ਹੋਣਗੇ। + ਤੁਸੀਂ ਹੁਣ ਵੇਰਵੇ \'ਚੋਂ ਲਿਖਤ ਨੂੰ ਚੁਣ ਸਕਦੇ ਹੋ। ਨੋਟ ਕਰੋ ਕਿ ਪੰਨਾ ਜਗ-ਬੁੱਝ ਸਕਦਾ ਹੈ ਅਤੇ ਚੋਣ ਮੋਡ ਵਿੱਚ ਹੋਣ ਵੇਲੇ ਲਿੰਕ ਕਲਿੱਕ ਕਰਨ ਯੋਗ ਨਹੀਂ ਹੋ ਸਕਦੇ ਹਨ। ਡਾਊਨਲੋਡ ਸ਼ੁਰੂ ਹੋ ਗਿਐ ਤੁਸੀਂ ਆਪਣੀ ਪਸੰਦੀਦਾ ਰਾਤ ਦੀ ਥੀਮ ਹੇਠਾਂ ਚੁਣ ਸਕਦੇ ਹੋ ਆਪਣੀ ਪਸੰਦੀਦਾ ਰਾਤ ਦੀ ਥੀਮ ਚੁਣੋ — %s @@ -592,14 +592,14 @@ URL ਪਛਾਣ ਨਹੀਂ ਹੋਇਆ। ਕਿਸੇ ਹੋਰ ਐਪ ਨਾਲ਼ ਖੋਲ੍ਹਣਾ ਹੈ\? ਆਟੋ ਕਤਾਰਬੱਧ ਕਰੋ ਸਟ੍ਰੀਮ ਦੇ ਕਰਤਾ, ਸਮੱਗਰੀ ਜਾਂ ਖੋਜ ਬੇਨਤੀ ਵਾਲੇ ਵਾਧੂ ਜਾਣਕਾਰੀ ਬਕਸਿਆਂ ਵਾਲ਼ੀ ਮੈਟਾ ਜਾਣਕਾਰੀ ਲੁਕਾਉਣ ਲਈ ਇਸਨੂੰ ਬੰਦ ਕਰ ਦਿਓ - ਮੈਟਾ ਜਾਣਕਾਰੀ ਦਿਖਾਓ + ਮੈਟਾ ਜਾਣਕਾਰੀ ਵਿਖਾਓ ਵੀਡੀਓ ਵੇਰਵਾ ਅਤੇ ਵਾਧੂ ਜਾਣਕਾਰੀ ਲੁਕਾਉਣ ਲਈ ਇਸਨੂੰ ਬੰਦ ਕਰੋ - ਵੇਰਵਾ ਦਿਖਾਓ + ਵੇਰਵਾ ਵਿਖਾਓ ਸਰਗਰਮ ਪਲੇਅਰ ਕਤਾਰ ਬਦਲ ਜਾਵੇਗੀ ਪਲੇਅਰ ਬਦਲਣ ਨਾਲ ਤੁਹਾਡੀ ਕਤਾਰ ਬਦਲ ਸਕਦੀ ਹੈ ਕਤਾਰ ਨੂੰ ਖ਼ਾਲੀ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ ਤਸਦੀਕ ਕਰਨ ਲਈ ਪੁੱਛੋ ਅੱਗੇ ਲੰਘਾਉਣ/ਪਿੱਛੇ ਕਰਨ ਦੀ ਸਮਾਂ ਮਿਆਦ - ਰਾਤ ਵਾਲੀ ਥੀਮ + ਰਾਤਰੀ ਥੀਮ ਐਂਡਰਾਇਡ ਨੂੰ ਥੰਮਨੇਲ ਦੇ ਮੁੱਖ ਰੰਗ ਮੁਤਾਬਕ ਇਲਤਾਹ ਦਾ ਰੰਗ ਬਦਲਣ ਦਿਓ (ਧਿਆਨ ਦਿਓ ਕਿ ਇਹ ਹਰੇਕ ਡਿਵਾਈਸ \'ਤੇ ਉਪਲਬਧ ਨਹੀਂ ਹੈ) ਰੰਗਦਾਰ ਨੋਟੀਫਿਕੇਸ਼ਨ ਕੁਝ ਵੀ ਨਹੀਂ @@ -631,7 +631,7 @@ ਇੱਕ ਖਾਮੀ ਪ੍ਰਭਾਵੀ ਹੋਈ ਹੈ, ਨੋਟੀਫੀਕੇਸ਼ਨ ਵੇਖੋ ਆਈਟਮਾਂ ਨੂੰ ਇੱਕ ਪਾਸੇ ਖਿੱਚ ਕੇ ਹਟਾਓ ਦ੍ਰਿਸ਼ ਸੂਚਕ ਵਿਖਾਓ - ਵਿਖਾਊ ਪਿਕਾਸੋ ਦੇ ਰੰਗਦਾਰ ਰੀਬਨ ਦ੍ਰਿਸ਼ਾਂ ਦੇ ਉੱਪਰ ਉਹਨਾਂ ਦੀ ਸਰੋਤ-ਪਛਾਣ ਅਨੁਸਾਰ: ਨੈੱਟਵਰਕ ਲਈ ਲਾਲ, ਡਿਸਕ ਲਈ ਨੀਲਾ ਤੇ ਮੈਮਰੀ ਲਈ ਹਰਾ + ਦ੍ਰਿਸ਼ਾਂ ਦੇ ਉੱਪਰ ਉਹਨਾਂ ਦੀ ਸਰੋਤ-ਪਛਾਣ ਲਈ ਪਿਕਾਸੋ ਦੇ ਰੰਗਦਾਰ ਰਿਬਨ ਵਿਖਾਓ : ਨੈੱਟਵਰਕ ਲਈ ਲਾਲ, ਡਿਸਕ ਲਈ ਨੀਲੇ ਤੇ ਮੈਮਰੀ ਲਈ ਹਰੇ ਨਵੀਂ ਸਟ੍ਰੀਮ ਦੇ ਨੋਟੀਫਿਕੇਸ਼ਨ ਪਿੰਨ ਕੀਤੀ ਟਿੱਪਣੀ ਅੱਪਡੇਟ ਦੀ ਉਪਲੱਬਧਤਾ ਪਰਖੀ ਜਾ ਰਹੀ… @@ -645,8 +645,8 @@ ਮੁੱਖ ਪਲੇਅਰ ਪੂਰੀ ਸਕਰੀਨ ਵਿੱਚ ਸ਼ੁਰੂ ਕਰੋ ਪਲੇਅਬੈਕ ਲੋਡ ਦਾ ਅੰਤਰਾਲ ਆਕਾਰ - %s ਨਵੀਂ ਸਟਰੀਮ - %s ਨਵੀਆਂ ਸਟਰੀਮਾਂ + %s ਨਵੀਂ ਸਟ੍ਰੀਮ + %s ਨਵੀਆਂ ਸਟ੍ਰੀਮਾਂ ਨਵੀਂਆ ਫੀਡ ਇਕਾਈਆਂ ਸੂਚਨਾ ਪ੍ਰਾਪਤ ਕਰੋ @@ -656,13 +656,13 @@ ਟਿੱਪਣੀਆਂ ਬੰਦ ਕੀਤੀਆਂ ਹੋਈਆਂ ਹਨ ਲੀਕ-ਕੈਨਰੀ ਉਪਲੱਬਧ ਨਹੀਂ ਹੈ ਤਰੁੱਟੀ ਤੇ ਸਨੈਕਬਾਰ ਵਿਖਾਓ - ਕੁਝ ਸੇਵਾਵਾਂ ਵਿੱਚ ਹੀ ਉਪਲੱਬਧ ਇਹ ਤਰੀਕਾ ਸਬਸਕ੍ਰਿਪਸ਼ਨ ਫੀਡ ਵਿੱਚ ਤੇਜ ਜਾਣਕਾਰੀ ਮੁਹੱਈਆ ਕਰਵਾਉਂਦਾ ਹੈ, ਪਰ ਕੁਝ ਗਿਣਤੀ ਦੀਆਂ ਹੀ ਆਈਟਮ ਪ੍ਰਦਾਨ ਕਰ ਸਕਦਾ ਹੈ ਉਹ ਵੀ ਅਕਸਰ ਬਿਨਾਂ ਪੂਰੀ ਜਾਣਕਾਰੀ( ਜਿਵੇਂ ਅਵਧੀ, ਸਟਰੀਮ ਦੀ ਕਿਸਮ, ਕੋਈ ਸਟਰੀਮ ਲਾਈਵ ਹੈ, ਨਹੀਂ ਦੱਸਦਾ) + ਕੁਝ ਸੇਵਾਵਾਂ ਵਿੱਚ ਹੀ ਉਪਲੱਬਧ ਇਹ ਤਰੀਕਾ ਸਬਸਕ੍ਰਿਪਸ਼ਨ ਫੀਡ ਵਿੱਚ ਤੇਜ ਜਾਣਕਾਰੀ ਮੁਹੱਈਆ ਕਰਵਾਉਂਦਾ ਹੈ, ਪਰ ਕੁਝ ਗਿਣਤੀ ਦੀਆਂ ਹੀ ਆਈਟਮ ਪ੍ਰਦਾਨ ਕਰ ਸਕਦਾ ਹੈ ਉਹ ਵੀ ਅਕਸਰ ਬਿਨਾਂ ਪੂਰੀ ਜਾਣਕਾਰੀ( ਜਿਵੇਂ ਅਵਧੀ, ਸਟ੍ਰੀਮ ਦੀ ਕਿਸਮ, ਕੋਈ ਸਟ੍ਰੀਮ ਲਾਈਵ ਹੈ, ਨਹੀਂ ਦੱਸਦਾ) ਇਹ ਸਾਊਂਡਕਲਾਊਡ ਗੋ-ਪਲੱਸ ਟਰੈਕ ਹੈ, ਤੁਹਾਡੇ ਦੇਸ਼ ਵਿੱਚ ਇਹ ਸਟ੍ਰੀਮ ਜਾਂ ਡਾਊਨਲੋਡ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ। ਅਗਿਆਤ ਫਾਰਮੈਟ ਅਗਿਆਤ ਕੁਆਲਿਟੀ ਆਮ ਸਵਾਲ ਵੈੱਬਸਾਈਟ \'ਤੇ ਵੇਖੋ - ਸਟਰੀਮ ਲੋਡ ਹੋ ਰਹੀ ਹੈ… + ਸਟ੍ਰੀਮ ਲੋਡ ਹੋ ਰਹੀ ਹੈ… ਕਾਰਵਾਈ ਵਿੱਚ... ਕੁਝ ਸਮਾਂ ਲੱਗ ਰਿਹਾ ਹੈ \"ਪਲੇਅਰ ਕਰੈਸ਼ ਕਰੋ\" ਵਿਖਾਉ ਵਰਤਦੇ ਸਮੇਂ ਪਲੇਅਰ ਕਰੈਸ਼ ਦਾ ਵਿਕਲਪ ਵਿਖਾਉਂਦਾ ਹੈ @@ -686,9 +686,9 @@ ਟੈਬਲੇਟ ਮੋਡ ਨੋਟੀਫਿਕੇਸ਼ਨ ਬੰਦ ਕੀਤੇ ਹੋਏ ਹਨ ਸਭ ਨੂੰ ਟੌਗਲ ਕਰੋ - ਚੁਣੀ ਸਟਰੀਮ ਬਾਹਰੀ ਪਲੇਅਰਾਂ ਲਈ ਸਹਿਯੋਗੀ ਨਹੀਂ ਹੈ - ਜਿਹੜੀਆਂ ਸਟਰੀਮਾਂ ਨੂੰ ਹਾਲੇ ਐਪ ਡਾਊਨਲੋਡ ਸਮਰਥਨ ਨਹੀਂ ਕਰਦੀ ਉਹ ਛੁਪਾ ਦਿੱਤੀਆਂ ਹਨ - ਕੋਈ ਆਡੀਓ ਸਟਰੀਮ ਬਾਹਰੀ ਪਲੇਅਰਾਂ ਲਈ ਉਪਲੱਬਧ ਨਹੀਂ ਹੈ + ਚੁਣੀ ਗਈ ਸਟ੍ਰੀਮ ਬਾਹਰੀ ਪਲੇਅਰਾਂ ਲਈ ਸਹਿਯੋਗੀ ਨਹੀਂ ਹੈ + ਜਿਹੜੀਆਂ ਸਟ੍ਰੀਮਾਂ ਦਾ ਹਾਲੇ ਐਪ ਡਾਊਨਲੋਡ ਸਮਰਥਨ ਨਹੀਂ ਕਰਦੀ ਉਹ ਛੁਪਾ ਦਿੱਤੀਆਂ ਗਈਆਂ ਹਨ + ਕੋਈ ਆਡੀਓ ਸਟ੍ਰੀਮ ਬਾਹਰੀ ਪਲੇਅਰਾਂ ਲਈ ਉਪਲੱਬਧ ਨਹੀਂ ਹੈ ਲੜੀਬੱਧ ਕਰੋ ਪਲੇਅਰ ਕਰੈਸ਼ ਕਰੋ ਵੀਡੀਓ ਮਿੰਨੀ ਪਲੇਅਰ ਚਲਾਉਣ ਦੀ ਵਜਾਏ ਪੂਰੇ ਸਕਰੀਨ ਵਿੱਚ ਚਲਾਉਂਦਾ ਹੈ। ਜੇ ਆਟੋ-ਰੋਟੇਸ਼ਨ ਲਾਕ ਹੈ ਮੇਨ-ਪਲੇਅਰ ਤੋਂ ਬਾਹਰ ਆਕੇ ਤੇ ਮਿੰਨੀ-ਪਲੇਅਰ ਤੱਕ ਰਸਾਈ ਹਾਸਿਲ ਕੀਤੀ ਜਾ ਸਕਦੀ ਹੈ @@ -700,7 +700,7 @@ ਇਸ ਕਾਰਜ ਲਈ ਕੋਈ ਢੁਕਵਾਂ ਫਾਈਲ ਮੈਨੇਜਰ ਨਹੀਂ ਮਿਲਿਆ। \nਕ੍ਰਿਪਾ ਕਰਕੇ ਫਾਈਲ ਮੈਨੇਜਰ ਇੰਨਸਟਾਲ ਕਰੋ ਜਾਂ ਡਾਊਨਲੋਡ ਸੈਟਿੰਗ ਵਿੱਚ \'%s\' ਅਸਮਰੱਥ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰੋ ਤੁਸੀਂ ਇਸ ਚੈਨਲ ਨੂੰ ਸਬਸਕ੍ਰਾਈਬ ਕਰ ਲਿਆ ਹੈ - ਕੋਈ ਵੀਡੀਓ ਸਟਰੀਮ ਬਾਹਰੀ ਪਲੇਅਰਾਂ ਲਈ ਉਪਲੱਬਧ ਨਹੀਂ ਹੈ + ਕੋਈ ਵੀਡੀਓ ਸਟ੍ਰੀਮ ਬਾਹਰੀ ਪਲੇਅਰਾਂ ਲਈ ਉਪਲੱਬਧ ਨਹੀਂ ਹੈ ਐਕਸੋਪਲੇਅਰ ਡਿਫਾਲਟ ਕੀ ਤੁਹਾਨੂੰ ਲੱਗਦਾ ਹੈ ਫੀਡ ਹੌਲੀ ਲੋਡ ਹੋ ਰਹੀ ਹੈ\? ਅਜਿਹਾ ਹੈ ਤਾਂ ਤੇਜ਼ ਫੀਡ ਕ੍ਰਿਆਸ਼ੀਲ ਕਰਕੇ ਵੇਖੋ (ਤੁਸੀਂ ਇਸਨੂੰ ਸੈਟਿੰਗਾਂ ਵਿੱਚ ਜਾ ਕੇ ਜਾਂ ਹੇਠਲਾ ਬਟਨ ਦੱਬ ਕੇ ਕਰ ਸਕਦੇ ਹੋ ) \n @@ -750,7 +750,7 @@ ਜੇ ਉਪਲਬਧ ਹੋਵੇ ਤਾਂ ਦ੍ਰਿਸ਼ਟੀ ਤੋਂ ਅਪੰਗ ਲੋਕਾਂ ਵਾਸਤੇ ਵਰਣਨਾਂ ਵਾਲਾ ਕੋਈ ਆਡੀਓ ਟਰੈਕ ਚੁਣੋ ਆਡੀਓ: %s ਆਡੀਓ ਟਰੈਕ - ਇੱਕ ਆਡੀਓ ਟਰੈਕ ਇਸ ਸਟਰੀਮ ਵਿੱਚ ਪਹਿਲਾਂ ਹੀ ਮੌਜੂਦ ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ + ਇੱਕ ਆਡੀਓ ਟਰੈਕ ਇਸ ਸਟ੍ਰੀਮ ਵਿੱਚ ਪਹਿਲਾਂ ਹੀ ਮੌਜੂਦ ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ ਬਾਹਰੀ ਪਲੇਅਰਾਂ ਲਈ ਆਡੀਓ ਟਰੈਕ ਚੁਣੋ ਅਗਿਆਤ ਐਕਸੋਪਲੇਅਰ ਸੈਟਿੰਗ @@ -764,4 +764,6 @@ ਮੁੱਖ ਟੈਬ ਸਿਲੈਕਟਰ ਨੂੰ ਹੇਠਾਂ ਲੈ ਜਾਓ %1s %2s ਮੀਡੀਆ ਟਨਲਿੰਗ ਤੁਹਾਡੀ ਡਿਵਾਈਸ \'ਤੇ ਡਿਫ਼ਾਲਟ ਤੌਰ \'ਤੇ ਅਸਮਰੱਥ ਕੀਤੀ ਗਈ ਸੀ ਕਿਉਂਕਿ ਤੁਹਾਡੀ ਡਿਵਾਈਸ ਮਾਡਲ ਇਸਦਾ ਸਮਰਥਨ ਨਹੀਂ ਕਰਨ ਲਈ ਜਾਣਿਆ ਜਾਂਦਾ ਹੈ। + ਕੋਈ ਸਟ੍ਰੀਮ ਨਹੀਂ + ਕੋਈ ਲਾਈਵ ਸਟ੍ਰੀਮ ਨਹੀਂ \ No newline at end of file diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 6c6b1bf3f..ab810cd6d 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -785,4 +785,6 @@ Przenieś selektor kart głównych na dół Pozycja kart głównych Tunelowanie multimediów zostało domyślnie wyłączone na Twoim urządzeniu, ponieważ wiadomo, że model Twojego urządzenia go nie obsługuje + Brak strumieni + Brak transmisji na żywo \ No newline at end of file diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 9dd784353..c575dcfba 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -606,9 +606,9 @@ Você pode selecionar seu tema noturno favorito abaixo Selecione seu tema noturno favorito — %s Automático (tema do dispositivo) - Tema Noturno + Tema noturno Mostrar detalhes do canal - Desative o tunelamento de mídia se aparecer uma tela preta ou se tiver engasgos durante a reprodução do vídeo + Desative o tunelamento de mídia se aparecer uma tela preta ou se tiver engasgos durante a reprodução do vídeo. Desativar tunelamento de mídia Interno Privado @@ -776,4 +776,7 @@ Habilite essa opção se você tiver problemas de inicialização do decodificador, que retorna codificadores de baixa prioridade se o decodificador primário falhar. Isso pode resultar em pior desempenho de reprodução Mova o seletor da aba principal para a parte inferior Posição das abas principais + Nenhuma transmissão + Nenhuma transmissão ao vivo + O tunelamento de mídia foi desabilitado por padrão em seu dispositivo porque seu modelo é conhecido por não suportá-lo. \ No newline at end of file diff --git a/app/src/main/res/values-pt-rPT/strings.xml b/app/src/main/res/values-pt-rPT/strings.xml index 57d1d2a44..62a551ef1 100644 --- a/app/src/main/res/values-pt-rPT/strings.xml +++ b/app/src/main/res/values-pt-rPT/strings.xml @@ -608,7 +608,7 @@ Automático (Tema do dispositivo) Tema escuro Mostrar detalhes do canal - Desative esta opção se estiverem a ocorrer erros de ecrã escuro ou paragens durante a reprodução + Desactive o túnel multimédia se tiver um ecrã preto ou gaguejo na reprodução de vídeo. Desativar túnel multimédia Desligado Ligado @@ -776,4 +776,5 @@ %1s %2s Mova o seletor da guia principal para a parte inferior Posição das guias principais + O túnel multimédia foi desativado por predefinição no seu dispositivo porque se sabe que o modelo do dispositivo não o suporta. \ No newline at end of file diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index 8340e25d6..81888a03f 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -1,7 +1,7 @@ Publicado em %1$s - Não tem um reprodutor de vídeo. Instalar o VLC\? + Reprodutor de vídeo não encontrado. Instalar VLC\? Instalar Cancelar Abrir no navegador @@ -13,7 +13,7 @@ Partilhar com Utilizar reprodutor de vídeo externo Utilizar reprodutor de áudio externo - Pasta para os ficheiros de vídeo + Pasta para ficheiros de vídeo Os ficheiros de vídeo descarregados serão guardados aqui Escolha a pasta para colocar os ficheiros de vídeo Resolução padrão @@ -199,11 +199,11 @@ Criar Mudar nome Doar - Não foi encontrado um reprodutor (pode instalar o VLC para reproduzir). + Reprodutor de vídeo não encontrado (pode instalar VLC para o efeito). Descarregar ficheiro de vídeo Adicionar a Utilizar pesquisa rápida - A pesquisa inexata permite que esta seja mais rápida, mas reduz a precisão. Procurar por 5, 15 ou 25 segundos não funciona corretamente + Este tipo de pesquisa e mais rápida mas reduz a precisão. Procurar por 5, 15 ou 25 segundos não funciona corretamente Carregar miniaturas Desative para parar o carregamento de miniaturas, poupar dados e utilização da memória. As alterações limpam a cache de imagens do disco e da memória Cache de imagens limpa @@ -547,7 +547,7 @@ Terceiro botão de ação Segundo botão de ação Primeiro botão de ação - Ajustar miniatura de vídeo mostrada na notificação de 16:9 para 1:1 (pode introduzir distorções) + Ajustar miniatura de vídeo mostrada na notificação de 16:9 para 1:1 Cortar miniatura na proporção 1:1 Iniciar reprodução automaticamente — %s Reproduzir fila @@ -561,7 +561,7 @@ Nada Mudar de um reprodutor para outro pode substituir a sua fila Pedir confirmação antes de limpar uma fila - Edite cada ação de notificação abaixo tocando nela. Selecione até três delas para serem mostrados na notificação compacta a usar as caixas de seleção à direita + Edite cada ação de notificação abaixo com um toque. Selecione até três para serem mostradas na notificação compacta utilizando as caixas de seleção à direita Pode selecionar, no máximo, três ações para mostrar na notificação compacta! Repetir Quinto botão de ação @@ -573,7 +573,7 @@ Limpar cookies reCAPTCHA O YouTube fornece um \"Modo restrito\" que oculta o conteúdo destinado a adultos Mostrar conteúdo possivelmente impróprio para crianças porque tem um limite de idade (como 18+) - Fazer com que o Android personalize a cor da notificação conforme a cor principal na miniatura (esta opção não está disponível em todos os dispositivos) + Personalizar a cor da notificação conforme a cor principal na miniatura (esta opção não está disponível em todos os dispositivos) Colorir notificação Usar miniaturas no fundo do ecrã de bloqueio e em notificações Mostrar miniatura @@ -608,7 +608,7 @@ Automático (Tema do dispositivo) Tema escuro Mostrar detalhes do canal - Desative esta opção se estiverem a ocorrer erros de ecrã escuro ou paragens durante a reprodução + Desative o túnel multimédia se tiver um ecrã preto ou gaguejo na reprodução de vídeo. Desativar túnel multimédia Sempre que descarregar um ficheiro, terá que indicar o local para o guardar Ainda não foi definida uma pasta de descarregamento, escolha agora a pasta de descarregamento padrão @@ -776,4 +776,7 @@ descritivo Mova o seletor da guia principal para a parte inferior Posição das guias principais + O túnel multimédia foi desativado por predefinição no seu dispositivo porque se sabe que o modelo do dispositivo não o suporta. + Nenhum vídeo em direto + Nenhum vídeo \ No newline at end of file diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 3cd056859..72e64691c 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -39,7 +39,7 @@ Светлая Ошибка сети Папка для скачанного аудио - Папка для скачанного аудио + Загруженные аудиофайлы хранятся здесь Введите путь к папке для скачивания аудио Нажмите на лупу, чтобы начать. Подождите… @@ -345,7 +345,7 @@ При переключении со встроенного плеера на другое приложение — %s Ничего не делать Фоновый плеер - Плеер в окне + Свернуть в плеер в окне Вид списка Список Сетка @@ -616,7 +616,7 @@ Популярное Решить Подробно о канале - Отключите туннелирование медиа, если видите чёрный экран или видео воспроизводится рывками + Отключите туннелирование медиа, если видите чёрный экран или видео воспроизводится рывками. Отключить туннелирование медиа Теперь вы можете выделить текст внутри описания. В режиме выделения страница может мерцать, ссылки могут быть неактивны. Поддержка @@ -686,7 +686,7 @@ Новые видео Уведомления о новых видео в подписках Частота проверки - Новые видео + Уведомления о новых видео Уведомлять о новых видео в подписках Тип подключения Любая сеть @@ -778,4 +778,9 @@ Этот обходной путь освобождает и повторно создаёт видеокодеки при изменении поверхности вместо того, чтобы напрямую устанавливать поверхность для кодека. Уже используется ExoPlayer на некоторых устройствах с этой проблемой, этот параметр влияет только на устройства с Android 6 и выше \n \nВключение этого параметра может предотвратить ошибки воспроизведения при переключении текущего видеоплеера или переключении в полноэкранный режим + Переместить основные вкладки в нижнюю часть экрана + Положение основных вкладок + Нет стримов + Нет прямых трансляций + Медиа-туннелирование на вашем устройстве отключено по умолчанию, поскольку известно, что ваша модель устройства его не поддерживает. \ No newline at end of file diff --git a/app/src/main/res/values-ryu/strings.xml b/app/src/main/res/values-ryu/strings.xml index d39a5fabb..30ef993b8 100644 --- a/app/src/main/res/values-ryu/strings.xml +++ b/app/src/main/res/values-ryu/strings.xml @@ -412,6 +412,7 @@ まじりぬさいせいいちさちゅるじょさびーが\? サービスぬきりけーい、ぎんじぇーぬしんたく: + %sふんぬちゃーしが %sふんぬちゃーしが デフォルトぬKiosk @@ -422,6 +423,7 @@ たーんちちゃびらん + %sんかいんがちょうしゅちゅう %sんかいんがちょうしゅちゅう アプリさいきちゃーしーねー、ぎんぐがへいるかんさりやびーん @@ -450,18 +452,22 @@ かんりょう ちゃーしが + %dびょう %dびょう ExoPlayerぬゆいてぃがろーくぬたみシークかんかこー%dびょうんかいしっていさりやびたん ミュート ミュートかいじょ + %dふん %dふん + %dじがん %dじがん + %dんかいち %dんかいち チャンネルグループ @@ -472,6 +478,7 @@ チャンネルしんたく チャンネルがせんたくされていません + %dさんたくちゅう %dさんたくちゅう グループみいがからやいびーん @@ -591,7 +598,7 @@ チャンネルぬしーょうさいひょうじ ラジオ うすすみ - ビデオさいゆいがとぅまたいでぃねーんばあえーメディアトンネリングんーかがしみそーれー + ビデオさいゆいがとぅまたいでぃねーんばあえーメディアトンネリングんーかがしみそーれー。 マルチメディアトンネリングんーかなすん かんかい ぎんてぃかんかい @@ -636,9 +643,11 @@ ちょくしちフルスクリーンモードんかいきりけーてぃ、ミニプレイヤーっしちゃーがかいしさびらん。じどーでぃんうぅてぃんがロックさりとーーあいやてぃん、フルスクリーンしーゅうりょうするくとぅでぃミニプレイヤーんかいアクセスなやびーん プレイヤーフルスクリーンっしかいし + %1$sちぬダウンロードさちゅるじょさびたん %1$sちぬダウンロードさちゅるじょさびたん + %sちぬダウンロードぬかんりょうさびたん %sちぬダウンロードぬかんりょうさびたん ピカソー、がぞうぬういに、がぞうくとぅどぅくるしーきびちするしきさいきしーょうひょうじさびーん: あかーネットワーク、あおーディスク、みどぅれーメモリ @@ -681,6 +690,7 @@ かんどぅちゅるチャンネルぬみーさるストリームんかいかんすんちうち みーさるストリームぬちうち + %sきんぬみーさるストリーム %sきんぬみーさるストリーム みーさるストリーム @@ -736,4 +746,24 @@ メインタブぬばしょ ゆみくみかんかくへいるかんさびーん。(ぎんじぇー %s)くぬあたいくーくしーねーさいせいかいしまでぃぬじがんがいんちゃくなやびーん。へんかんてぃきようすんがーさいきちゃーがふぃちようやいびーん りようかのうなばあいんかいしかくしょうがいしゃむきのおんせいかいしちトラックさんたくすん + オーディオ:%s + オーディオトラック + やしがいぶプレイヤーようぬオーディオトラックしんたく + ふめいうぅい + ExoPlayer しってい + オーディオトラックーしでぃにくぬししらぎんかいすんじぇーそーるふぃちようがあいびーん + うちかいぬデバイスぬモデルっしぇーメディアトンネリングぬサポートさりてぃうぅらんたみ、くぬデバイスっしぇーメディアトンネリングぬデフォルトっしんーかなとーいびーん。 + デコーダぬしーむんだいぬあーあえー、くぬオプションゆーいるこうかしプライマリデコーダしーょきかしっぺーじにふぃくいゆうしんどぅぬデコーダんかいフォールバックさびーん。プライマリデコーダしようじやかパフォーマンスぬあっかすがのうゆいがあいびーん + くぬかいきちさこーちょくしちコーデックサーフェスんかいしっていしーんかわりんかい、サーフェスぬへいるかんさったるさいんかいえいぞうコーデックかいほうしさいインスタンスがさびーん。しでぃにいくちがぬデバイスっしくぬかいきちさくぬささりとーいびーしが、Android 6いくてぃぬみちぬーさびーん +\n +\nくぬオプションゆーいるこうかしーんくとぅっしプレイヤーきりけーたい、フルスクリーンんかいきりけーたいしーんさいぬさいせいエラーふしじゃびーん + ふきけー + ExoPlayerぬしっていかんりさびーん。くりらぬへんかんはんえいすんがープレイヤーぬさいきちゃーがふぃちようやいびーん + ちゃーExoPlayerぬえいぞうしーゅちりょくサーフェスしっていぬかいきちさくしようすん + %1s %2s + うんせいかいしち + ExoPlayerぬデコーダフォールバックちぬーさすん + オリジナル + ストリームーあいびらん + ライブーいしのーあいびらん \ No newline at end of file diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml index 55c8d3f9b..3be801c0a 100644 --- a/app/src/main/res/values-sk/strings.xml +++ b/app/src/main/res/values-sk/strings.xml @@ -301,7 +301,7 @@ Ovládanie rýchlosti prehrávania Rýchlosť Výška - Spraviť nezavislími (môže spôsobovať skreslenie) + Spraviť nezávislými (môže spôsobovať skreslenie) Vymazať históriu pozretí Odstráni históriu a pozície prehrávaných streamov Vymazať celú históriu pozretí\? diff --git a/app/src/main/res/values-sq/strings.xml b/app/src/main/res/values-sq/strings.xml index f9929ac8d..41d9f22ad 100644 --- a/app/src/main/res/values-sq/strings.xml +++ b/app/src/main/res/values-sq/strings.xml @@ -637,4 +637,22 @@ Parapamje e pamjes miniaturë të lëvizësit të kohës Komentet janë të ç\'aktivizuara Shëno si të parë + Drita + Volumi + Njoftohu + Qualitet i panjohur + Cilidi rrjet + Kartë + Panjohur + Format i panjohur + Hiq duplikatet\? + Së shpejti + Te shikuara në plotësi + Gjysmë të shikuar + origjinal + dubluar + përshkruese + Hiq duplikatet + Modi i shpejtë + Rradhit \ No newline at end of file diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index 27575d2a0..1074ff7fd 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -631,7 +631,7 @@ Natt-tema Aviseringar för videohashningsframsteg Miniatyrbild-webbadress - Inaktivera medietunnel om du upplever en svart skärm eller stamning vid videouppspelning + Inaktivera medietunnel om du upplever en svart skärm eller att videouppspelningen hackar. Inaktivera medietunnel Hjärtmärkt av innehållsskaparen Du kan välja det natt-tema du föredrar nedan @@ -763,4 +763,7 @@ dubbad Flytta huvudflik väljaren till botten Huvudflikarnas position + Inga strömmar + Inga live-strömmar + Medietunnel har inaktiverats som standard på din enhet eftersom att enhetsmodellen inte stöder funktionen. \ No newline at end of file diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 49eb5b70c..23c55b15a 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -781,4 +781,6 @@ Перемістити селектор головної вкладки вниз Розташування основних вкладок Тунелювання медіа типово було вимкнено на вашому пристрої, оскільки ваша модель його не підтримує. + Немає трансляцій + Немає трансляцій наживо \ No newline at end of file diff --git a/app/src/main/res/values-ur/strings.xml b/app/src/main/res/values-ur/strings.xml index 29956f162..c05fc095c 100644 --- a/app/src/main/res/values-ur/strings.xml +++ b/app/src/main/res/values-ur/strings.xml @@ -56,7 +56,7 @@ بالواسطہ رسائی استعمال کریں بالواسطہ تلاش مشکلات کو کم کر کے پلیئر کو تیز رفتاری سے مقامات تک رسائی کرنے دیتی ہے۔ 5 ، 15 یا 25 سیکنڈ کی تلاش اس کے ساتھ کام نہیں کرتی ہے: نظرِ انگشتی لوڈ کریں - ڈیٹا کی بچت اور میموری کے استعمال کو روکنے کیلئے نظرِ انگشتی کو بند کریں۔ تبدیلیاں میموری اور آن ڈسک عکس کے کیشے کو صاف کرتی ہیں۔ + ڈیٹا کی بچت اور میموری کے استعمال کو روکنے کیلئے تھمب نیل کو بند کریں۔ تبدیلیاں میموری اور آن ڈسک ایمیج کیشے کو صاف کریں گی تصویری کیشے کی صفائی ہوئی کیشے میٹا ڈیٹا کو صاف کریں ویب پیج کے سبھی کیشے ڈیٹا کو ہٹا دیں @@ -73,7 +73,7 @@ مداخلت کے بعد چلانا جاری رکھیں (مثلاً فون کالز) ڈاؤن لوڈ \'اگلی\' اور \'ملتی جلتی\' ویڈیوز دکھائیں - ’’شامل کرنے کے لئے پکڑیں‘‘ اشارہ دکھائیں + ’’شامل کرنے کے لئے ہولڈ کریں‘‘ اشارہ دکھائیں ویڈیو کی \"تفصیلات:\" میں پس منظر یا پاپ اپ بٹن دبانے پر اشارے دکھائیں غیر موافق URL مشمولات کا طے شدہ ملک @@ -467,7 +467,7 @@ وہ مواد دکھائیں جو بچوں کے لیے ممکنہ طور پر نا مناسب ہیں کیوں کہ اس میں عمر کی حد ہے (جیسے 18+) URL کو نہیں پہچان سکے۔ کسی اور ایپ کے ساتھ کھولیں؟ خود کار قطار - اسٹریم کے موجد، اسٹریم مواد یا تلاش کی درخواست کے بارے میں اضافی معلومات والے میٹا انفارمیشن بکسوں کو چھپانے کیلئے بند کریں۔ + اسٹریم کے موجد، اسٹریم مواد یا تلاش کی درخواست کے بارے میں اضافی معلومات والے میٹا انفارمیشن بکسوں کو چھپانے کیلئے بند کریں میٹا معلومات دکھائیں ویڈیو کی تفصیل اور اضافی معلومات کو چھپانے کیلئے بند کریں تفصیل دکھائیں @@ -495,7 +495,7 @@ دیکھے ہوئے کو نشان لگائیں مقامی تلاش کی سفارشات اطلاعات - فل اسکرین میں مین پلیئر شروع کریں + مین پلیئر فل اسکرین میں شروع کریں خرابی کی اطلاع کا نوٹیفکیشن خرابیوں کی اطلاع کی نوٹیفیکیشنس جب ٹھیک ہو جائے تو \"Done\" دبائیں @@ -555,4 +555,7 @@ ترتیب کے لیے عنوان۔ ترتیب کی تفصیل یہاں محفوظ ہے: https://hosted.weblate.org/translate/newpipe/strings/en/\?checksum=b23a75618764df0f اگر دستیاب ہو تو بصارت سے محروم افراد کے لئے تفصیل کے ساتھ آڈیو ٹریک منتخب کریں بائیں اشارے کی کارروائی + مستقل تھمب نیل کو ان سیٹ کریں + ہارڈ ویئر میڈیا بٹن کے واقعات کو نظر انداز کریں + کار آمد، مثلاً، اگر آپ ہیڈسیٹ ٹوٹے ہوئے فزیکل بٹن کے ساتھ استعمال کر رہے ہیں \ No newline at end of file diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index d0b52df5d..871fb9c12 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -6,7 +6,7 @@ Cài vô Hủy Mở trong trình duyệt - Mở trong chế độ bật lên + Mở trong chế độ cửa sổ nổi Chia sẻ Tải về Tìm kiếm diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 788650206..2fd22fb06 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -751,4 +751,6 @@ 主标签页位置 %1s %2s 媒体隧道功能在你的设备上默认停用,因为已知你的设备型号不支持它。 + 无直播 + 无音视频流 \ No newline at end of file diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index ee28e477f..b473f8124 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -751,4 +751,6 @@ 主分頁位置 %1s %2s 因為您的裝置型號已知不支援媒體隧道,因此已預設停用。 + 無串流 + 無直播串流 \ No newline at end of file diff --git a/fastlane/metadata/android/cs/changelogs/994.txt b/fastlane/metadata/android/cs/changelogs/994.txt new file mode 100644 index 000000000..0dfedc1b1 --- /dev/null +++ b/fastlane/metadata/android/cs/changelogs/994.txt @@ -0,0 +1,15 @@ +Nové +- Podpora více zvukových stop/jazyků +- Umožňuje nastavení hlasitosti a jasu gesty na libovolné straně obrazovky +- Podpora zobrazování hlavních karet ve spodní části obrazovky + +Vylepšeno +- [Bandcamp] Zpracování skladeb za paywallem + +Opraveno +- [YouTube] Chyby 403 HTTP pro streamy +- Černý přehrávač při přepnutí do hlavního přehrávače ze zobrazení seznamu skladeb +- Únik paměti služby přehrávače +- [PeerTube] Avatary nahrávače a podkanálu byly prohozeny + +a další diff --git a/fastlane/metadata/android/ml/changelogs/64.txt b/fastlane/metadata/android/ml/changelogs/64.txt new file mode 100644 index 000000000..d35e465ff --- /dev/null +++ b/fastlane/metadata/android/ml/changelogs/64.txt @@ -0,0 +1,8 @@ +### മെച്ചപ്പെടുത്തലുകൾ +- മൊബൈൽ ഡാറ്റാ ഉപയോഗിക്കുമ്പോൾ ഉള്ള വീഡിയോ ക്വാളിറ്റി നിജപ്പെടുത്താൻ ഉള്ള ക്രമീകരണം വരുത്തി #1339 +- ഒരു സെഷനിലെ ഓർത്തിരിക്കുന്നു #1442. +- ശേഷി കുറഞ്ഞ പ്രൊസസ്സറുകൾക്കുള്ള ഡൌൺലോഡ് പെർഫോമൻസ് പുരോഗമനം വരുത്തി. +-മീഡിയ സെഷന് സപ്പോർട്ട് ലഭ്യമാക്കി (പ്രവർത്തനം ) + +### പരിഹരണങ്ങൾ +- ഡൗൺലോഡ്സ് തുറക്കുമ്പോൾ ഉള്ള ക്റാഷ് പരിഹരിച്ചു. (പരിഹാരം പുതിയ ബിൽഡിൽ ലഭ്യമാണ് ) #1441 diff --git a/fastlane/metadata/android/pt-PT/changelogs/994.txt b/fastlane/metadata/android/pt-PT/changelogs/994.txt new file mode 100644 index 000000000..289db33e0 --- /dev/null +++ b/fastlane/metadata/android/pt-PT/changelogs/994.txt @@ -0,0 +1,15 @@ +Novo +- Suporte para várias faixas de áudio/idiomas +- Permitir definir gestos de volume e brilho em qualquer lado do ecrã +- Suporte para a apresentação dos separadores principais na parte inferior do ecrã + +Melhorado +- Bandcamp] Lidar com faixas atrás do muro de pagamento + +Corrigido +- YouTube] Erros HTTP 403 para streams +- Leitor preto ao mudar para o leitor principal a partir da vista de lista de reprodução +- Fuga de memória do serviço do leitor +- PeerTube] Os avatares do carregador e do sub-canal foram trocados + +e mais diff --git a/fastlane/metadata/android/pt/changelogs/994.txt b/fastlane/metadata/android/pt/changelogs/994.txt new file mode 100644 index 000000000..289db33e0 --- /dev/null +++ b/fastlane/metadata/android/pt/changelogs/994.txt @@ -0,0 +1,15 @@ +Novo +- Suporte para várias faixas de áudio/idiomas +- Permitir definir gestos de volume e brilho em qualquer lado do ecrã +- Suporte para a apresentação dos separadores principais na parte inferior do ecrã + +Melhorado +- Bandcamp] Lidar com faixas atrás do muro de pagamento + +Corrigido +- YouTube] Erros HTTP 403 para streams +- Leitor preto ao mudar para o leitor principal a partir da vista de lista de reprodução +- Fuga de memória do serviço do leitor +- PeerTube] Os avatares do carregador e do sub-canal foram trocados + +e mais diff --git a/fastlane/metadata/android/uk/changelogs/994.txt b/fastlane/metadata/android/uk/changelogs/994.txt new file mode 100644 index 000000000..ba5c66158 --- /dev/null +++ b/fastlane/metadata/android/uk/changelogs/994.txt @@ -0,0 +1,15 @@ +Нове +• Підтримка кількох звукових доріжок/мов +• Регулювання гучності та яскравості жестами з будь-якого боку екрана +• Підтримка показу основних вкладок у нижній частині екрана + +Поліпшено +• [Bandcamp] Обробка платних доріжок + +Виправлено +• [YouTube] 403 HTTP помилки для трансляцій +• Чорний програвач під час переходу до головного програвача з добірки +• Витік службової пам'яті програвача +• [PeerTube] Поміняно місцями аватарки завантажувача та підканалу + +та багато іншого From 510db568eb9cb09d6ef9fafb089b3f455fcee13f Mon Sep 17 00:00:00 2001 From: TobiGr Date: Thu, 24 Aug 2023 11:53:35 +0200 Subject: [PATCH 016/172] Image minizier: replace Number.toFixed(0) with Math.floor() Number.toFixed returns a string, Math.floor a number --- .github/workflows/image-minimizer.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/image-minimizer.js b/.github/workflows/image-minimizer.js index d3532ad83..d099068ba 100644 --- a/.github/workflows/image-minimizer.js +++ b/.github/workflows/image-minimizer.js @@ -86,7 +86,7 @@ module.exports = async ({github, context}) => { }); } - // Asnyc replace function from https://stackoverflow.com/a/48032528 + // Async replace function from https://stackoverflow.com/a/48032528 async function replaceAsync(str, regex, asyncFn) { const promises = []; str.replace(regex, (match, ...args) => { @@ -138,7 +138,7 @@ module.exports = async ({github, context}) => { if (shouldModify) { wasMatchModified = true; console.log(`Modifying match '${match}'`); - return `${g1}`; + return `${g1}`; } console.log(`Match '${match}' is ok/will not be modified`); From 2b833c5250d020c2d004dcf64919115bde65e8f1 Mon Sep 17 00:00:00 2001 From: AudricV <74829229+AudricV@users.noreply.github.com> Date: Wed, 23 Aug 2023 00:20:12 +0200 Subject: [PATCH 017/172] Fix audio_track_name string formats --- app/src/main/res/values-ar/strings.xml | 2 +- app/src/main/res/values-be/strings.xml | 2 +- app/src/main/res/values-cs/strings.xml | 2 +- app/src/main/res/values-de/strings.xml | 2 +- app/src/main/res/values-el/strings.xml | 2 +- app/src/main/res/values-es/strings.xml | 2 +- app/src/main/res/values-et/strings.xml | 2 +- app/src/main/res/values-fi/strings.xml | 2 +- app/src/main/res/values-fr/strings.xml | 2 +- app/src/main/res/values-gl/strings.xml | 2 +- app/src/main/res/values-he/strings.xml | 2 +- app/src/main/res/values-hi/strings.xml | 2 +- app/src/main/res/values-hu/strings.xml | 2 +- app/src/main/res/values-in/strings.xml | 2 +- app/src/main/res/values-it/strings.xml | 2 +- app/src/main/res/values-ja/strings.xml | 2 +- app/src/main/res/values-ko/strings.xml | 2 +- app/src/main/res/values-nl/strings.xml | 2 +- app/src/main/res/values-or/strings.xml | 2 +- app/src/main/res/values-pa/strings.xml | 2 +- app/src/main/res/values-pl/strings.xml | 2 +- app/src/main/res/values-pt-rBR/strings.xml | 2 +- app/src/main/res/values-pt-rPT/strings.xml | 2 +- app/src/main/res/values-pt/strings.xml | 2 +- app/src/main/res/values-ru/strings.xml | 2 +- app/src/main/res/values-ryu/strings.xml | 2 +- app/src/main/res/values-sc/strings.xml | 2 +- app/src/main/res/values-sk/strings.xml | 2 +- app/src/main/res/values-sv/strings.xml | 2 +- app/src/main/res/values-tr/strings.xml | 2 +- app/src/main/res/values-uk/strings.xml | 2 +- app/src/main/res/values-zh-rCN/strings.xml | 2 +- app/src/main/res/values-zh-rTW/strings.xml | 2 +- app/src/main/res/values/strings.xml | 2 +- 34 files changed, 34 insertions(+), 34 deletions(-) diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index 595a3182f..d0cf90db4 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -801,7 +801,7 @@ إعدادات ExoPlayer إدارة بعض إعدادات ExoPlayer. تتطلب هذه التغييرات إعادة تشغيل المشغل لتصبح سارية المفعول استخدم دائمًا الحل البديل لإعداد سطح إخراج فيديو ExoPlayer - %1s %2s + %1$s %2$s الافتراضي مدبلجة وصفي diff --git a/app/src/main/res/values-be/strings.xml b/app/src/main/res/values-be/strings.xml index 22a3eb03a..979553372 100644 --- a/app/src/main/res/values-be/strings.xml +++ b/app/src/main/res/values-be/strings.xml @@ -775,7 +775,7 @@ Налады ExoPlayer Выкарыстоўваць функцыю рэзервовага дэкодэра ExoPlayer Заўсёды выкарыстоўваць спосаб абыходу налад паверхні відэавываду ExoPlayer - %1s %2s + %1$s %2$s арыгінальны дубляваны апісальны diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index f7214176f..1eb38085c 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -763,7 +763,7 @@ Použít funkci náhradního dekodéru přehrávače ExoPlayer Tuto možnost povolte, pokud máte problémy s inicializací dekodéru. V případě selhání inicializace primárních dekodérů se přehrávač vrátí zpět k dekodérům s nižší prioritou. To může mít za následek nižší výkon přehrávání než při použití primárních dekodérů Vždy použít nastavení povrchu výstupu videa v přehrávači ExoPlayer - %1s %2s + %1$s %2$s původní dabovaná popisná diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index ed02258b8..dfc26a4e2 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -760,7 +760,7 @@ Einschalten, wenn es Probleme mit der Decoderinitialisierung gibt, die auf Decoder mit niedrigerer Priorität zurückgreift, wenn die Initialisierung des primären Decoders fehlschlägt. Dies kann zu einer schlechteren Wiedergabeleistung führen als bei der Verwendung von Primärdecodern Unbekannt ExoPlayer-Einstellungen - %1s %2s + %1$s %2$s Hauptauswahltab nach unten verschieben Position des Haupttabs Das Media-Tunneling wurde auf dem Gerät standardmäßig deaktiviert, da das Gerätemodell diese Funktion bekanntermaßen nicht unterstützt. diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index 9b746067d..094ac0ccd 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -755,7 +755,7 @@ Αυτή η λύση απελευθερώνει και επαναφέρει τους κωδικοποιητές βίντεο όταν συμβαίνει μια αλλαγή επιφάνειας, αντί να ρυθμίζει την επιφάνεια απευθείας στον κωδικοποιητή. Χρησιμοποιείται ήδη από το ExoPlayer σε ορισμένες συσκευές με αυτό το πρόβλημα, αυτή η ρύθμιση έχει επίδραση μόνο σε Android 6 και νεότερη έκδοση. \n \nΗ ενεργοποίηση αυτής της επιλογής μπορεί να αποτρέψει σφάλματα αναπαραγωγής κατά την εναλλαγή του τρέχοντος προγράμματος αναπαραγωγής βίντεο ή τη μετάβαση σε πλήρη οθόνη - %1s %2s + %1$s %2$s αρχικό μεταγλωττισμένο περιγραφικό diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 676fe2434..d1d7fdcd4 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -766,7 +766,7 @@ Desconocido Utilice la función de respaldo del decodificador de ExoPlayer Utiliza siempre la configuración de ExoPlayer para la interfaz de salida del video como una solución alternativa - %1s %2s + %1$s %2$s original doblado descriptivo diff --git a/app/src/main/res/values-et/strings.xml b/app/src/main/res/values-et/strings.xml index e534c6569..b55870c75 100644 --- a/app/src/main/res/values-et/strings.xml +++ b/app/src/main/res/values-et/strings.xml @@ -748,7 +748,7 @@ Selles meediavoos peaks heliriba juba olemas olema Kasuta ExoPlayer\'i alternatiivset dekooderit Kasuta alati ExoPlayer\'i video väljundpinna seadistamise lahendust - %1s %2s + %1$s %2$s algne dubleeritud kirjeldav diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml index 7832e3dae..641e55b21 100644 --- a/app/src/main/res/values-fi/strings.xml +++ b/app/src/main/res/values-fi/strings.xml @@ -679,7 +679,7 @@ Käytä aina ExoPlayerin videolähtöpinnan asetusta kuvaileva dubattu - %1s %2s + %1$s %2$s alkuperäinen Soittimen ilmoitus Määritä toistettavan lähetysvirran ilmoitus diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 258b44809..b899ec7f8 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -766,7 +766,7 @@ Gérez certains paramètres d\'ExoPlayer. Ces modifications nécessitent un redémarrage du lecteur pour être prises en compte Utiliser la fonctionnalité de repli du décodeur d\'ExoPlayer Toujours utiliser la solution de contournement de définition de surface de sortie vidéo d\'ExoPlayer - %1s %2s + %1$s %2$s original doublée descriptif diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml index fdc74a7d8..98d3d472b 100644 --- a/app/src/main/res/values-gl/strings.xml +++ b/app/src/main/res/values-gl/strings.xml @@ -748,7 +748,7 @@ Use a función fallback do decodificador do ExoPlayer Habilite esta opción se ten problemas na inciciación do decodificador. Usaranse decodificadores de menor prioridade se os primarios fallan. Isto pode resultar nun menor rendemento comparado co dos primarios Usar sempre Explayer como alternativa de saída de vídeo - %1s %2s + %1$s %2$s orixinal dobrado descritivo diff --git a/app/src/main/res/values-he/strings.xml b/app/src/main/res/values-he/strings.xml index 91287e7d0..5c55d0bad 100644 --- a/app/src/main/res/values-he/strings.xml +++ b/app/src/main/res/values-he/strings.xml @@ -788,7 +788,7 @@ \nהפעלת האפשרות עשויה למנוע שגיאות נגינה בעת חזרה לנגן הווידאו הנוכחית או במעבר למסך מלא מקום לשוניות ראשיות להעביר את בורר הלשוניות הראשי לתחתית - %1s %2s + %1$s %2$s תיעול מדיה הושבת כברירת מחדל במכשיר שלך כיוון שדגם המכשיר ידוע בכך שאינו תומך בזה. אין תזרימים חיים אין תזרימים diff --git a/app/src/main/res/values-hi/strings.xml b/app/src/main/res/values-hi/strings.xml index 726a0e107..a2bbaf672 100644 --- a/app/src/main/res/values-hi/strings.xml +++ b/app/src/main/res/values-hi/strings.xml @@ -762,7 +762,7 @@ \nइस विकल्प को सक्षम करने से वर्तमान वीडियो प्लेयर स्विच करते समय या फुलस्क्रीन पर स्विच करते समय प्लेबैक त्रुटियों को रोका जा सकता है मुख्य टैब की स्थिति मुख्य टैब सिलेक्टर को नीचे ले जाएँ - %1s %2s + %1$s %2$s आपके डिवाइस पर मीडिया टनलिंग डिफ़ॉल्ट रूप से अक्षम कर दी गई थी क्योंकि यह ज्ञात है कि आपका डिवाइस मॉडल इसका समर्थन नहीं करता। कोई स्ट्रीम नहीं कोई लाइव स्ट्रीम नहीं diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml index 90507786b..9f3ddf9cf 100644 --- a/app/src/main/res/values-hu/strings.xml +++ b/app/src/main/res/values-hu/strings.xml @@ -749,7 +749,7 @@ Ez a kerülőmegoldás elengedi és újból előkészíti a videokodekeket, ha felületváltozás történik, ahelyett, hogy közvetlenül a kodeknél állítaná be a felületet. Ez már alapból használatban van egyes, az ezzel a problémával érintett eszközöknél, a beállításnak Android 6 vagy újabb esetén van hatása. \n \nA beállítás bekapcsolása megakadályozhatja a lejátszási hibákat, ha átváltja a jelenlegi videolejátszót, vagy teljes képernyőre vált. - %1s %2s + %1$s %2$s szinkronizált leíró Hasznos, ha olyan fülhallgatót használ, melyen meghibásodtak a fizikai gombok diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index 04880fc73..292430861 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -749,6 +749,6 @@ deskriptif Pindahkan pemilih tab utama ke bawah Posisi tab utama - %1s %2s + %1$s %2$s Terowongan media dinonaktifkan secara bawaan di perangkat Anda karena model perangkat Anda tidak mendukungnya. \ No newline at end of file diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 0e307a3be..05604e998 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -765,7 +765,7 @@ Impostazioni ExoPlayer Usa la funzione di fallback del decoder di ExoPlayer Usa sempre la soluzione alternativa per impostare la superficie di uscita video di ExoPlayer - %1s %2s + %1$s %2$s originale doppiato descrittivo diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index dedb5763e..0eeeaf8dd 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -749,7 +749,7 @@ オーディオトラックは既にこのせせらぎに存在している必要があります メインタブの場所 メインタブセレクタを下に移動 - %1s %2s + %1$s %2$s お使いのデバイスのモデルではメディアトンネリングがサポートされていないため、このデバイスではメディアトンネリングがデフォルトで無効になっています。 ストリームはありません ライブ配信はありません diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index f0640b56b..127db9bcb 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -748,7 +748,7 @@ \n \n이 옵션을 활성화하면 현재 동영상 플레이어를 전환하거나 전체 화면으로 전환할 때 재생 오류를 방지할 수 있음 메인 탭 선택기를 하단으로 이동 - %1s %2s + %1$s %2$s 메인 탭 위치 장치 모델에서 미디어 터널링을 지원하지 않는 것으로 알려져 있기 때문에 장치에서 기본적으로 미디어 터널링이 비활성화되었습니다. \ No newline at end of file diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 3530071fb..b6622c210 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -757,7 +757,7 @@ Gebruik de terugvalfunctie van de ExoPlayer-decoder Schakel deze optie in als je problemen hebt met de initialisatie van de decoder, die terugvalt op decoders met een lagere prioriteit als de initialisatie van de primaire decoder mislukt. Dit kan leiden tot slechtere afspeelprestaties dan bij gebruik van primaire decoders Gebruik altijd de tijdelijke oplossing voor het instellen van het video-uitvoeroppervlak van ExoPlayer - %1s %2s + %1$s %2$s origineel nagesynchroniseerd beschrijvend diff --git a/app/src/main/res/values-or/strings.xml b/app/src/main/res/values-or/strings.xml index f01ca2843..084f21ca2 100644 --- a/app/src/main/res/values-or/strings.xml +++ b/app/src/main/res/values-or/strings.xml @@ -745,7 +745,7 @@ କିଛି ExoPlayer ବିନ୍ୟାସକୁ ପରିଚାଳନା କରନ୍ତୁ । ଏହି ପରିବର୍ତ୍ତନଗୁଡ଼ିକୁ ପ୍ରଭାବୀ ହେବା ପାଇଁ ଗୋଟିଏ ଚାଳକକୁ ପୁନଃଚାଳନ କରିବା ଆବଶ୍ୟକ ExoPlayer ର ଡିକୋଡର୍ ଫଲବ୍ୟାକ୍ ବୈଶିଷ୍ଟ୍ୟକୁ ବ୍ୟବହାର କରନ୍ତୁ ଯଦି ଆପଣଙ୍କର ଡିକୋଡର ପ୍ରାରମ୍ଭିକ ସମସ୍ୟା ଅଛି ତେବେ ଏହି ବିକଳ୍ପକୁ ସକ୍ରିୟ କରନ୍ତୁ, ଯାହା ପ୍ରାଥମିକ ଡିକୋଡର ପ୍ରାରମ୍ଭିକତା ବିଫଳ ହେଲେ ନିମ୍ନ ପ୍ରାଥମିକତା ଡିକୋଡରକୁ ଫେରିଥାଏ । ପ୍ରାଥମିକ ଡିକୋଡର ବ୍ୟବହାର କରିବା ସମୟରେ ଏହା ଖରାପ ପ୍ଲେବ୍ୟାକ ପ୍ରଦର୍ଶନର କାରଣ ହୋଇପାରେ - %1s ଓ %2s + %1$s ଓ %2$s ବର୍ଣ୍ଣନାତ୍ମକ ମୂଳ ଡବିଙ୍ଗ୍ ହୋଇଛି diff --git a/app/src/main/res/values-pa/strings.xml b/app/src/main/res/values-pa/strings.xml index 3142f3cc5..a10ddd125 100644 --- a/app/src/main/res/values-pa/strings.xml +++ b/app/src/main/res/values-pa/strings.xml @@ -762,7 +762,7 @@ ਵਰਣਨਾਤਮਕ ਮੁੱਖ ਟੈਬਾਂ ਦੀ ਸਥਿਤੀ ਮੁੱਖ ਟੈਬ ਸਿਲੈਕਟਰ ਨੂੰ ਹੇਠਾਂ ਲੈ ਜਾਓ - %1s %2s + %1$s %2$s ਮੀਡੀਆ ਟਨਲਿੰਗ ਤੁਹਾਡੀ ਡਿਵਾਈਸ \'ਤੇ ਡਿਫ਼ਾਲਟ ਤੌਰ \'ਤੇ ਅਸਮਰੱਥ ਕੀਤੀ ਗਈ ਸੀ ਕਿਉਂਕਿ ਤੁਹਾਡੀ ਡਿਵਾਈਸ ਮਾਡਲ ਇਸਦਾ ਸਮਰਥਨ ਨਹੀਂ ਕਰਨ ਲਈ ਜਾਣਿਆ ਜਾਂਦਾ ਹੈ। ਕੋਈ ਸਟ੍ਰੀਮ ਨਹੀਂ ਕੋਈ ਲਾਈਵ ਸਟ੍ਰੀਮ ਨਹੀਂ diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index ab810cd6d..613433f5e 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -774,7 +774,7 @@ Używaj funkcji zapasowego dekodera ExoPlayera Włącz tę opcję, jeśli masz problemy z inicjalizacją dekodera. Przywraca dekodery o niższym priorytecie, jeśli inicjalizacja podstawowych dekoderów się nie powiedzie. Może to spowodować słabszą wydajność odtwarzania niż podczas korzystania z podstawowych dekoderów Zawsze używaj obejścia ustawienia powierzchni wyjścia wideo ExoPlayera - %1s %2s + %1$s %2$s oryginalna dubbing audiodeskrypcja diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index c575dcfba..831adfe9e 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -763,7 +763,7 @@ Desconhecido Configurações de ExoPlayer Gerenciar algumas configurações de ExoPlayer. É necessário reiniciar o player para aplicar as mudanças - %1s %2s + %1$s %2$s original dublado descritivo diff --git a/app/src/main/res/values-pt-rPT/strings.xml b/app/src/main/res/values-pt-rPT/strings.xml index 62a551ef1..24a8185db 100644 --- a/app/src/main/res/values-pt-rPT/strings.xml +++ b/app/src/main/res/values-pt-rPT/strings.xml @@ -773,7 +773,7 @@ Configurações ExoPlayer Gere algumas configurações de ExoPlayer. É necessário reiniciar o reprodutor para aplicar as alterações Utilizar a função de fallback do descodificador do ExoPlayer - %1s %2s + %1$s %2$s Mova o seletor da guia principal para a parte inferior Posição das guias principais O túnel multimédia foi desativado por predefinição no seu dispositivo porque se sabe que o modelo do dispositivo não o suporta. diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index 81888a03f..87b475a8b 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -770,7 +770,7 @@ Utilizar a função de fallback do descodificador do ExoPlayer Ative esta opção se tiver problemas de inicialização do descodificador, que retorna codificadores de baixa prioridade se o descodificador primário falhar. Isto pode resultar num desempenho inferior de reprodução Usar sempre a configuração de saída alternativa de vídeo do ExoPlayer - %1s %2s + %1$s %2$s original dobrado descritivo diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 72e64691c..f033b6cf6 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -765,7 +765,7 @@ Управление некоторыми настройками ExoPlayer. Эти изменения требуют перезапуска плеера, чтобы они вступили в силу Использовать резервную функцию декодера ExoPlayer Всегда использовать обходной путь настройки поверхности видеовыхода ExoPlayer - %1s %2s + %1$s %2$s оригинальный дублированный описательный diff --git a/app/src/main/res/values-ryu/strings.xml b/app/src/main/res/values-ryu/strings.xml index 30ef993b8..930a9585f 100644 --- a/app/src/main/res/values-ryu/strings.xml +++ b/app/src/main/res/values-ryu/strings.xml @@ -760,7 +760,7 @@ ふきけー ExoPlayerぬしっていかんりさびーん。くりらぬへんかんはんえいすんがープレイヤーぬさいきちゃーがふぃちようやいびーん ちゃーExoPlayerぬえいぞうしーゅちりょくサーフェスしっていぬかいきちさくしようすん - %1s %2s + %1$s %2$s うんせいかいしち ExoPlayerぬデコーダフォールバックちぬーさすん オリジナル diff --git a/app/src/main/res/values-sc/strings.xml b/app/src/main/res/values-sc/strings.xml index a32d1658a..2f44a8664 100644 --- a/app/src/main/res/values-sc/strings.xml +++ b/app/src/main/res/values-sc/strings.xml @@ -748,7 +748,7 @@ Disconnotu Manìgia unas cantas impostatziones de ExoPlayer. Custas modìficas tenent bisòngiu de torrare a allùghere su riproduidore pro chi tèngiant efetu Imprea sa funtzionalidade de riserva de su decodificadore de ExoPlayer - %1s %2s + %1$s %2$s originale dopiadu descritivu diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml index 3be801c0a..6e218e16c 100644 --- a/app/src/main/res/values-sk/strings.xml +++ b/app/src/main/res/values-sk/strings.xml @@ -764,7 +764,7 @@ Túto možnosť povoľte, ak máte problémy s inicializáciou dekodéra, ktorý sa v prípade zlyhania inicializácie primárnych dekodérov vráti k dekodérom s nižšou prioritou. To môže mať za následok nižší výkon prehrávania ako pri použití primárnych dekodérov Používať funkciu záložného dekodéra prehrávača ExoPlayer Vždy použiť nastavenia výstupu videa ExoPlayera - %1s %2s + %1$s %2$s povodná dabovaná Vyberať zvukovú stopu s popisom pre zrakovo postihnutých ak je k dispozicií diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index 1074ff7fd..01b503d3f 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -757,7 +757,7 @@ Denna lösning frigör och återinstansierar videokodeker när en ytförändring inträffar, istället för att ställa in ytan direkt till kodeken. Används redan av ExoPlayer på vissa enheter med detta problem, denna inställning har endast effekt på Android 6 och senare \n \nOm du aktiverar det här alternativet kan det förhindra uppspelningsfel när du byter aktuell videospelare eller växlar till fullskärm - %1s %2s + %1$s %2$s original beskrivande dubbad diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index 1271dee72..2400a8bd5 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -743,7 +743,7 @@ özgün dublaj betimlemeli - %1s %2s + %1$s %2$s Dış oynatıcılar için ses parçası seç Dil ne olursa olsun özgün ses parçasını seç Ses: %s diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 23c55b15a..25b3a43d2 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -769,7 +769,7 @@ Керування деякими налаштуваннями ExoPlayer. Щоб ці зміни набули чинності, потрібно перезапустити програвач Використовувати запасну функцію декодера ExoPlayer Завжди використовувати обхідний шлях налаштування поверхні відеовиходу ExoPlayer - %1s %2s + %1$s %2$s оригінальна дубльована описова diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 2fd22fb06..9a888c74d 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -749,7 +749,7 @@ 如遇解码器初始化方面的问题可开启此选项。启用后,如主解码器初始化失败,ExoPlayer 将使用较低优先级的解码器进行播放。请注意,这可能导致播放性能下降 将主标签页选择器移到底部 主标签页位置 - %1s %2s + %1$s %2$s 媒体隧道功能在你的设备上默认停用,因为已知你的设备型号不支持它。 无直播 无音视频流 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index b473f8124..8eb964406 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -749,7 +749,7 @@ \n啟用此選項可以避免在切換目前視訊播放程式或切換到全螢幕時出現播放錯誤 將主分頁選擇器移動至底部 主分頁位置 - %1s %2s + %1$s %2$s 因為您的裝置型號已知不支援媒體隧道,因此已預設停用。 無串流 無直播串流 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 472d1ea43..5cf214c0d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -791,7 +791,7 @@ Enable this option if you have decoder initialization issues, which falls back to lower-priority decoders if primary decoders initialization fail. This may result in poor playback performance than when using primary decoders Always use ExoPlayer\'s video output surface setting workaround This workaround releases and re-instantiates video codecs when a surface change occurs, instead of setting the surface to the codec directly. Already used by ExoPlayer on some devices with this issue, this setting has only an effect on Android 6 and higher\n\nEnabling this option may prevent playback errors when switching the current video player or switching to fullscreen - %1s %2s + %1$s %2$s original dubbed descriptive From 2d16a06bc40b82a0e8339386d4328e7eaac5b075 Mon Sep 17 00:00:00 2001 From: AudricV <74829229+AudricV@users.noreply.github.com> Date: Mon, 28 Aug 2023 00:26:10 +0200 Subject: [PATCH 018/172] Show play queue button in main player when there is one stream --- .../main/java/org/schabi/newpipe/player/ui/MainPlayerUi.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/org/schabi/newpipe/player/ui/MainPlayerUi.java b/app/src/main/java/org/schabi/newpipe/player/ui/MainPlayerUi.java index 683629c25..92e38a6a2 100644 --- a/app/src/main/java/org/schabi/newpipe/player/ui/MainPlayerUi.java +++ b/app/src/main/java/org/schabi/newpipe/player/ui/MainPlayerUi.java @@ -434,7 +434,7 @@ public final class MainPlayerUi extends VideoPlayerUi implements View.OnLayoutCh return; } - final boolean showQueue = playQueue.getStreams().size() > 1; + final boolean showQueue = !playQueue.getStreams().isEmpty(); final boolean showSegment = !player.getCurrentStreamInfo() .map(StreamInfo::getStreamSegments) .map(List::isEmpty) From 862546205a99a42da0a2b23e9034af62dbaac14b Mon Sep 17 00:00:00 2001 From: K Gill <60492161+ShareASmile@users.noreply.github.com> Date: Fri, 8 Sep 2023 16:33:17 +0530 Subject: [PATCH 019/172] fix wrongly placed uchinaguchi in language selector settings caus.. ..ing language picker to select wrong languages --- app/src/main/res/values/settings_keys.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/values/settings_keys.xml b/app/src/main/res/values/settings_keys.xml index a41d41fdb..56fc19eed 100644 --- a/app/src/main/res/values/settings_keys.xml +++ b/app/src/main/res/values/settings_keys.xml @@ -1238,7 +1238,6 @@ Íslenska Italiano 日本語 - うちなーぐち ꦧꦱꦗꦮ Taqbaylit Kurmancî @@ -1263,6 +1262,7 @@ Português (PT) Română Pусский + うちなーぐち ᱥᱟᱱᱛᱟᱲᱤ sardu Slovenčina From 2cb973f1504c724fc37cac29f98486a9023520fe Mon Sep 17 00:00:00 2001 From: Isira Seneviratne Date: Sat, 11 Mar 2023 09:48:56 +0530 Subject: [PATCH 020/172] Use desugar_jdk_libs_nio. --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index e48f6e907..e1d6bc1f6 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -192,7 +192,7 @@ sonar { dependencies { /** Desugaring **/ - coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.3' + coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs_nio:2.0.3' /** NewPipe libraries **/ // You can use a local version by uncommenting a few lines in settings.gradle From 6df808f266ff3a46630bd3b1d2612de23669b016 Mon Sep 17 00:00:00 2001 From: Isira Seneviratne Date: Sat, 11 Mar 2023 10:44:11 +0530 Subject: [PATCH 021/172] Use Path in the download helper classes. --- .../streams/io/StoredDirectoryHelper.java | 51 +++++++----- .../newpipe/streams/io/StoredFileHelper.java | 78 +++++++++++-------- 2 files changed, 77 insertions(+), 52 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/streams/io/StoredDirectoryHelper.java b/app/src/main/java/org/schabi/newpipe/streams/io/StoredDirectoryHelper.java index 48ae54284..dede5088e 100644 --- a/app/src/main/java/org/schabi/newpipe/streams/io/StoredDirectoryHelper.java +++ b/app/src/main/java/org/schabi/newpipe/streams/io/StoredDirectoryHelper.java @@ -6,6 +6,7 @@ import android.content.Intent; import android.database.Cursor; import android.net.Uri; import android.provider.DocumentsContract; +import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -14,21 +15,27 @@ import androidx.documentfile.provider.DocumentFile; import org.schabi.newpipe.settings.NewPipeSettings; import org.schabi.newpipe.util.FilePickerActivityHelper; -import java.io.File; import java.io.IOException; import java.net.URI; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; import static android.provider.DocumentsContract.Document.COLUMN_DISPLAY_NAME; import static android.provider.DocumentsContract.Root.COLUMN_DOCUMENT_ID; import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty; public class StoredDirectoryHelper { + private static final String TAG = StoredDirectoryHelper.class.getSimpleName(); public static final int PERMISSION_FLAGS = Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION; - private File ioTree; + private Path ioTree; private DocumentFile docTree; private Context context; @@ -40,7 +47,7 @@ public class StoredDirectoryHelper { this.tag = tag; if (ContentResolver.SCHEME_FILE.equalsIgnoreCase(path.getScheme())) { - this.ioTree = new File(URI.create(path.toString())); + ioTree = Paths.get(URI.create(path.toString())); return; } @@ -64,13 +71,17 @@ public class StoredDirectoryHelper { } public StoredFileHelper createUniqueFile(final String name, final String mime) { - final ArrayList matches = new ArrayList<>(); + final List matches = new ArrayList<>(); final String[] filename = splitFilename(name); - final String lcFilename = filename[0].toLowerCase(); + final String lcFileName = filename[0].toLowerCase(); if (docTree == null) { - for (final File file : ioTree.listFiles()) { - addIfStartWith(matches, lcFilename, file.getName()); + try (Stream stream = Files.list(ioTree)) { + matches.addAll(stream.map(path -> path.getFileName().toString().toLowerCase()) + .filter(fileName -> fileName.startsWith(lcFileName)) + .collect(Collectors.toList())); + } catch (final IOException e) { + Log.e(TAG, "Exception while traversing " + ioTree, e); } } else { // warning: SAF file listing is very slow @@ -82,10 +93,10 @@ public class StoredDirectoryHelper { final ContentResolver cr = context.getContentResolver(); try (Cursor cursor = cr.query(docTreeChildren, projection, selection, - new String[]{lcFilename}, null)) { + new String[]{lcFileName}, null)) { if (cursor != null) { while (cursor.moveToNext()) { - addIfStartWith(matches, lcFilename, cursor.getString(0)); + addIfStartWith(matches, lcFileName, cursor.getString(0)); } } } @@ -112,7 +123,7 @@ public class StoredDirectoryHelper { Collections.sort(matches, String::compareTo); for (int i = 1; i < 1000; i++) { - if (Collections.binarySearch(matches, makeFileName(lcFilename, i, filename[1])) < 0) { + if (Collections.binarySearch(matches, makeFileName(lcFileName, i, filename[1])) < 0) { return createFile(makeFileName(filename[0], i, filename[1]), mime, true); } } @@ -141,11 +152,11 @@ public class StoredDirectoryHelper { } public Uri getUri() { - return docTree == null ? Uri.fromFile(ioTree) : docTree.getUri(); + return docTree == null ? Uri.fromFile(ioTree.toFile()) : docTree.getUri(); } public boolean exists() { - return docTree == null ? ioTree.exists() : docTree.exists(); + return docTree == null ? Files.exists(ioTree) : docTree.exists(); } /** @@ -169,7 +180,9 @@ public class StoredDirectoryHelper { */ public boolean mkdirs() { if (docTree == null) { - return ioTree.exists() || ioTree.mkdirs(); + // TODO: Use Files.createDirectories() when AGP 8.1 is available: + // https://issuetracker.google.com/issues/282544786 + return Files.exists(ioTree) || ioTree.toFile().mkdirs(); } if (docTree.exists()) { @@ -206,8 +219,8 @@ public class StoredDirectoryHelper { public Uri findFile(final String filename) { if (docTree == null) { - final File res = new File(ioTree, filename); - return res.exists() ? Uri.fromFile(res) : null; + final Path res = ioTree.resolve(filename); + return Files.exists(res) ? Uri.fromFile(res.toFile()) : null; } final DocumentFile res = findFileSAFHelper(context, docTree, filename); @@ -215,7 +228,7 @@ public class StoredDirectoryHelper { } public boolean canWrite() { - return docTree == null ? ioTree.canWrite() : docTree.canWrite(); + return docTree == null ? Files.isWritable(ioTree) : docTree.canWrite(); } /** @@ -230,14 +243,14 @@ public class StoredDirectoryHelper { @NonNull @Override public String toString() { - return (docTree == null ? Uri.fromFile(ioTree) : docTree.getUri()).toString(); + return (docTree == null ? Uri.fromFile(ioTree.toFile()) : docTree.getUri()).toString(); } //////////////////// // Utils /////////////////// - private static void addIfStartWith(final ArrayList list, @NonNull final String base, + private static void addIfStartWith(final List list, @NonNull final String base, final String str) { if (isNullOrEmpty(str)) { return; @@ -259,7 +272,7 @@ public class StoredDirectoryHelper { } private static String makeFileName(final String name, final int idx, final String ext) { - return name.concat(" (").concat(String.valueOf(idx)).concat(")").concat(ext); + return name + "(" + idx + ")" + ext; } /** diff --git a/app/src/main/java/org/schabi/newpipe/streams/io/StoredFileHelper.java b/app/src/main/java/org/schabi/newpipe/streams/io/StoredFileHelper.java index 1f0c91456..9f8ef2e6c 100644 --- a/app/src/main/java/org/schabi/newpipe/streams/io/StoredFileHelper.java +++ b/app/src/main/java/org/schabi/newpipe/streams/io/StoredFileHelper.java @@ -23,6 +23,9 @@ import java.io.File; import java.io.IOException; import java.io.Serializable; import java.net.URI; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import us.shandian.giga.io.FileStream; import us.shandian.giga.io.FileStreamSAF; @@ -36,7 +39,7 @@ public class StoredFileHelper implements Serializable { private transient DocumentFile docFile; private transient DocumentFile docTree; - private transient File ioFile; + private transient Path ioPath; private transient Context context; protected String source; @@ -49,7 +52,8 @@ public class StoredFileHelper implements Serializable { public StoredFileHelper(final Context context, final Uri uri, final String mime) { if (FilePickerActivityHelper.isOwnFileUri(context, uri)) { - ioFile = Utils.getFileForUri(uri); + final File ioFile = Utils.getFileForUri(uri); + ioPath = ioFile.toPath(); source = Uri.fromFile(ioFile).toString(); } else { docFile = DocumentFile.fromSingleUri(context, uri); @@ -100,26 +104,18 @@ public class StoredFileHelper implements Serializable { this.srcType = this.docFile.getType(); } - StoredFileHelper(final File location, final String filename, final String mime) + StoredFileHelper(final Path location, final String filename, final String mime) throws IOException { - this.ioFile = new File(location, filename); + ioPath = location.resolve(filename); - if (this.ioFile.exists()) { - if (!this.ioFile.isFile() && !this.ioFile.delete()) { - throw new IOException("The filename is already in use by non-file entity " - + "and cannot overwrite it"); - } - } else { - if (!this.ioFile.createNewFile()) { - throw new IOException("Cannot create the file"); - } - } + Files.deleteIfExists(ioPath); + Files.createFile(ioPath); - this.source = Uri.fromFile(this.ioFile).toString(); - this.sourceTree = Uri.fromFile(location).toString(); + source = Uri.fromFile(ioPath.toFile()).toString(); + sourceTree = Uri.fromFile(location.toFile()).toString(); - this.srcName = ioFile.getName(); - this.srcType = mime; + srcName = ioPath.getFileName().toString(); + srcType = mime; } public StoredFileHelper(final Context context, @Nullable final Uri parent, @@ -129,7 +125,7 @@ public class StoredFileHelper implements Serializable { if (path.getScheme() == null || path.getScheme().equalsIgnoreCase(ContentResolver.SCHEME_FILE)) { - this.ioFile = new File(URI.create(this.source)); + this.ioPath = Paths.get(URI.create(this.source)); } else { final DocumentFile file = DocumentFile.fromSingleUri(context, path); @@ -187,7 +183,7 @@ public class StoredFileHelper implements Serializable { assertValid(); if (docFile == null) { - return new FileStream(ioFile); + return new FileStream(ioPath.toFile()); } else { return new FileStreamSAF(context.getContentResolver(), docFile.getUri()); } @@ -211,7 +207,7 @@ public class StoredFileHelper implements Serializable { public Uri getUri() { assertValid(); - return docFile == null ? Uri.fromFile(ioFile) : docFile.getUri(); + return docFile == null ? Uri.fromFile(ioPath.toFile()) : docFile.getUri(); } public Uri getParentUri() { @@ -233,7 +229,12 @@ public class StoredFileHelper implements Serializable { return true; } if (docFile == null) { - return ioFile.delete(); + try { + return Files.deleteIfExists(ioPath); + } catch (final IOException e) { + Log.e(TAG, "Exception while deleting " + ioPath, e); + return false; + } } final boolean res = docFile.delete(); @@ -252,21 +253,30 @@ public class StoredFileHelper implements Serializable { public long length() { assertValid(); - return docFile == null ? ioFile.length() : docFile.length(); + if (docFile == null) { + try { + return Files.size(ioPath); + } catch (final IOException e) { + Log.e(TAG, "Exception while getting the size of " + ioPath, e); + return 0; + } + } else { + return docFile.length(); + } } public boolean canWrite() { if (source == null) { return false; } - return docFile == null ? ioFile.canWrite() : docFile.canWrite(); + return docFile == null ? Files.isWritable(ioPath) : docFile.canWrite(); } public String getName() { if (source == null) { return srcName; } else if (docFile == null) { - return ioFile.getName(); + return ioPath.getFileName().toString(); } final String name = docFile.getName(); @@ -287,12 +297,11 @@ public class StoredFileHelper implements Serializable { } public boolean existsAsFile() { - if (source == null || (docFile == null && ioFile == null)) { + if (source == null || (docFile == null && ioPath == null)) { if (DEBUG) { Log.d(TAG, "existsAsFile called but something is null: source = [" + (source == null ? "null => storage is invalid" : source) - + "], docFile = [" + (docFile == null ? "null" : docFile) - + "], ioFile = [" + (ioFile == null ? "null" : ioFile) + "]"); + + "], docFile = [" + docFile + "], ioPath = [" + ioPath + "]"); } return false; } @@ -300,7 +309,7 @@ public class StoredFileHelper implements Serializable { // WARNING: DocumentFile.exists() and DocumentFile.isFile() methods are slow // docFile.isVirtual() means it is non-physical? return docFile == null - ? (ioFile.exists() && ioFile.isFile()) + ? Files.isRegularFile(ioPath) : (docFile.exists() && docFile.isFile()); } @@ -310,8 +319,10 @@ public class StoredFileHelper implements Serializable { if (docFile == null) { try { - result = ioFile.createNewFile(); + Files.createFile(ioPath); + result = true; } catch (final IOException e) { + Log.e(TAG, "Exception while creating " + ioPath, e); return false; } } else if (docTree == null) { @@ -332,7 +343,8 @@ public class StoredFileHelper implements Serializable { } if (result) { - source = (docFile == null ? Uri.fromFile(ioFile) : docFile.getUri()).toString(); + source = (docFile == null ? Uri.fromFile(ioPath.toFile()) : docFile.getUri()) + .toString(); srcName = getName(); srcType = getType(); } @@ -352,7 +364,7 @@ public class StoredFileHelper implements Serializable { docTree = null; docFile = null; - ioFile = null; + ioPath = null; context = null; } @@ -383,7 +395,7 @@ public class StoredFileHelper implements Serializable { } if (this.isDirect()) { - return this.ioFile.getPath().equalsIgnoreCase(storage.ioFile.getPath()); + return this.ioPath.equals(storage.ioPath); } return DocumentsContract.getDocumentId(this.docFile.getUri()) From 4e41e12bd24286a6c903e55a3c9f8eae58f18e6e Mon Sep 17 00:00:00 2001 From: TobiGr Date: Sun, 17 Sep 2023 15:31:06 +0200 Subject: [PATCH 022/172] Small code and doc improvements Remove unnecessary else-branch and use Collections.isEmpty(). Add doc comment for splitFilename() --- .../streams/io/StoredDirectoryHelper.java | 32 +++++++++++-------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/streams/io/StoredDirectoryHelper.java b/app/src/main/java/org/schabi/newpipe/streams/io/StoredDirectoryHelper.java index dede5088e..1b74c90a5 100644 --- a/app/src/main/java/org/schabi/newpipe/streams/io/StoredDirectoryHelper.java +++ b/app/src/main/java/org/schabi/newpipe/streams/io/StoredDirectoryHelper.java @@ -102,24 +102,24 @@ public class StoredDirectoryHelper { } } - if (matches.size() < 1) { + if (matches.isEmpty()) { return createFile(name, mime, true); - } else { - // check if the filename is in use - String lcName = name.toLowerCase(); - for (final String testName : matches) { - if (testName.equals(lcName)) { - lcName = null; - break; - } - } + } - // check if not in use - if (lcName != null) { - return createFile(name, mime, true); + // check if the filename is in use + String lcName = name.toLowerCase(); + for (final String testName : matches) { + if (testName.equals(lcName)) { + lcName = null; + break; } } + // create file if filename not in use + if (lcName != null) { + return createFile(name, mime, true); + } + Collections.sort(matches, String::compareTo); for (int i = 1; i < 1000; i++) { @@ -261,6 +261,12 @@ public class StoredDirectoryHelper { } } + /** + * Splits the filename into the name and extension. + * + * @param filename The filename to split + * @return A String array with the name at index 0 and extension at index 1 + */ private static String[] splitFilename(@NonNull final String filename) { final int dotIndex = filename.lastIndexOf('.'); From f2c2f1735e6c986c3631d601ebe3ff42658069bd Mon Sep 17 00:00:00 2001 From: TobiGr Date: Sun, 17 Sep 2023 15:25:47 +0200 Subject: [PATCH 023/172] Replace RuntimeException with IOException The RuntimeException was not explicitly declared and thus not caught at every call of this constructor. This change ensures that this possible exception is handled by the dedicated error handlers. --- .../java/org/schabi/newpipe/streams/io/StoredFileHelper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/org/schabi/newpipe/streams/io/StoredFileHelper.java b/app/src/main/java/org/schabi/newpipe/streams/io/StoredFileHelper.java index 9f8ef2e6c..5404426c4 100644 --- a/app/src/main/java/org/schabi/newpipe/streams/io/StoredFileHelper.java +++ b/app/src/main/java/org/schabi/newpipe/streams/io/StoredFileHelper.java @@ -130,7 +130,7 @@ public class StoredFileHelper implements Serializable { final DocumentFile file = DocumentFile.fromSingleUri(context, path); if (file == null) { - throw new RuntimeException("SAF not available"); + throw new IOException("SAF not available"); } this.context = context; From c74bd11a6fb7ae7e5460ac923636c73fa162e0dc Mon Sep 17 00:00:00 2001 From: TacoTheDank Date: Thu, 20 Jul 2023 17:07:52 -0400 Subject: [PATCH 024/172] Update miscellaneous libraries --- app/build.gradle | 7 ++----- build.gradle | 2 +- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index e48f6e907..42719d181 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -50,9 +50,6 @@ android { } } - // Keep the release build type at the end of the list to override 'archivesBaseName' of - // debug build. This seems to be a Gradle bug, therefore - // TODO: update Gradle version release { if (System.properties.containsKey('packageSuffix')) { applicationIdSuffix System.getProperty('packageSuffix') @@ -115,7 +112,7 @@ ext { icepickVersion = '3.2.0' exoPlayerVersion = '2.18.7' - googleAutoServiceVersion = '1.0.1' + googleAutoServiceVersion = '1.1.1' groupieVersion = '2.10.1' markwonVersion = '4.6.2' @@ -208,7 +205,7 @@ dependencies { ktlint 'com.pinterest:ktlint:0.45.2' /** Kotlin **/ - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:${kotlin_version}" + implementation "org.jetbrains.kotlin:kotlin-stdlib:${kotlin_version}" /** AndroidX **/ implementation 'androidx.appcompat:appcompat:1.5.1' diff --git a/build.gradle b/build.gradle index 24a28bd6e..c14a1fcd7 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,7 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { - ext.kotlin_version = '1.8.21' + ext.kotlin_version = '1.8.22' repositories { google() mavenCentral() From d1a82a85cdc28d9226a3b4e6d7dcfceac479e6b6 Mon Sep 17 00:00:00 2001 From: Edward Date: Wed, 29 Mar 2023 01:04:26 +0800 Subject: [PATCH 025/172] Include a high-resolution option in the default resolution settings. --- .../settings/VideoAudioSettingsFragment.java | 65 ++++++++++++++++++- .../org/schabi/newpipe/util/ListHelper.java | 25 +++++++ app/src/main/res/values/settings_keys.xml | 15 +++++ app/src/main/res/values/strings.xml | 4 ++ 4 files changed, 108 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/schabi/newpipe/settings/VideoAudioSettingsFragment.java b/app/src/main/java/org/schabi/newpipe/settings/VideoAudioSettingsFragment.java index aae9cfca5..b498bcf30 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/VideoAudioSettingsFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/VideoAudioSettingsFragment.java @@ -13,6 +13,7 @@ import androidx.preference.ListPreference; import com.google.android.material.snackbar.Snackbar; import org.schabi.newpipe.R; +import org.schabi.newpipe.util.ListHelper; import org.schabi.newpipe.util.PermissionHelper; import java.util.LinkedList; @@ -26,7 +27,7 @@ public class VideoAudioSettingsFragment extends BasePreferenceFragment { addPreferencesFromResourceRegistry(); updateSeekOptions(); - + updateResolutionOptions(); listener = (sharedPreferences, key) -> { // on M and above, if user chooses to minimise to popup player on exit @@ -48,10 +49,72 @@ public class VideoAudioSettingsFragment extends BasePreferenceFragment { } } else if (getString(R.string.use_inexact_seek_key).equals(key)) { updateSeekOptions(); + } else if (getString(R.string.show_higher_resolutions_key).equals(key)) { + updateResolutionOptions(); } }; } + /** + * Update default resolution, default popup resolution & mobile data resolution options. + * show high resolution when "Show higher resolution" option enabled. + */ + private void updateResolutionOptions() { + final ListPreference defaultResolution = findPreference( + getString(R.string.default_resolution_key)); + final ListPreference defaultPopupResolution = findPreference( + getString(R.string.default_popup_resolution_key)); + final ListPreference mobileDataResolution = findPreference( + getString(R.string.limit_mobile_data_usage_key)); + final Resources resources = getResources(); + final boolean showHigherResolutions = getPreferenceManager().getSharedPreferences() + .getBoolean(resources.getString(R.string.show_higher_resolutions_key), false); + final List resolutionListDescriptions = ListHelper.getSortedResolutionList( + resources, + R.array.resolution_list_description, + R.array.high_resolution_list_descriptions, + showHigherResolutions); + final List resolutionListValues = ListHelper.getSortedResolutionList( + resources, + R.array.resolution_list_values, + R.array.high_resolution_list_values, + showHigherResolutions); + final List limitDataUsageResolutionValues = ListHelper.getSortedResolutionList( + resources, + R.array.limit_data_usage_values_list, + R.array.high_resolution_limit_data_usage_values_list, + showHigherResolutions); + final List limitDataUsageResolutionDescriptions = ListHelper + .getSortedResolutionList(resources, + R.array.limit_data_usage_description_list, + R.array.high_resolution_list_descriptions, + showHigherResolutions); + defaultResolution.setEntries(resolutionListDescriptions.toArray(new String[0])); + defaultResolution.setEntryValues(resolutionListValues.toArray(new String[0])); + defaultPopupResolution.setEntries(resolutionListDescriptions.toArray(new String[0])); + defaultPopupResolution.setEntryValues(resolutionListValues.toArray(new String[0])); + mobileDataResolution.setEntries( + limitDataUsageResolutionDescriptions.toArray(new String[0])); + mobileDataResolution.setEntryValues(limitDataUsageResolutionValues.toArray(new String[0])); + if (!showHigherResolutions) { + if (ListHelper.isHighResolutionSelected(defaultResolution.getValue(), + R.array.high_resolution_list_values, + resources)) { + defaultResolution.setValueIndex(0); + } + if (ListHelper.isHighResolutionSelected(defaultPopupResolution.getValue(), + R.array.high_resolution_list_values, + resources)) { + defaultPopupResolution.setValueIndex(0); + } + if (ListHelper.isHighResolutionSelected(mobileDataResolution.getValue(), + R.array.high_resolution_limit_data_usage_values_list, + resources)) { + mobileDataResolution.setValueIndex(0); + } + } + } + /** * Update fast-forward/-rewind seek duration options * according to language and inexact seek setting. diff --git a/app/src/main/java/org/schabi/newpipe/util/ListHelper.java b/app/src/main/java/org/schabi/newpipe/util/ListHelper.java index f45f3786d..ead98211e 100644 --- a/app/src/main/java/org/schabi/newpipe/util/ListHelper.java +++ b/app/src/main/java/org/schabi/newpipe/util/ListHelper.java @@ -4,6 +4,7 @@ import static org.schabi.newpipe.extractor.ServiceList.YouTube; import android.content.Context; import android.content.SharedPreferences; +import android.content.res.Resources; import android.net.ConnectivityManager; import androidx.annotation.NonNull; @@ -239,6 +240,30 @@ public final class ListHelper { videoOnlyStreams, ascendingOrder, preferVideoOnlyStreams); } + public static List getSortedResolutionList( + final Resources resources, + final int defaultResolutionKey, + final int additionalResolutionKey, + final boolean showHigherResolutions) { + final List defaultResolution = new ArrayList(Arrays.asList( + resources.getStringArray(defaultResolutionKey))); + if (!showHigherResolutions) { + return defaultResolution; + } + final List additionalResolutions = Arrays.asList( + resources.getStringArray(additionalResolutionKey)); + defaultResolution.addAll(1, additionalResolutions); + return defaultResolution; + } + + public static boolean isHighResolutionSelected(final String selectedResolution, + final int additionalResolutionKey, + final Resources resources) { + return Arrays.asList(resources.getStringArray( + additionalResolutionKey)) + .contains(selectedResolution); + } + /** * Filter the list of audio streams and return a list with the preferred stream for * each audio track. Streams are sorted with the preferred language in the first position. diff --git a/app/src/main/res/values/settings_keys.xml b/app/src/main/res/values/settings_keys.xml index 56fc19eed..0ec60dbdf 100644 --- a/app/src/main/res/values/settings_keys.xml +++ b/app/src/main/res/values/settings_keys.xml @@ -124,6 +124,16 @@ 480p best_resolution + + 2160p + 1440p + + + + 2160p + 1440p + + @string/best_resolution_key 1080p60 @@ -1301,6 +1311,11 @@ 144p + + 2160p + 1440p + + list_view_mode @string/list_view_mode_auto_key diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 5cf214c0d..984f52233 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -543,6 +543,10 @@ 240p 144p + + 2160p + 1440p + New streams notifications Notify about new streams from subscriptions From 19640d5e7cbd57ce7a30cda8bcf267c13f521d4d Mon Sep 17 00:00:00 2001 From: TobiGr Date: Mon, 18 Sep 2023 01:43:14 +0200 Subject: [PATCH 026/172] Add documentation to increase maintainablilty Rename a variable --- .../settings/VideoAudioSettingsFragment.java | 26 ++++++++++++++----- .../org/schabi/newpipe/util/ListHelper.java | 19 +++++++++++--- 2 files changed, 34 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/settings/VideoAudioSettingsFragment.java b/app/src/main/java/org/schabi/newpipe/settings/VideoAudioSettingsFragment.java index b498bcf30..a1f563724 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/VideoAudioSettingsFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/VideoAudioSettingsFragment.java @@ -57,18 +57,17 @@ public class VideoAudioSettingsFragment extends BasePreferenceFragment { /** * Update default resolution, default popup resolution & mobile data resolution options. - * show high resolution when "Show higher resolution" option enabled. + *
+ * Show high resolutions when "Show higher resolution" option is enabled. + * Set default resolution to "best resolution" when "Show higher resolution" option + * is disabled. */ private void updateResolutionOptions() { - final ListPreference defaultResolution = findPreference( - getString(R.string.default_resolution_key)); - final ListPreference defaultPopupResolution = findPreference( - getString(R.string.default_popup_resolution_key)); - final ListPreference mobileDataResolution = findPreference( - getString(R.string.limit_mobile_data_usage_key)); final Resources resources = getResources(); final boolean showHigherResolutions = getPreferenceManager().getSharedPreferences() .getBoolean(resources.getString(R.string.show_higher_resolutions_key), false); + + // get sorted resolution lists final List resolutionListDescriptions = ListHelper.getSortedResolutionList( resources, R.array.resolution_list_description, @@ -89,6 +88,16 @@ public class VideoAudioSettingsFragment extends BasePreferenceFragment { R.array.limit_data_usage_description_list, R.array.high_resolution_list_descriptions, showHigherResolutions); + + // get resolution preferences + final ListPreference defaultResolution = findPreference( + getString(R.string.default_resolution_key)); + final ListPreference defaultPopupResolution = findPreference( + getString(R.string.default_popup_resolution_key)); + final ListPreference mobileDataResolution = findPreference( + getString(R.string.limit_mobile_data_usage_key)); + + // update resolution preferences with new resolutions, entries & values for each defaultResolution.setEntries(resolutionListDescriptions.toArray(new String[0])); defaultResolution.setEntryValues(resolutionListValues.toArray(new String[0])); defaultPopupResolution.setEntries(resolutionListDescriptions.toArray(new String[0])); @@ -96,6 +105,9 @@ public class VideoAudioSettingsFragment extends BasePreferenceFragment { mobileDataResolution.setEntries( limitDataUsageResolutionDescriptions.toArray(new String[0])); mobileDataResolution.setEntryValues(limitDataUsageResolutionValues.toArray(new String[0])); + + // if "Show higher resolution" option is disabled, + // set default resolution to "best resolution" if (!showHigherResolutions) { if (ListHelper.isHighResolutionSelected(defaultResolution.getValue(), R.array.high_resolution_list_values, diff --git a/app/src/main/java/org/schabi/newpipe/util/ListHelper.java b/app/src/main/java/org/schabi/newpipe/util/ListHelper.java index ead98211e..5918ece25 100644 --- a/app/src/main/java/org/schabi/newpipe/util/ListHelper.java +++ b/app/src/main/java/org/schabi/newpipe/util/ListHelper.java @@ -240,20 +240,31 @@ public final class ListHelper { videoOnlyStreams, ascendingOrder, preferVideoOnlyStreams); } + /** + * Get a sorted list containing a set of default resolution info + * and additional resolution info if showHigherResolutions is true. + * + * @param resources the resources to get the resolutions from + * @param defaultResolutionKey the settings key of the default resolution + * @param additionalResolutionKey the settings key of the additional resolutions + * @param showHigherResolutions if higher resolutions should be included in the sorted list + * @return a sorted list containing the default and maybe additional resolutions + */ public static List getSortedResolutionList( final Resources resources, final int defaultResolutionKey, final int additionalResolutionKey, final boolean showHigherResolutions) { - final List defaultResolution = new ArrayList(Arrays.asList( + final List resolutions = new ArrayList<>(Arrays.asList( resources.getStringArray(defaultResolutionKey))); if (!showHigherResolutions) { - return defaultResolution; + return resolutions; } final List additionalResolutions = Arrays.asList( resources.getStringArray(additionalResolutionKey)); - defaultResolution.addAll(1, additionalResolutions); - return defaultResolution; + // keep "best resolution" at the top + resolutions.addAll(1, additionalResolutions); + return resolutions; } public static boolean isHighResolutionSelected(final String selectedResolution, From 7e2ab0d38448e382b92a1ffacea7ae1538104820 Mon Sep 17 00:00:00 2001 From: Rishab Aggarwal Date: Mon, 18 Sep 2023 05:24:03 +0530 Subject: [PATCH 027/172] Improved downloading experience (#10407) * added LoadingDialog for improving download experience * [LoadingDialog] Apply some review comments and make title customizable. * removed permission handling from loading Dialog * fix checks * remove

Tag from first sentence --------- Co-authored-by: rishabaggarwal Co-authored-by: TobiGr --- .../org/schabi/newpipe/RouterActivity.java | 16 ++-- .../newpipe/download/LoadingDialog.java | 87 +++++++++++++++++++ .../res/layout/download_loading_dialog.xml | 18 ++++ app/src/main/res/values/strings.xml | 1 + 4 files changed, 117 insertions(+), 5 deletions(-) create mode 100644 app/src/main/java/org/schabi/newpipe/download/LoadingDialog.java create mode 100644 app/src/main/res/layout/download_loading_dialog.xml diff --git a/app/src/main/java/org/schabi/newpipe/RouterActivity.java b/app/src/main/java/org/schabi/newpipe/RouterActivity.java index e9c19a22d..70c377de9 100644 --- a/app/src/main/java/org/schabi/newpipe/RouterActivity.java +++ b/app/src/main/java/org/schabi/newpipe/RouterActivity.java @@ -45,6 +45,7 @@ import org.schabi.newpipe.database.stream.model.StreamEntity; import org.schabi.newpipe.databinding.ListRadioIconItemBinding; import org.schabi.newpipe.databinding.SingleChoiceDialogViewBinding; import org.schabi.newpipe.download.DownloadDialog; +import org.schabi.newpipe.download.LoadingDialog; import org.schabi.newpipe.error.ErrorInfo; import org.schabi.newpipe.error.ErrorUtil; import org.schabi.newpipe.error.ReCaptchaActivity; @@ -789,10 +790,10 @@ public class RouterActivity extends AppCompatActivity { } } - }, () -> { + }, () -> // this branch is executed if there is no activity context - inFlight(false); - }); + inFlight(false) + ); } Single pleaseWait(final Single single) { @@ -812,19 +813,24 @@ public class RouterActivity extends AppCompatActivity { @SuppressLint("CheckResult") private void openDownloadDialog(final int currentServiceId, final String currentUrl) { inFlight(true); + final LoadingDialog loadingDialog = new LoadingDialog(R.string.loading_metadata_title); + loadingDialog.show(getParentFragmentManager(), "loadingDialog"); disposables.add(ExtractorHelper.getStreamInfo(currentServiceId, currentUrl, true) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .compose(this::pleaseWait) .subscribe(result -> runOnVisible(ctx -> { + loadingDialog.dismiss(); final FragmentManager fm = ctx.getSupportFragmentManager(); final DownloadDialog downloadDialog = new DownloadDialog(ctx, result); // dismiss listener to be handled by FragmentManager downloadDialog.show(fm, "downloadDialog"); } - ), throwable -> runOnVisible(ctx -> - ((RouterActivity) ctx).showUnsupportedUrlDialog(currentUrl)))); + ), throwable -> runOnVisible(ctx -> { + loadingDialog.dismiss(); + ((RouterActivity) ctx).showUnsupportedUrlDialog(currentUrl); + }))); } private void openAddToPlaylistDialog(final int currentServiceId, final String currentUrl) { diff --git a/app/src/main/java/org/schabi/newpipe/download/LoadingDialog.java b/app/src/main/java/org/schabi/newpipe/download/LoadingDialog.java new file mode 100644 index 000000000..9e6861908 --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/download/LoadingDialog.java @@ -0,0 +1,87 @@ +package org.schabi.newpipe.download; + +import android.os.Bundle; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.StringRes; +import androidx.appcompat.widget.Toolbar; +import androidx.fragment.app.DialogFragment; + +import org.schabi.newpipe.MainActivity; +import org.schabi.newpipe.R; +import org.schabi.newpipe.databinding.DownloadLoadingDialogBinding; + +/** + * This class contains a dialog which shows a loading indicator and has a customizable title. + */ +public class LoadingDialog extends DialogFragment { + private static final String TAG = "LoadingDialog"; + private static final boolean DEBUG = MainActivity.DEBUG; + private DownloadLoadingDialogBinding dialogLoadingBinding; + private final @StringRes int title; + + /** + * Create a new LoadingDialog. + * + *

+ * The dialog contains a loading indicator and has a customizable title. + *
+ * Use {@code show()} to display the dialog to the user. + *

+ * + * @param title an informative title shown in the dialog's toolbar + */ + public LoadingDialog(final @StringRes int title) { + this.title = title; + } + + @Override + public void onCreate(@Nullable final Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + if (DEBUG) { + Log.d(TAG, "onCreate() called with: " + + "savedInstanceState = [" + savedInstanceState + "]"); + } + this.setCancelable(false); + } + + @Override + public View onCreateView( + @NonNull final LayoutInflater inflater, + final ViewGroup container, + final Bundle savedInstanceState) { + if (DEBUG) { + Log.d(TAG, "onCreateView() called with: " + + "inflater = [" + inflater + "], container = [" + container + "], " + + "savedInstanceState = [" + savedInstanceState + "]"); + } + return inflater.inflate(R.layout.download_loading_dialog, container); + } + + @Override + public void onViewCreated(@NonNull final View view, @Nullable final Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + dialogLoadingBinding = DownloadLoadingDialogBinding.bind(view); + initToolbar(dialogLoadingBinding.toolbarLayout.toolbar); + } + + private void initToolbar(final Toolbar toolbar) { + if (DEBUG) { + Log.d(TAG, "initToolbar() called with: toolbar = [" + toolbar + "]"); + } + toolbar.setTitle(requireContext().getString(title)); + toolbar.setNavigationOnClickListener(v -> dismiss()); + + } + + @Override + public void onDestroyView() { + dialogLoadingBinding = null; + super.onDestroyView(); + } +} diff --git a/app/src/main/res/layout/download_loading_dialog.xml b/app/src/main/res/layout/download_loading_dialog.xml new file mode 100644 index 000000000..3a7869f3f --- /dev/null +++ b/app/src/main/res/layout/download_loading_dialog.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 5cf214c0d..a37bfeb82 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -167,6 +167,7 @@ Live Downloads Downloads + Loading Metadata… Error report All Channels From 6d13cf5e71bcc429c2b80f4a1af0ec3b65b97f2f Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Sun, 23 Oct 2022 10:27:35 +0200 Subject: [PATCH 028/172] feat: add channel tabs --- app/build.gradle | 2 +- .../list/channel/ChannelFragment.java | 571 +++-------------- .../list/channel/ChannelInfoFragment.java | 38 ++ .../list/channel/ChannelTabFragment.java | 68 ++ .../list/channel/ChannelVideosFragment.java | 584 ++++++++++++++++++ .../org/schabi/newpipe/settings/tabs/Tab.java | 6 +- .../schabi/newpipe/util/ExtractorHelper.java | 42 +- app/src/main/res/layout/fragment_channel.xml | 67 +- .../main/res/layout/fragment_channel_info.xml | 36 ++ .../main/res/layout/fragment_channel_tab.xml | 41 ++ .../res/layout/fragment_channel_videos.xml | 71 +++ app/src/main/res/menu/menu_channel_videos.xml | 14 + 12 files changed, 997 insertions(+), 543 deletions(-) create mode 100644 app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelInfoFragment.java create mode 100644 app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelTabFragment.java create mode 100644 app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelVideosFragment.java create mode 100644 app/src/main/res/layout/fragment_channel_info.xml create mode 100644 app/src/main/res/layout/fragment_channel_tab.xml create mode 100644 app/src/main/res/layout/fragment_channel_videos.xml create mode 100644 app/src/main/res/menu/menu_channel_videos.xml diff --git a/app/build.gradle b/app/build.gradle index 396f119b2..22ac7d67d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -197,7 +197,7 @@ dependencies { // name and the commit hash with the commit hash of the (pushed) commit you want to test // This works thanks to JitPack: https://jitpack.io/ implementation 'com.github.TeamNewPipe:nanojson:1d9e1aea9049fc9f85e68b43ba39fe7be1c1f751' - implementation 'com.github.TeamNewPipe:NewPipeExtractor:340095515d45ecbee576872c7198992ebd8e4f08' + implementation 'com.github.Theta-Dev:NewPipeExtractor:8446e20a71dbddbe1626a118d0adf490e5e63bbb' implementation 'com.github.TeamNewPipe:NoNonsense-FilePicker:5.0.0' /** Checkstyle **/ diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java index 8a0b49249..6989552f2 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java @@ -1,96 +1,55 @@ package org.schabi.newpipe.fragments.list.channel; -import static org.schabi.newpipe.ktx.TextViewUtils.animateTextColor; -import static org.schabi.newpipe.ktx.ViewUtils.animate; -import static org.schabi.newpipe.ktx.ViewUtils.animateBackgroundColor; - -import android.content.Context; -import android.graphics.Color; import android.os.Bundle; import android.text.TextUtils; import android.util.Log; -import android.util.TypedValue; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; -import android.widget.Button; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.appcompat.app.ActionBar; -import androidx.core.content.ContextCompat; - -import com.google.android.material.snackbar.Snackbar; -import com.jakewharton.rxbinding4.view.RxView; import org.schabi.newpipe.R; -import org.schabi.newpipe.database.subscription.NotificationMode; -import org.schabi.newpipe.database.subscription.SubscriptionEntity; -import org.schabi.newpipe.databinding.ChannelHeaderBinding; import org.schabi.newpipe.databinding.FragmentChannelBinding; -import org.schabi.newpipe.databinding.PlaylistControlBinding; import org.schabi.newpipe.error.ErrorInfo; -import org.schabi.newpipe.error.ErrorUtil; import org.schabi.newpipe.error.UserAction; -import org.schabi.newpipe.extractor.ListExtractor; import org.schabi.newpipe.extractor.channel.ChannelInfo; -import org.schabi.newpipe.extractor.exceptions.ContentNotSupportedException; -import org.schabi.newpipe.extractor.stream.StreamInfoItem; -import org.schabi.newpipe.fragments.list.BaseListInfoFragment; -import org.schabi.newpipe.ktx.AnimationType; -import org.schabi.newpipe.local.subscription.SubscriptionManager; -import org.schabi.newpipe.local.feed.notifications.NotificationHelper; -import org.schabi.newpipe.player.PlayerType; -import org.schabi.newpipe.player.playqueue.ChannelPlayQueue; -import org.schabi.newpipe.player.playqueue.PlayQueue; +import org.schabi.newpipe.extractor.linkhandler.ChannelTabHandler; +import org.schabi.newpipe.fragments.BaseStateFragment; +import org.schabi.newpipe.fragments.detail.TabAdapter; +import org.schabi.newpipe.util.Constants; import org.schabi.newpipe.util.ExtractorHelper; -import org.schabi.newpipe.util.Localization; import org.schabi.newpipe.util.NavigationHelper; -import org.schabi.newpipe.util.PicassoHelper; -import org.schabi.newpipe.util.ThemeHelper; import org.schabi.newpipe.util.external_communication.ShareUtils; -import java.util.List; -import java.util.concurrent.TimeUnit; -import java.util.function.Supplier; -import java.util.stream.Collectors; - +import icepick.State; import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; -import io.reactivex.rxjava3.core.Observable; -import io.reactivex.rxjava3.core.Single; -import io.reactivex.rxjava3.disposables.CompositeDisposable; import io.reactivex.rxjava3.disposables.Disposable; -import io.reactivex.rxjava3.functions.Action; -import io.reactivex.rxjava3.functions.Consumer; -import io.reactivex.rxjava3.functions.Function; import io.reactivex.rxjava3.schedulers.Schedulers; -public class ChannelFragment extends BaseListInfoFragment - implements View.OnClickListener { +public class ChannelFragment extends BaseStateFragment { + @State + protected int serviceId = Constants.NO_SERVICE_ID; + @State + protected String name; + @State + protected String url; - private static final int BUTTON_DEBOUNCE_INTERVAL = 100; - private static final String PICASSO_CHANNEL_TAG = "PICASSO_CHANNEL_TAG"; + private ChannelInfo currentInfo; + private Disposable currentWorker; - private final CompositeDisposable disposables = new CompositeDisposable(); - private Disposable subscribeButtonMonitor; - - private boolean channelContentNotSupported = false; + private MenuItem menuRssButton; /*////////////////////////////////////////////////////////////////////////// // Views //////////////////////////////////////////////////////////////////////////*/ - private SubscriptionManager subscriptionManager; - - private FragmentChannelBinding channelBinding; - private ChannelHeaderBinding headerBinding; - private PlaylistControlBinding playlistControlBinding; - - private MenuItem menuRssButton; - private MenuItem menuNotifyButton; + private FragmentChannelBinding binding; + private TabAdapter tabAdapter; public static ChannelFragment getInstance(final int serviceId, final String url, final String name) { @@ -100,15 +59,13 @@ public class ChannelFragment extends BaseListInfoFragment getListHeaderSupplier() { - headerBinding = ChannelHeaderBinding - .inflate(activity.getLayoutInflater(), itemsList, false); - playlistControlBinding = headerBinding.playlistControl; - - return headerBinding::getRoot; - } - - @Override - protected void initListeners() { - super.initListeners(); - - headerBinding.subChannelTitleView.setOnClickListener(this); - headerBinding.subChannelAvatarView.setOnClickListener(this); - } - - /*////////////////////////////////////////////////////////////////////////// + /*////////////////////////////////////////////////////////////////////////// // Menu //////////////////////////////////////////////////////////////////////////*/ @@ -176,19 +109,14 @@ public class ChannelFragment extends BaseListInfoFragment onError = (Throwable throwable) -> { - animate(headerBinding.channelSubscribeButton, false, 100); - showSnackBarError(new ErrorInfo(throwable, UserAction.SUBSCRIPTION_GET, - "Get subscription status", currentInfo)); - }; + private void updateTabs() { + tabAdapter.clearAllItems(); - final Observable> observable = subscriptionManager - .subscriptionTable() - .getSubscriptionFlowable(info.getServiceId(), info.getUrl()) - .toObservable(); + if (currentInfo != null) { + tabAdapter.addFragment(ChannelVideosFragment.getInstance(currentInfo), "Videos"); - disposables.add(observable - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(getSubscribeUpdateMonitor(info), onError)); - - disposables.add(observable - .map(List::isEmpty) - .distinctUntilChanged() - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(isEmpty -> updateSubscribeButton(!isEmpty), onError)); - - disposables.add(observable - .map(List::isEmpty) - .distinctUntilChanged() - .skip(1) // channel has just been opened - .filter(x -> NotificationHelper.areNewStreamsNotificationsEnabled(requireContext())) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(isEmpty -> { - if (!isEmpty) { - showNotifySnackbar(); - } - }, onError)); - } - - private Function mapOnSubscribe(final SubscriptionEntity subscription, - final ChannelInfo info) { - return (@NonNull Object o) -> { - subscriptionManager.insertSubscription(subscription, info); - return o; - }; - } - - private Function mapOnUnsubscribe(final SubscriptionEntity subscription) { - return (@NonNull Object o) -> { - subscriptionManager.deleteSubscription(subscription); - return o; - }; - } - - private void updateSubscription(final ChannelInfo info) { - if (DEBUG) { - Log.d(TAG, "updateSubscription() called with: info = [" + info + "]"); - } - final Action onComplete = () -> { - if (DEBUG) { - Log.d(TAG, "Updated subscription: " + info.getUrl()); + for (final ChannelTabHandler tab : currentInfo.getTabs()) { + tabAdapter.addFragment( + ChannelTabFragment.getInstance(serviceId, tab), tab.getTab().name()); } - }; - final Consumer onError = (@NonNull Throwable throwable) -> - showSnackBarError(new ErrorInfo(throwable, UserAction.SUBSCRIPTION_UPDATE, - "Updating subscription for " + info.getUrl(), info)); + final String description = currentInfo.getDescription(); + if (!description.isEmpty()) { + tabAdapter.addFragment(ChannelInfoFragment.getInstance(description), "Info"); + } + } - disposables.add(subscriptionManager.updateChannelInfo(info) + tabAdapter.notifyDataSetUpdate(); + + for (int i = 0; i < tabAdapter.getCount(); i++) { + binding.tabLayout.getTabAt(i).setText(tabAdapter.getItemTitle(i)); + } + } + + @Override + public void startLoading(final boolean forceLoad) { + super.startLoading(forceLoad); + + currentInfo = null; + updateTabs(); + if (currentWorker != null) { + currentWorker.dispose(); + } + + runWorker(forceLoad); + } + + private void runWorker(final boolean forceLoad) { + currentWorker = ExtractorHelper.getChannelInfo(serviceId, url, forceLoad) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) - .subscribe(onComplete, onError)); - } - - private Disposable monitorSubscribeButton(final Button subscribeButton, - final Function action) { - final Consumer onNext = (@NonNull Object o) -> { - if (DEBUG) { - Log.d(TAG, "Changed subscription status to this channel!"); - } - }; - - final Consumer onError = (@NonNull Throwable throwable) -> - showSnackBarError(new ErrorInfo(throwable, UserAction.SUBSCRIPTION_CHANGE, - "Changing subscription for " + currentInfo.getUrl(), currentInfo)); - - /* Emit clicks from main thread unto io thread */ - return RxView.clicks(subscribeButton) - .subscribeOn(AndroidSchedulers.mainThread()) - .observeOn(Schedulers.io()) - .debounce(BUTTON_DEBOUNCE_INTERVAL, TimeUnit.MILLISECONDS) // Ignore rapid clicks - .map(action) - .subscribe(onNext, onError); - } - - private Consumer> getSubscribeUpdateMonitor(final ChannelInfo info) { - return (List subscriptionEntities) -> { - if (DEBUG) { - Log.d(TAG, "subscriptionManager.subscriptionTable.doOnNext() called with: " - + "subscriptionEntities = [" + subscriptionEntities + "]"); - } - if (subscribeButtonMonitor != null) { - subscribeButtonMonitor.dispose(); - } - - if (subscriptionEntities.isEmpty()) { - if (DEBUG) { - Log.d(TAG, "No subscription to this channel!"); - } - final SubscriptionEntity channel = new SubscriptionEntity(); - channel.setServiceId(info.getServiceId()); - channel.setUrl(info.getUrl()); - channel.setData(info.getName(), - info.getAvatarUrl(), - info.getDescription(), - info.getSubscriberCount()); - updateNotifyButton(null); - subscribeButtonMonitor = monitorSubscribeButton( - headerBinding.channelSubscribeButton, mapOnSubscribe(channel, info)); - } else { - if (DEBUG) { - Log.d(TAG, "Found subscription to this channel!"); - } - final SubscriptionEntity subscription = subscriptionEntities.get(0); - updateNotifyButton(subscription); - subscribeButtonMonitor = monitorSubscribeButton( - headerBinding.channelSubscribeButton, mapOnUnsubscribe(subscription)); - } - }; - } - - private void updateSubscribeButton(final boolean isSubscribed) { - if (DEBUG) { - Log.d(TAG, "updateSubscribeButton() called with: " - + "isSubscribed = [" + isSubscribed + "]"); - } - - final boolean isButtonVisible = headerBinding.channelSubscribeButton.getVisibility() - == View.VISIBLE; - final int backgroundDuration = isButtonVisible ? 300 : 0; - final int textDuration = isButtonVisible ? 200 : 0; - - final int subscribeBackground = ThemeHelper - .resolveColorFromAttr(activity, R.attr.colorPrimary); - final int subscribeText = ContextCompat.getColor(activity, R.color.subscribe_text_color); - final int subscribedBackground = ContextCompat - .getColor(activity, R.color.subscribed_background_color); - final int subscribedText = ContextCompat.getColor(activity, R.color.subscribed_text_color); - - if (!isSubscribed) { - headerBinding.channelSubscribeButton.setText(R.string.subscribe_button_title); - animateBackgroundColor(headerBinding.channelSubscribeButton, backgroundDuration, - subscribedBackground, subscribeBackground); - animateTextColor(headerBinding.channelSubscribeButton, textDuration, subscribedText, - subscribeText); - } else { - headerBinding.channelSubscribeButton.setText(R.string.subscribed_button_title); - animateBackgroundColor(headerBinding.channelSubscribeButton, backgroundDuration, - subscribeBackground, subscribedBackground); - animateTextColor(headerBinding.channelSubscribeButton, textDuration, subscribeText, - subscribedText); - } - - animate(headerBinding.channelSubscribeButton, true, 100, - AnimationType.LIGHT_SCALE_AND_ALPHA); - } - - private void updateNotifyButton(@Nullable final SubscriptionEntity subscription) { - if (menuNotifyButton == null) { - return; - } - if (subscription != null) { - menuNotifyButton.setEnabled( - NotificationHelper.areNewStreamsNotificationsEnabled(requireContext()) - ); - menuNotifyButton.setChecked( - subscription.getNotificationMode() == NotificationMode.ENABLED - ); - } - - menuNotifyButton.setVisible(subscription != null); - } - - private void setNotify(final boolean isEnabled) { - disposables.add( - subscriptionManager - .updateNotificationMode( - currentInfo.getServiceId(), - currentInfo.getUrl(), - isEnabled ? NotificationMode.ENABLED : NotificationMode.DISABLED) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe() - ); - } - - /** - * Show a snackbar with the option to enable notifications on new streams for this channel. - */ - private void showNotifySnackbar() { - Snackbar.make(itemsList, R.string.you_successfully_subscribed, Snackbar.LENGTH_LONG) - .setAction(R.string.get_notified, v -> setNotify(true)) - .setActionTextColor(Color.YELLOW) - .show(); - } - - /*////////////////////////////////////////////////////////////////////////// - // Load and handle - //////////////////////////////////////////////////////////////////////////*/ - - @Override - protected Single> loadMoreItemsLogic() { - return ExtractorHelper.getMoreChannelItems(serviceId, url, currentNextPage); + .subscribe(result -> { + isLoading.set(false); + handleResult(result); + }, throwable -> showError(new ErrorInfo(throwable, UserAction.REQUESTED_STREAM, + url == null ? "no url" : url, serviceId))); } @Override - protected Single loadResult(final boolean forceLoad) { - return ExtractorHelper.getChannelInfo(serviceId, url, forceLoad); - } + public void handleResult(@NonNull final ChannelInfo info) { + super.handleResult(info); - /*////////////////////////////////////////////////////////////////////////// - // OnClick - //////////////////////////////////////////////////////////////////////////*/ - - @Override - public void onClick(final View v) { - if (isLoading.get() || currentInfo == null) { - return; - } - - switch (v.getId()) { - case R.id.sub_channel_avatar_view: - case R.id.sub_channel_title_view: - if (!TextUtils.isEmpty(currentInfo.getParentChannelUrl())) { - try { - NavigationHelper.openChannelFragment(getFM(), currentInfo.getServiceId(), - currentInfo.getParentChannelUrl(), - currentInfo.getParentChannelName()); - } catch (final Exception e) { - ErrorUtil.showUiErrorSnackbar(this, "Opening channel fragment", e); - } - } else if (DEBUG) { - Log.i(TAG, "Can't open parent channel because we got no channel URL"); - } - break; - } - } - - /*////////////////////////////////////////////////////////////////////////// - // Contract - //////////////////////////////////////////////////////////////////////////*/ - - @Override - public void showLoading() { - super.showLoading(); - PicassoHelper.cancelTag(PICASSO_CHANNEL_TAG); - animate(headerBinding.channelSubscribeButton, false, 100); - } - - @Override - public void handleResult(@NonNull final ChannelInfo result) { - super.handleResult(result); - - headerBinding.getRoot().setVisibility(View.VISIBLE); - PicassoHelper.loadBanner(result.getBannerUrl()).tag(PICASSO_CHANNEL_TAG) - .into(headerBinding.channelBannerImage); - PicassoHelper.loadAvatar(result.getAvatarUrl()).tag(PICASSO_CHANNEL_TAG) - .into(headerBinding.channelAvatarView); - PicassoHelper.loadAvatar(result.getParentChannelAvatarUrl()).tag(PICASSO_CHANNEL_TAG) - .into(headerBinding.subChannelAvatarView); - - headerBinding.channelSubscriberView.setVisibility(View.VISIBLE); - if (result.getSubscriberCount() >= 0) { - headerBinding.channelSubscriberView.setText(Localization - .shortSubscriberCount(activity, result.getSubscriberCount())); - } else { - headerBinding.channelSubscriberView.setText(R.string.subscribers_count_not_available); - } - - if (!TextUtils.isEmpty(currentInfo.getParentChannelName())) { - headerBinding.subChannelTitleView.setText(String.format( - getString(R.string.channel_created_by), - currentInfo.getParentChannelName()) - ); - headerBinding.subChannelTitleView.setVisibility(View.VISIBLE); - headerBinding.subChannelAvatarView.setVisibility(View.VISIBLE); - } else { - headerBinding.subChannelTitleView.setVisibility(View.GONE); - } - - if (menuRssButton != null) { - menuRssButton.setVisible(!TextUtils.isEmpty(result.getFeedUrl())); - } - - // PlaylistControls should be visible only if there is some item in - // infoListAdapter other than header - if (infoListAdapter.getItemCount() != 1) { - playlistControlBinding.getRoot().setVisibility(View.VISIBLE); - } else { - playlistControlBinding.getRoot().setVisibility(View.GONE); - } - - channelContentNotSupported = false; - for (final Throwable throwable : result.getErrors()) { - if (throwable instanceof ContentNotSupportedException) { - channelContentNotSupported = true; - showContentNotSupportedIfNeeded(); - break; - } - } - - disposables.clear(); - if (subscribeButtonMonitor != null) { - subscribeButtonMonitor.dispose(); - } - updateSubscription(result); - monitorSubscription(result); - - playlistControlBinding.playlistCtrlPlayAllButton - .setOnClickListener(view -> NavigationHelper - .playOnMainPlayer(activity, getPlayQueue())); - playlistControlBinding.playlistCtrlPlayPopupButton - .setOnClickListener(view -> NavigationHelper - .playOnPopupPlayer(activity, getPlayQueue(), false)); - playlistControlBinding.playlistCtrlPlayBgButton - .setOnClickListener(view -> NavigationHelper - .playOnBackgroundPlayer(activity, getPlayQueue(), false)); - - playlistControlBinding.playlistCtrlPlayPopupButton.setOnLongClickListener(view -> { - NavigationHelper.enqueueOnPlayer(activity, getPlayQueue(), PlayerType.POPUP); - return true; - }); - - playlistControlBinding.playlistCtrlPlayBgButton.setOnLongClickListener(view -> { - NavigationHelper.enqueueOnPlayer(activity, getPlayQueue(), PlayerType.AUDIO); - return true; - }); - } - - private void showContentNotSupportedIfNeeded() { - // channelBinding might not be initialized when handleResult() is called - // (e.g. after rotating the screen, #6696) - if (!channelContentNotSupported || channelBinding == null) { - return; - } - - channelBinding.errorContentNotSupported.setVisibility(View.VISIBLE); - channelBinding.channelKaomoji.setText("(︶︹︺)"); - channelBinding.channelKaomoji.setTextSize(TypedValue.COMPLEX_UNIT_SP, 45f); - channelBinding.emptyStateMessage.setVisibility(View.GONE); - } - - private PlayQueue getPlayQueue() { - final List streamItems = infoListAdapter.getItemsList().stream() - .filter(StreamInfoItem.class::isInstance) - .map(StreamInfoItem.class::cast) - .collect(Collectors.toList()); - - return new ChannelPlayQueue(currentInfo.getServiceId(), currentInfo.getUrl(), - currentInfo.getNextPage(), streamItems, 0); - } - - /*////////////////////////////////////////////////////////////////////////// - // Utils - //////////////////////////////////////////////////////////////////////////*/ - - @Override - public void setTitle(final String title) { - super.setTitle(title); - if (!useAsFrontPage) { - headerBinding.channelTitleView.setText(title); - } + currentInfo = info; + setInitialData(info.getServiceId(), info.getOriginalUrl(), info.getName()); + updateTabs(); + updateRssButton(); } } diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelInfoFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelInfoFragment.java new file mode 100644 index 000000000..c9273f528 --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelInfoFragment.java @@ -0,0 +1,38 @@ +package org.schabi.newpipe.fragments.list.channel; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import org.schabi.newpipe.BaseFragment; +import org.schabi.newpipe.databinding.FragmentChannelInfoBinding; + +public class ChannelInfoFragment extends BaseFragment { + private String description; + + public static ChannelInfoFragment getInstance(final String description) { + final ChannelInfoFragment fragment = new ChannelInfoFragment(); + fragment.description = description; + return fragment; + } + + public ChannelInfoFragment() { + super(); + } + + @Override + public View onCreateView(@NonNull final LayoutInflater inflater, + @Nullable final ViewGroup container, + final Bundle savedInstanceState) { + final FragmentChannelInfoBinding binding = + FragmentChannelInfoBinding.inflate(inflater, container, false); + binding.descriptionText.setText(description); + + return binding.getRoot(); + } + +} diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelTabFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelTabFragment.java new file mode 100644 index 000000000..12514a55c --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelTabFragment.java @@ -0,0 +1,68 @@ +package org.schabi.newpipe.fragments.list.channel; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import org.schabi.newpipe.R; +import org.schabi.newpipe.error.UserAction; +import org.schabi.newpipe.extractor.InfoItem; +import org.schabi.newpipe.extractor.ListExtractor; +import org.schabi.newpipe.extractor.channel.ChannelTabInfo; +import org.schabi.newpipe.extractor.linkhandler.ChannelTabHandler; +import org.schabi.newpipe.fragments.list.BaseListInfoFragment; +import org.schabi.newpipe.util.Constants; +import org.schabi.newpipe.util.ExtractorHelper; + +import icepick.State; +import io.reactivex.rxjava3.core.Single; + +public class ChannelTabFragment extends BaseListInfoFragment { + + @State + protected int serviceId = Constants.NO_SERVICE_ID; + + @State + protected ChannelTabHandler tabHandler; + + public static ChannelTabFragment getInstance(final int serviceId, + final ChannelTabHandler tabHandler) { + final ChannelTabFragment instance = new ChannelTabFragment(); + instance.serviceId = serviceId; + instance.tabHandler = tabHandler; + return instance; + } + + public ChannelTabFragment() { + super(UserAction.REQUESTED_CHANNEL); + } + + /*////////////////////////////////////////////////////////////////////////// + // LifeCycle + //////////////////////////////////////////////////////////////////////////*/ + + @Override + public View onCreateView(@NonNull final LayoutInflater inflater, + @Nullable final ViewGroup container, + @Nullable final Bundle savedInstanceState) { + return inflater.inflate(R.layout.fragment_channel_tab, container, false); + } + + @Override + protected Single loadResult(final boolean forceLoad) { + return ExtractorHelper.getChannelTab(serviceId, tabHandler, forceLoad); + } + + @Override + protected Single> loadMoreItemsLogic() { + return ExtractorHelper.getMoreChannelTabItems(serviceId, tabHandler, currentNextPage); + } + + @Override + public void setTitle(final String title) { + } +} diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelVideosFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelVideosFragment.java new file mode 100644 index 000000000..9f8c83ce7 --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelVideosFragment.java @@ -0,0 +1,584 @@ +package org.schabi.newpipe.fragments.list.channel; + +import static org.schabi.newpipe.ktx.TextViewUtils.animateTextColor; +import static org.schabi.newpipe.ktx.ViewUtils.animate; +import static org.schabi.newpipe.ktx.ViewUtils.animateBackgroundColor; + +import android.content.Context; +import android.graphics.Color; +import android.os.Bundle; +import android.text.TextUtils; +import android.util.Log; +import android.util.TypedValue; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.ActionBar; +import androidx.core.content.ContextCompat; + +import com.google.android.material.snackbar.Snackbar; +import com.jakewharton.rxbinding4.view.RxView; + +import org.schabi.newpipe.R; +import org.schabi.newpipe.database.subscription.NotificationMode; +import org.schabi.newpipe.database.subscription.SubscriptionEntity; +import org.schabi.newpipe.databinding.ChannelHeaderBinding; +import org.schabi.newpipe.databinding.FragmentChannelVideosBinding; +import org.schabi.newpipe.databinding.PlaylistControlBinding; +import org.schabi.newpipe.error.ErrorInfo; +import org.schabi.newpipe.error.ErrorUtil; +import org.schabi.newpipe.error.UserAction; +import org.schabi.newpipe.extractor.ListExtractor; +import org.schabi.newpipe.extractor.channel.ChannelInfo; +import org.schabi.newpipe.extractor.exceptions.ContentNotSupportedException; +import org.schabi.newpipe.extractor.stream.StreamInfoItem; +import org.schabi.newpipe.fragments.list.BaseListInfoFragment; +import org.schabi.newpipe.ktx.AnimationType; +import org.schabi.newpipe.local.feed.notifications.NotificationHelper; +import org.schabi.newpipe.local.subscription.SubscriptionManager; +import org.schabi.newpipe.player.PlayerType; +import org.schabi.newpipe.player.playqueue.ChannelPlayQueue; +import org.schabi.newpipe.player.playqueue.PlayQueue; +import org.schabi.newpipe.util.ExtractorHelper; +import org.schabi.newpipe.util.Localization; +import org.schabi.newpipe.util.NavigationHelper; +import org.schabi.newpipe.util.PicassoHelper; +import org.schabi.newpipe.util.ThemeHelper; +import org.schabi.newpipe.util.external_communication.ShareUtils; + +import java.util.List; +import java.util.concurrent.TimeUnit; +import java.util.function.Supplier; +import java.util.stream.Collectors; + +import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; +import io.reactivex.rxjava3.core.Observable; +import io.reactivex.rxjava3.core.Single; +import io.reactivex.rxjava3.disposables.CompositeDisposable; +import io.reactivex.rxjava3.disposables.Disposable; +import io.reactivex.rxjava3.functions.Action; +import io.reactivex.rxjava3.functions.Consumer; +import io.reactivex.rxjava3.functions.Function; +import io.reactivex.rxjava3.schedulers.Schedulers; + +public class ChannelVideosFragment extends BaseListInfoFragment + implements View.OnClickListener { + + private static final int BUTTON_DEBOUNCE_INTERVAL = 100; + private static final String PICASSO_CHANNEL_TAG = "PICASSO_CHANNEL_TAG"; + + private final CompositeDisposable disposables = new CompositeDisposable(); + private Disposable subscribeButtonMonitor; + + private boolean channelContentNotSupported = false; + + /*////////////////////////////////////////////////////////////////////////// + // Views + //////////////////////////////////////////////////////////////////////////*/ + + private SubscriptionManager subscriptionManager; + + private FragmentChannelVideosBinding channelBinding; + private ChannelHeaderBinding headerBinding; + private PlaylistControlBinding playlistControlBinding; + + private MenuItem menuNotifyButton; + + public static ChannelVideosFragment getInstance(@NonNull final ChannelInfo channelInfo) { + final ChannelVideosFragment instance = new ChannelVideosFragment(); + instance.setInitialData(channelInfo.getServiceId(), channelInfo.getUrl(), + channelInfo.getName()); + instance.currentInfo = channelInfo; + instance.currentNextPage = channelInfo.getNextPage(); + return instance; + } + + public static ChannelVideosFragment getInstance( + final int serviceId, final String url, final String name) { + final ChannelVideosFragment instance = new ChannelVideosFragment(); + instance.setInitialData(serviceId, url, name); + return instance; + } + + public ChannelVideosFragment() { + super(UserAction.REQUESTED_CHANNEL); + } + + @Override + public void onResume() { + super.onResume(); + if (activity != null && useAsFrontPage) { + setTitle(currentInfo != null ? currentInfo.getName() : name); + } + } + + /*////////////////////////////////////////////////////////////////////////// + // LifeCycle + //////////////////////////////////////////////////////////////////////////*/ + + @Override + public void onAttach(@NonNull final Context context) { + super.onAttach(context); + subscriptionManager = new SubscriptionManager(activity); + } + + @Override + public View onCreateView(@NonNull final LayoutInflater inflater, + @Nullable final ViewGroup container, + @Nullable final Bundle savedInstanceState) { + return inflater.inflate(R.layout.fragment_channel_videos, container, false); + } + + @Override + public void onViewCreated(@NonNull final View rootView, final Bundle savedInstanceState) { + super.onViewCreated(rootView, savedInstanceState); + channelBinding = FragmentChannelVideosBinding.bind(rootView); + showContentNotSupportedIfNeeded(); + } + + @Override + public void onDestroy() { + super.onDestroy(); + disposables.clear(); + if (subscribeButtonMonitor != null) { + subscribeButtonMonitor.dispose(); + } + channelBinding = null; + headerBinding = null; + playlistControlBinding = null; + } + + /*////////////////////////////////////////////////////////////////////////// + // Init + //////////////////////////////////////////////////////////////////////////*/ + + @Override + protected Supplier getListHeaderSupplier() { + headerBinding = ChannelHeaderBinding + .inflate(activity.getLayoutInflater(), itemsList, false); + playlistControlBinding = headerBinding.playlistControl; + + return headerBinding::getRoot; + } + + @Override + protected void initListeners() { + super.initListeners(); + + headerBinding.subChannelTitleView.setOnClickListener(this); + headerBinding.subChannelAvatarView.setOnClickListener(this); + } + + /*////////////////////////////////////////////////////////////////////////// + // Menu + //////////////////////////////////////////////////////////////////////////*/ + + @Override + public void onCreateOptionsMenu(@NonNull final Menu menu, + @NonNull final MenuInflater inflater) { + super.onCreateOptionsMenu(menu, inflater); + final ActionBar supportActionBar = activity.getSupportActionBar(); + if (useAsFrontPage && supportActionBar != null) { + supportActionBar.setDisplayHomeAsUpEnabled(false); + } else { + inflater.inflate(R.menu.menu_channel_videos, menu); + + if (DEBUG) { + Log.d(TAG, "onCreateOptionsMenu() called with: " + + "menu = [" + menu + "], inflater = [" + inflater + "]"); + } + menuNotifyButton = menu.findItem(R.id.menu_item_notify); + } + } + + @Override + public boolean onOptionsItemSelected(final MenuItem item) { + switch (item.getItemId()) { + case R.id.menu_item_notify: + final boolean value = !item.isChecked(); + item.setEnabled(false); + setNotify(value); + break; + default: + return super.onOptionsItemSelected(item); + } + return true; + } + + private void updateNotifyButton(@Nullable final SubscriptionEntity subscription) { + if (menuNotifyButton == null) { + return; + } + if (subscription != null) { + menuNotifyButton.setEnabled( + NotificationHelper.areNewStreamsNotificationsEnabled(requireContext()) + ); + menuNotifyButton.setChecked( + subscription.getNotificationMode() == NotificationMode.ENABLED + ); + } + + menuNotifyButton.setVisible(subscription != null); + } + + private void setNotify(final boolean isEnabled) { + disposables.add( + subscriptionManager + .updateNotificationMode( + currentInfo.getServiceId(), + currentInfo.getUrl(), + isEnabled ? NotificationMode.ENABLED : NotificationMode.DISABLED) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe() + ); + } + + /*////////////////////////////////////////////////////////////////////////// + // Channel Subscription + //////////////////////////////////////////////////////////////////////////*/ + + private void monitorSubscription(final ChannelInfo info) { + final Consumer onError = (Throwable throwable) -> { + animate(headerBinding.channelSubscribeButton, false, 100); + showSnackBarError(new ErrorInfo(throwable, UserAction.SUBSCRIPTION_GET, + "Get subscription status", currentInfo)); + }; + + final Observable> observable = subscriptionManager + .subscriptionTable() + .getSubscriptionFlowable(info.getServiceId(), info.getUrl()) + .toObservable(); + + disposables.add(observable + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(getSubscribeUpdateMonitor(info), onError)); + + disposables.add(observable + .map(List::isEmpty) + .distinctUntilChanged() + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(isEmpty -> updateSubscribeButton(!isEmpty), onError)); + + disposables.add(observable + .map(List::isEmpty) + .distinctUntilChanged() + .skip(1) // channel has just been opened + .filter(x -> NotificationHelper.areNewStreamsNotificationsEnabled(requireContext())) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(isEmpty -> { + if (!isEmpty) { + showNotifySnackbar(); + } + }, onError)); + } + + private Function mapOnSubscribe(final SubscriptionEntity subscription, + final ChannelInfo info) { + return (@NonNull Object o) -> { + subscriptionManager.insertSubscription(subscription, info); + return o; + }; + } + + private Function mapOnUnsubscribe(final SubscriptionEntity subscription) { + return (@NonNull Object o) -> { + subscriptionManager.deleteSubscription(subscription); + return o; + }; + } + + private void updateSubscription(final ChannelInfo info) { + if (DEBUG) { + Log.d(TAG, "updateSubscription() called with: info = [" + info + "]"); + } + final Action onComplete = () -> { + if (DEBUG) { + Log.d(TAG, "Updated subscription: " + info.getUrl()); + } + }; + + final Consumer onError = (@NonNull Throwable throwable) -> + showSnackBarError(new ErrorInfo(throwable, UserAction.SUBSCRIPTION_UPDATE, + "Updating subscription for " + info.getUrl(), info)); + + disposables.add(subscriptionManager.updateChannelInfo(info) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(onComplete, onError)); + } + + private Disposable monitorSubscribeButton(final Button subscribeButton, + final Function action) { + final Consumer onNext = (@NonNull Object o) -> { + if (DEBUG) { + Log.d(TAG, "Changed subscription status to this channel!"); + } + }; + + final Consumer onError = (@NonNull Throwable throwable) -> + showSnackBarError(new ErrorInfo(throwable, UserAction.SUBSCRIPTION_CHANGE, + "Changing subscription for " + currentInfo.getUrl(), currentInfo)); + + /* Emit clicks from main thread unto io thread */ + return RxView.clicks(subscribeButton) + .subscribeOn(AndroidSchedulers.mainThread()) + .observeOn(Schedulers.io()) + .debounce(BUTTON_DEBOUNCE_INTERVAL, TimeUnit.MILLISECONDS) // Ignore rapid clicks + .map(action) + .subscribe(onNext, onError); + } + + private Consumer> getSubscribeUpdateMonitor(final ChannelInfo info) { + return (List subscriptionEntities) -> { + if (DEBUG) { + Log.d(TAG, "subscriptionManager.subscriptionTable.doOnNext() called with: " + + "subscriptionEntities = [" + subscriptionEntities + "]"); + } + if (subscribeButtonMonitor != null) { + subscribeButtonMonitor.dispose(); + } + + if (subscriptionEntities.isEmpty()) { + if (DEBUG) { + Log.d(TAG, "No subscription to this channel!"); + } + final SubscriptionEntity channel = new SubscriptionEntity(); + channel.setServiceId(info.getServiceId()); + channel.setUrl(info.getUrl()); + channel.setData(info.getName(), + info.getAvatarUrl(), + info.getDescription(), + info.getSubscriberCount()); + updateNotifyButton(null); + subscribeButtonMonitor = monitorSubscribeButton( + headerBinding.channelSubscribeButton, mapOnSubscribe(channel, info)); + } else { + if (DEBUG) { + Log.d(TAG, "Found subscription to this channel!"); + } + final SubscriptionEntity subscription = subscriptionEntities.get(0); + updateNotifyButton(subscription); + subscribeButtonMonitor = monitorSubscribeButton( + headerBinding.channelSubscribeButton, mapOnUnsubscribe(subscription)); + } + }; + } + + private void updateSubscribeButton(final boolean isSubscribed) { + if (DEBUG) { + Log.d(TAG, "updateSubscribeButton() called with: " + + "isSubscribed = [" + isSubscribed + "]"); + } + + final boolean isButtonVisible = headerBinding.channelSubscribeButton.getVisibility() + == View.VISIBLE; + final int backgroundDuration = isButtonVisible ? 300 : 0; + final int textDuration = isButtonVisible ? 200 : 0; + + final int subscribeBackground = ThemeHelper + .resolveColorFromAttr(activity, R.attr.colorPrimary); + final int subscribeText = ContextCompat.getColor(activity, R.color.subscribe_text_color); + final int subscribedBackground = ContextCompat + .getColor(activity, R.color.subscribed_background_color); + final int subscribedText = ContextCompat.getColor(activity, R.color.subscribed_text_color); + + if (!isSubscribed) { + headerBinding.channelSubscribeButton.setText(R.string.subscribe_button_title); + animateBackgroundColor(headerBinding.channelSubscribeButton, backgroundDuration, + subscribedBackground, subscribeBackground); + animateTextColor(headerBinding.channelSubscribeButton, textDuration, subscribedText, + subscribeText); + } else { + headerBinding.channelSubscribeButton.setText(R.string.subscribed_button_title); + animateBackgroundColor(headerBinding.channelSubscribeButton, backgroundDuration, + subscribeBackground, subscribedBackground); + animateTextColor(headerBinding.channelSubscribeButton, textDuration, subscribeText, + subscribedText); + } + + animate(headerBinding.channelSubscribeButton, true, 100, + AnimationType.LIGHT_SCALE_AND_ALPHA); + } + + /** + * Show a snackbar with the option to enable notifications on new streams for this channel. + */ + private void showNotifySnackbar() { + Snackbar.make(itemsList, R.string.you_successfully_subscribed, Snackbar.LENGTH_LONG) + .setAction(R.string.get_notified, v -> setNotify(true)) + .setActionTextColor(Color.YELLOW) + .show(); + } + + /*////////////////////////////////////////////////////////////////////////// + // Load and handle + //////////////////////////////////////////////////////////////////////////*/ + + @Override + protected Single> loadMoreItemsLogic() { + return ExtractorHelper.getMoreChannelItems(serviceId, url, currentNextPage); + } + + @Override + protected Single loadResult(final boolean forceLoad) { + return ExtractorHelper.getChannelInfo(serviceId, url, forceLoad); + } + + /*////////////////////////////////////////////////////////////////////////// + // OnClick + //////////////////////////////////////////////////////////////////////////*/ + + @Override + public void onClick(final View v) { + if (isLoading.get() || currentInfo == null) { + return; + } + + switch (v.getId()) { + case R.id.sub_channel_avatar_view: + case R.id.sub_channel_title_view: + if (!TextUtils.isEmpty(currentInfo.getParentChannelUrl())) { + try { + NavigationHelper.openChannelFragment(getFM(), currentInfo.getServiceId(), + currentInfo.getParentChannelUrl(), + currentInfo.getParentChannelName()); + } catch (final Exception e) { + ErrorUtil.showUiErrorSnackbar(this, "Opening channel fragment", e); + } + } else if (DEBUG) { + Log.i(TAG, "Can't open parent channel because we got no channel URL"); + } + break; + } + } + + /*////////////////////////////////////////////////////////////////////////// + // Contract + //////////////////////////////////////////////////////////////////////////*/ + + @Override + public void showLoading() { + super.showLoading(); + PicassoHelper.cancelTag(PICASSO_CHANNEL_TAG); + animate(headerBinding.channelSubscribeButton, false, 100); + } + + @Override + public void handleResult(@NonNull final ChannelInfo result) { + super.handleResult(result); + + headerBinding.getRoot().setVisibility(View.VISIBLE); + PicassoHelper.loadBanner(result.getBannerUrl()).tag(PICASSO_CHANNEL_TAG) + .into(headerBinding.channelBannerImage); + PicassoHelper.loadAvatar(result.getAvatarUrl()).tag(PICASSO_CHANNEL_TAG) + .into(headerBinding.channelAvatarView); + PicassoHelper.loadAvatar(result.getParentChannelAvatarUrl()).tag(PICASSO_CHANNEL_TAG) + .into(headerBinding.subChannelAvatarView); + + headerBinding.channelSubscriberView.setVisibility(View.VISIBLE); + if (result.getSubscriberCount() >= 0) { + headerBinding.channelSubscriberView.setText(Localization + .shortSubscriberCount(activity, result.getSubscriberCount())); + } else { + headerBinding.channelSubscriberView.setText(R.string.subscribers_count_not_available); + } + + if (!TextUtils.isEmpty(currentInfo.getParentChannelName())) { + headerBinding.subChannelTitleView.setText(String.format( + getString(R.string.channel_created_by), + currentInfo.getParentChannelName()) + ); + headerBinding.subChannelTitleView.setVisibility(View.VISIBLE); + headerBinding.subChannelAvatarView.setVisibility(View.VISIBLE); + } else { + headerBinding.subChannelTitleView.setVisibility(View.GONE); + } + + // updateRssButton(); + + // PlaylistControls should be visible only if there is some item in + // infoListAdapter other than header + if (infoListAdapter.getItemCount() != 1) { + playlistControlBinding.getRoot().setVisibility(View.VISIBLE); + } else { + playlistControlBinding.getRoot().setVisibility(View.GONE); + } + + channelContentNotSupported = false; + for (final Throwable throwable : result.getErrors()) { + if (throwable instanceof ContentNotSupportedException) { + channelContentNotSupported = true; + showContentNotSupportedIfNeeded(); + break; + } + } + + disposables.clear(); + if (subscribeButtonMonitor != null) { + subscribeButtonMonitor.dispose(); + } + updateSubscription(result); + monitorSubscription(result); + + playlistControlBinding.playlistCtrlPlayAllButton + .setOnClickListener(view -> NavigationHelper + .playOnMainPlayer(activity, getPlayQueue())); + playlistControlBinding.playlistCtrlPlayPopupButton + .setOnClickListener(view -> NavigationHelper + .playOnPopupPlayer(activity, getPlayQueue(), false)); + playlistControlBinding.playlistCtrlPlayBgButton + .setOnClickListener(view -> NavigationHelper + .playOnBackgroundPlayer(activity, getPlayQueue(), false)); + + playlistControlBinding.playlistCtrlPlayPopupButton.setOnLongClickListener(view -> { + NavigationHelper.enqueueOnPlayer(activity, getPlayQueue(), PlayerType.POPUP); + return true; + }); + + playlistControlBinding.playlistCtrlPlayBgButton.setOnLongClickListener(view -> { + NavigationHelper.enqueueOnPlayer(activity, getPlayQueue(), PlayerType.AUDIO); + return true; + }); + } + + private void showContentNotSupportedIfNeeded() { + // channelBinding might not be initialized when handleResult() is called + // (e.g. after rotating the screen, #6696) + if (!channelContentNotSupported || channelBinding == null) { + return; + } + + channelBinding.errorContentNotSupported.setVisibility(View.VISIBLE); + channelBinding.channelKaomoji.setText("(︶︹︺)"); + channelBinding.channelKaomoji.setTextSize(TypedValue.COMPLEX_UNIT_SP, 45f); + channelBinding.channelNoVideos.setVisibility(View.GONE); + } + + private PlayQueue getPlayQueue() { + final List streamItems = infoListAdapter.getItemsList().stream() + .filter(StreamInfoItem.class::isInstance) + .map(StreamInfoItem.class::cast) + .collect(Collectors.toList()); + + return new ChannelPlayQueue(currentInfo.getServiceId(), currentInfo.getUrl(), + currentInfo.getNextPage(), streamItems, 0); + } + + /*////////////////////////////////////////////////////////////////////////// + // Utils + //////////////////////////////////////////////////////////////////////////*/ + + @Override + public void setTitle(final String title) { + super.setTitle(title); + headerBinding.channelTitleView.setText(title); + } +} diff --git a/app/src/main/java/org/schabi/newpipe/settings/tabs/Tab.java b/app/src/main/java/org/schabi/newpipe/settings/tabs/Tab.java index 7e3f5d0c8..a06bf32d4 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/tabs/Tab.java +++ b/app/src/main/java/org/schabi/newpipe/settings/tabs/Tab.java @@ -19,7 +19,7 @@ import org.schabi.newpipe.extractor.NewPipe; import org.schabi.newpipe.extractor.StreamingService; import org.schabi.newpipe.extractor.exceptions.ExtractionException; import org.schabi.newpipe.fragments.BlankFragment; -import org.schabi.newpipe.fragments.list.channel.ChannelFragment; +import org.schabi.newpipe.fragments.list.channel.ChannelVideosFragment; import org.schabi.newpipe.fragments.list.kiosk.DefaultKioskFragment; import org.schabi.newpipe.fragments.list.kiosk.KioskFragment; import org.schabi.newpipe.fragments.list.playlist.PlaylistFragment; @@ -432,8 +432,8 @@ public abstract class Tab { } @Override - public ChannelFragment getFragment(final Context context) { - return ChannelFragment.getInstance(channelServiceId, channelUrl, channelName); + public ChannelVideosFragment getFragment(final Context context) { + return ChannelVideosFragment.getInstance(channelServiceId, channelUrl, channelName); } @Override diff --git a/app/src/main/java/org/schabi/newpipe/util/ExtractorHelper.java b/app/src/main/java/org/schabi/newpipe/util/ExtractorHelper.java index d5d472d6f..b4648c79b 100644 --- a/app/src/main/java/org/schabi/newpipe/util/ExtractorHelper.java +++ b/app/src/main/java/org/schabi/newpipe/util/ExtractorHelper.java @@ -42,11 +42,13 @@ import org.schabi.newpipe.extractor.NewPipe; import org.schabi.newpipe.extractor.Page; import org.schabi.newpipe.extractor.StreamingService; import org.schabi.newpipe.extractor.channel.ChannelInfo; +import org.schabi.newpipe.extractor.channel.ChannelTabInfo; import org.schabi.newpipe.extractor.comments.CommentsInfo; import org.schabi.newpipe.extractor.comments.CommentsInfoItem; import org.schabi.newpipe.extractor.feed.FeedExtractor; import org.schabi.newpipe.extractor.feed.FeedInfo; import org.schabi.newpipe.extractor.kiosk.KioskInfo; +import org.schabi.newpipe.extractor.linkhandler.ChannelTabHandler; import org.schabi.newpipe.extractor.playlist.PlaylistInfo; import org.schabi.newpipe.extractor.search.SearchInfo; import org.schabi.newpipe.extractor.stream.StreamInfo; @@ -151,6 +153,25 @@ public final class ExtractorHelper { return maybeFeedInfo.switchIfEmpty(getChannelInfo(serviceId, url, true)); } + public static Single getChannelTab(final int serviceId, + final ChannelTabHandler tabHandler, + final boolean forceLoad) { + checkServiceId(serviceId); + return checkCache(forceLoad, serviceId, + tabHandler.getUrl() + tabHandler.getTab().name(), InfoItem.InfoType.CHANNEL, + Single.fromCallable(() -> + ChannelTabInfo.getInfo(NewPipe.getService(serviceId), tabHandler))); + } + + public static Single> getMoreChannelTabItems(final int serviceId, + final ChannelTabHandler + tabHandler, + final Page nextPage) { + checkServiceId(serviceId); + return Single.fromCallable(() -> + ChannelTabInfo.getMoreItems(NewPipe.getService(serviceId), tabHandler, nextPage)); + } + public static Single getCommentsInfo(final int serviceId, final String url, final boolean forceLoad) { checkServiceId(serviceId); @@ -229,7 +250,7 @@ public final class ExtractorHelper { load = actualLoadFromNetwork; } else { load = Maybe.concat(ExtractorHelper.loadFromCache(serviceId, url, infoType), - actualLoadFromNetwork.toMaybe()) + actualLoadFromNetwork.toMaybe()) .firstElement() // Take the first valid .toSingle(); } @@ -240,10 +261,10 @@ public final class ExtractorHelper { /** * Default implementation uses the {@link InfoCache} to get cached results. * - * @param the item type's class that extends {@link Info} - * @param serviceId the service to load from - * @param url the URL to load - * @param infoType the {@link InfoItem.InfoType} of the item + * @param the item type's class that extends {@link Info} + * @param serviceId the service to load from + * @param url the URL to load + * @param infoType the {@link InfoItem.InfoType} of the item * @return a {@link Single} that loads the item */ private static Maybe loadFromCache(final int serviceId, final String url, @@ -274,11 +295,12 @@ public final class ExtractorHelper { * Formats the text contained in the meta info list as HTML and puts it into the text view, * while also making the separator visible. If the list is null or empty, or the user chose not * to see meta information, both the text view and the separator are hidden - * @param metaInfos a list of meta information, can be null or empty - * @param metaInfoTextView the text view in which to show the formatted HTML + * + * @param metaInfos a list of meta information, can be null or empty + * @param metaInfoTextView the text view in which to show the formatted HTML * @param metaInfoSeparator another view to be shown or hidden accordingly to the text view - * @param disposables disposables created by the method are added here and their lifecycle - * should be handled by the calling class + * @param disposables disposables created by the method are added here and their lifecycle + * should be handled by the calling class */ public static void showMetaInfoInTextView(@Nullable final List metaInfos, final TextView metaInfoTextView, @@ -287,7 +309,7 @@ public final class ExtractorHelper { final Context context = metaInfoTextView.getContext(); if (metaInfos == null || metaInfos.isEmpty() || !PreferenceManager.getDefaultSharedPreferences(context).getBoolean( - context.getString(R.string.show_meta_info_key), true)) { + context.getString(R.string.show_meta_info_key), true)) { metaInfoTextView.setVisibility(View.GONE); metaInfoSeparator.setVisibility(View.GONE); diff --git a/app/src/main/res/layout/fragment_channel.xml b/app/src/main/res/layout/fragment_channel.xml index 714b9d4f9..d938f71a7 100644 --- a/app/src/main/res/layout/fragment_channel.xml +++ b/app/src/main/res/layout/fragment_channel.xml @@ -1,15 +1,25 @@ - + + + android:layout_below="@id/tab_layout" /> - - - - - - - - - - - - - - + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_channel_info.xml b/app/src/main/res/layout/fragment_channel_info.xml new file mode 100644 index 000000000..fbb8e355b --- /dev/null +++ b/app/src/main/res/layout/fragment_channel_info.xml @@ -0,0 +1,36 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_channel_tab.xml b/app/src/main/res/layout/fragment_channel_tab.xml new file mode 100644 index 000000000..519156296 --- /dev/null +++ b/app/src/main/res/layout/fragment_channel_tab.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_channel_videos.xml b/app/src/main/res/layout/fragment_channel_videos.xml new file mode 100644 index 000000000..2dfb2fbf6 --- /dev/null +++ b/app/src/main/res/layout/fragment_channel_videos.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/menu/menu_channel_videos.xml b/app/src/main/res/menu/menu_channel_videos.xml new file mode 100644 index 000000000..a3b2e7ae0 --- /dev/null +++ b/app/src/main/res/menu/menu_channel_videos.xml @@ -0,0 +1,14 @@ + + + + From 8627efd0a1dd3e8f3afc4e7ade8bc7f7241f3fd5 Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Sun, 23 Oct 2022 11:28:34 +0200 Subject: [PATCH 029/172] fix: get notified menu option on all tabs --- .../list/channel/ChannelFragment.java | 91 ++++++++++++++++++ .../list/channel/ChannelTabFragment.java | 8 ++ .../list/channel/ChannelVideosFragment.java | 95 ++++--------------- app/src/main/res/menu/menu_channel_videos.xml | 14 --- 4 files changed, 118 insertions(+), 90 deletions(-) delete mode 100644 app/src/main/res/menu/menu_channel_videos.xml diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java index 6989552f2..4938d1c00 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java @@ -1,5 +1,6 @@ package org.schabi.newpipe.fragments.list.channel; +import android.content.Context; import android.os.Bundle; import android.text.TextUtils; import android.util.Log; @@ -14,6 +15,8 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import org.schabi.newpipe.R; +import org.schabi.newpipe.database.subscription.NotificationMode; +import org.schabi.newpipe.database.subscription.SubscriptionEntity; import org.schabi.newpipe.databinding.FragmentChannelBinding; import org.schabi.newpipe.error.ErrorInfo; import org.schabi.newpipe.error.UserAction; @@ -21,14 +24,21 @@ import org.schabi.newpipe.extractor.channel.ChannelInfo; import org.schabi.newpipe.extractor.linkhandler.ChannelTabHandler; import org.schabi.newpipe.fragments.BaseStateFragment; import org.schabi.newpipe.fragments.detail.TabAdapter; +import org.schabi.newpipe.local.feed.notifications.NotificationHelper; +import org.schabi.newpipe.local.subscription.SubscriptionManager; import org.schabi.newpipe.util.Constants; import org.schabi.newpipe.util.ExtractorHelper; import org.schabi.newpipe.util.NavigationHelper; import org.schabi.newpipe.util.external_communication.ShareUtils; +import java.util.List; + import icepick.State; import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; +import io.reactivex.rxjava3.core.Observable; +import io.reactivex.rxjava3.disposables.CompositeDisposable; import io.reactivex.rxjava3.disposables.Disposable; +import io.reactivex.rxjava3.functions.Consumer; import io.reactivex.rxjava3.schedulers.Schedulers; public class ChannelFragment extends BaseStateFragment { @@ -41,8 +51,12 @@ public class ChannelFragment extends BaseStateFragment { private ChannelInfo currentInfo; private Disposable currentWorker; + private Disposable subscriptionMonitor; + private final CompositeDisposable disposables = new CompositeDisposable(); + private SubscriptionManager subscriptionManager; private MenuItem menuRssButton; + private MenuItem menuNotifyButton; /*////////////////////////////////////////////////////////////////////////// // Views @@ -78,6 +92,12 @@ public class ChannelFragment extends BaseStateFragment { setHasOptionsMenu(true); } + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + subscriptionManager = new SubscriptionManager(activity); + } + @Override public View onCreateView(@NonNull final LayoutInflater inflater, @Nullable final ViewGroup container, @@ -98,6 +118,13 @@ public class ChannelFragment extends BaseStateFragment { @Override public void onDestroy() { super.onDestroy(); + if (currentWorker != null) { + currentWorker.dispose(); + } + if (subscriptionMonitor != null) { + subscriptionMonitor.dispose(); + } + disposables.clear(); binding = null; } @@ -116,12 +143,19 @@ public class ChannelFragment extends BaseStateFragment { + "menu = [" + menu + "], inflater = [" + inflater + "]"); } menuRssButton = menu.findItem(R.id.menu_item_rss); + menuNotifyButton = menu.findItem(R.id.menu_item_notify); updateRssButton(); + monitorSubscription(); } @Override public boolean onOptionsItemSelected(final MenuItem item) { switch (item.getItemId()) { + case R.id.menu_item_notify: + final boolean value = !item.isChecked(); + item.setEnabled(false); + setNotify(value); + break; case R.id.action_settings: NavigationHelper.openSettings(requireContext()); break; @@ -153,6 +187,62 @@ public class ChannelFragment extends BaseStateFragment { } } + private void monitorSubscription() { + if (currentInfo != null) { + final Observable> observable = subscriptionManager + .subscriptionTable() + .getSubscriptionFlowable(currentInfo.getServiceId(), currentInfo.getUrl()) + .toObservable(); + + if (subscriptionMonitor != null) { + subscriptionMonitor.dispose(); + } + subscriptionMonitor = observable + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(getSubscribeUpdateMonitor()); + } + } + + private Consumer> getSubscribeUpdateMonitor() { + return (List subscriptionEntities) -> { + if (subscriptionEntities.isEmpty()) { + updateNotifyButton(null); + } else { + final SubscriptionEntity subscription = subscriptionEntities.get(0); + updateNotifyButton(subscription); + } + }; + } + + private void updateNotifyButton(@Nullable final SubscriptionEntity subscription) { + if (menuNotifyButton == null) { + return; + } + if (subscription != null) { + menuNotifyButton.setEnabled( + NotificationHelper.areNewStreamsNotificationsEnabled(requireContext()) + ); + menuNotifyButton.setChecked( + subscription.getNotificationMode() == NotificationMode.ENABLED + ); + } + + menuNotifyButton.setVisible(subscription != null); + } + + private void setNotify(final boolean isEnabled) { + disposables.add( + subscriptionManager + .updateNotificationMode( + currentInfo.getServiceId(), + currentInfo.getUrl(), + isEnabled ? NotificationMode.ENABLED : NotificationMode.DISABLED) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe() + ); + } + /*////////////////////////////////////////////////////////////////////////// // Init //////////////////////////////////////////////////////////////////////////*/ @@ -213,5 +303,6 @@ public class ChannelFragment extends BaseStateFragment { setInitialData(info.getServiceId(), info.getOriginalUrl(), info.getName()); updateTabs(); updateRssButton(); + monitorSubscription(); } } diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelTabFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelTabFragment.java index 12514a55c..21613d717 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelTabFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelTabFragment.java @@ -2,6 +2,8 @@ package org.schabi.newpipe.fragments.list.channel; import android.os.Bundle; import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; import android.view.View; import android.view.ViewGroup; @@ -45,6 +47,12 @@ public class ChannelTabFragment extends BaseListInfoFragment - - - From 6d84d195204873535f64912cbb78ab259f3289cc Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Sun, 23 Oct 2022 15:37:40 +0200 Subject: [PATCH 030/172] fix: handle unsupported content --- .../list/channel/ChannelFragment.java | 41 +++++++++++++------ .../list/channel/ChannelVideosFragment.java | 4 +- app/src/main/res/layout/fragment_channel.xml | 32 +++++++++++++++ 3 files changed, 63 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java index 4938d1c00..4cd8313fc 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java @@ -21,6 +21,7 @@ import org.schabi.newpipe.databinding.FragmentChannelBinding; import org.schabi.newpipe.error.ErrorInfo; import org.schabi.newpipe.error.UserAction; import org.schabi.newpipe.extractor.channel.ChannelInfo; +import org.schabi.newpipe.extractor.exceptions.ContentNotSupportedException; import org.schabi.newpipe.extractor.linkhandler.ChannelTabHandler; import org.schabi.newpipe.fragments.BaseStateFragment; import org.schabi.newpipe.fragments.detail.TabAdapter; @@ -247,20 +248,36 @@ public class ChannelFragment extends BaseStateFragment { // Init //////////////////////////////////////////////////////////////////////////*/ + private boolean isContentUnsupported() { + for (final Throwable throwable : currentInfo.getErrors()) { + if (throwable instanceof ContentNotSupportedException) { + return true; + } + } + return false; + } + private void updateTabs() { tabAdapter.clearAllItems(); if (currentInfo != null) { - tabAdapter.addFragment(ChannelVideosFragment.getInstance(currentInfo), "Videos"); - - for (final ChannelTabHandler tab : currentInfo.getTabs()) { + if (isContentUnsupported()) { + showEmptyState(); + binding.errorContentNotSupported.setVisibility(View.VISIBLE); + } else { tabAdapter.addFragment( - ChannelTabFragment.getInstance(serviceId, tab), tab.getTab().name()); - } + ChannelVideosFragment.getInstance(currentInfo), "Videos"); - final String description = currentInfo.getDescription(); - if (!description.isEmpty()) { - tabAdapter.addFragment(ChannelInfoFragment.getInstance(description), "Info"); + for (final ChannelTabHandler tab : currentInfo.getTabs()) { + tabAdapter.addFragment( + ChannelTabFragment.getInstance(serviceId, tab), tab.getTab().name()); + } + + final String description = currentInfo.getDescription(); + if (description != null && !description.isEmpty()) { + tabAdapter.addFragment( + ChannelInfoFragment.getInstance(description), "Info"); + } } } @@ -296,11 +313,11 @@ public class ChannelFragment extends BaseStateFragment { } @Override - public void handleResult(@NonNull final ChannelInfo info) { - super.handleResult(info); + public void handleResult(@NonNull final ChannelInfo result) { + super.handleResult(result); + currentInfo = result; + setInitialData(result.getServiceId(), result.getOriginalUrl(), result.getName()); - currentInfo = info; - setInitialData(info.getServiceId(), info.getOriginalUrl(), info.getName()); updateTabs(); updateRssButton(); monitorSubscription(); diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelVideosFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelVideosFragment.java index f147e4f9d..23655dee2 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelVideosFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelVideosFragment.java @@ -132,13 +132,13 @@ public class ChannelVideosFragment extends BaseListInfoFragment + + + + + + + + Date: Sun, 23 Oct 2022 17:01:39 +0200 Subject: [PATCH 031/172] feat: prettier channel info page --- .../list/channel/ChannelFragment.java | 2 +- .../list/channel/ChannelInfoFragment.java | 120 +++++++++++++++++- .../list/channel/ChannelTabFragment.java | 2 - .../main/res/layout/fragment_channel_info.xml | 50 +++++++- app/src/main/res/values-de/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + 6 files changed, 160 insertions(+), 16 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java index 4cd8313fc..6e7473b1e 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java @@ -276,7 +276,7 @@ public class ChannelFragment extends BaseStateFragment { final String description = currentInfo.getDescription(); if (description != null && !description.isEmpty()) { tabAdapter.addFragment( - ChannelInfoFragment.getInstance(description), "Info"); + ChannelInfoFragment.getInstance(currentInfo), "Info"); } } } diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelInfoFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelInfoFragment.java index c9273f528..2ab4ce419 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelInfoFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelInfoFragment.java @@ -1,22 +1,47 @@ package org.schabi.newpipe.fragments.list.channel; +import static org.schabi.newpipe.extractor.stream.StreamExtractor.UNKNOWN_SUBSCRIBER_COUNT; +import static org.schabi.newpipe.extractor.utils.Utils.isBlank; + +import android.content.Context; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.LinearLayout; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.annotation.StringRes; + +import com.google.android.material.chip.Chip; import org.schabi.newpipe.BaseFragment; +import org.schabi.newpipe.R; import org.schabi.newpipe.databinding.FragmentChannelInfoBinding; +import org.schabi.newpipe.databinding.ItemMetadataBinding; +import org.schabi.newpipe.databinding.ItemMetadataTagsBinding; +import org.schabi.newpipe.extractor.channel.ChannelInfo; +import org.schabi.newpipe.util.Localization; +import org.schabi.newpipe.util.NavigationHelper; +import org.schabi.newpipe.util.external_communication.ShareUtils; +import org.schabi.newpipe.util.external_communication.TextLinkifier; + +import java.util.List; + +import icepick.State; +import io.reactivex.rxjava3.disposables.CompositeDisposable; public class ChannelInfoFragment extends BaseFragment { - private String description; + @State + protected ChannelInfo channelInfo; - public static ChannelInfoFragment getInstance(final String description) { + private final CompositeDisposable disposables = new CompositeDisposable(); + private FragmentChannelInfoBinding binding; + + public static ChannelInfoFragment getInstance(final ChannelInfo channelInfo) { final ChannelInfoFragment fragment = new ChannelInfoFragment(); - fragment.description = description; + fragment.channelInfo = channelInfo; return fragment; } @@ -28,11 +53,92 @@ public class ChannelInfoFragment extends BaseFragment { public View onCreateView(@NonNull final LayoutInflater inflater, @Nullable final ViewGroup container, final Bundle savedInstanceState) { - final FragmentChannelInfoBinding binding = - FragmentChannelInfoBinding.inflate(inflater, container, false); - binding.descriptionText.setText(description); - + binding = FragmentChannelInfoBinding.inflate(inflater, container, false); + loadDescription(); + setupMetadata(inflater, binding.detailMetadataLayout); return binding.getRoot(); } + @Override + public void onDestroy() { + super.onDestroy(); + disposables.clear(); + } + + private void loadDescription() { + final String description = channelInfo.getDescription(); + + if (description == null || description.isEmpty()) { + binding.descriptionTitle.setVisibility(View.GONE); + binding.descriptionView.setVisibility(View.GONE); + } else { + TextLinkifier.createLinksFromPlainText( + binding.descriptionView, description, null, disposables); + } + } + + private void setupMetadata(final LayoutInflater inflater, + final LinearLayout layout) { + Context context = getActivity(); + + if (channelInfo.getSubscriberCount() != UNKNOWN_SUBSCRIBER_COUNT) { + addMetadataItem(inflater, layout, R.string.metadata_subscribers, + Localization.localizeNumber(context, channelInfo.getSubscriberCount())); + } + + addTagsMetadataItem(inflater, layout); + } + + private void addMetadataItem(final LayoutInflater inflater, + final LinearLayout layout, + @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; + }); + + itemBinding.metadataContentView.setText(content); + + layout.addView(itemBinding.getRoot()); + } + + private void addTagsMetadataItem(final LayoutInflater inflater, final LinearLayout layout) { + final List tags = channelInfo.getTags(); + + if (!tags.isEmpty()) { + final var itemBinding = ItemMetadataTagsBinding.inflate(inflater, layout, false); + + tags.stream().sorted(String.CASE_INSENSITIVE_ORDER).forEach(tag -> { + 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(), + channelInfo.getServiceId(), ((Chip) chip).getText().toString()); + } + } + + private boolean onTagLongClick(final View chip) { + ShareUtils.copyToClipboard(requireContext(), ((Chip) chip).getText().toString()); + return true; + } } diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelTabFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelTabFragment.java index 21613d717..5a26371b7 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelTabFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelTabFragment.java @@ -2,8 +2,6 @@ package org.schabi.newpipe.fragments.list.channel; import android.os.Bundle; import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuInflater; import android.view.View; import android.view.ViewGroup; diff --git a/app/src/main/res/layout/fragment_channel_info.xml b/app/src/main/res/layout/fragment_channel_info.xml index fbb8e355b..8cbadba1f 100644 --- a/app/src/main/res/layout/fragment_channel_info.xml +++ b/app/src/main/res/layout/fragment_channel_info.xml @@ -5,6 +5,19 @@ android:layout_width="match_parent" android:layout_height="match_parent"> + + + - --> + + + tools:layout_editor_absoluteX="0dp" + tools:text="Cupcake ipsum dolor sit amet I love. I love macaroon cake sweet topping jelly beans chocolate chupa chups candy canes. Marshmallow cake jelly fruitcake soufflé pie. Jelly jelly beans cupcake topping chocolate bar jelly pudding pastry sweet roll." + tools:visibility="visible" /> + + \ No newline at end of file diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index dfc26a4e2..c5260fa03 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -620,6 +620,7 @@ Vorschaubild-URL Server Unterstützung + Abonnenten Auswählen von Text in der Beschreibung deaktivieren Auswählen von Text in der Beschreibung aktivieren Du kannst nun Text innerhalb der Beschreibung auswählen. Beachte, dass die Seite flackern kann und Links im Auswahlmodus möglicherweise nicht anklickbar sind. diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a37bfeb82..7d65807b7 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -758,6 +758,7 @@ Unlisted Private Internal + Subscribers Pinned comment Hearted by creator Open website From 506e3724a61204bb1764e4f58c6c755b95dadd7a Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Sun, 23 Oct 2022 17:11:07 +0200 Subject: [PATCH 032/172] fix: add progress spinners --- app/src/main/res/layout/fragment_channel_tab.xml | 9 +++++++++ app/src/main/res/layout/fragment_channel_videos.xml | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/app/src/main/res/layout/fragment_channel_tab.xml b/app/src/main/res/layout/fragment_channel_tab.xml index 519156296..dd114cb77 100644 --- a/app/src/main/res/layout/fragment_channel_tab.xml +++ b/app/src/main/res/layout/fragment_channel_tab.xml @@ -11,6 +11,15 @@ android:scrollbars="vertical" tools:listitem="@layout/list_stream_item" /> + + + + Date: Sun, 23 Oct 2022 17:21:07 +0200 Subject: [PATCH 033/172] fix: scrollable channel description --- .../main/res/layout/fragment_channel_info.xml | 103 +++++++----------- 1 file changed, 40 insertions(+), 63 deletions(-) diff --git a/app/src/main/res/layout/fragment_channel_info.xml b/app/src/main/res/layout/fragment_channel_info.xml index 8cbadba1f..c9648e01f 100644 --- a/app/src/main/res/layout/fragment_channel_info.xml +++ b/app/src/main/res/layout/fragment_channel_info.xml @@ -1,74 +1,51 @@ - - + android:layout_height="wrap_content"> - + - + - + - - - \ No newline at end of file + + From bb062f07f9415150f4c4b53df6d599de5fae5009 Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Sun, 23 Oct 2022 21:13:43 +0200 Subject: [PATCH 034/172] feat: add option to hide channel tabs --- .../list/channel/ChannelFragment.java | 18 ++++- .../list/channel/ChannelInfoFragment.java | 2 +- .../org/schabi/newpipe/util/ChannelTabs.java | 65 +++++++++++++++++++ app/src/main/res/values-de/strings.xml | 8 +++ app/src/main/res/values/settings_keys.xml | 20 ++++++ app/src/main/res/values/strings.xml | 8 +++ app/src/main/res/xml/content_settings.xml | 10 +++ 7 files changed, 127 insertions(+), 4 deletions(-) create mode 100644 app/src/main/java/org/schabi/newpipe/util/ChannelTabs.java diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java index 6e7473b1e..f71791d8e 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java @@ -1,6 +1,7 @@ package org.schabi.newpipe.fragments.list.channel; import android.content.Context; +import android.content.SharedPreferences; import android.os.Bundle; import android.text.TextUtils; import android.util.Log; @@ -13,6 +14,7 @@ import android.view.ViewGroup; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.preference.PreferenceManager; import org.schabi.newpipe.R; import org.schabi.newpipe.database.subscription.NotificationMode; @@ -27,6 +29,7 @@ import org.schabi.newpipe.fragments.BaseStateFragment; import org.schabi.newpipe.fragments.detail.TabAdapter; import org.schabi.newpipe.local.feed.notifications.NotificationHelper; import org.schabi.newpipe.local.subscription.SubscriptionManager; +import org.schabi.newpipe.util.ChannelTabs; import org.schabi.newpipe.util.Constants; import org.schabi.newpipe.util.ExtractorHelper; import org.schabi.newpipe.util.NavigationHelper; @@ -268,13 +271,22 @@ public class ChannelFragment extends BaseStateFragment { tabAdapter.addFragment( ChannelVideosFragment.getInstance(currentInfo), "Videos"); + final Context context = getContext(); + final SharedPreferences preferences = PreferenceManager + .getDefaultSharedPreferences(context); + for (final ChannelTabHandler tab : currentInfo.getTabs()) { - tabAdapter.addFragment( - ChannelTabFragment.getInstance(serviceId, tab), tab.getTab().name()); + if (ChannelTabs.showChannelTab(context, preferences, tab.getTab())) { + tabAdapter.addFragment( + ChannelTabFragment.getInstance(serviceId, tab), + context.getString(ChannelTabs.getTranslationKey(tab.getTab()))); + } } final String description = currentInfo.getDescription(); - if (description != null && !description.isEmpty()) { + if (description != null && !description.isEmpty() && + ChannelTabs.showChannelTab( + context, preferences, R.string.show_channel_tabs_info)) { tabAdapter.addFragment( ChannelInfoFragment.getInstance(currentInfo), "Info"); } diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelInfoFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelInfoFragment.java index 2ab4ce419..6e7e49876 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelInfoFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelInfoFragment.java @@ -79,7 +79,7 @@ public class ChannelInfoFragment extends BaseFragment { private void setupMetadata(final LayoutInflater inflater, final LinearLayout layout) { - Context context = getActivity(); + Context context = getContext(); if (channelInfo.getSubscriberCount() != UNKNOWN_SUBSCRIBER_COUNT) { addMetadataItem(inflater, layout, R.string.metadata_subscribers, diff --git a/app/src/main/java/org/schabi/newpipe/util/ChannelTabs.java b/app/src/main/java/org/schabi/newpipe/util/ChannelTabs.java new file mode 100644 index 000000000..983daf349 --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/util/ChannelTabs.java @@ -0,0 +1,65 @@ +package org.schabi.newpipe.util; + +import android.content.Context; +import android.content.SharedPreferences; + +import androidx.annotation.StringRes; + +import org.schabi.newpipe.R; +import org.schabi.newpipe.extractor.linkhandler.ChannelTabHandler.Tab; + +import java.util.Set; + +public class ChannelTabs { + @StringRes + private static int getShowTabKey(final Tab tab) { + switch (tab) { + case Playlists: + return R.string.show_channel_tabs_playlists; + case Livestreams: + return R.string.show_channel_tabs_livestreams; + case Shorts: + return R.string.show_channel_tabs_shorts; + case Channels: + return R.string.show_channel_tabs_channels; + } + return -1; + } + + @StringRes + public static int getTranslationKey(final Tab tab) { + switch (tab) { + case Playlists: + return R.string.channel_tab_playlists; + case Livestreams: + return R.string.channel_tab_livestreams; + case Shorts: + return R.string.channel_tab_shorts; + case Channels: + return R.string.channel_tab_channels; + } + return R.string.unknown_content; + } + + public static boolean showChannelTab(final Context context, + final SharedPreferences sharedPreferences, + @StringRes final int key) { + final Set enabledTabs = sharedPreferences.getStringSet( + context.getString(R.string.show_channel_tabs_key), null); + if (enabledTabs == null) { + return true; // default to true + } else { + return enabledTabs.contains(context.getString(key)); + } + } + + public static boolean showChannelTab(final Context context, + final SharedPreferences sharedPreferences, + final Tab tab) { + final int key = ChannelTabs.getShowTabKey(tab); + if (key == -1) { + return false; + } + return showChannelTab(context, sharedPreferences, key); + } +} diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index c5260fa03..76abdfbe2 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -767,4 +767,12 @@ Das Media-Tunneling wurde auf dem Gerät standardmäßig deaktiviert, da das Gerätemodell diese Funktion bekanntermaßen nicht unterstützt. Keine Live-Streams Keine Streams + Videos + Live + Shorts + Wiedergabelisten + Kanäle + Info + Tabs auf den Kanalseiten + Welche Tabs auf den Kanalseiten angezeigt werden \ No newline at end of file diff --git a/app/src/main/res/values/settings_keys.xml b/app/src/main/res/values/settings_keys.xml index 56fc19eed..00c501643 100644 --- a/app/src/main/res/values/settings_keys.xml +++ b/app/src/main/res/values/settings_keys.xml @@ -274,6 +274,26 @@ main_tabs_position + channel_tabs + show_channel_tabs_playlists + show_channel_tabs_live + show_channel_tabs_shorts + show_channel_tabs_channels + show_channel_tabs_info + + @string/show_channel_tabs_playlists + @string/show_channel_tabs_livestreams + @string/show_channel_tabs_shorts + @string/show_channel_tabs_channels + @string/show_channel_tabs_info + + + @string/channel_tab_playlists + @string/channel_tab_livestreams + @string/channel_tab_shorts + @string/channel_tab_channels + @string/channel_tab_info + show_search_suggestions show_local_search_suggestions show_remote_search_suggestions diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 7d65807b7..fd0971761 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -797,4 +797,12 @@ original dubbed descriptive + Videos + Live + Shorts + Playlists + Channels + Info + Channel tabs + What tabs are shown on the channel pages \ No newline at end of file diff --git a/app/src/main/res/xml/content_settings.xml b/app/src/main/res/xml/content_settings.xml index fddb966c8..8783ff1ed 100644 --- a/app/src/main/res/xml/content_settings.xml +++ b/app/src/main/res/xml/content_settings.xml @@ -41,6 +41,16 @@ app:singleLineTitle="false" app:iconSpaceReserved="false" /> + + Date: Sun, 23 Oct 2022 21:28:54 +0200 Subject: [PATCH 035/172] fix: remember selected channel tab on screen rotation --- .../list/channel/ChannelFragment.java | 27 ++++++++++++++++--- .../list/channel/ChannelInfoFragment.java | 2 +- .../list/channel/ChannelTabFragment.java | 2 +- .../list/channel/ChannelVideosFragment.java | 2 +- .../org/schabi/newpipe/util/ChannelTabs.java | 5 +++- 5 files changed, 31 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java index f71791d8e..51625d202 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java @@ -16,6 +16,8 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.preference.PreferenceManager; +import com.google.android.material.tabs.TabLayout; + import org.schabi.newpipe.R; import org.schabi.newpipe.database.subscription.NotificationMode; import org.schabi.newpipe.database.subscription.SubscriptionEntity; @@ -58,6 +60,7 @@ public class ChannelFragment extends BaseStateFragment { private Disposable subscriptionMonitor; private final CompositeDisposable disposables = new CompositeDisposable(); private SubscriptionManager subscriptionManager; + private int lastTab; private MenuItem menuRssButton; private MenuItem menuNotifyButton; @@ -94,10 +97,16 @@ public class ChannelFragment extends BaseStateFragment { public void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); setHasOptionsMenu(true); + + if (savedInstanceState != null) { + lastTab = savedInstanceState.getInt("LastTab"); + } else { + lastTab = 0; + } } @Override - public void onAttach(@NonNull Context context) { + public void onAttach(final @NonNull Context context) { super.onAttach(context); subscriptionManager = new SubscriptionManager(activity); } @@ -119,6 +128,12 @@ public class ChannelFragment extends BaseStateFragment { binding.tabLayout.setupWithViewPager(binding.viewPager); } + @Override + public void onSaveInstanceState(final @NonNull Bundle outState) { + super.onSaveInstanceState(outState); + outState.putInt("LastTab", binding.tabLayout.getSelectedTabPosition()); + } + @Override public void onDestroy() { super.onDestroy(); @@ -284,8 +299,8 @@ public class ChannelFragment extends BaseStateFragment { } final String description = currentInfo.getDescription(); - if (description != null && !description.isEmpty() && - ChannelTabs.showChannelTab( + if (description != null && !description.isEmpty() + && ChannelTabs.showChannelTab( context, preferences, R.string.show_channel_tabs_info)) { tabAdapter.addFragment( ChannelInfoFragment.getInstance(currentInfo), "Info"); @@ -298,6 +313,12 @@ public class ChannelFragment extends BaseStateFragment { for (int i = 0; i < tabAdapter.getCount(); i++) { binding.tabLayout.getTabAt(i).setText(tabAdapter.getItemTitle(i)); } + + // Restore previously selected tab + final TabLayout.Tab ltab = binding.tabLayout.getTabAt(lastTab); + if (ltab != null) { + binding.tabLayout.selectTab(ltab); + } } @Override diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelInfoFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelInfoFragment.java index 6e7e49876..ba1faab8f 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelInfoFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelInfoFragment.java @@ -79,7 +79,7 @@ public class ChannelInfoFragment extends BaseFragment { private void setupMetadata(final LayoutInflater inflater, final LinearLayout layout) { - Context context = getContext(); + final Context context = getContext(); if (channelInfo.getSubscriberCount() != UNKNOWN_SUBSCRIBER_COUNT) { addMetadataItem(inflater, layout, R.string.metadata_subscribers, diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelTabFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelTabFragment.java index 5a26371b7..1ce55df81 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelTabFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelTabFragment.java @@ -46,7 +46,7 @@ public class ChannelTabFragment extends BaseListInfoFragment Date: Sun, 23 Oct 2022 21:36:55 +0200 Subject: [PATCH 036/172] feat: add album tab --- app/src/main/java/org/schabi/newpipe/util/ChannelTabs.java | 4 ++++ app/src/main/res/values-de/strings.xml | 1 + app/src/main/res/values/settings_keys.xml | 3 +++ app/src/main/res/values/strings.xml | 1 + 4 files changed, 9 insertions(+) diff --git a/app/src/main/java/org/schabi/newpipe/util/ChannelTabs.java b/app/src/main/java/org/schabi/newpipe/util/ChannelTabs.java index 0147e9c08..029339cef 100644 --- a/app/src/main/java/org/schabi/newpipe/util/ChannelTabs.java +++ b/app/src/main/java/org/schabi/newpipe/util/ChannelTabs.java @@ -25,6 +25,8 @@ public final class ChannelTabs { return R.string.show_channel_tabs_shorts; case Channels: return R.string.show_channel_tabs_channels; + case Albums: + break; } return -1; } @@ -40,6 +42,8 @@ public final class ChannelTabs { return R.string.channel_tab_shorts; case Channels: return R.string.channel_tab_channels; + case Albums: + return R.string.channel_tab_albums; } return R.string.unknown_content; } diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 76abdfbe2..1720d2b0a 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -772,6 +772,7 @@ Shorts Wiedergabelisten Kanäle + Alben Info Tabs auf den Kanalseiten Welche Tabs auf den Kanalseiten angezeigt werden diff --git a/app/src/main/res/values/settings_keys.xml b/app/src/main/res/values/settings_keys.xml index 00c501643..9746d7889 100644 --- a/app/src/main/res/values/settings_keys.xml +++ b/app/src/main/res/values/settings_keys.xml @@ -279,12 +279,14 @@ show_channel_tabs_live show_channel_tabs_shorts show_channel_tabs_channels + show_channel_tabs_albums show_channel_tabs_info @string/show_channel_tabs_playlists @string/show_channel_tabs_livestreams @string/show_channel_tabs_shorts @string/show_channel_tabs_channels + @string/show_channel_tabs_albums @string/show_channel_tabs_info @@ -292,6 +294,7 @@ @string/channel_tab_livestreams @string/channel_tab_shorts @string/channel_tab_channels + @string/channel_tab_albums @string/channel_tab_info show_search_suggestions diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index fd0971761..87577a81a 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -802,6 +802,7 @@ Shorts Playlists Channels + Albums Info Channel tabs What tabs are shown on the channel pages From 16cd47fa2e3b37913729113c35b8862a0dda0a9a Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Mon, 24 Oct 2022 00:03:19 +0200 Subject: [PATCH 037/172] fix: missing album tab key --- app/src/main/java/org/schabi/newpipe/util/ChannelTabs.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/org/schabi/newpipe/util/ChannelTabs.java b/app/src/main/java/org/schabi/newpipe/util/ChannelTabs.java index 029339cef..b861824d5 100644 --- a/app/src/main/java/org/schabi/newpipe/util/ChannelTabs.java +++ b/app/src/main/java/org/schabi/newpipe/util/ChannelTabs.java @@ -26,7 +26,7 @@ public final class ChannelTabs { case Channels: return R.string.show_channel_tabs_channels; case Albums: - break; + return R.string.show_channel_tabs_albums; } return -1; } From 2c98d079dec6abf42bdf5fe7c9b4e033332e3f21 Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Tue, 25 Oct 2022 09:01:11 +0200 Subject: [PATCH 038/172] fix: cache channel data --- .../list/channel/ChannelFragment.java | 53 ++++++++++++++----- .../schabi/newpipe/util/ExtractorHelper.java | 3 +- 2 files changed, 41 insertions(+), 15 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java index 51625d202..d7955eb9d 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java @@ -35,9 +35,11 @@ import org.schabi.newpipe.util.ChannelTabs; import org.schabi.newpipe.util.Constants; import org.schabi.newpipe.util.ExtractorHelper; import org.schabi.newpipe.util.NavigationHelper; +import org.schabi.newpipe.util.StateSaver; import org.schabi.newpipe.util.external_communication.ShareUtils; import java.util.List; +import java.util.Queue; import icepick.State; import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; @@ -47,7 +49,8 @@ import io.reactivex.rxjava3.disposables.Disposable; import io.reactivex.rxjava3.functions.Consumer; import io.reactivex.rxjava3.schedulers.Schedulers; -public class ChannelFragment extends BaseStateFragment { +public class ChannelFragment extends BaseStateFragment + implements StateSaver.WriteRead { @State protected int serviceId = Constants.NO_SERVICE_ID; @State @@ -97,12 +100,6 @@ public class ChannelFragment extends BaseStateFragment { public void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); setHasOptionsMenu(true); - - if (savedInstanceState != null) { - lastTab = savedInstanceState.getInt("LastTab"); - } else { - lastTab = 0; - } } @Override @@ -128,12 +125,6 @@ public class ChannelFragment extends BaseStateFragment { binding.tabLayout.setupWithViewPager(binding.viewPager); } - @Override - public void onSaveInstanceState(final @NonNull Bundle outState) { - super.onSaveInstanceState(outState); - outState.putInt("LastTab", binding.tabLayout.getSelectedTabPosition()); - } - @Override public void onDestroy() { super.onDestroy(); @@ -301,7 +292,7 @@ public class ChannelFragment extends BaseStateFragment { final String description = currentInfo.getDescription(); if (description != null && !description.isEmpty() && ChannelTabs.showChannelTab( - context, preferences, R.string.show_channel_tabs_info)) { + context, preferences, R.string.show_channel_tabs_info)) { tabAdapter.addFragment( ChannelInfoFragment.getInstance(currentInfo), "Info"); } @@ -321,6 +312,40 @@ public class ChannelFragment extends BaseStateFragment { } } + /*////////////////////////////////////////////////////////////////////////// + // State Saving + //////////////////////////////////////////////////////////////////////////*/ + + @Override + public String generateSuffix() { + return null; + } + + @Override + public void writeTo(final Queue objectsToSave) { + objectsToSave.add(currentInfo); + if (binding != null) { + objectsToSave.add(binding.tabLayout.getSelectedTabPosition()); + } else { + objectsToSave.add(0); + } + } + + @Override + public void readFrom(@NonNull final Queue savedObjects) { + currentInfo = (ChannelInfo) savedObjects.poll(); + lastTab = (Integer) savedObjects.poll(); + } + + @Override + protected void doInitialLoadLogic() { + if (currentInfo == null) { + startLoading(false); + } else { + handleResult(currentInfo); + } + } + @Override public void startLoading(final boolean forceLoad) { super.startLoading(forceLoad); diff --git a/app/src/main/java/org/schabi/newpipe/util/ExtractorHelper.java b/app/src/main/java/org/schabi/newpipe/util/ExtractorHelper.java index b4648c79b..bf99ae3d3 100644 --- a/app/src/main/java/org/schabi/newpipe/util/ExtractorHelper.java +++ b/app/src/main/java/org/schabi/newpipe/util/ExtractorHelper.java @@ -158,7 +158,8 @@ public final class ExtractorHelper { final boolean forceLoad) { checkServiceId(serviceId); return checkCache(forceLoad, serviceId, - tabHandler.getUrl() + tabHandler.getTab().name(), InfoItem.InfoType.CHANNEL, + tabHandler.getUrl() + "/" + + tabHandler.getTab().name(), InfoItem.InfoType.CHANNEL, Single.fromCallable(() -> ChannelTabInfo.getInfo(NewPipe.getService(serviceId), tabHandler))); } From 2c03ba204eabf505c9876945dcc3c95f54d8b786 Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Sat, 5 Nov 2022 00:23:03 +0100 Subject: [PATCH 039/172] refactor: adjustments to updated tab extractor API --- .../list/channel/ChannelFragment.java | 15 ++++---- .../list/channel/ChannelTabFragment.java | 6 ++-- ...ChannelTabs.java => ChannelTabHelper.java} | 34 +++++++++---------- .../schabi/newpipe/util/ExtractorHelper.java | 16 ++++----- 4 files changed, 36 insertions(+), 35 deletions(-) rename app/src/main/java/org/schabi/newpipe/util/{ChannelTabs.java => ChannelTabHelper.java} (69%) diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java index d7955eb9d..322093781 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java @@ -26,12 +26,12 @@ import org.schabi.newpipe.error.ErrorInfo; import org.schabi.newpipe.error.UserAction; import org.schabi.newpipe.extractor.channel.ChannelInfo; import org.schabi.newpipe.extractor.exceptions.ContentNotSupportedException; -import org.schabi.newpipe.extractor.linkhandler.ChannelTabHandler; +import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler; import org.schabi.newpipe.fragments.BaseStateFragment; import org.schabi.newpipe.fragments.detail.TabAdapter; import org.schabi.newpipe.local.feed.notifications.NotificationHelper; import org.schabi.newpipe.local.subscription.SubscriptionManager; -import org.schabi.newpipe.util.ChannelTabs; +import org.schabi.newpipe.util.ChannelTabHelper; import org.schabi.newpipe.util.Constants; import org.schabi.newpipe.util.ExtractorHelper; import org.schabi.newpipe.util.NavigationHelper; @@ -281,17 +281,18 @@ public class ChannelFragment extends BaseStateFragment final SharedPreferences preferences = PreferenceManager .getDefaultSharedPreferences(context); - for (final ChannelTabHandler tab : currentInfo.getTabs()) { - if (ChannelTabs.showChannelTab(context, preferences, tab.getTab())) { + for (final ListLinkHandler linkHandler : currentInfo.getTabs()) { + final String tab = linkHandler.getContentFilters().get(0); + if (ChannelTabHelper.showChannelTab(context, preferences, tab)) { tabAdapter.addFragment( - ChannelTabFragment.getInstance(serviceId, tab), - context.getString(ChannelTabs.getTranslationKey(tab.getTab()))); + ChannelTabFragment.getInstance(serviceId, linkHandler), + context.getString(ChannelTabHelper.getTranslationKey(tab))); } } final String description = currentInfo.getDescription(); if (description != null && !description.isEmpty() - && ChannelTabs.showChannelTab( + && ChannelTabHelper.showChannelTab( context, preferences, R.string.show_channel_tabs_info)) { tabAdapter.addFragment( ChannelInfoFragment.getInstance(currentInfo), "Info"); diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelTabFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelTabFragment.java index 1ce55df81..d00cb5cf9 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelTabFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelTabFragment.java @@ -13,7 +13,7 @@ import org.schabi.newpipe.error.UserAction; import org.schabi.newpipe.extractor.InfoItem; import org.schabi.newpipe.extractor.ListExtractor; import org.schabi.newpipe.extractor.channel.ChannelTabInfo; -import org.schabi.newpipe.extractor.linkhandler.ChannelTabHandler; +import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler; import org.schabi.newpipe.fragments.list.BaseListInfoFragment; import org.schabi.newpipe.util.Constants; import org.schabi.newpipe.util.ExtractorHelper; @@ -27,10 +27,10 @@ public class ChannelTabFragment extends BaseListInfoFragment getChannelTab(final int serviceId, - final ChannelTabHandler tabHandler, + final ListLinkHandler listLinkHandler, final boolean forceLoad) { checkServiceId(serviceId); return checkCache(forceLoad, serviceId, - tabHandler.getUrl() + "/" - + tabHandler.getTab().name(), InfoItem.InfoType.CHANNEL, + listLinkHandler.getUrl(), InfoItem.InfoType.CHANNEL, Single.fromCallable(() -> - ChannelTabInfo.getInfo(NewPipe.getService(serviceId), tabHandler))); + ChannelTabInfo.getInfo(NewPipe.getService(serviceId), listLinkHandler))); } public static Single> getMoreChannelTabItems(final int serviceId, - final ChannelTabHandler - tabHandler, + final ListLinkHandler + listLinkHandler, final Page nextPage) { checkServiceId(serviceId); return Single.fromCallable(() -> - ChannelTabInfo.getMoreItems(NewPipe.getService(serviceId), tabHandler, nextPage)); + ChannelTabInfo.getMoreItems(NewPipe.getService(serviceId), + listLinkHandler, nextPage)); } public static Single getCommentsInfo(final int serviceId, final String url, From 4357a343394ed7317253ad5a36fad36042e24574 Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Tue, 22 Nov 2022 02:52:25 +0100 Subject: [PATCH 040/172] fix: ChannelFragment: save last tab --- .../fragments/list/channel/ChannelFragment.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java index 322093781..f0810a03c 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java @@ -100,6 +100,12 @@ public class ChannelFragment extends BaseStateFragment public void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); setHasOptionsMenu(true); + + if (savedInstanceState != null) { + lastTab = savedInstanceState.getInt("LastTab"); + } else { + lastTab = 0; + } } @Override @@ -125,6 +131,12 @@ public class ChannelFragment extends BaseStateFragment binding.tabLayout.setupWithViewPager(binding.viewPager); } + @Override + public void onSaveInstanceState(final @NonNull Bundle outState) { + super.onSaveInstanceState(outState); + outState.putInt("LastTab", binding.tabLayout.getSelectedTabPosition()); + } + @Override public void onDestroy() { super.onDestroy(); From be548dcb521d4604f15ce313816ab82cf73845da Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Tue, 29 Nov 2022 19:25:35 +0100 Subject: [PATCH 041/172] fix: channel tab title not being set --- .../newpipe/fragments/list/channel/ChannelFragment.java | 2 +- .../fragments/list/channel/ChannelTabFragment.java | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java index f0810a03c..8b6c0084e 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java @@ -297,7 +297,7 @@ public class ChannelFragment extends BaseStateFragment final String tab = linkHandler.getContentFilters().get(0); if (ChannelTabHelper.showChannelTab(context, preferences, tab)) { tabAdapter.addFragment( - ChannelTabFragment.getInstance(serviceId, linkHandler), + ChannelTabFragment.getInstance(serviceId, linkHandler, name), context.getString(ChannelTabHelper.getTranslationKey(tab))); } } diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelTabFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelTabFragment.java index d00cb5cf9..3f400bdf8 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelTabFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelTabFragment.java @@ -29,11 +29,16 @@ public class ChannelTabFragment extends BaseListInfoFragment Date: Wed, 5 Apr 2023 14:55:02 +0200 Subject: [PATCH 042/172] update NewPipeExtractor --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 22ac7d67d..10dd4bef0 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -197,7 +197,7 @@ dependencies { // name and the commit hash with the commit hash of the (pushed) commit you want to test // This works thanks to JitPack: https://jitpack.io/ implementation 'com.github.TeamNewPipe:nanojson:1d9e1aea9049fc9f85e68b43ba39fe7be1c1f751' - implementation 'com.github.Theta-Dev:NewPipeExtractor:8446e20a71dbddbe1626a118d0adf490e5e63bbb' + implementation 'com.github.Theta-Dev:NewPipeExtractor:e57d43f92d0c7132b569835a659da2d3b3017602' implementation 'com.github.TeamNewPipe:NoNonsense-FilePicker:5.0.0' /** Checkstyle **/ From 39b4ed082c5ade58aaf098d5a9d3b20b839f047a Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Wed, 5 Apr 2023 16:17:31 +0200 Subject: [PATCH 043/172] refactor: common code from ChannelInfo/Description -> BaseInfoFragment --- .../fragments/detail/BaseInfoFragment.java | 206 ++++++++++++++++++ .../fragments/detail/DescriptionFragment.java | 186 ++++------------ .../list/channel/ChannelInfoFragment.java | 143 ++++-------- 3 files changed, 286 insertions(+), 249 deletions(-) create mode 100644 app/src/main/java/org/schabi/newpipe/fragments/detail/BaseInfoFragment.java diff --git a/app/src/main/java/org/schabi/newpipe/fragments/detail/BaseInfoFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/detail/BaseInfoFragment.java new file mode 100644 index 000000000..d8aea1a03 --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/fragments/detail/BaseInfoFragment.java @@ -0,0 +1,206 @@ +package org.schabi.newpipe.fragments.detail; + +import static android.text.TextUtils.isEmpty; +import static org.schabi.newpipe.extractor.utils.Utils.isBlank; +import static org.schabi.newpipe.util.text.TextLinkifier.SET_LINK_MOVEMENT_METHOD; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +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.StreamingService; +import org.schabi.newpipe.extractor.stream.Description; +import org.schabi.newpipe.util.NavigationHelper; +import org.schabi.newpipe.util.external_communication.ShareUtils; +import org.schabi.newpipe.util.text.TextLinkifier; + +import java.util.List; + +import io.reactivex.rxjava3.disposables.CompositeDisposable; + +public abstract class BaseInfoFragment extends BaseFragment { + final CompositeDisposable descriptionDisposables = new CompositeDisposable(); + FragmentDescriptionBinding binding; + + @Override + public View onCreateView(@NonNull final LayoutInflater inflater, + @Nullable final ViewGroup container, + @Nullable final Bundle savedInstanceState) { + binding = FragmentDescriptionBinding.inflate(inflater, container, false); + setupDescription(); + setupMetadata(inflater, binding.detailMetadataLayout); + addTagsMetadataItem(inflater, binding.detailMetadataLayout); + return binding.getRoot(); + } + + @Override + public void onDestroy() { + descriptionDisposables.clear(); + super.onDestroy(); + } + + /** + * Get the description to display. + * @return description object + */ + @Nullable + protected abstract Description getDescription(); + + /** + * Get the streaming service. Used for generating description links. + * @return streaming service + */ + @Nullable + protected abstract StreamingService getService(); + + /** + * Get the streaming service ID. Used for tag links. + * @return service ID + */ + protected abstract int getServiceId(); + + /** + * Get the URL of the described video. Used for generating description links. + * @return stream URL + */ + @Nullable + protected abstract String getStreamUrl(); + + /** + * Get the list of tags to display below the description. + * @return tag list + */ + @Nullable + public abstract List getTags(); + + /** + * Add additional metadata to display. + * @param inflater LayoutInflater + * @param layout detailMetadataLayout + */ + protected abstract void setupMetadata(LayoutInflater inflater, LinearLayout layout); + + private void setupDescription() { + final Description description = getDescription(); + if (description == null || isEmpty(description.getContent()) + || description == Description.EMPTY_DESCRIPTION) { + 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 + TextLinkifier.fromDescription(binding.detailDescriptionView, + getDescription(), HtmlCompat.FROM_HTML_MODE_LEGACY, + getService(), getStreamUrl(), + descriptionDisposables, SET_LINK_MOVEMENT_METHOD); + + 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); + } + + protected 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.fromPlainText(itemBinding.metadataContentView, content, null, null, + descriptionDisposables, SET_LINK_MOVEMENT_METHOD); + } else { + itemBinding.metadataContentView.setText(content); + } + + itemBinding.metadataContentView.setClickable(true); + + layout.addView(itemBinding.getRoot()); + } + + private void addTagsMetadataItem(final LayoutInflater inflater, final LinearLayout layout) { + final List tags = getTags(); + + if (tags != null && !tags.isEmpty()) { + final var itemBinding = ItemMetadataTagsBinding.inflate(inflater, layout, false); + + tags.stream().sorted(String.CASE_INSENSITIVE_ORDER).forEach(tag -> { + 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(), + getServiceId(), ((Chip) chip).getText().toString()); + } + } + + private boolean onTagLongClick(final View chip) { + ShareUtils.copyToClipboard(requireContext(), ((Chip) chip).getText().toString()); + return true; + } +} diff --git a/app/src/main/java/org/schabi/newpipe/fragments/detail/DescriptionFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/detail/DescriptionFragment.java index d364c0c0f..cf99365dc 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/detail/DescriptionFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/detail/DescriptionFragment.java @@ -1,46 +1,29 @@ package org.schabi.newpipe.fragments.detail; -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; import static org.schabi.newpipe.util.Localization.getAppLocale; -import static org.schabi.newpipe.util.text.TextLinkifier.SET_LINK_MOVEMENT_METHOD; -import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; -import android.view.ViewGroup; 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.StreamingService; 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.external_communication.ShareUtils; -import org.schabi.newpipe.util.text.TextLinkifier; + +import java.util.List; import icepick.State; -import io.reactivex.rxjava3.disposables.CompositeDisposable; -public class DescriptionFragment extends BaseFragment { +public class DescriptionFragment extends BaseInfoFragment { @State StreamInfo streamInfo = null; - final CompositeDisposable descriptionDisposables = new CompositeDisposable(); - FragmentDescriptionBinding binding; public DescriptionFragment() { } @@ -49,86 +32,56 @@ public class DescriptionFragment extends BaseFragment { this.streamInfo = streamInfo; } + @Nullable @Override - public View onCreateView(@NonNull final LayoutInflater inflater, - @Nullable final ViewGroup container, - @Nullable final Bundle savedInstanceState) { - binding = FragmentDescriptionBinding.inflate(inflater, container, false); - if (streamInfo != null) { - setupUploadDate(); - setupDescription(); - setupMetadata(inflater, binding.detailMetadataLayout); + protected Description getDescription() { + if (streamInfo == null) { + return null; } - return binding.getRoot(); + return streamInfo.getDescription(); + } + + @Nullable + @Override + protected StreamingService getService() { + if (streamInfo == null) { + return null; + } + return streamInfo.getService(); } @Override - public void onDestroy() { - descriptionDisposables.clear(); - super.onDestroy(); + protected int getServiceId() { + return streamInfo.getServiceId(); } + @Nullable + @Override + protected String getStreamUrl() { + if (streamInfo == null) { + return null; + } + return streamInfo.getUrl(); + } - private void setupUploadDate() { + @Nullable + @Override + public List getTags() { + if (streamInfo == null) { + return null; + } + return streamInfo.getTags(); + } + + protected void setupMetadata(final LayoutInflater inflater, + final LinearLayout layout) { if (streamInfo.getUploadDate() != null) { binding.detailUploadDateView.setText(Localization .localizeUploadDate(activity, streamInfo.getUploadDate().offsetDateTime())); } else { binding.detailUploadDateView.setVisibility(View.GONE); } - } - - private void setupDescription() { - final Description description = streamInfo.getDescription(); - if (description == null || isEmpty(description.getContent()) - || description == Description.EMPTY_DESCRIPTION) { - 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 - TextLinkifier.fromDescription(binding.detailDescriptionView, - streamInfo.getDescription(), HtmlCompat.FROM_HTML_MODE_LEGACY, - streamInfo.getService(), streamInfo.getUrl(), - descriptionDisposables, SET_LINK_MOVEMENT_METHOD); - - 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 setupMetadata(final LayoutInflater inflater, - final LinearLayout layout) { addMetadataItem(inflater, layout, false, R.string.metadata_category, streamInfo.getCategory()); @@ -153,67 +106,6 @@ public class DescriptionFragment extends BaseFragment { streamInfo.getHost()); addMetadataItem(inflater, layout, true, R.string.metadata_thumbnail_url, streamInfo.getThumbnailUrl()); - - addTagsMetadataItem(inflater, layout); - } - - 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.fromPlainText(itemBinding.metadataContentView, content, null, null, - descriptionDisposables, SET_LINK_MOVEMENT_METHOD); - } else { - itemBinding.metadataContentView.setText(content); - } - - itemBinding.metadataContentView.setClickable(true); - - layout.addView(itemBinding.getRoot()); - } - - private void addTagsMetadataItem(final LayoutInflater inflater, final LinearLayout layout) { - if (streamInfo.getTags() != null && !streamInfo.getTags().isEmpty()) { - final var itemBinding = ItemMetadataTagsBinding.inflate(inflater, layout, false); - - streamInfo.getTags().stream().sorted(String.CASE_INSENSITIVE_ORDER).forEach(tag -> { - 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) { diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelInfoFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelInfoFragment.java index ba1faab8f..70b182a75 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelInfoFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelInfoFragment.java @@ -1,44 +1,28 @@ package org.schabi.newpipe.fragments.list.channel; import static org.schabi.newpipe.extractor.stream.StreamExtractor.UNKNOWN_SUBSCRIBER_COUNT; -import static org.schabi.newpipe.extractor.utils.Utils.isBlank; import android.content.Context; -import android.os.Bundle; import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; import android.widget.LinearLayout; -import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.annotation.StringRes; -import com.google.android.material.chip.Chip; - -import org.schabi.newpipe.BaseFragment; import org.schabi.newpipe.R; -import org.schabi.newpipe.databinding.FragmentChannelInfoBinding; -import org.schabi.newpipe.databinding.ItemMetadataBinding; -import org.schabi.newpipe.databinding.ItemMetadataTagsBinding; +import org.schabi.newpipe.extractor.StreamingService; import org.schabi.newpipe.extractor.channel.ChannelInfo; +import org.schabi.newpipe.extractor.stream.Description; +import org.schabi.newpipe.fragments.detail.BaseInfoFragment; import org.schabi.newpipe.util.Localization; -import org.schabi.newpipe.util.NavigationHelper; -import org.schabi.newpipe.util.external_communication.ShareUtils; -import org.schabi.newpipe.util.external_communication.TextLinkifier; import java.util.List; import icepick.State; -import io.reactivex.rxjava3.disposables.CompositeDisposable; -public class ChannelInfoFragment extends BaseFragment { +public class ChannelInfoFragment extends BaseInfoFragment { @State protected ChannelInfo channelInfo; - private final CompositeDisposable disposables = new CompositeDisposable(); - private FragmentChannelInfoBinding binding; - public static ChannelInfoFragment getInstance(final ChannelInfo channelInfo) { final ChannelInfoFragment fragment = new ChannelInfoFragment(); fragment.channelInfo = channelInfo; @@ -49,96 +33,51 @@ public class ChannelInfoFragment extends BaseFragment { super(); } + @Nullable @Override - public View onCreateView(@NonNull final LayoutInflater inflater, - @Nullable final ViewGroup container, - final Bundle savedInstanceState) { - binding = FragmentChannelInfoBinding.inflate(inflater, container, false); - loadDescription(); - setupMetadata(inflater, binding.detailMetadataLayout); - return binding.getRoot(); - } - - @Override - public void onDestroy() { - super.onDestroy(); - disposables.clear(); - } - - private void loadDescription() { - final String description = channelInfo.getDescription(); - - if (description == null || description.isEmpty()) { - binding.descriptionTitle.setVisibility(View.GONE); - binding.descriptionView.setVisibility(View.GONE); - } else { - TextLinkifier.createLinksFromPlainText( - binding.descriptionView, description, null, disposables); + protected Description getDescription() { + if (channelInfo == null) { + return null; } + return new Description(channelInfo.getDescription(), Description.PLAIN_TEXT); } - private void setupMetadata(final LayoutInflater inflater, - final LinearLayout layout) { + @Nullable + @Override + protected StreamingService getService() { + if (channelInfo == null) { + return null; + } + return channelInfo.getService(); + } + + @Override + protected int getServiceId() { + return channelInfo.getServiceId(); + } + + @Nullable + @Override + protected String getStreamUrl() { + return null; + } + + @Nullable + @Override + public List getTags() { + if (channelInfo == null) { + return null; + } + return channelInfo.getTags(); + } + + protected void setupMetadata(final LayoutInflater inflater, + final LinearLayout layout) { final Context context = getContext(); if (channelInfo.getSubscriberCount() != UNKNOWN_SUBSCRIBER_COUNT) { - addMetadataItem(inflater, layout, R.string.metadata_subscribers, + addMetadataItem(inflater, layout, false, R.string.metadata_subscribers, Localization.localizeNumber(context, channelInfo.getSubscriberCount())); } - - addTagsMetadataItem(inflater, layout); - } - - private void addMetadataItem(final LayoutInflater inflater, - final LinearLayout layout, - @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; - }); - - itemBinding.metadataContentView.setText(content); - - layout.addView(itemBinding.getRoot()); - } - - private void addTagsMetadataItem(final LayoutInflater inflater, final LinearLayout layout) { - final List tags = channelInfo.getTags(); - - if (!tags.isEmpty()) { - final var itemBinding = ItemMetadataTagsBinding.inflate(inflater, layout, false); - - tags.stream().sorted(String.CASE_INSENSITIVE_ORDER).forEach(tag -> { - 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(), - channelInfo.getServiceId(), ((Chip) chip).getText().toString()); - } - } - - private boolean onTagLongClick(final View chip) { - ShareUtils.copyToClipboard(requireContext(), ((Chip) chip).getText().toString()); - return true; } } From 88384dc35ec9c88d3fff36c1275d6ff9498fc770 Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Wed, 5 Apr 2023 21:42:21 +0200 Subject: [PATCH 044/172] update extractor --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 10dd4bef0..b7430287a 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -197,7 +197,7 @@ dependencies { // name and the commit hash with the commit hash of the (pushed) commit you want to test // This works thanks to JitPack: https://jitpack.io/ implementation 'com.github.TeamNewPipe:nanojson:1d9e1aea9049fc9f85e68b43ba39fe7be1c1f751' - implementation 'com.github.Theta-Dev:NewPipeExtractor:e57d43f92d0c7132b569835a659da2d3b3017602' + implementation 'com.github.Theta-Dev:NewPipeExtractor:e278a2d6d428dec82a304d271803d35afbd7340c' implementation 'com.github.TeamNewPipe:NoNonsense-FilePicker:5.0.0' /** Checkstyle **/ From b7911a8fd8a40452bfc6d7afb446ec9ecaae4978 Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Wed, 5 Apr 2023 21:53:45 +0200 Subject: [PATCH 045/172] remove fragment_channel_info --- .../main/res/layout/fragment_channel_info.xml | 51 ------------------- 1 file changed, 51 deletions(-) delete mode 100644 app/src/main/res/layout/fragment_channel_info.xml diff --git a/app/src/main/res/layout/fragment_channel_info.xml b/app/src/main/res/layout/fragment_channel_info.xml deleted file mode 100644 index c9648e01f..000000000 --- a/app/src/main/res/layout/fragment_channel_info.xml +++ /dev/null @@ -1,51 +0,0 @@ - - - - - - - - - - - - - From 25e303183007a0f7b9310eb882daf897f2bcced3 Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Wed, 5 Apr 2023 21:56:01 +0200 Subject: [PATCH 046/172] cleanup: remove empty constructor from ChannelFragment --- .../newpipe/fragments/list/channel/ChannelFragment.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java index 8b6c0084e..96f2522eb 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java @@ -82,10 +82,6 @@ public class ChannelFragment extends BaseStateFragment return instance; } - public ChannelFragment() { - super(); - } - protected void setInitialData(final int sid, final String u, final String title) { this.serviceId = sid; this.url = u; From c03c344f4998ca76ffef1260bbaa8c4c8cf6afc5 Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Wed, 5 Apr 2023 22:56:25 +0200 Subject: [PATCH 047/172] refactor: rename ChannelInfo to ChannelAbout fix: localize about tab name --- ...eInfoFragment.java => BaseDescriptionFragment.java} | 2 +- .../newpipe/fragments/detail/DescriptionFragment.java | 2 +- ...nnelInfoFragment.java => ChannelAboutFragment.java} | 10 +++++----- .../fragments/list/channel/ChannelFragment.java | 5 +++-- app/src/main/res/values/settings_keys.xml | 6 +++--- app/src/main/res/values/strings.xml | 2 +- 6 files changed, 14 insertions(+), 13 deletions(-) rename app/src/main/java/org/schabi/newpipe/fragments/detail/{BaseInfoFragment.java => BaseDescriptionFragment.java} (99%) rename app/src/main/java/org/schabi/newpipe/fragments/list/channel/{ChannelInfoFragment.java => ChannelAboutFragment.java} (85%) diff --git a/app/src/main/java/org/schabi/newpipe/fragments/detail/BaseInfoFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/detail/BaseDescriptionFragment.java similarity index 99% rename from app/src/main/java/org/schabi/newpipe/fragments/detail/BaseInfoFragment.java rename to app/src/main/java/org/schabi/newpipe/fragments/detail/BaseDescriptionFragment.java index d8aea1a03..fbbfdf23f 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/detail/BaseInfoFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/detail/BaseDescriptionFragment.java @@ -33,7 +33,7 @@ import java.util.List; import io.reactivex.rxjava3.disposables.CompositeDisposable; -public abstract class BaseInfoFragment extends BaseFragment { +public abstract class BaseDescriptionFragment extends BaseFragment { final CompositeDisposable descriptionDisposables = new CompositeDisposable(); FragmentDescriptionBinding binding; diff --git a/app/src/main/java/org/schabi/newpipe/fragments/detail/DescriptionFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/detail/DescriptionFragment.java index cf99365dc..ded4e907a 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/detail/DescriptionFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/detail/DescriptionFragment.java @@ -20,7 +20,7 @@ import java.util.List; import icepick.State; -public class DescriptionFragment extends BaseInfoFragment { +public class DescriptionFragment extends BaseDescriptionFragment { @State StreamInfo streamInfo = null; diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelInfoFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelAboutFragment.java similarity index 85% rename from app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelInfoFragment.java rename to app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelAboutFragment.java index 70b182a75..ae04e8b00 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelInfoFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelAboutFragment.java @@ -12,24 +12,24 @@ import org.schabi.newpipe.R; import org.schabi.newpipe.extractor.StreamingService; import org.schabi.newpipe.extractor.channel.ChannelInfo; import org.schabi.newpipe.extractor.stream.Description; -import org.schabi.newpipe.fragments.detail.BaseInfoFragment; +import org.schabi.newpipe.fragments.detail.BaseDescriptionFragment; import org.schabi.newpipe.util.Localization; import java.util.List; import icepick.State; -public class ChannelInfoFragment extends BaseInfoFragment { +public class ChannelAboutFragment extends BaseDescriptionFragment { @State protected ChannelInfo channelInfo; - public static ChannelInfoFragment getInstance(final ChannelInfo channelInfo) { - final ChannelInfoFragment fragment = new ChannelInfoFragment(); + public static ChannelAboutFragment getInstance(final ChannelInfo channelInfo) { + final ChannelAboutFragment fragment = new ChannelAboutFragment(); fragment.channelInfo = channelInfo; return fragment; } - public ChannelInfoFragment() { + public ChannelAboutFragment() { super(); } diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java index 96f2522eb..95aa2c45a 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java @@ -301,9 +301,10 @@ public class ChannelFragment extends BaseStateFragment final String description = currentInfo.getDescription(); if (description != null && !description.isEmpty() && ChannelTabHelper.showChannelTab( - context, preferences, R.string.show_channel_tabs_info)) { + context, preferences, R.string.show_channel_tabs_about)) { tabAdapter.addFragment( - ChannelInfoFragment.getInstance(currentInfo), "Info"); + ChannelAboutFragment.getInstance(currentInfo), + context.getString(R.string.channel_tab_about)); } } } diff --git a/app/src/main/res/values/settings_keys.xml b/app/src/main/res/values/settings_keys.xml index 9746d7889..d32fbce0c 100644 --- a/app/src/main/res/values/settings_keys.xml +++ b/app/src/main/res/values/settings_keys.xml @@ -280,14 +280,14 @@ show_channel_tabs_shorts show_channel_tabs_channels show_channel_tabs_albums - show_channel_tabs_info + show_channel_tabs_about @string/show_channel_tabs_playlists @string/show_channel_tabs_livestreams @string/show_channel_tabs_shorts @string/show_channel_tabs_channels @string/show_channel_tabs_albums - @string/show_channel_tabs_info + @string/show_channel_tabs_about @string/channel_tab_playlists @@ -295,7 +295,7 @@ @string/channel_tab_shorts @string/channel_tab_channels @string/channel_tab_albums - @string/channel_tab_info + @string/channel_tab_about show_search_suggestions show_local_search_suggestions diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 87577a81a..259689231 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -803,7 +803,7 @@ Playlists Channels Albums - Info + About Channel tabs What tabs are shown on the channel pages \ No newline at end of file From 193c3e5b3dd012ef9d1a8372fc093bebddf3213c Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Thu, 6 Apr 2023 11:44:01 +0200 Subject: [PATCH 048/172] fix: NPE in ChannelFragment::onSaveInstanceState --- .../newpipe/fragments/list/channel/ChannelFragment.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java index 95aa2c45a..96de433f5 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java @@ -130,7 +130,9 @@ public class ChannelFragment extends BaseStateFragment @Override public void onSaveInstanceState(final @NonNull Bundle outState) { super.onSaveInstanceState(outState); - outState.putInt("LastTab", binding.tabLayout.getSelectedTabPosition()); + if (binding != null) { + outState.putInt("LastTab", binding.tabLayout.getSelectedTabPosition()); + } } @Override From e3614cb93231a7ed9a8e430ef6566004a6958ed5 Mon Sep 17 00:00:00 2001 From: Stypox Date: Thu, 13 Apr 2023 00:00:23 +0200 Subject: [PATCH 049/172] Move channel header to collapsible app bar --- .../list/channel/ChannelFragment.java | 411 +++++++++++++---- .../list/channel/ChannelVideosFragment.java | 420 ++---------------- .../org/schabi/newpipe/settings/tabs/Tab.java | 2 +- .../schabi/newpipe/util/PicassoHelper.java | 6 +- app/src/main/res/layout/channel_header.xml | 131 ------ app/src/main/res/layout/fragment_channel.xml | 242 +++++++--- app/src/main/res/values-land/dimens.xml | 1 - app/src/main/res/values/dimens.xml | 1 - 8 files changed, 541 insertions(+), 673 deletions(-) delete mode 100644 app/src/main/res/layout/channel_header.xml diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java index 96de433f5..9de143518 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java @@ -1,10 +1,16 @@ package org.schabi.newpipe.fragments.list.channel; +import static org.schabi.newpipe.ktx.TextViewUtils.animateTextColor; +import static org.schabi.newpipe.ktx.ViewUtils.animate; +import static org.schabi.newpipe.ktx.ViewUtils.animateBackgroundColor; + import android.content.Context; import android.content.SharedPreferences; +import android.graphics.Color; import android.os.Bundle; import android.text.TextUtils; import android.util.Log; +import android.util.TypedValue; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; @@ -14,43 +20,59 @@ import android.view.ViewGroup; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; +import androidx.core.graphics.ColorUtils; import androidx.preference.PreferenceManager; +import com.google.android.material.snackbar.Snackbar; import com.google.android.material.tabs.TabLayout; +import com.jakewharton.rxbinding4.view.RxView; import org.schabi.newpipe.R; import org.schabi.newpipe.database.subscription.NotificationMode; import org.schabi.newpipe.database.subscription.SubscriptionEntity; import org.schabi.newpipe.databinding.FragmentChannelBinding; import org.schabi.newpipe.error.ErrorInfo; +import org.schabi.newpipe.error.ErrorUtil; import org.schabi.newpipe.error.UserAction; import org.schabi.newpipe.extractor.channel.ChannelInfo; import org.schabi.newpipe.extractor.exceptions.ContentNotSupportedException; import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler; import org.schabi.newpipe.fragments.BaseStateFragment; import org.schabi.newpipe.fragments.detail.TabAdapter; +import org.schabi.newpipe.ktx.AnimationType; import org.schabi.newpipe.local.feed.notifications.NotificationHelper; import org.schabi.newpipe.local.subscription.SubscriptionManager; import org.schabi.newpipe.util.ChannelTabHelper; import org.schabi.newpipe.util.Constants; import org.schabi.newpipe.util.ExtractorHelper; +import org.schabi.newpipe.util.Localization; import org.schabi.newpipe.util.NavigationHelper; +import org.schabi.newpipe.util.PicassoHelper; import org.schabi.newpipe.util.StateSaver; +import org.schabi.newpipe.util.ThemeHelper; import org.schabi.newpipe.util.external_communication.ShareUtils; import java.util.List; import java.util.Queue; +import java.util.concurrent.TimeUnit; import icepick.State; import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; import io.reactivex.rxjava3.core.Observable; import io.reactivex.rxjava3.disposables.CompositeDisposable; import io.reactivex.rxjava3.disposables.Disposable; +import io.reactivex.rxjava3.functions.Action; import io.reactivex.rxjava3.functions.Consumer; +import io.reactivex.rxjava3.functions.Function; import io.reactivex.rxjava3.schedulers.Schedulers; public class ChannelFragment extends BaseStateFragment implements StateSaver.WriteRead { + + private static final int BUTTON_DEBOUNCE_INTERVAL = 100; + private static final String PICASSO_CHANNEL_TAG = "PICASSO_CHANNEL_TAG"; + @State protected int serviceId = Constants.NO_SERVICE_ID; @State @@ -60,13 +82,11 @@ public class ChannelFragment extends BaseStateFragment private ChannelInfo currentInfo; private Disposable currentWorker; - private Disposable subscriptionMonitor; private final CompositeDisposable disposables = new CompositeDisposable(); + private Disposable subscribeButtonMonitor; private SubscriptionManager subscriptionManager; private int lastTab; - - private MenuItem menuRssButton; - private MenuItem menuNotifyButton; + private boolean channelContentNotSupported = false; /*////////////////////////////////////////////////////////////////////////// // Views @@ -75,6 +95,9 @@ public class ChannelFragment extends BaseStateFragment private FragmentChannelBinding binding; private TabAdapter tabAdapter; + private MenuItem menuRssButton; + private MenuItem menuNotifyButton; + public static ChannelFragment getInstance(final int serviceId, final String url, final String name) { final ChannelFragment instance = new ChannelFragment(); @@ -82,12 +105,13 @@ public class ChannelFragment extends BaseStateFragment return instance; } - protected void setInitialData(final int sid, final String u, final String title) { + private void setInitialData(final int sid, final String u, final String title) { this.serviceId = sid; this.url = u; this.name = !TextUtils.isEmpty(title) ? title : ""; } + /*////////////////////////////////////////////////////////////////////////// // LifeCycle //////////////////////////////////////////////////////////////////////////*/ @@ -96,12 +120,6 @@ public class ChannelFragment extends BaseStateFragment public void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); setHasOptionsMenu(true); - - if (savedInstanceState != null) { - lastTab = savedInstanceState.getInt("LastTab"); - } else { - lastTab = 0; - } } @Override @@ -125,14 +143,29 @@ public class ChannelFragment extends BaseStateFragment tabAdapter = new TabAdapter(getChildFragmentManager()); binding.viewPager.setAdapter(tabAdapter); binding.tabLayout.setupWithViewPager(binding.viewPager); + + binding.channelTitleView.setText(name); } @Override - public void onSaveInstanceState(final @NonNull Bundle outState) { - super.onSaveInstanceState(outState); - if (binding != null) { - outState.putInt("LastTab", binding.tabLayout.getSelectedTabPosition()); - } + protected void initListeners() { + super.initListeners(); + + final View.OnClickListener openSubChannel = v -> { + if (!TextUtils.isEmpty(currentInfo.getParentChannelUrl())) { + try { + NavigationHelper.openChannelFragment(getFM(), currentInfo.getServiceId(), + currentInfo.getParentChannelUrl(), + currentInfo.getParentChannelName()); + } catch (final Exception e) { + ErrorUtil.showUiErrorSnackbar(this, "Opening channel fragment", e); + } + } else if (DEBUG) { + Log.i(TAG, "Can't open parent channel because we got no channel URL"); + } + }; + binding.subChannelAvatarView.setOnClickListener(openSubChannel); + binding.subChannelTitleView.setOnClickListener(openSubChannel); } @Override @@ -141,14 +174,12 @@ public class ChannelFragment extends BaseStateFragment if (currentWorker != null) { currentWorker.dispose(); } - if (subscriptionMonitor != null) { - subscriptionMonitor.dispose(); - } disposables.clear(); binding = null; } - /*////////////////////////////////////////////////////////////////////////// + + /*////////////////////////////////////////////////////////////////////////// // Menu //////////////////////////////////////////////////////////////////////////*/ @@ -164,8 +195,6 @@ public class ChannelFragment extends BaseStateFragment } menuRssButton = menu.findItem(R.id.menu_item_rss); menuNotifyButton = menu.findItem(R.id.menu_item_notify); - updateRssButton(); - monitorSubscription(); } @Override @@ -201,37 +230,168 @@ public class ChannelFragment extends BaseStateFragment return true; } - private void updateRssButton() { - if (currentInfo != null && menuRssButton != null) { - menuRssButton.setVisible(!TextUtils.isEmpty(currentInfo.getFeedUrl())); - } + + /*////////////////////////////////////////////////////////////////////////// + // Channel Subscription + //////////////////////////////////////////////////////////////////////////*/ + + private void monitorSubscription(final ChannelInfo info) { + final Consumer onError = (Throwable throwable) -> { + animate(binding.channelSubscribeButton, false, 100); + showSnackBarError(new ErrorInfo(throwable, UserAction.SUBSCRIPTION_GET, + "Get subscription status", currentInfo)); + }; + + final Observable> observable = subscriptionManager + .subscriptionTable() + .getSubscriptionFlowable(info.getServiceId(), info.getUrl()) + .toObservable(); + + disposables.add(observable + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(getSubscribeUpdateMonitor(info), onError)); + + disposables.add(observable + .map(List::isEmpty) + .distinctUntilChanged() + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(isEmpty -> updateSubscribeButton(!isEmpty), onError)); + + disposables.add(observable + .map(List::isEmpty) + .distinctUntilChanged() + .skip(1) // channel has just been opened + .filter(x -> NotificationHelper.areNewStreamsNotificationsEnabled(requireContext())) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(isEmpty -> { + if (!isEmpty) { + showNotifySnackbar(); + } + }, onError)); } - private void monitorSubscription() { - if (currentInfo != null) { - final Observable> observable = subscriptionManager - .subscriptionTable() - .getSubscriptionFlowable(currentInfo.getServiceId(), currentInfo.getUrl()) - .toObservable(); - - if (subscriptionMonitor != null) { - subscriptionMonitor.dispose(); - } - subscriptionMonitor = observable - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(getSubscribeUpdateMonitor()); - } + private Function mapOnSubscribe(final SubscriptionEntity subscription, + final ChannelInfo info) { + return (@NonNull Object o) -> { + subscriptionManager.insertSubscription(subscription, info); + return o; + }; } - private Consumer> getSubscribeUpdateMonitor() { - return (List subscriptionEntities) -> { - if (subscriptionEntities.isEmpty()) { - updateNotifyButton(null); - } else { - final SubscriptionEntity subscription = subscriptionEntities.get(0); - updateNotifyButton(subscription); + private Function mapOnUnsubscribe(final SubscriptionEntity subscription) { + return (@NonNull Object o) -> { + subscriptionManager.deleteSubscription(subscription); + return o; + }; + } + + private void updateSubscription(final ChannelInfo info) { + if (DEBUG) { + Log.d(TAG, "updateSubscription() called with: info = [" + info + "]"); + } + final Action onComplete = () -> { + if (DEBUG) { + Log.d(TAG, "Updated subscription: " + info.getUrl()); } }; + + final Consumer onError = (@NonNull Throwable throwable) -> + showSnackBarError(new ErrorInfo(throwable, UserAction.SUBSCRIPTION_UPDATE, + "Updating subscription for " + info.getUrl(), info)); + + disposables.add(subscriptionManager.updateChannelInfo(info) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(onComplete, onError)); + } + + private Disposable monitorSubscribeButton(final Function action) { + final Consumer onNext = (@NonNull Object o) -> { + if (DEBUG) { + Log.d(TAG, "Changed subscription status to this channel!"); + } + }; + + final Consumer onError = (@NonNull Throwable throwable) -> + showSnackBarError(new ErrorInfo(throwable, UserAction.SUBSCRIPTION_CHANGE, + "Changing subscription for " + currentInfo.getUrl(), currentInfo)); + + /* Emit clicks from main thread unto io thread */ + return RxView.clicks(binding.channelSubscribeButton) + .subscribeOn(AndroidSchedulers.mainThread()) + .observeOn(Schedulers.io()) + .debounce(BUTTON_DEBOUNCE_INTERVAL, TimeUnit.MILLISECONDS) // Ignore rapid clicks + .map(action) + .subscribe(onNext, onError); + } + + private Consumer> getSubscribeUpdateMonitor(final ChannelInfo info) { + return (List subscriptionEntities) -> { + if (DEBUG) { + Log.d(TAG, "subscriptionManager.subscriptionTable.doOnNext() called with: " + + "subscriptionEntities = [" + subscriptionEntities + "]"); + } + if (subscribeButtonMonitor != null) { + subscribeButtonMonitor.dispose(); + } + + if (subscriptionEntities.isEmpty()) { + if (DEBUG) { + Log.d(TAG, "No subscription to this channel!"); + } + final SubscriptionEntity channel = new SubscriptionEntity(); + channel.setServiceId(info.getServiceId()); + channel.setUrl(info.getUrl()); + channel.setData(info.getName(), + info.getAvatarUrl(), + info.getDescription(), + info.getSubscriberCount()); + updateNotifyButton(null); + subscribeButtonMonitor = monitorSubscribeButton(mapOnSubscribe(channel, info)); + } else { + if (DEBUG) { + Log.d(TAG, "Found subscription to this channel!"); + } + final SubscriptionEntity subscription = subscriptionEntities.get(0); + updateNotifyButton(subscription); + subscribeButtonMonitor = monitorSubscribeButton(mapOnUnsubscribe(subscription)); + } + }; + } + + private void updateSubscribeButton(final boolean isSubscribed) { + if (DEBUG) { + Log.d(TAG, "updateSubscribeButton() called with: " + + "isSubscribed = [" + isSubscribed + "]"); + } + + final boolean isButtonVisible = binding.channelSubscribeButton.getVisibility() + == View.VISIBLE; + final int backgroundDuration = isButtonVisible ? 300 : 0; + final int textDuration = isButtonVisible ? 200 : 0; + + final int subscribedBackground = ContextCompat + .getColor(activity, R.color.subscribed_background_color); + final int subscribedText = ContextCompat.getColor(activity, R.color.subscribed_text_color); + final int subscribeBackground = ColorUtils.blendARGB(ThemeHelper + .resolveColorFromAttr(activity, R.attr.colorPrimary), subscribedBackground, 0.35f); + final int subscribeText = ContextCompat.getColor(activity, R.color.subscribe_text_color); + + if (isSubscribed) { + binding.channelSubscribeButton.setText(R.string.subscribed_button_title); + animateBackgroundColor(binding.channelSubscribeButton, backgroundDuration, + subscribeBackground, subscribedBackground); + animateTextColor(binding.channelSubscribeButton, textDuration, subscribeText, + subscribedText); + } else { + binding.channelSubscribeButton.setText(R.string.subscribe_button_title); + animateBackgroundColor(binding.channelSubscribeButton, backgroundDuration, + subscribedBackground, subscribeBackground); + animateTextColor(binding.channelSubscribeButton, textDuration, subscribedText, + subscribeText); + } + + animate(binding.channelSubscribeButton, true, 100, AnimationType.LIGHT_SCALE_AND_ALPHA); } private void updateNotifyButton(@Nullable final SubscriptionEntity subscription) { @@ -263,52 +423,48 @@ public class ChannelFragment extends BaseStateFragment ); } + /** + * Show a snackbar with the option to enable notifications on new streams for this channel. + */ + private void showNotifySnackbar() { + Snackbar.make(binding.getRoot(), R.string.you_successfully_subscribed, Snackbar.LENGTH_LONG) + .setAction(R.string.get_notified, v -> setNotify(true)) + .setActionTextColor(Color.YELLOW) + .show(); + } + + /*////////////////////////////////////////////////////////////////////////// // Init //////////////////////////////////////////////////////////////////////////*/ - private boolean isContentUnsupported() { - for (final Throwable throwable : currentInfo.getErrors()) { - if (throwable instanceof ContentNotSupportedException) { - return true; - } - } - return false; - } - private void updateTabs() { tabAdapter.clearAllItems(); - if (currentInfo != null) { - if (isContentUnsupported()) { - showEmptyState(); - binding.errorContentNotSupported.setVisibility(View.VISIBLE); - } else { - tabAdapter.addFragment( - ChannelVideosFragment.getInstance(currentInfo), "Videos"); + if (currentInfo != null && !channelContentNotSupported) { + tabAdapter.addFragment(new ChannelVideosFragment(currentInfo), "Videos"); - final Context context = getContext(); - final SharedPreferences preferences = PreferenceManager - .getDefaultSharedPreferences(context); + final Context context = requireContext(); + final SharedPreferences preferences = PreferenceManager + .getDefaultSharedPreferences(context); - for (final ListLinkHandler linkHandler : currentInfo.getTabs()) { - final String tab = linkHandler.getContentFilters().get(0); - if (ChannelTabHelper.showChannelTab(context, preferences, tab)) { - tabAdapter.addFragment( - ChannelTabFragment.getInstance(serviceId, linkHandler, name), - context.getString(ChannelTabHelper.getTranslationKey(tab))); - } - } - - final String description = currentInfo.getDescription(); - if (description != null && !description.isEmpty() - && ChannelTabHelper.showChannelTab( - context, preferences, R.string.show_channel_tabs_about)) { + for (final ListLinkHandler linkHandler : currentInfo.getTabs()) { + final String tab = linkHandler.getContentFilters().get(0); + if (ChannelTabHelper.showChannelTab(context, preferences, tab)) { tabAdapter.addFragment( - ChannelAboutFragment.getInstance(currentInfo), - context.getString(R.string.channel_tab_about)); + ChannelTabFragment.getInstance(serviceId, linkHandler, name), + context.getString(ChannelTabHelper.getTranslationKey(tab))); } } + + final String description = currentInfo.getDescription(); + if (description != null && !description.isEmpty() + && ChannelTabHelper.showChannelTab( + context, preferences, R.string.show_channel_tabs_about)) { + tabAdapter.addFragment( + ChannelAboutFragment.getInstance(currentInfo), + context.getString(R.string.channel_tab_about)); + } } tabAdapter.notifyDataSetUpdate(); @@ -324,6 +480,7 @@ public class ChannelFragment extends BaseStateFragment } } + /*////////////////////////////////////////////////////////////////////////// // State Saving //////////////////////////////////////////////////////////////////////////*/ @@ -336,11 +493,7 @@ public class ChannelFragment extends BaseStateFragment @Override public void writeTo(final Queue objectsToSave) { objectsToSave.add(currentInfo); - if (binding != null) { - objectsToSave.add(binding.tabLayout.getSelectedTabPosition()); - } else { - objectsToSave.add(0); - } + objectsToSave.add(binding == null ? 0 : binding.tabLayout.getSelectedTabPosition()); } @Override @@ -349,6 +502,25 @@ public class ChannelFragment extends BaseStateFragment lastTab = (Integer) savedObjects.poll(); } + @Override + public void onSaveInstanceState(final @NonNull Bundle outState) { + super.onSaveInstanceState(outState); + if (binding != null) { + outState.putInt("LastTab", binding.tabLayout.getSelectedTabPosition()); + } + } + + @Override + protected void onRestoreInstanceState(@NonNull final Bundle savedInstanceState) { + super.onRestoreInstanceState(savedInstanceState); + lastTab = savedInstanceState.getInt("LastTab", 0); + } + + + /*////////////////////////////////////////////////////////////////////////// + // Contract + //////////////////////////////////////////////////////////////////////////*/ + @Override protected void doInitialLoadLogic() { if (currentInfo == null) { @@ -382,14 +554,77 @@ public class ChannelFragment extends BaseStateFragment url == null ? "no url" : url, serviceId))); } + @Override + public void showLoading() { + super.showLoading(); + PicassoHelper.cancelTag(PICASSO_CHANNEL_TAG); + animate(binding.channelSubscribeButton, false, 100); + } + @Override public void handleResult(@NonNull final ChannelInfo result) { super.handleResult(result); currentInfo = result; setInitialData(result.getServiceId(), result.getOriginalUrl(), result.getName()); + binding.getRoot().setVisibility(View.VISIBLE); + PicassoHelper.loadBanner(result.getBannerUrl()).tag(PICASSO_CHANNEL_TAG) + .into(binding.channelBannerImage); + PicassoHelper.loadAvatar(result.getAvatarUrl()).tag(PICASSO_CHANNEL_TAG) + .into(binding.channelAvatarView); + PicassoHelper.loadAvatar(result.getParentChannelAvatarUrl()).tag(PICASSO_CHANNEL_TAG) + .into(binding.subChannelAvatarView); + + binding.channelTitleView.setText(result.getName()); + binding.channelSubscriberView.setVisibility(View.VISIBLE); + if (result.getSubscriberCount() >= 0) { + binding.channelSubscriberView.setText(Localization + .shortSubscriberCount(activity, result.getSubscriberCount())); + } else { + binding.channelSubscriberView.setText(R.string.subscribers_count_not_available); + } + + if (!TextUtils.isEmpty(currentInfo.getParentChannelName())) { + binding.subChannelTitleView.setText(String.format( + getString(R.string.channel_created_by), + currentInfo.getParentChannelName()) + ); + binding.subChannelTitleView.setVisibility(View.VISIBLE); + binding.subChannelAvatarView.setVisibility(View.VISIBLE); + } + + if (menuRssButton != null) { + menuRssButton.setVisible(!TextUtils.isEmpty(result.getFeedUrl())); + } + + channelContentNotSupported = false; + for (final Throwable throwable : result.getErrors()) { + if (throwable instanceof ContentNotSupportedException) { + channelContentNotSupported = true; + showContentNotSupportedIfNeeded(); + break; + } + } + + disposables.clear(); + if (subscribeButtonMonitor != null) { + subscribeButtonMonitor.dispose(); + } + updateTabs(); - updateRssButton(); - monitorSubscription(); + updateSubscription(result); + monitorSubscription(result); + } + + private void showContentNotSupportedIfNeeded() { + // channelBinding might not be initialized when handleResult() is called + // (e.g. after rotating the screen, #6696) + if (!channelContentNotSupported || binding == null) { + return; + } + + binding.errorContentNotSupported.setVisibility(View.VISIBLE); + binding.channelKaomoji.setText("(︶︹︺)"); + binding.channelKaomoji.setTextSize(TypedValue.COMPLEX_UNIT_SP, 45f); } } diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelVideosFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelVideosFragment.java index a38b913d6..a2d50836b 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelVideosFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelVideosFragment.java @@ -1,109 +1,61 @@ package org.schabi.newpipe.fragments.list.channel; -import static org.schabi.newpipe.ktx.TextViewUtils.animateTextColor; -import static org.schabi.newpipe.ktx.ViewUtils.animate; -import static org.schabi.newpipe.ktx.ViewUtils.animateBackgroundColor; - -import android.content.Context; -import android.graphics.Color; import android.os.Bundle; -import android.text.TextUtils; -import android.util.Log; -import android.util.TypedValue; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.Button; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.core.content.ContextCompat; -import com.google.android.material.snackbar.Snackbar; -import com.jakewharton.rxbinding4.view.RxView; - -import org.schabi.newpipe.R; -import org.schabi.newpipe.database.subscription.NotificationMode; -import org.schabi.newpipe.database.subscription.SubscriptionEntity; -import org.schabi.newpipe.databinding.ChannelHeaderBinding; import org.schabi.newpipe.databinding.FragmentChannelVideosBinding; import org.schabi.newpipe.databinding.PlaylistControlBinding; -import org.schabi.newpipe.error.ErrorInfo; -import org.schabi.newpipe.error.ErrorUtil; import org.schabi.newpipe.error.UserAction; import org.schabi.newpipe.extractor.ListExtractor; import org.schabi.newpipe.extractor.channel.ChannelInfo; -import org.schabi.newpipe.extractor.exceptions.ContentNotSupportedException; import org.schabi.newpipe.extractor.stream.StreamInfoItem; import org.schabi.newpipe.fragments.list.BaseListInfoFragment; -import org.schabi.newpipe.ktx.AnimationType; -import org.schabi.newpipe.local.feed.notifications.NotificationHelper; -import org.schabi.newpipe.local.subscription.SubscriptionManager; import org.schabi.newpipe.player.PlayerType; import org.schabi.newpipe.player.playqueue.ChannelPlayQueue; import org.schabi.newpipe.player.playqueue.PlayQueue; import org.schabi.newpipe.util.ExtractorHelper; -import org.schabi.newpipe.util.Localization; import org.schabi.newpipe.util.NavigationHelper; -import org.schabi.newpipe.util.PicassoHelper; -import org.schabi.newpipe.util.ThemeHelper; import java.util.List; -import java.util.concurrent.TimeUnit; import java.util.function.Supplier; import java.util.stream.Collectors; -import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; -import io.reactivex.rxjava3.core.Observable; import io.reactivex.rxjava3.core.Single; import io.reactivex.rxjava3.disposables.CompositeDisposable; -import io.reactivex.rxjava3.disposables.Disposable; -import io.reactivex.rxjava3.functions.Action; -import io.reactivex.rxjava3.functions.Consumer; -import io.reactivex.rxjava3.functions.Function; -import io.reactivex.rxjava3.schedulers.Schedulers; -public class ChannelVideosFragment extends BaseListInfoFragment - implements View.OnClickListener { - - private static final int BUTTON_DEBOUNCE_INTERVAL = 100; - private static final String PICASSO_CHANNEL_TAG = "PICASSO_CHANNEL_TAG"; +public class ChannelVideosFragment extends BaseListInfoFragment { private final CompositeDisposable disposables = new CompositeDisposable(); - private Disposable subscribeButtonMonitor; - - private boolean channelContentNotSupported = false; - - /*////////////////////////////////////////////////////////////////////////// - // Views - //////////////////////////////////////////////////////////////////////////*/ - - private SubscriptionManager subscriptionManager; private FragmentChannelVideosBinding channelBinding; - private ChannelHeaderBinding headerBinding; private PlaylistControlBinding playlistControlBinding; - public static ChannelVideosFragment getInstance(@NonNull final ChannelInfo channelInfo) { - final ChannelVideosFragment instance = new ChannelVideosFragment(); - instance.setInitialData(channelInfo.getServiceId(), channelInfo.getUrl(), - channelInfo.getName()); - instance.currentInfo = channelInfo; - instance.currentNextPage = channelInfo.getNextPage(); - return instance; - } - public static ChannelVideosFragment getInstance( - final int serviceId, final String url, final String name) { - final ChannelVideosFragment instance = new ChannelVideosFragment(); - instance.setInitialData(serviceId, url, name); - return instance; - } + /*////////////////////////////////////////////////////////////////////////// + // Constructors and lifecycle + //////////////////////////////////////////////////////////////////////////*/ + // required by the Android framework to restore fragments after saving public ChannelVideosFragment() { super(UserAction.REQUESTED_CHANNEL); } + public ChannelVideosFragment(final int serviceId, final String url, final String name) { + this(); + setInitialData(serviceId, url, name); + } + + public ChannelVideosFragment(@NonNull final ChannelInfo info) { + this(info.getServiceId(), info.getUrl(), info.getName()); + this.currentInfo = info; + this.currentNextPage = info.getNextPage(); + } + @Override public void onResume() { super.onResume(); @@ -112,22 +64,12 @@ public class ChannelVideosFragment extends BaseListInfoFragment getListHeaderSupplier() { - headerBinding = ChannelHeaderBinding + playlistControlBinding = PlaylistControlBinding .inflate(activity.getLayoutInflater(), itemsList, false); - playlistControlBinding = headerBinding.playlistControl; - - return headerBinding::getRoot; + return playlistControlBinding::getRoot; } - @Override - protected void initListeners() { - super.initListeners(); - - headerBinding.subChannelTitleView.setOnClickListener(this); - headerBinding.subChannelAvatarView.setOnClickListener(this); - } /*////////////////////////////////////////////////////////////////////////// - // Channel Subscription - //////////////////////////////////////////////////////////////////////////*/ - - private void monitorSubscription(final ChannelInfo info) { - final Consumer onError = (Throwable throwable) -> { - animate(headerBinding.channelSubscribeButton, false, 100); - showSnackBarError(new ErrorInfo(throwable, UserAction.SUBSCRIPTION_GET, - "Get subscription status", currentInfo)); - }; - - final Observable> observable = subscriptionManager - .subscriptionTable() - .getSubscriptionFlowable(info.getServiceId(), info.getUrl()) - .toObservable(); - - disposables.add(observable - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(getSubscribeUpdateMonitor(info), onError)); - - disposables.add(observable - .map(List::isEmpty) - .distinctUntilChanged() - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(isEmpty -> updateSubscribeButton(!isEmpty), onError)); - - disposables.add(observable - .map(List::isEmpty) - .distinctUntilChanged() - .skip(1) // channel has just been opened - .filter(x -> NotificationHelper.areNewStreamsNotificationsEnabled(requireContext())) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(isEmpty -> { - if (!isEmpty) { - showNotifySnackbar(); - } - }, onError)); - } - - private Function mapOnSubscribe(final SubscriptionEntity subscription, - final ChannelInfo info) { - return (@NonNull Object o) -> { - subscriptionManager.insertSubscription(subscription, info); - return o; - }; - } - - private Function mapOnUnsubscribe(final SubscriptionEntity subscription) { - return (@NonNull Object o) -> { - subscriptionManager.deleteSubscription(subscription); - return o; - }; - } - - private void updateSubscription(final ChannelInfo info) { - if (DEBUG) { - Log.d(TAG, "updateSubscription() called with: info = [" + info + "]"); - } - final Action onComplete = () -> { - if (DEBUG) { - Log.d(TAG, "Updated subscription: " + info.getUrl()); - } - }; - - final Consumer onError = (@NonNull Throwable throwable) -> - showSnackBarError(new ErrorInfo(throwable, UserAction.SUBSCRIPTION_UPDATE, - "Updating subscription for " + info.getUrl(), info)); - - disposables.add(subscriptionManager.updateChannelInfo(info) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(onComplete, onError)); - } - - private Disposable monitorSubscribeButton(final Button subscribeButton, - final Function action) { - final Consumer onNext = (@NonNull Object o) -> { - if (DEBUG) { - Log.d(TAG, "Changed subscription status to this channel!"); - } - }; - - final Consumer onError = (@NonNull Throwable throwable) -> - showSnackBarError(new ErrorInfo(throwable, UserAction.SUBSCRIPTION_CHANGE, - "Changing subscription for " + currentInfo.getUrl(), currentInfo)); - - /* Emit clicks from main thread unto io thread */ - return RxView.clicks(subscribeButton) - .subscribeOn(AndroidSchedulers.mainThread()) - .observeOn(Schedulers.io()) - .debounce(BUTTON_DEBOUNCE_INTERVAL, TimeUnit.MILLISECONDS) // Ignore rapid clicks - .map(action) - .subscribe(onNext, onError); - } - - private Consumer> getSubscribeUpdateMonitor(final ChannelInfo info) { - return (List subscriptionEntities) -> { - if (DEBUG) { - Log.d(TAG, "subscriptionManager.subscriptionTable.doOnNext() called with: " - + "subscriptionEntities = [" + subscriptionEntities + "]"); - } - if (subscribeButtonMonitor != null) { - subscribeButtonMonitor.dispose(); - } - - if (subscriptionEntities.isEmpty()) { - if (DEBUG) { - Log.d(TAG, "No subscription to this channel!"); - } - final SubscriptionEntity channel = new SubscriptionEntity(); - channel.setServiceId(info.getServiceId()); - channel.setUrl(info.getUrl()); - channel.setData(info.getName(), - info.getAvatarUrl(), - info.getDescription(), - info.getSubscriberCount()); - subscribeButtonMonitor = monitorSubscribeButton( - headerBinding.channelSubscribeButton, mapOnSubscribe(channel, info)); - } else { - if (DEBUG) { - Log.d(TAG, "Found subscription to this channel!"); - } - final SubscriptionEntity subscription = subscriptionEntities.get(0); - subscribeButtonMonitor = monitorSubscribeButton( - headerBinding.channelSubscribeButton, mapOnUnsubscribe(subscription)); - } - }; - } - - private void updateSubscribeButton(final boolean isSubscribed) { - if (DEBUG) { - Log.d(TAG, "updateSubscribeButton() called with: " - + "isSubscribed = [" + isSubscribed + "]"); - } - - final boolean isButtonVisible = headerBinding.channelSubscribeButton.getVisibility() - == View.VISIBLE; - final int backgroundDuration = isButtonVisible ? 300 : 0; - final int textDuration = isButtonVisible ? 200 : 0; - - final int subscribeBackground = ThemeHelper - .resolveColorFromAttr(activity, R.attr.colorPrimary); - final int subscribeText = ContextCompat.getColor(activity, R.color.subscribe_text_color); - final int subscribedBackground = ContextCompat - .getColor(activity, R.color.subscribed_background_color); - final int subscribedText = ContextCompat.getColor(activity, R.color.subscribed_text_color); - - if (!isSubscribed) { - headerBinding.channelSubscribeButton.setText(R.string.subscribe_button_title); - animateBackgroundColor(headerBinding.channelSubscribeButton, backgroundDuration, - subscribedBackground, subscribeBackground); - animateTextColor(headerBinding.channelSubscribeButton, textDuration, subscribedText, - subscribeText); - } else { - headerBinding.channelSubscribeButton.setText(R.string.subscribed_button_title); - animateBackgroundColor(headerBinding.channelSubscribeButton, backgroundDuration, - subscribeBackground, subscribedBackground); - animateTextColor(headerBinding.channelSubscribeButton, textDuration, subscribeText, - subscribedText); - } - - animate(headerBinding.channelSubscribeButton, true, 100, - AnimationType.LIGHT_SCALE_AND_ALPHA); - } - - /** - * Show a snackbar with the option to enable notifications on new streams for this channel. - */ - private void showNotifySnackbar() { - Snackbar.make(itemsList, R.string.you_successfully_subscribed, Snackbar.LENGTH_LONG) - .setAction(R.string.get_notified, v -> setNotify(true)) - .setActionTextColor(Color.YELLOW) - .show(); - } - - private void setNotify(final boolean isEnabled) { - disposables.add( - subscriptionManager - .updateNotificationMode( - currentInfo.getServiceId(), - currentInfo.getUrl(), - isEnabled ? NotificationMode.ENABLED : NotificationMode.DISABLED) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe() - ); - } - - /*////////////////////////////////////////////////////////////////////////// - // Load and handle + // Loading //////////////////////////////////////////////////////////////////////////*/ @Override @@ -377,76 +108,15 @@ public class ChannelVideosFragment extends BaseListInfoFragment= 0) { - headerBinding.channelSubscriberView.setText(Localization - .shortSubscriberCount(activity, result.getSubscriberCount())); - } else { - headerBinding.channelSubscriberView.setText(R.string.subscribers_count_not_available); - } - - if (!TextUtils.isEmpty(currentInfo.getParentChannelName())) { - headerBinding.subChannelTitleView.setText(String.format( - getString(R.string.channel_created_by), - currentInfo.getParentChannelName()) - ); - headerBinding.subChannelTitleView.setVisibility(View.VISIBLE); - headerBinding.subChannelAvatarView.setVisibility(View.VISIBLE); - } else { - headerBinding.subChannelTitleView.setVisibility(View.GONE); - } - // PlaylistControls should be visible only if there is some item in // infoListAdapter other than header if (infoListAdapter.getItemCount() != 1) { @@ -455,31 +125,14 @@ public class ChannelVideosFragment extends BaseListInfoFragment NavigationHelper - .playOnMainPlayer(activity, getPlayQueue())); - playlistControlBinding.playlistCtrlPlayPopupButton - .setOnClickListener(view -> NavigationHelper - .playOnPopupPlayer(activity, getPlayQueue(), false)); - playlistControlBinding.playlistCtrlPlayBgButton - .setOnClickListener(view -> NavigationHelper - .playOnBackgroundPlayer(activity, getPlayQueue(), false)); + playlistControlBinding.playlistCtrlPlayAllButton.setOnClickListener( + view -> NavigationHelper.playOnMainPlayer(activity, getPlayQueue())); + playlistControlBinding.playlistCtrlPlayPopupButton.setOnClickListener( + view -> NavigationHelper.playOnPopupPlayer(activity, getPlayQueue(), false)); + playlistControlBinding.playlistCtrlPlayBgButton.setOnClickListener( + view -> NavigationHelper.playOnBackgroundPlayer(activity, getPlayQueue(), false)); playlistControlBinding.playlistCtrlPlayPopupButton.setOnLongClickListener(view -> { NavigationHelper.enqueueOnPlayer(activity, getPlayQueue(), PlayerType.POPUP); @@ -492,19 +145,6 @@ public class ChannelVideosFragment extends BaseListInfoFragment streamItems = infoListAdapter.getItemsList().stream() .filter(StreamInfoItem.class::isInstance) @@ -514,14 +154,4 @@ public class ChannelVideosFragment extends BaseListInfoFragment - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/fragment_channel.xml b/app/src/main/res/layout/fragment_channel.xml index db77391bc..29d9143c5 100644 --- a/app/src/main/res/layout/fragment_channel.xml +++ b/app/src/main/res/layout/fragment_channel.xml @@ -1,75 +1,207 @@ - - + app:elevation="0dp"> - + + + + + + + + + + + + + + + + + + + + + - - - - + app:layout_behavior="@string/appbar_scrolling_view_behavior"> - + + + + + android:layout_centerInParent="true" + android:indeterminate="true" + android:visibility="gone" + tools:visibility="visible" /> - + android:layout_centerInParent="true" + android:orientation="vertical" + android:paddingTop="90dp" + android:visibility="gone" + tools:visibility="visible"> - + - - - \ No newline at end of file + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values-land/dimens.xml b/app/src/main/res/values-land/dimens.xml index 77e18695d..46244b3c9 100644 --- a/app/src/main/res/values-land/dimens.xml +++ b/app/src/main/res/values-land/dimens.xml @@ -32,7 +32,6 @@ 16sp 14sp 14sp - 14sp 14sp 42dp diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index e47b72c9a..0e5fd126f 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -75,7 +75,6 @@ 14sp 13sp 13sp - 12sp 12sp 32dp From b5893f3fa3a0926edc0286e102464e1a0a5a08b0 Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Thu, 13 Apr 2023 21:55:37 +0200 Subject: [PATCH 050/172] fix: notification menu option disappears when switching tabs --- .../fragments/list/channel/ChannelFragment.java | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java index 9de143518..2947cdb16 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java @@ -97,6 +97,7 @@ public class ChannelFragment extends BaseStateFragment private MenuItem menuRssButton; private MenuItem menuNotifyButton; + private SubscriptionEntity channelSubscription; public static ChannelFragment getInstance(final int serviceId, final String url, final String name) { @@ -193,8 +194,14 @@ public class ChannelFragment extends BaseStateFragment Log.d(TAG, "onCreateOptionsMenu() called with: " + "menu = [" + menu + "], inflater = [" + inflater + "]"); } + } + + @Override + public void onPrepareOptionsMenu(final @NonNull Menu menu) { + super.onPrepareOptionsMenu(menu); menuRssButton = menu.findItem(R.id.menu_item_rss); menuNotifyButton = menu.findItem(R.id.menu_item_notify); + updateNotifyButton(channelSubscription); } @Override @@ -346,15 +353,17 @@ public class ChannelFragment extends BaseStateFragment info.getAvatarUrl(), info.getDescription(), info.getSubscriberCount()); + channelSubscription = null; updateNotifyButton(null); subscribeButtonMonitor = monitorSubscribeButton(mapOnSubscribe(channel, info)); } else { if (DEBUG) { Log.d(TAG, "Found subscription to this channel!"); } - final SubscriptionEntity subscription = subscriptionEntities.get(0); - updateNotifyButton(subscription); - subscribeButtonMonitor = monitorSubscribeButton(mapOnUnsubscribe(subscription)); + channelSubscription = subscriptionEntities.get(0); + updateNotifyButton(channelSubscription); + subscribeButtonMonitor = + monitorSubscribeButton(mapOnUnsubscribe(channelSubscription)); } }; } From dfbd39e8985ad4b043bc382746bf2b1126711d3d Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Thu, 13 Apr 2023 22:39:55 +0200 Subject: [PATCH 051/172] fix: limit channel header height --- app/src/main/res/layout/fragment_channel.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/layout/fragment_channel.xml b/app/src/main/res/layout/fragment_channel.xml index 29d9143c5..15995f8f3 100644 --- a/app/src/main/res/layout/fragment_channel.xml +++ b/app/src/main/res/layout/fragment_channel.xml @@ -29,6 +29,7 @@ android:id="@+id/channel_banner_image" android:layout_width="match_parent" android:layout_height="wrap_content" + android:maxHeight="70dp" android:adjustViewBounds="true" android:scaleType="centerCrop" tools:src="@drawable/placeholder_channel_banner" From c076a0f77127fe6a875461dc879605405ada5ede Mon Sep 17 00:00:00 2001 From: Stypox Date: Fri, 14 Apr 2023 10:19:58 +0200 Subject: [PATCH 052/172] Channels are now an Info The previous "main" tab is now just a normal tab returned in getTabs(). Various part of the code that used to handle channels as ListInfo now either take the first (playable, i.e. with streams) tab (e.g. the ChannelTabPlayQueue), or take all of them combined (e.g. the feed). --- app/build.gradle | 2 +- .../org/schabi/newpipe/RouterActivity.java | 15 +- .../fragments/list/BaseListInfoFragment.java | 5 +- .../list/channel/ChannelFragment.java | 9 +- .../list/channel/ChannelVideosFragment.java | 157 ------------------ .../feed/notifications/NotificationHelper.kt | 8 +- .../local/feed/service/FeedLoadManager.kt | 130 ++++++++++----- .../local/feed/service/FeedLoadService.kt | 14 +- .../local/feed/service/FeedUpdateInfo.kt | 16 +- .../local/subscription/SubscriptionManager.kt | 43 +++-- .../services/SubscriptionsImportService.java | 31 +++- .../playqueue/AbstractInfoPlayQueue.java | 22 ++- .../player/playqueue/ChannelPlayQueue.java | 47 ------ .../player/playqueue/ChannelTabPlayQueue.java | 53 ++++++ .../org/schabi/newpipe/settings/tabs/Tab.java | 6 +- .../schabi/newpipe/util/ChannelTabHelper.java | 54 +++++- .../schabi/newpipe/util/ExtractorHelper.java | 28 ---- app/src/main/res/values/settings_keys.xml | 18 +- app/src/main/res/values/strings.xml | 5 +- 19 files changed, 301 insertions(+), 362 deletions(-) delete mode 100644 app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelVideosFragment.java delete mode 100644 app/src/main/java/org/schabi/newpipe/player/playqueue/ChannelPlayQueue.java create mode 100644 app/src/main/java/org/schabi/newpipe/player/playqueue/ChannelTabPlayQueue.java diff --git a/app/build.gradle b/app/build.gradle index b7430287a..1f924b12f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -197,7 +197,7 @@ dependencies { // name and the commit hash with the commit hash of the (pushed) commit you want to test // This works thanks to JitPack: https://jitpack.io/ implementation 'com.github.TeamNewPipe:nanojson:1d9e1aea9049fc9f85e68b43ba39fe7be1c1f751' - implementation 'com.github.Theta-Dev:NewPipeExtractor:e278a2d6d428dec82a304d271803d35afbd7340c' + implementation 'com.github.Theta-Dev:NewPipeExtractor:c3651bef5c622abf0cdfc34c9985ba8c33d1491e' implementation 'com.github.TeamNewPipe:NoNonsense-FilePicker:5.0.0' /** Checkstyle **/ diff --git a/app/src/main/java/org/schabi/newpipe/RouterActivity.java b/app/src/main/java/org/schabi/newpipe/RouterActivity.java index 70c377de9..c59dc7532 100644 --- a/app/src/main/java/org/schabi/newpipe/RouterActivity.java +++ b/app/src/main/java/org/schabi/newpipe/RouterActivity.java @@ -65,6 +65,7 @@ import org.schabi.newpipe.extractor.exceptions.PrivateContentException; import org.schabi.newpipe.extractor.exceptions.ReCaptchaException; import org.schabi.newpipe.extractor.exceptions.SoundCloudGoPlusContentException; import org.schabi.newpipe.extractor.exceptions.YoutubeMusicPremiumContentException; +import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler; import org.schabi.newpipe.extractor.playlist.PlaylistInfo; import org.schabi.newpipe.extractor.stream.StreamInfo; import org.schabi.newpipe.ktx.ExceptionUtils; @@ -72,10 +73,11 @@ import org.schabi.newpipe.local.dialog.PlaylistDialog; import org.schabi.newpipe.player.PlayerType; import org.schabi.newpipe.player.helper.PlayerHelper; import org.schabi.newpipe.player.helper.PlayerHolder; -import org.schabi.newpipe.player.playqueue.ChannelPlayQueue; +import org.schabi.newpipe.player.playqueue.ChannelTabPlayQueue; import org.schabi.newpipe.player.playqueue.PlayQueue; import org.schabi.newpipe.player.playqueue.PlaylistPlayQueue; import org.schabi.newpipe.player.playqueue.SinglePlayQueue; +import org.schabi.newpipe.util.ChannelTabHelper; import org.schabi.newpipe.util.Constants; import org.schabi.newpipe.util.DeviceUtils; import org.schabi.newpipe.util.ExtractorHelper; @@ -1022,7 +1024,16 @@ public class RouterActivity extends AppCompatActivity { } playQueue = new SinglePlayQueue((StreamInfo) info); } else if (info instanceof ChannelInfo) { - playQueue = new ChannelPlayQueue((ChannelInfo) info); + final Optional playableTab = ((ChannelInfo) info).getTabs() + .stream() + .filter(ChannelTabHelper::isStreamsTab) + .findFirst(); + + if (playableTab.isPresent()) { + playQueue = new ChannelTabPlayQueue(info.getServiceId(), playableTab.get()); + } else { + return; // there is no playable tab + } } else if (info instanceof PlaylistInfo) { playQueue = new PlaylistPlayQueue((PlaylistInfo) info); } else { diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListInfoFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListInfoFragment.java index c73ae8be0..d30dadfd1 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListInfoFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListInfoFragment.java @@ -16,7 +16,6 @@ import org.schabi.newpipe.extractor.InfoItem; import org.schabi.newpipe.extractor.ListExtractor; import org.schabi.newpipe.extractor.ListInfo; import org.schabi.newpipe.extractor.Page; -import org.schabi.newpipe.extractor.channel.ChannelInfo; import org.schabi.newpipe.extractor.exceptions.ContentNotSupportedException; import org.schabi.newpipe.util.Constants; import org.schabi.newpipe.views.NewPipeRecyclerView; @@ -236,9 +235,7 @@ public abstract class BaseListInfoFragment }, onError)); } - private Function mapOnSubscribe(final SubscriptionEntity subscription, - final ChannelInfo info) { + private Function mapOnSubscribe(final SubscriptionEntity subscription) { return (@NonNull Object o) -> { - subscriptionManager.insertSubscription(subscription, info); + subscriptionManager.insertSubscription(subscription); return o; }; } @@ -355,7 +354,7 @@ public class ChannelFragment extends BaseStateFragment info.getSubscriberCount()); channelSubscription = null; updateNotifyButton(null); - subscribeButtonMonitor = monitorSubscribeButton(mapOnSubscribe(channel, info)); + subscribeButtonMonitor = monitorSubscribeButton(mapOnSubscribe(channel)); } else { if (DEBUG) { Log.d(TAG, "Found subscription to this channel!"); @@ -451,8 +450,6 @@ public class ChannelFragment extends BaseStateFragment tabAdapter.clearAllItems(); if (currentInfo != null && !channelContentNotSupported) { - tabAdapter.addFragment(new ChannelVideosFragment(currentInfo), "Videos"); - final Context context = requireContext(); final SharedPreferences preferences = PreferenceManager .getDefaultSharedPreferences(context); diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelVideosFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelVideosFragment.java deleted file mode 100644 index a2d50836b..000000000 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelVideosFragment.java +++ /dev/null @@ -1,157 +0,0 @@ -package org.schabi.newpipe.fragments.list.channel; - -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import org.schabi.newpipe.databinding.FragmentChannelVideosBinding; -import org.schabi.newpipe.databinding.PlaylistControlBinding; -import org.schabi.newpipe.error.UserAction; -import org.schabi.newpipe.extractor.ListExtractor; -import org.schabi.newpipe.extractor.channel.ChannelInfo; -import org.schabi.newpipe.extractor.stream.StreamInfoItem; -import org.schabi.newpipe.fragments.list.BaseListInfoFragment; -import org.schabi.newpipe.player.PlayerType; -import org.schabi.newpipe.player.playqueue.ChannelPlayQueue; -import org.schabi.newpipe.player.playqueue.PlayQueue; -import org.schabi.newpipe.util.ExtractorHelper; -import org.schabi.newpipe.util.NavigationHelper; - -import java.util.List; -import java.util.function.Supplier; -import java.util.stream.Collectors; - -import io.reactivex.rxjava3.core.Single; -import io.reactivex.rxjava3.disposables.CompositeDisposable; - -public class ChannelVideosFragment extends BaseListInfoFragment { - - private final CompositeDisposable disposables = new CompositeDisposable(); - - private FragmentChannelVideosBinding channelBinding; - private PlaylistControlBinding playlistControlBinding; - - - /*////////////////////////////////////////////////////////////////////////// - // Constructors and lifecycle - //////////////////////////////////////////////////////////////////////////*/ - - // required by the Android framework to restore fragments after saving - public ChannelVideosFragment() { - super(UserAction.REQUESTED_CHANNEL); - } - - public ChannelVideosFragment(final int serviceId, final String url, final String name) { - this(); - setInitialData(serviceId, url, name); - } - - public ChannelVideosFragment(@NonNull final ChannelInfo info) { - this(info.getServiceId(), info.getUrl(), info.getName()); - this.currentInfo = info; - this.currentNextPage = info.getNextPage(); - } - - @Override - public void onResume() { - super.onResume(); - if (activity != null && useAsFrontPage) { - setTitle(currentInfo != null ? currentInfo.getName() : name); - } - } - - @Override - public void onCreate(final Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setHasOptionsMenu(false); - } - - @Override - public View onCreateView(@NonNull final LayoutInflater inflater, - @Nullable final ViewGroup container, - @Nullable final Bundle savedInstanceState) { - channelBinding = FragmentChannelVideosBinding.inflate(inflater, container, false); - return channelBinding.getRoot(); - } - - @Override - public void onDestroy() { - super.onDestroy(); - disposables.clear(); - channelBinding = null; - playlistControlBinding = null; - } - - @Override - protected Supplier getListHeaderSupplier() { - playlistControlBinding = PlaylistControlBinding - .inflate(activity.getLayoutInflater(), itemsList, false); - return playlistControlBinding::getRoot; - } - - - /*////////////////////////////////////////////////////////////////////////// - // Loading - //////////////////////////////////////////////////////////////////////////*/ - - @Override - protected Single> loadMoreItemsLogic() { - return ExtractorHelper.getMoreChannelItems(serviceId, url, currentNextPage); - } - - @Override - protected Single loadResult(final boolean forceLoad) { - return ExtractorHelper.getChannelInfo(serviceId, url, forceLoad); - } - - - /*////////////////////////////////////////////////////////////////////////// - // Contract - //////////////////////////////////////////////////////////////////////////*/ - - @Override - public void handleResult(@NonNull final ChannelInfo result) { - super.handleResult(result); - - // PlaylistControls should be visible only if there is some item in - // infoListAdapter other than header - if (infoListAdapter.getItemCount() != 1) { - playlistControlBinding.getRoot().setVisibility(View.VISIBLE); - } else { - playlistControlBinding.getRoot().setVisibility(View.GONE); - } - - disposables.clear(); - - playlistControlBinding.playlistCtrlPlayAllButton.setOnClickListener( - view -> NavigationHelper.playOnMainPlayer(activity, getPlayQueue())); - playlistControlBinding.playlistCtrlPlayPopupButton.setOnClickListener( - view -> NavigationHelper.playOnPopupPlayer(activity, getPlayQueue(), false)); - playlistControlBinding.playlistCtrlPlayBgButton.setOnClickListener( - view -> NavigationHelper.playOnBackgroundPlayer(activity, getPlayQueue(), false)); - - playlistControlBinding.playlistCtrlPlayPopupButton.setOnLongClickListener(view -> { - NavigationHelper.enqueueOnPlayer(activity, getPlayQueue(), PlayerType.POPUP); - return true; - }); - - playlistControlBinding.playlistCtrlPlayBgButton.setOnLongClickListener(view -> { - NavigationHelper.enqueueOnPlayer(activity, getPlayQueue(), PlayerType.AUDIO); - return true; - }); - } - - private PlayQueue getPlayQueue() { - final List streamItems = infoListAdapter.getItemsList().stream() - .filter(StreamInfoItem.class::isInstance) - .map(StreamInfoItem.class::cast) - .collect(Collectors.toList()); - - return new ChannelPlayQueue(currentInfo.getServiceId(), currentInfo.getUrl(), - currentInfo.getNextPage(), streamItems, 0); - } -} diff --git a/app/src/main/java/org/schabi/newpipe/local/feed/notifications/NotificationHelper.kt b/app/src/main/java/org/schabi/newpipe/local/feed/notifications/NotificationHelper.kt index 5aca3ad26..782f5ee47 100644 --- a/app/src/main/java/org/schabi/newpipe/local/feed/notifications/NotificationHelper.kt +++ b/app/src/main/java/org/schabi/newpipe/local/feed/notifications/NotificationHelper.kt @@ -58,7 +58,7 @@ class NotificationHelper(val context: Context) { .setAutoCancel(true) .setCategory(NotificationCompat.CATEGORY_SOCIAL) .setGroupSummary(true) - .setGroup(data.listInfo.url) + .setGroup(data.originalInfo.url) .setGroupAlertBehavior(NotificationCompat.GROUP_ALERT_SUMMARY) // Build a summary notification for Android versions < 7.0 @@ -73,7 +73,7 @@ class NotificationHelper(val context: Context) { context, data.pseudoId, NavigationHelper - .getChannelIntent(context, data.listInfo.serviceId, data.listInfo.url) + .getChannelIntent(context, data.originalInfo.serviceId, data.originalInfo.url) .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK), 0, false @@ -88,7 +88,7 @@ class NotificationHelper(val context: Context) { // Show individual stream notifications, set channel icon only if there is actually // one - showStreamNotifications(newStreams, data.listInfo.serviceId, bitmap) + showStreamNotifications(newStreams, data.originalInfo.serviceId, bitmap) // Show summary notification manager.notify(data.pseudoId, summaryBuilder.build()) @@ -97,7 +97,7 @@ class NotificationHelper(val context: Context) { override fun onBitmapFailed(e: Exception, errorDrawable: Drawable) { // Show individual stream notifications - showStreamNotifications(newStreams, data.listInfo.serviceId, null) + showStreamNotifications(newStreams, data.originalInfo.serviceId, null) // Show summary notification manager.notify(data.pseudoId, summaryBuilder.build()) iconLoadingTargets.remove(this) // allow it to be garbage-collected diff --git a/app/src/main/java/org/schabi/newpipe/local/feed/service/FeedLoadManager.kt b/app/src/main/java/org/schabi/newpipe/local/feed/service/FeedLoadManager.kt index fec50a579..be2c2490e 100644 --- a/app/src/main/java/org/schabi/newpipe/local/feed/service/FeedLoadManager.kt +++ b/app/src/main/java/org/schabi/newpipe/local/feed/service/FeedLoadManager.kt @@ -13,11 +13,16 @@ import io.reactivex.rxjava3.schedulers.Schedulers import org.schabi.newpipe.R import org.schabi.newpipe.database.feed.model.FeedGroupEntity import org.schabi.newpipe.database.subscription.NotificationMode -import org.schabi.newpipe.extractor.ListInfo +import org.schabi.newpipe.extractor.Info +import org.schabi.newpipe.extractor.NewPipe +import org.schabi.newpipe.extractor.feed.FeedInfo import org.schabi.newpipe.extractor.stream.StreamInfoItem import org.schabi.newpipe.local.feed.FeedDatabaseManager import org.schabi.newpipe.local.subscription.SubscriptionManager -import org.schabi.newpipe.util.ExtractorHelper +import org.schabi.newpipe.util.ChannelTabHelper +import org.schabi.newpipe.util.ExtractorHelper.getChannelInfo +import org.schabi.newpipe.util.ExtractorHelper.getChannelTab +import org.schabi.newpipe.util.ExtractorHelper.getMoreChannelTabItems import java.time.OffsetDateTime import java.time.ZoneOffset import java.util.concurrent.atomic.AtomicBoolean @@ -102,49 +107,88 @@ class FeedLoadManager(private val context: Context) { .filter { !cancelSignal.get() } .map { subscriptionEntity -> var error: Throwable? = null + val storeOriginalErrorAndRethrow = { e: Throwable -> + // keep original to prevent blockingGet() from wrapping it into RuntimeException + error = e + throw e + } + try { // check for and load new streams // either by using the dedicated feed method or by getting the channel info - val listInfo = if (useFeedExtractor) { - ExtractorHelper - .getFeedInfoFallbackToChannelInfo( - subscriptionEntity.serviceId, - subscriptionEntity.url - ) - .onErrorReturn { - error = it // store error, otherwise wrapped into RuntimeException - throw it + var originalInfo: Info? = null + var streams: List? = null + val errors = ArrayList() + + if (useFeedExtractor) { + NewPipe.getService(subscriptionEntity.serviceId) + .getFeedExtractor(subscriptionEntity.url) + ?.also { feedExtractor -> + // the user wants to use a feed extractor and there is one, use it + val feedInfo = FeedInfo.getInfo(feedExtractor) + errors.addAll(feedInfo.errors) + originalInfo = feedInfo + streams = feedInfo.relatedItems } + } + + if (originalInfo == null) { + // use the normal channel tabs extractor if either the user wants it, or + // the current service does not have a dedicated feed extractor + + val channelInfo = getChannelInfo( + subscriptionEntity.serviceId, + subscriptionEntity.url, true + ) + .onErrorReturn(storeOriginalErrorAndRethrow) .blockingGet() - } else { - ExtractorHelper - .getChannelInfo( - subscriptionEntity.serviceId, - subscriptionEntity.url, - true - ) - .onErrorReturn { - error = it // store error, otherwise wrapped into RuntimeException - throw it + errors.addAll(channelInfo.errors) + originalInfo = channelInfo + + streams = channelInfo.tabs + .filter(ChannelTabHelper::isStreamsTab) + .map { + Pair( + getChannelTab(subscriptionEntity.serviceId, it, true) + .onErrorReturn(storeOriginalErrorAndRethrow) + .blockingGet(), + it + ) } - .blockingGet() - } as ListInfo + .flatMap { (channelTabInfo, linkHandler) -> + errors.addAll(channelTabInfo.errors) + if (channelTabInfo.relatedItems.isEmpty()) { + val infoItemsPage = getMoreChannelTabItems( + subscriptionEntity.serviceId, + linkHandler, channelTabInfo.nextPage + ) + .blockingGet() + + errors.addAll(infoItemsPage.errors) + return@flatMap infoItemsPage.items + } else { + return@flatMap channelTabInfo.relatedItems + } + } + .filterIsInstance() + } return@map Notification.createOnNext( FeedUpdateInfo( subscriptionEntity, - listInfo + originalInfo!!, + streams!!, + errors, ) ) } catch (e: Throwable) { - if (error == null) { - // do this to prevent blockingGet() from wrapping into RuntimeException - error = e - } - val request = "${subscriptionEntity.serviceId}:${subscriptionEntity.url}" - val wrapper = - FeedLoadService.RequestException(subscriptionEntity.uid, request, error!!) + val wrapper = FeedLoadService.RequestException( + subscriptionEntity.uid, + request, + // do this to prevent blockingGet() from wrapping into RuntimeException + error ?: e + ) return@map Notification.createOnError(wrapper) } } @@ -203,24 +247,24 @@ class FeedLoadManager(private val context: Context) { for (notification in list) { when { notification.isOnNext -> { - val subscriptionId = notification.value!!.uid - val info = notification.value!!.listInfo + val info = notification.value!! - notification.value!!.newStreams = filterNewStreams( - notification.value!!.listInfo.relatedItems - ) + notification.value!!.newStreams = filterNewStreams(info.streams) - feedDatabaseManager.upsertAll(subscriptionId, info.relatedItems) - subscriptionManager.updateFromInfo(subscriptionId, info) + feedDatabaseManager.upsertAll(info.uid, info.streams) + subscriptionManager.updateFromInfo(info.uid, info.originalInfo) if (info.errors.isNotEmpty()) { feedResultsHolder.addErrors( - FeedLoadService.RequestException.wrapList( - subscriptionId, - info - ) + info.errors.map { + FeedLoadService.RequestException( + info.uid, + "${info.originalInfo.serviceId}:${info.originalInfo.url}", + it + ) + } ) - feedDatabaseManager.markAsOutdated(subscriptionId) + feedDatabaseManager.markAsOutdated(info.uid) } } notification.isOnError -> { diff --git a/app/src/main/java/org/schabi/newpipe/local/feed/service/FeedLoadService.kt b/app/src/main/java/org/schabi/newpipe/local/feed/service/FeedLoadService.kt index bde301b92..f960040de 100644 --- a/app/src/main/java/org/schabi/newpipe/local/feed/service/FeedLoadService.kt +++ b/app/src/main/java/org/schabi/newpipe/local/feed/service/FeedLoadService.kt @@ -39,8 +39,6 @@ import org.schabi.newpipe.App import org.schabi.newpipe.MainActivity.DEBUG import org.schabi.newpipe.R import org.schabi.newpipe.database.feed.model.FeedGroupEntity -import org.schabi.newpipe.extractor.ListInfo -import org.schabi.newpipe.extractor.stream.StreamInfoItem import org.schabi.newpipe.local.feed.service.FeedEventManager.Event.ErrorResultEvent import org.schabi.newpipe.local.feed.service.FeedEventManager.postEvent import java.util.concurrent.TimeUnit @@ -126,17 +124,7 @@ class FeedLoadService : Service() { // Loading & Handling // ///////////////////////////////////////////////////////////////////////// - class RequestException(val subscriptionId: Long, message: String, cause: Throwable) : Exception(message, cause) { - companion object { - fun wrapList(subscriptionId: Long, info: ListInfo): List { - val toReturn = ArrayList(info.errors.size) - info.errors.mapTo(toReturn) { - RequestException(subscriptionId, info.serviceId.toString() + ":" + info.url, it) - } - return toReturn - } - } - } + class RequestException(val subscriptionId: Long, message: String, cause: Throwable) : Exception(message, cause) // ///////////////////////////////////////////////////////////////////////// // Notification diff --git a/app/src/main/java/org/schabi/newpipe/local/feed/service/FeedUpdateInfo.kt b/app/src/main/java/org/schabi/newpipe/local/feed/service/FeedUpdateInfo.kt index 5f72a6b84..12fbe8d41 100644 --- a/app/src/main/java/org/schabi/newpipe/local/feed/service/FeedUpdateInfo.kt +++ b/app/src/main/java/org/schabi/newpipe/local/feed/service/FeedUpdateInfo.kt @@ -2,7 +2,7 @@ package org.schabi.newpipe.local.feed.service import org.schabi.newpipe.database.subscription.NotificationMode import org.schabi.newpipe.database.subscription.SubscriptionEntity -import org.schabi.newpipe.extractor.ListInfo +import org.schabi.newpipe.extractor.Info import org.schabi.newpipe.extractor.stream.StreamInfoItem data class FeedUpdateInfo( @@ -11,24 +11,30 @@ data class FeedUpdateInfo( val notificationMode: Int, val name: String, val avatarUrl: String, - val listInfo: ListInfo, + val originalInfo: Info, + val streams: List, + val errors: List, ) { constructor( subscription: SubscriptionEntity, - listInfo: ListInfo, + originalInfo: Info, + streams: List, + errors: List, ) : this( uid = subscription.uid, notificationMode = subscription.notificationMode, name = subscription.name, avatarUrl = subscription.avatarUrl, - listInfo = listInfo, + originalInfo = originalInfo, + streams = streams, + errors = errors, ) /** * Integer id, can be used as notification id, etc. */ val pseudoId: Int - get() = listInfo.url.hashCode() + get() = originalInfo.url.hashCode() lateinit var newStreams: List } diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionManager.kt b/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionManager.kt index b17f49801..9a8b53e90 100644 --- a/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionManager.kt +++ b/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionManager.kt @@ -1,6 +1,7 @@ package org.schabi.newpipe.local.subscription import android.content.Context +import android.util.Pair import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers import io.reactivex.rxjava3.core.Completable import io.reactivex.rxjava3.core.Flowable @@ -11,8 +12,9 @@ import org.schabi.newpipe.database.stream.model.StreamEntity import org.schabi.newpipe.database.subscription.NotificationMode import org.schabi.newpipe.database.subscription.SubscriptionDAO import org.schabi.newpipe.database.subscription.SubscriptionEntity -import org.schabi.newpipe.extractor.ListInfo +import org.schabi.newpipe.extractor.Info import org.schabi.newpipe.extractor.channel.ChannelInfo +import org.schabi.newpipe.extractor.channel.ChannelTabInfo import org.schabi.newpipe.extractor.feed.FeedInfo import org.schabi.newpipe.extractor.stream.StreamInfoItem import org.schabi.newpipe.local.feed.FeedDatabaseManager @@ -46,28 +48,33 @@ class SubscriptionManager(context: Context) { } } - fun upsertAll(infoList: List): List { + fun upsertAll(infoList: List>>): List { val listEntities = subscriptionTable.upsertAll( - infoList.map { SubscriptionEntity.from(it) } + infoList.map { SubscriptionEntity.from(it.first) } ) database.runInTransaction { infoList.forEachIndexed { index, info -> - feedDatabaseManager.upsertAll(listEntities[index].uid, info.relatedItems) + info.second.forEach { + feedDatabaseManager.upsertAll( + listEntities[index].uid, + it.relatedItems.filterIsInstance() + ) + } } } return listEntities } - fun updateChannelInfo(info: ChannelInfo): Completable = subscriptionTable.getSubscription(info.serviceId, info.url) - .flatMapCompletable { - Completable.fromRunnable { - it.setData(info.name, info.avatarUrl, info.description, info.subscriberCount) - subscriptionTable.update(it) - feedDatabaseManager.upsertAll(it.uid, info.relatedItems) + fun updateChannelInfo(info: ChannelInfo): Completable = + subscriptionTable.getSubscription(info.serviceId, info.url) + .flatMapCompletable { + Completable.fromRunnable { + it.setData(info.name, info.avatarUrl, info.description, info.subscriberCount) + subscriptionTable.update(it) + } } - } fun updateNotificationMode(serviceId: Int, url: String, @NotificationMode mode: Int): Completable { return subscriptionTable().getSubscription(serviceId, url) @@ -84,7 +91,7 @@ class SubscriptionManager(context: Context) { } } - fun updateFromInfo(subscriptionId: Long, info: ListInfo) { + fun updateFromInfo(subscriptionId: Long, info: Info) { val subscriptionEntity = subscriptionTable.getSubscription(subscriptionId) if (info is FeedInfo) { @@ -107,11 +114,8 @@ class SubscriptionManager(context: Context) { .observeOn(AndroidSchedulers.mainThread()) } - fun insertSubscription(subscriptionEntity: SubscriptionEntity, info: ChannelInfo) { - database.runInTransaction { - val subscriptionId = subscriptionTable.insert(subscriptionEntity) - feedDatabaseManager.upsertAll(subscriptionId, info.relatedItems) - } + fun insertSubscription(subscriptionEntity: SubscriptionEntity) { + subscriptionTable.insert(subscriptionEntity) } fun deleteSubscription(subscriptionEntity: SubscriptionEntity) { @@ -125,7 +129,10 @@ class SubscriptionManager(context: Context) { */ private fun rememberAllStreams(subscription: SubscriptionEntity): Completable { return ExtractorHelper.getChannelInfo(subscription.serviceId, subscription.url, false) - .map { channel -> channel.relatedItems.map { stream -> StreamEntity(stream) } } + .flatMap { info -> + ExtractorHelper.getChannelTab(subscription.serviceId, info.tabs.first(), false) + } + .map { channel -> channel.relatedItems.filterIsInstance().map { stream -> StreamEntity(stream) } } .flatMapCompletable { entities -> Completable.fromAction { database.streamDAO().upsertAll(entities) diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/services/SubscriptionsImportService.java b/app/src/main/java/org/schabi/newpipe/local/subscription/services/SubscriptionsImportService.java index af598b106..66164807d 100644 --- a/app/src/main/java/org/schabi/newpipe/local/subscription/services/SubscriptionsImportService.java +++ b/app/src/main/java/org/schabi/newpipe/local/subscription/services/SubscriptionsImportService.java @@ -26,6 +26,7 @@ import android.content.Intent; import android.net.Uri; import android.text.TextUtils; import android.util.Log; +import android.util.Pair; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -38,6 +39,7 @@ import org.schabi.newpipe.R; import org.schabi.newpipe.database.subscription.SubscriptionEntity; import org.schabi.newpipe.extractor.NewPipe; import org.schabi.newpipe.extractor.channel.ChannelInfo; +import org.schabi.newpipe.extractor.channel.ChannelTabInfo; import org.schabi.newpipe.extractor.subscription.SubscriptionItem; import org.schabi.newpipe.ktx.ExceptionUtils; import org.schabi.newpipe.streams.io.SharpInputStream; @@ -48,6 +50,7 @@ import org.schabi.newpipe.util.ExtractorHelper; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Objects; @@ -199,12 +202,19 @@ public class SubscriptionsImportService extends BaseImportExportService { .parallel(PARALLEL_EXTRACTIONS) .runOn(Schedulers.io()) - .map((Function>) subscriptionItem -> { + .map((Function>>>) subscriptionItem -> { try { - return Notification.createOnNext(ExtractorHelper + final ChannelInfo channelInfo = ExtractorHelper .getChannelInfo(subscriptionItem.getServiceId(), subscriptionItem.getUrl(), true) - .blockingGet()); + .blockingGet(); + return Notification.createOnNext(new Pair<>(channelInfo, + Collections.singletonList( + ExtractorHelper.getChannelTab( + subscriptionItem.getServiceId(), + channelInfo.getTabs().get(0), true).blockingGet() + ))); } catch (final Throwable e) { return Notification.createOnError(e); } @@ -223,7 +233,7 @@ public class SubscriptionsImportService extends BaseImportExportService { } private Subscriber> getSubscriber() { - return new Subscriber>() { + return new Subscriber<>() { @Override public void onSubscribe(final Subscription s) { subscription = s; @@ -254,10 +264,11 @@ public class SubscriptionsImportService extends BaseImportExportService { }; } - private Consumer> getNotificationsConsumer() { + private Consumer>>> getNotificationsConsumer() { return notification -> { if (notification.isOnNext()) { - final String name = notification.getValue().getName(); + final String name = notification.getValue().first.getName(); eventListener.onItemCompleted(!TextUtils.isEmpty(name) ? name : ""); } else if (notification.isOnError()) { final Throwable error = notification.getError(); @@ -275,10 +286,12 @@ public class SubscriptionsImportService extends BaseImportExportService { }; } - private Function>, List> upsertBatch() { + private Function>>>, + List> upsertBatch() { return notificationList -> { - final List infoList = new ArrayList<>(notificationList.size()); - for (final Notification n : notificationList) { + final List>> infoList = + new ArrayList<>(notificationList.size()); + for (final Notification>> n : notificationList) { if (n.isOnNext()) { infoList.add(n.getValue()); } diff --git a/app/src/main/java/org/schabi/newpipe/player/playqueue/AbstractInfoPlayQueue.java b/app/src/main/java/org/schabi/newpipe/player/playqueue/AbstractInfoPlayQueue.java index e51ee4720..a0fc88eae 100644 --- a/app/src/main/java/org/schabi/newpipe/player/playqueue/AbstractInfoPlayQueue.java +++ b/app/src/main/java/org/schabi/newpipe/player/playqueue/AbstractInfoPlayQueue.java @@ -4,6 +4,7 @@ import android.util.Log; import androidx.annotation.NonNull; +import org.schabi.newpipe.extractor.InfoItem; import org.schabi.newpipe.extractor.ListExtractor; import org.schabi.newpipe.extractor.ListInfo; import org.schabi.newpipe.extractor.Page; @@ -15,7 +16,7 @@ import java.util.stream.Collectors; import io.reactivex.rxjava3.core.SingleObserver; import io.reactivex.rxjava3.disposables.Disposable; -abstract class AbstractInfoPlayQueue> +abstract class AbstractInfoPlayQueue> extends PlayQueue { boolean isInitial; private boolean isComplete; @@ -27,7 +28,10 @@ abstract class AbstractInfoPlayQueue> private transient Disposable fetchReactor; protected AbstractInfoPlayQueue(final T info) { - this(info.getServiceId(), info.getUrl(), info.getNextPage(), info.getRelatedItems(), 0); + this(info.getServiceId(), info.getUrl(), info.getNextPage(), + info.getRelatedItems().stream().filter(StreamInfoItem.class::isInstance) + .map(StreamInfoItem.class::cast).collect( + Collectors.toList()), 0); } protected AbstractInfoPlayQueue(final int serviceId, @@ -72,7 +76,10 @@ abstract class AbstractInfoPlayQueue> } nextPage = result.getNextPage(); - append(extractListItems(result.getRelatedItems())); + append(extractListItems(result.getRelatedItems().stream() + .filter(StreamInfoItem.class::isInstance) + .map(StreamInfoItem.class::cast).collect( + Collectors.toList()))); fetchReactor.dispose(); fetchReactor = null; @@ -87,7 +94,7 @@ abstract class AbstractInfoPlayQueue> }; } - SingleObserver> getNextPageObserver() { + SingleObserver> getNextPageObserver() { return new SingleObserver<>() { @Override public void onSubscribe(@NonNull final Disposable d) { @@ -101,13 +108,16 @@ abstract class AbstractInfoPlayQueue> @Override public void onSuccess( - @NonNull final ListExtractor.InfoItemsPage result) { + @NonNull final ListExtractor.InfoItemsPage result) { if (!result.hasNextPage()) { isComplete = true; } nextPage = result.getNextPage(); - append(extractListItems(result.getItems())); + append(extractListItems(result.getItems().stream() + .filter(StreamInfoItem.class::isInstance) + .map(StreamInfoItem.class::cast).collect( + Collectors.toList()))); fetchReactor.dispose(); fetchReactor = null; diff --git a/app/src/main/java/org/schabi/newpipe/player/playqueue/ChannelPlayQueue.java b/app/src/main/java/org/schabi/newpipe/player/playqueue/ChannelPlayQueue.java deleted file mode 100644 index 1e1fef85e..000000000 --- a/app/src/main/java/org/schabi/newpipe/player/playqueue/ChannelPlayQueue.java +++ /dev/null @@ -1,47 +0,0 @@ -package org.schabi.newpipe.player.playqueue; - - -import org.schabi.newpipe.extractor.Page; -import org.schabi.newpipe.extractor.channel.ChannelInfo; -import org.schabi.newpipe.extractor.stream.StreamInfoItem; -import org.schabi.newpipe.util.ExtractorHelper; - -import java.util.List; - -import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; -import io.reactivex.rxjava3.schedulers.Schedulers; - -public final class ChannelPlayQueue extends AbstractInfoPlayQueue { - - public ChannelPlayQueue(final ChannelInfo info) { - super(info); - } - - public ChannelPlayQueue(final int serviceId, - final String url, - final Page nextPage, - final List streams, - final int index) { - super(serviceId, url, nextPage, streams, index); - } - - @Override - protected String getTag() { - return "ChannelPlayQueue@" + Integer.toHexString(hashCode()); - } - - @Override - public void fetch() { - if (this.isInitial) { - ExtractorHelper.getChannelInfo(this.serviceId, this.baseUrl, false) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(getHeadListObserver()); - } else { - ExtractorHelper.getMoreChannelItems(this.serviceId, this.baseUrl, this.nextPage) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(getNextPageObserver()); - } - } -} diff --git a/app/src/main/java/org/schabi/newpipe/player/playqueue/ChannelTabPlayQueue.java b/app/src/main/java/org/schabi/newpipe/player/playqueue/ChannelTabPlayQueue.java new file mode 100644 index 000000000..e422a5c52 --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/player/playqueue/ChannelTabPlayQueue.java @@ -0,0 +1,53 @@ +package org.schabi.newpipe.player.playqueue; + + +import org.schabi.newpipe.extractor.Page; +import org.schabi.newpipe.extractor.channel.ChannelTabInfo; +import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler; +import org.schabi.newpipe.extractor.stream.StreamInfoItem; +import org.schabi.newpipe.util.ExtractorHelper; + +import java.util.Collections; +import java.util.List; + +import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; +import io.reactivex.rxjava3.schedulers.Schedulers; + +public final class ChannelTabPlayQueue extends AbstractInfoPlayQueue { + + final ListLinkHandler linkHandler; + + public ChannelTabPlayQueue(final int serviceId, + final ListLinkHandler linkHandler, + final Page nextPage, + final List streams, + final int index) { + super(serviceId, linkHandler.getUrl(), nextPage, streams, index); + this.linkHandler = linkHandler; + } + + public ChannelTabPlayQueue(final int serviceId, + final ListLinkHandler linkHandler) { + this(serviceId, linkHandler, null, Collections.emptyList(), 0); + } + + @Override + protected String getTag() { + return "ChannelTabPlayQueue@" + Integer.toHexString(hashCode()); + } + + @Override + public void fetch() { + if (isInitial) { + ExtractorHelper.getChannelTab(this.serviceId, this.linkHandler, false) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(getHeadListObserver()); + } else { + ExtractorHelper.getMoreChannelTabItems(this.serviceId, this.linkHandler, this.nextPage) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(getNextPageObserver()); + } + } +} diff --git a/app/src/main/java/org/schabi/newpipe/settings/tabs/Tab.java b/app/src/main/java/org/schabi/newpipe/settings/tabs/Tab.java index b5375075f..7e3f5d0c8 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/tabs/Tab.java +++ b/app/src/main/java/org/schabi/newpipe/settings/tabs/Tab.java @@ -19,7 +19,7 @@ import org.schabi.newpipe.extractor.NewPipe; import org.schabi.newpipe.extractor.StreamingService; import org.schabi.newpipe.extractor.exceptions.ExtractionException; import org.schabi.newpipe.fragments.BlankFragment; -import org.schabi.newpipe.fragments.list.channel.ChannelVideosFragment; +import org.schabi.newpipe.fragments.list.channel.ChannelFragment; import org.schabi.newpipe.fragments.list.kiosk.DefaultKioskFragment; import org.schabi.newpipe.fragments.list.kiosk.KioskFragment; import org.schabi.newpipe.fragments.list.playlist.PlaylistFragment; @@ -432,8 +432,8 @@ public abstract class Tab { } @Override - public ChannelVideosFragment getFragment(final Context context) { - return new ChannelVideosFragment(channelServiceId, channelUrl, channelName); + public ChannelFragment getFragment(final Context context) { + return ChannelFragment.getInstance(channelServiceId, channelUrl, channelName); } @Override diff --git a/app/src/main/java/org/schabi/newpipe/util/ChannelTabHelper.java b/app/src/main/java/org/schabi/newpipe/util/ChannelTabHelper.java index fb384e076..974445a96 100644 --- a/app/src/main/java/org/schabi/newpipe/util/ChannelTabHelper.java +++ b/app/src/main/java/org/schabi/newpipe/util/ChannelTabHelper.java @@ -7,24 +7,58 @@ import androidx.annotation.StringRes; import org.schabi.newpipe.R; import org.schabi.newpipe.extractor.linkhandler.ChannelTabs; +import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler; +import java.util.List; import java.util.Set; public final class ChannelTabHelper { private ChannelTabHelper() { } + /** + * @param tab the channel tab to check + * @return whether the tab should contain (playable) streams or not + */ + public static boolean isStreamsTab(final String tab) { + switch (tab) { + case ChannelTabs.VIDEOS: + case ChannelTabs.TRACKS: + case ChannelTabs.SHORTS: + case ChannelTabs.LIVESTREAMS: + return true; + } + return false; + } + + /** + * @param tab the channel tab link handler to check + * @return whether the tab should contain (playable) streams or not + */ + public static boolean isStreamsTab(final ListLinkHandler tab) { + final List contentFilters = tab.getContentFilters(); + if (contentFilters.isEmpty()) { + return false; // this should never happen, but check just to be sure + } else { + return isStreamsTab(contentFilters.get(0)); + } + } + @StringRes private static int getShowTabKey(final String tab) { switch (tab) { - case ChannelTabs.PLAYLISTS: - return R.string.show_channel_tabs_playlists; - case ChannelTabs.LIVESTREAMS: - return R.string.show_channel_tabs_livestreams; + case ChannelTabs.VIDEOS: + return R.string.show_channel_tabs_videos; + case ChannelTabs.TRACKS: + return R.string.show_channel_tabs_tracks; case ChannelTabs.SHORTS: return R.string.show_channel_tabs_shorts; + case ChannelTabs.LIVESTREAMS: + return R.string.show_channel_tabs_livestreams; case ChannelTabs.CHANNELS: return R.string.show_channel_tabs_channels; + case ChannelTabs.PLAYLISTS: + return R.string.show_channel_tabs_playlists; case ChannelTabs.ALBUMS: return R.string.show_channel_tabs_albums; } @@ -34,14 +68,18 @@ public final class ChannelTabHelper { @StringRes public static int getTranslationKey(final String tab) { switch (tab) { - case ChannelTabs.PLAYLISTS: - return R.string.channel_tab_playlists; - case ChannelTabs.LIVESTREAMS: - return R.string.channel_tab_livestreams; + case ChannelTabs.VIDEOS: + return R.string.channel_tab_videos; + case ChannelTabs.TRACKS: + return R.string.channel_tab_tracks; case ChannelTabs.SHORTS: return R.string.channel_tab_shorts; + case ChannelTabs.LIVESTREAMS: + return R.string.channel_tab_livestreams; case ChannelTabs.CHANNELS: return R.string.channel_tab_channels; + case ChannelTabs.PLAYLISTS: + return R.string.channel_tab_playlists; case ChannelTabs.ALBUMS: return R.string.channel_tab_albums; } diff --git a/app/src/main/java/org/schabi/newpipe/util/ExtractorHelper.java b/app/src/main/java/org/schabi/newpipe/util/ExtractorHelper.java index d8d68f0e4..59a5df205 100644 --- a/app/src/main/java/org/schabi/newpipe/util/ExtractorHelper.java +++ b/app/src/main/java/org/schabi/newpipe/util/ExtractorHelper.java @@ -36,17 +36,13 @@ import org.schabi.newpipe.R; import org.schabi.newpipe.extractor.Info; import org.schabi.newpipe.extractor.InfoItem; import org.schabi.newpipe.extractor.ListExtractor.InfoItemsPage; -import org.schabi.newpipe.extractor.ListInfo; import org.schabi.newpipe.extractor.MetaInfo; import org.schabi.newpipe.extractor.NewPipe; import org.schabi.newpipe.extractor.Page; -import org.schabi.newpipe.extractor.StreamingService; import org.schabi.newpipe.extractor.channel.ChannelInfo; import org.schabi.newpipe.extractor.channel.ChannelTabInfo; import org.schabi.newpipe.extractor.comments.CommentsInfo; import org.schabi.newpipe.extractor.comments.CommentsInfoItem; -import org.schabi.newpipe.extractor.feed.FeedExtractor; -import org.schabi.newpipe.extractor.feed.FeedInfo; import org.schabi.newpipe.extractor.kiosk.KioskInfo; import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler; import org.schabi.newpipe.extractor.playlist.PlaylistInfo; @@ -129,30 +125,6 @@ public final class ExtractorHelper { ChannelInfo.getInfo(NewPipe.getService(serviceId), url))); } - public static Single> getMoreChannelItems(final int serviceId, - final String url, - final Page nextPage) { - checkServiceId(serviceId); - return Single.fromCallable(() -> - ChannelInfo.getMoreItems(NewPipe.getService(serviceId), url, nextPage)); - } - - public static Single> getFeedInfoFallbackToChannelInfo( - final int serviceId, final String url) { - final Maybe> maybeFeedInfo = Maybe.fromCallable(() -> { - final StreamingService service = NewPipe.getService(serviceId); - final FeedExtractor feedExtractor = service.getFeedExtractor(url); - - if (feedExtractor == null) { - return null; - } - - return FeedInfo.getInfo(feedExtractor); - }); - - return maybeFeedInfo.switchIfEmpty(getChannelInfo(serviceId, url, true)); - } - public static Single getChannelTab(final int serviceId, final ListLinkHandler listLinkHandler, final boolean forceLoad) { diff --git a/app/src/main/res/values/settings_keys.xml b/app/src/main/res/values/settings_keys.xml index d32fbce0c..9c5610703 100644 --- a/app/src/main/res/values/settings_keys.xml +++ b/app/src/main/res/values/settings_keys.xml @@ -275,25 +275,31 @@ channel_tabs - show_channel_tabs_playlists - show_channel_tabs_live + show_channel_tabs_videos + show_channel_tabs_tracks show_channel_tabs_shorts + show_channel_tabs_live show_channel_tabs_channels + show_channel_tabs_playlists show_channel_tabs_albums show_channel_tabs_about - @string/show_channel_tabs_playlists - @string/show_channel_tabs_livestreams + @string/show_channel_tabs_videos + @string/show_channel_tabs_tracks @string/show_channel_tabs_shorts + @string/show_channel_tabs_livestreams @string/show_channel_tabs_channels + @string/show_channel_tabs_playlists @string/show_channel_tabs_albums @string/show_channel_tabs_about - @string/channel_tab_playlists - @string/channel_tab_livestreams + @string/channel_tab_videos + @string/channel_tab_tracks @string/channel_tab_shorts + @string/channel_tab_livestreams @string/channel_tab_channels + @string/channel_tab_playlists @string/channel_tab_albums @string/channel_tab_about diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 259689231..565c91b54 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -798,10 +798,11 @@ dubbed descriptive Videos - Live + Tracks Shorts - Playlists + Live Channels + Playlists Albums About Channel tabs From a1e8b9be4e16bfc1d27baf2af05a6e5e2391407b Mon Sep 17 00:00:00 2001 From: Stypox Date: Fri, 14 Apr 2023 10:27:25 +0200 Subject: [PATCH 053/172] Fix channel tabs in main page setting title themselves --- .../newpipe/fragments/list/channel/ChannelFragment.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java index 3a8d46a4d..46faaf277 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java @@ -457,8 +457,10 @@ public class ChannelFragment extends BaseStateFragment for (final ListLinkHandler linkHandler : currentInfo.getTabs()) { final String tab = linkHandler.getContentFilters().get(0); if (ChannelTabHelper.showChannelTab(context, preferences, tab)) { - tabAdapter.addFragment( - ChannelTabFragment.getInstance(serviceId, linkHandler, name), + final ChannelTabFragment channelTabFragment = + ChannelTabFragment.getInstance(serviceId, linkHandler, name); + channelTabFragment.useAsFrontPage(useAsFrontPage); + tabAdapter.addFragment(channelTabFragment, context.getString(ChannelTabHelper.getTranslationKey(tab))); } } From 371f98677328e6fbfe85a8cbd30fd9a39c22321c Mon Sep 17 00:00:00 2001 From: Stypox Date: Fri, 14 Apr 2023 11:00:01 +0200 Subject: [PATCH 054/172] Fix some code smells --- .../fragments/list/channel/ChannelTabFragment.java | 5 ----- .../java/org/schabi/newpipe/util/ChannelTabHelper.java | 9 ++++++--- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelTabFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelTabFragment.java index 3f400bdf8..df3aced50 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelTabFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelTabFragment.java @@ -15,7 +15,6 @@ import org.schabi.newpipe.extractor.ListExtractor; import org.schabi.newpipe.extractor.channel.ChannelTabInfo; import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler; import org.schabi.newpipe.fragments.list.BaseListInfoFragment; -import org.schabi.newpipe.util.Constants; import org.schabi.newpipe.util.ExtractorHelper; import icepick.State; @@ -23,12 +22,8 @@ import io.reactivex.rxjava3.core.Single; public class ChannelTabFragment extends BaseListInfoFragment { - @State - protected int serviceId = Constants.NO_SERVICE_ID; - @State protected ListLinkHandler tabHandler; - @State protected String channelName; diff --git a/app/src/main/java/org/schabi/newpipe/util/ChannelTabHelper.java b/app/src/main/java/org/schabi/newpipe/util/ChannelTabHelper.java index 974445a96..d10e0a3dd 100644 --- a/app/src/main/java/org/schabi/newpipe/util/ChannelTabHelper.java +++ b/app/src/main/java/org/schabi/newpipe/util/ChannelTabHelper.java @@ -27,8 +27,9 @@ public final class ChannelTabHelper { case ChannelTabs.SHORTS: case ChannelTabs.LIVESTREAMS: return true; + default: + return false; } - return false; } /** @@ -61,8 +62,9 @@ public final class ChannelTabHelper { return R.string.show_channel_tabs_playlists; case ChannelTabs.ALBUMS: return R.string.show_channel_tabs_albums; + default: + return -1; } - return -1; } @StringRes @@ -82,8 +84,9 @@ public final class ChannelTabHelper { return R.string.channel_tab_playlists; case ChannelTabs.ALBUMS: return R.string.channel_tab_albums; + default: + return R.string.unknown_content; } - return R.string.unknown_content; } public static boolean showChannelTab(final Context context, From 753a92055c18cbee58e6b7cf4edbdd80b63d56ef Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Sun, 16 Apr 2023 00:58:30 +0200 Subject: [PATCH 055/172] feat: add playlist controls to channel tab --- .../list/channel/ChannelTabFragment.java | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelTabFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelTabFragment.java index df3aced50..86e429bea 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelTabFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelTabFragment.java @@ -9,13 +9,24 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import org.schabi.newpipe.R; +import org.schabi.newpipe.databinding.PlaylistControlBinding; import org.schabi.newpipe.error.UserAction; import org.schabi.newpipe.extractor.InfoItem; import org.schabi.newpipe.extractor.ListExtractor; import org.schabi.newpipe.extractor.channel.ChannelTabInfo; import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler; +import org.schabi.newpipe.extractor.stream.StreamInfoItem; import org.schabi.newpipe.fragments.list.BaseListInfoFragment; +import org.schabi.newpipe.player.PlayerType; +import org.schabi.newpipe.player.playqueue.ChannelTabPlayQueue; +import org.schabi.newpipe.player.playqueue.PlayQueue; +import org.schabi.newpipe.util.ChannelTabHelper; import org.schabi.newpipe.util.ExtractorHelper; +import org.schabi.newpipe.util.NavigationHelper; + +import java.util.List; +import java.util.function.Supplier; +import java.util.stream.Collectors; import icepick.State; import io.reactivex.rxjava3.core.Single; @@ -27,6 +38,8 @@ public class ChannelTabFragment extends BaseListInfoFragment getListHeaderSupplier() { + if (ChannelTabHelper.isStreamsTab(tabHandler)) { + playlistControlBinding = PlaylistControlBinding + .inflate(activity.getLayoutInflater(), itemsList, false); + return playlistControlBinding::getRoot; + } + return null; + } + @Override protected Single loadResult(final boolean forceLoad) { return ExtractorHelper.getChannelTab(serviceId, tabHandler, forceLoad); @@ -72,4 +101,47 @@ public class ChannelTabFragment extends BaseListInfoFragment 1) { + playlistControlBinding.getRoot().setVisibility(View.VISIBLE); + } else { + playlistControlBinding.getRoot().setVisibility(View.GONE); + } + + playlistControlBinding.playlistCtrlPlayAllButton.setOnClickListener( + view -> NavigationHelper.playOnMainPlayer(activity, getPlayQueue())); + playlistControlBinding.playlistCtrlPlayPopupButton.setOnClickListener( + view -> NavigationHelper.playOnPopupPlayer(activity, getPlayQueue(), false)); + playlistControlBinding.playlistCtrlPlayBgButton.setOnClickListener( + view -> NavigationHelper.playOnBackgroundPlayer(activity, getPlayQueue(), + false)); + + playlistControlBinding.playlistCtrlPlayPopupButton.setOnLongClickListener(view -> { + NavigationHelper.enqueueOnPlayer(activity, getPlayQueue(), PlayerType.POPUP); + return true; + }); + + playlistControlBinding.playlistCtrlPlayBgButton.setOnLongClickListener(view -> { + NavigationHelper.enqueueOnPlayer(activity, getPlayQueue(), PlayerType.AUDIO); + return true; + }); + } + } + + private PlayQueue getPlayQueue() { + final List streamItems = infoListAdapter.getItemsList().stream() + .filter(StreamInfoItem.class::isInstance) + .map(StreamInfoItem.class::cast) + .collect(Collectors.toList()); + + return new ChannelTabPlayQueue(currentInfo.getServiceId(), tabHandler, + currentInfo.getNextPage(), streamItems, 0); + } } From a2a717bd49faa7a9009366550a71ef874dba0c5e Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Sun, 16 Apr 2023 16:00:46 +0200 Subject: [PATCH 056/172] update NPE --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 1f924b12f..d73cca424 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -197,7 +197,7 @@ dependencies { // name and the commit hash with the commit hash of the (pushed) commit you want to test // This works thanks to JitPack: https://jitpack.io/ implementation 'com.github.TeamNewPipe:nanojson:1d9e1aea9049fc9f85e68b43ba39fe7be1c1f751' - implementation 'com.github.Theta-Dev:NewPipeExtractor:c3651bef5c622abf0cdfc34c9985ba8c33d1491e' + implementation 'com.github.Theta-Dev:NewPipeExtractor:2ad496fc2b932dd89009f3892462014cb231f6ca' implementation 'com.github.TeamNewPipe:NoNonsense-FilePicker:5.0.0' /** Checkstyle **/ From 28d952a643076811c217338736ff60ff58dc2a85 Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Sun, 16 Apr 2023 16:30:40 +0200 Subject: [PATCH 057/172] feat: filter fetched channel tabs --- .../local/feed/service/FeedLoadManager.kt | 19 ++++++++-- .../schabi/newpipe/util/ChannelTabHelper.java | 38 +++++++++++++++++++ app/src/main/res/values/settings_keys.xml | 18 +++++++++ app/src/main/res/values/strings.xml | 2 + app/src/main/res/xml/content_settings.xml | 10 +++++ 5 files changed, 84 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/local/feed/service/FeedLoadManager.kt b/app/src/main/java/org/schabi/newpipe/local/feed/service/FeedLoadManager.kt index be2c2490e..b55549704 100644 --- a/app/src/main/java/org/schabi/newpipe/local/feed/service/FeedLoadManager.kt +++ b/app/src/main/java/org/schabi/newpipe/local/feed/service/FeedLoadManager.kt @@ -80,7 +80,9 @@ class FeedLoadManager(private val context: Context) { * subscriptions which have not been updated within the feed updated threshold */ val outdatedSubscriptions = when (groupId) { - FeedGroupEntity.GROUP_ALL_ID -> feedDatabaseManager.outdatedSubscriptions(outdatedThreshold) + FeedGroupEntity.GROUP_ALL_ID -> feedDatabaseManager.outdatedSubscriptions( + outdatedThreshold + ) GROUP_NOTIFICATION_ENABLED -> feedDatabaseManager.outdatedSubscriptionsWithNotificationMode( outdatedThreshold, NotificationMode.ENABLED ) @@ -146,7 +148,13 @@ class FeedLoadManager(private val context: Context) { originalInfo = channelInfo streams = channelInfo.tabs - .filter(ChannelTabHelper::isStreamsTab) + .filter { tab -> + ChannelTabHelper.fetchFeedChannelTab( + context, + defaultSharedPreferences, + tab + ) + } .map { Pair( getChannelTab(subscriptionEntity.serviceId, it, true) @@ -208,7 +216,12 @@ class FeedLoadManager(private val context: Context) { } private fun broadcastProgress() { - FeedEventManager.postEvent(FeedEventManager.Event.ProgressEvent(currentProgress.get(), maxProgress.get())) + FeedEventManager.postEvent( + FeedEventManager.Event.ProgressEvent( + currentProgress.get(), + maxProgress.get() + ) + ) } /** diff --git a/app/src/main/java/org/schabi/newpipe/util/ChannelTabHelper.java b/app/src/main/java/org/schabi/newpipe/util/ChannelTabHelper.java index d10e0a3dd..5db438863 100644 --- a/app/src/main/java/org/schabi/newpipe/util/ChannelTabHelper.java +++ b/app/src/main/java/org/schabi/newpipe/util/ChannelTabHelper.java @@ -67,6 +67,22 @@ public final class ChannelTabHelper { } } + @StringRes + private static int getFetchFeedTabKey(final String tab) { + switch (tab) { + case ChannelTabs.VIDEOS: + return R.string.fetch_channel_tabs_videos; + case ChannelTabs.TRACKS: + return R.string.fetch_channel_tabs_tracks; + case ChannelTabs.SHORTS: + return R.string.fetch_channel_tabs_shorts; + case ChannelTabs.LIVESTREAMS: + return R.string.fetch_channel_tabs_livestreams; + default: + return -1; + } + } + @StringRes public static int getTranslationKey(final String tab) { switch (tab) { @@ -110,4 +126,26 @@ public final class ChannelTabHelper { } return showChannelTab(context, sharedPreferences, key); } + + public static boolean fetchFeedChannelTab(final Context context, + final SharedPreferences sharedPreferences, + final ListLinkHandler tab) { + final List contentFilters = tab.getContentFilters(); + if (contentFilters.isEmpty()) { + return false; // this should never happen, but check just to be sure + } + + final int key = ChannelTabHelper.getFetchFeedTabKey(contentFilters.get(0)); + if (key == -1) { + return false; + } + + final Set enabledTabs = sharedPreferences.getStringSet( + context.getString(R.string.feed_fetch_channel_tabs_key), null); + if (enabledTabs == null) { + return true; // default to true + } else { + return enabledTabs.contains(context.getString(key)); + } + } } diff --git a/app/src/main/res/values/settings_keys.xml b/app/src/main/res/values/settings_keys.xml index 9c5610703..d9d8e60be 100644 --- a/app/src/main/res/values/settings_keys.xml +++ b/app/src/main/res/values/settings_keys.xml @@ -372,6 +372,24 @@ feed_use_dedicated_fetch_method + feed_fetch_channel_tabs + fetch_channel_tabs_videos + fetch_channel_tabs_tracks + fetch_channel_tabs_shorts + fetch_channel_tabs_live + + @string/fetch_channel_tabs_videos + @string/fetch_channel_tabs_tracks + @string/fetch_channel_tabs_shorts + @string/fetch_channel_tabs_livestreams + + + @string/channel_tab_videos + @string/channel_tab_tracks + @string/channel_tab_shorts + @string/channel_tab_livestreams + + import_export_data_path import_data export_data diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 565c91b54..44e8f5e74 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -714,6 +714,8 @@ \nSo the choice boils down to what you prefer: speed or precise information. Show the following streams Show/Hide streams + Fetch channel tabs + Tabs to fetch when updating the feed. This option has no effect if a channel is updated using fast mode. This content is not yet supported by NewPipe.\n\nIt will hopefully be supported in a future version. Channel\'s avatar thumbnail Created by %s diff --git a/app/src/main/res/xml/content_settings.xml b/app/src/main/res/xml/content_settings.xml index 8783ff1ed..73a849af7 100644 --- a/app/src/main/res/xml/content_settings.xml +++ b/app/src/main/res/xml/content_settings.xml @@ -162,5 +162,15 @@ app:singleLineTitle="false" app:iconSpaceReserved="false" /> + + From dca32efadf42b2a140aef74964a0f187a8fbb099 Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Wed, 19 Apr 2023 18:29:59 +0200 Subject: [PATCH 058/172] add channel banner placeholder --- app/src/main/res/layout/fragment_channel.xml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/src/main/res/layout/fragment_channel.xml b/app/src/main/res/layout/fragment_channel.xml index 15995f8f3..e1744739c 100644 --- a/app/src/main/res/layout/fragment_channel.xml +++ b/app/src/main/res/layout/fragment_channel.xml @@ -28,11 +28,10 @@ From 013d51345073034a42381709bd4772f0c7110fa5 Mon Sep 17 00:00:00 2001 From: Stypox Date: Fri, 21 Apr 2023 15:42:23 +0200 Subject: [PATCH 059/172] Add space above channel description (About tab) --- .../fragments/detail/BaseDescriptionFragment.java | 2 +- .../fragments/list/channel/ChannelAboutFragment.java | 9 +++++++++ app/src/main/res/layout/fragment_description.xml | 1 + 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/schabi/newpipe/fragments/detail/BaseDescriptionFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/detail/BaseDescriptionFragment.java index fbbfdf23f..47f8598af 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/detail/BaseDescriptionFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/detail/BaseDescriptionFragment.java @@ -35,7 +35,7 @@ import io.reactivex.rxjava3.disposables.CompositeDisposable; public abstract class BaseDescriptionFragment extends BaseFragment { final CompositeDisposable descriptionDisposables = new CompositeDisposable(); - FragmentDescriptionBinding binding; + protected FragmentDescriptionBinding binding; @Override public View onCreateView(@NonNull final LayoutInflater inflater, diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelAboutFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelAboutFragment.java index ae04e8b00..271be3939 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelAboutFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelAboutFragment.java @@ -3,7 +3,9 @@ package org.schabi.newpipe.fragments.list.channel; import static org.schabi.newpipe.extractor.stream.StreamExtractor.UNKNOWN_SUBSCRIBER_COUNT; import android.content.Context; +import android.os.Bundle; import android.view.LayoutInflater; +import android.view.View; import android.widget.LinearLayout; import androidx.annotation.Nullable; @@ -13,6 +15,7 @@ import org.schabi.newpipe.extractor.StreamingService; import org.schabi.newpipe.extractor.channel.ChannelInfo; import org.schabi.newpipe.extractor.stream.Description; import org.schabi.newpipe.fragments.detail.BaseDescriptionFragment; +import org.schabi.newpipe.util.DeviceUtils; import org.schabi.newpipe.util.Localization; import java.util.List; @@ -33,6 +36,12 @@ public class ChannelAboutFragment extends BaseDescriptionFragment { super(); } + @Override + protected void initViews(final View rootView, final Bundle savedInstanceState) { + super.initViews(rootView, savedInstanceState); + binding.constraintLayout.setPadding(0, DeviceUtils.dpToPx(8, requireContext()), 0, 0); + } + @Nullable @Override protected Description getDescription() { diff --git a/app/src/main/res/layout/fragment_description.xml b/app/src/main/res/layout/fragment_description.xml index 157b8f394..b20905d4a 100644 --- a/app/src/main/res/layout/fragment_description.xml +++ b/app/src/main/res/layout/fragment_description.xml @@ -8,6 +8,7 @@ android:scrollbars="vertical"> From 1061bce4f347def9b8f86d3bd2ad25e339ab713a Mon Sep 17 00:00:00 2001 From: Stypox Date: Fri, 21 Apr 2023 15:54:22 +0200 Subject: [PATCH 060/172] Add avatar and bannner URLs to channel About tab --- .../newpipe/fragments/list/channel/ChannelAboutFragment.java | 5 +++++ app/src/main/res/values/strings.xml | 2 ++ 2 files changed, 7 insertions(+) diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelAboutFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelAboutFragment.java index 271be3939..e78d5a922 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelAboutFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelAboutFragment.java @@ -88,5 +88,10 @@ public class ChannelAboutFragment extends BaseDescriptionFragment { addMetadataItem(inflater, layout, false, R.string.metadata_subscribers, Localization.localizeNumber(context, channelInfo.getSubscriberCount())); } + + addMetadataItem(inflater, layout, true, R.string.metadata_avatar_url, + channelInfo.getAvatarUrl()); + addMetadataItem(inflater, layout, true, R.string.metadata_banner_url, + channelInfo.getBannerUrl()); } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 44e8f5e74..e6fb35a16 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -756,6 +756,8 @@ Support Host Thumbnail URL + Avatar URL + Banner URL Public Unlisted Private From c48e702a50bfcfc6329aa43a26ac9aaac71e2efb Mon Sep 17 00:00:00 2001 From: Stypox Date: Fri, 21 Apr 2023 17:05:28 +0200 Subject: [PATCH 061/172] Improve placeholder channel banner handling Now the placeholder gets hidden if there is no banner url or the user disabled images, to save space --- .../fragments/list/channel/ChannelFragment.java | 16 +++++++++++++--- .../org/schabi/newpipe/util/PicassoHelper.java | 6 +----- app/src/main/res/layout/fragment_channel.xml | 7 ++++--- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java index 46faaf277..f709fc226 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java @@ -1,5 +1,6 @@ package org.schabi.newpipe.fragments.list.channel; +import static org.schabi.newpipe.extractor.utils.Utils.isBlank; import static org.schabi.newpipe.ktx.TextViewUtils.animateTextColor; import static org.schabi.newpipe.ktx.ViewUtils.animate; import static org.schabi.newpipe.ktx.ViewUtils.animateBackgroundColor; @@ -146,6 +147,10 @@ public class ChannelFragment extends BaseStateFragment binding.tabLayout.setupWithViewPager(binding.viewPager); binding.channelTitleView.setText(name); + if (!PicassoHelper.getShouldLoadImages()) { + // do not waste space for the banner if it is not going to be loaded + binding.channelBannerImage.setImageDrawable(null); + } } @Override @@ -575,9 +580,14 @@ public class ChannelFragment extends BaseStateFragment currentInfo = result; setInitialData(result.getServiceId(), result.getOriginalUrl(), result.getName()); - binding.getRoot().setVisibility(View.VISIBLE); - PicassoHelper.loadBanner(result.getBannerUrl()).tag(PICASSO_CHANNEL_TAG) - .into(binding.channelBannerImage); + if (PicassoHelper.getShouldLoadImages() && !isBlank(result.getBannerUrl())) { + PicassoHelper.loadBanner(result.getBannerUrl()).tag(PICASSO_CHANNEL_TAG) + .into(binding.channelBannerImage); + } else { + // do not waste space for the banner, if the user disabled images or there is not one + binding.channelBannerImage.setImageDrawable(null); + } + PicassoHelper.loadAvatar(result.getAvatarUrl()).tag(PICASSO_CHANNEL_TAG) .into(binding.channelAvatarView); PicassoHelper.loadAvatar(result.getParentChannelAvatarUrl()).tag(PICASSO_CHANNEL_TAG) diff --git a/app/src/main/java/org/schabi/newpipe/util/PicassoHelper.java b/app/src/main/java/org/schabi/newpipe/util/PicassoHelper.java index 750b8e799..ece0c7e87 100644 --- a/app/src/main/java/org/schabi/newpipe/util/PicassoHelper.java +++ b/app/src/main/java/org/schabi/newpipe/util/PicassoHelper.java @@ -109,11 +109,7 @@ public final class PicassoHelper { } public static RequestCreator loadBanner(final String url) { - if (!shouldLoadImages || isBlank(url)) { - return picassoInstance.load((String) null); - } else { - return picassoInstance.load(url); - } + return loadImageDefault(url, R.drawable.placeholder_channel_banner); } public static RequestCreator loadPlaylistThumbnail(final String url) { diff --git a/app/src/main/res/layout/fragment_channel.xml b/app/src/main/res/layout/fragment_channel.xml index e1744739c..cd3e371c5 100644 --- a/app/src/main/res/layout/fragment_channel.xml +++ b/app/src/main/res/layout/fragment_channel.xml @@ -28,10 +28,11 @@ From 604419dd1f35b55eee252b7baf25b32ef4f5b269 Mon Sep 17 00:00:00 2001 From: Stypox Date: Fri, 21 Apr 2023 17:08:43 +0200 Subject: [PATCH 062/172] Make channel banner placeholder match YouTube's size YouTube's "Desktop Max" thumbnails are 2560x423, while our previous placeholder banner was 2550x427. The extractor actually returns a lower resolution "Desktop Max" banner at 1060x175, but the ratio wrt 2560x423 is off by ~0.1% The PNG was optimized with OptiPNG --- .../placeholder_channel_banner.png | Bin 30565 -> 36256 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/app/src/main/res/drawable-nodpi/placeholder_channel_banner.png b/app/src/main/res/drawable-nodpi/placeholder_channel_banner.png index 12e70bb6dae6f1d68ba8fe521b9f88b0dbc43e58..cad11fa50410302df5c5f75fd4debbb464a4bbdf 100644 GIT binary patch literal 36256 zcmeFZdpwkD`!+76kUYADZ{E1CJ`2)?2SD$2o(|SB&D(&8f|7mXw^_i zWs^;|HBv}qFHN-~72!Sa88kg>J#WH(rq|-cb@HZO z`I`HUk{TdIzGW9TCKc1~Fw|2&q2jc$ zKHlwN?B1oax5edzVwWa(y$qIeZ2PR&vM2TN?~^UNBb!15YPQG&D5ZWoS6}K=2rp^n}vg zmHMJFk8Yhg9dUMB%pccpcRm+&dYdh>C`Q6s#nv^^-p<6y=+5Sc$Na7?y&EI_O<-K0 zHRIHZ6|{ivz^zJOGt||a?{h#fXYh^3-9~|u&9Qq^Li9c!uNwV+ z+I8%P^MlmE=`DBvqQ+gfuw2oHuX z33WBY=pM1ANAIX#Wx%IYfV!XQ-4EO528_6psPg~VV`rDmov^~ z?Y6A~TMp^K1$@Ad~%dl$Aq5LX<+(mHYzTl~r*#oU)3V zvYMJAd_s{F>PvP!r07eMMJ~a)#_z5q=Rl%Ands*$ja<{w$uEekw{|UjUwZETeEdyK z=P&O|njHlg59LFS{>rLKD#|`S%G^IeB5x0di_G58KmG)1A1otfb61jIP@uEx_Fz|E zvMl!{T%6~B-ajbNoBcR0&dRRdu0HTl68u)xUw-AzU8ZL9KY2 z5w4@@h|^ZbsW~aSs%p6@YG|sfE8?7-v=m*n)wLZpur8V^YFb>E*b_*ES?TD_eOJh( zT;Ng~8qTV2+BjE5M^!f!MGa>cxEnXDtD=juvxb(7lRErag?%X(XPq5>fj*A#I*C4x z?yk!IzV7UAAOo(0H`}GRR!xcXQTA8NydBAI@B?~lO^Cihhkkx^AJNCvg6xQlrm7ZJ zO$Ce7P*qb?)xc_K|NM}ZYaj_`B63Yt6(w~I_IHriq5}^D1M7&)Q@8;8>+mc(hJmh* zWWT_DetzD1Ympm}Mt*Ys+orIbTpY=czdMp$;i4*P>N+YKI%=x>RJCmt2dFol%%EEi$cfInezxF z$6!|%_I<*&INx&iaP)O|1@xGmu5(`}{=-yoQP;w%YdB*SRn>9MiW*vKI7LS%HLRku znx>9fy&|J4ZmS0DbL+4cY1a0&b@r(Au31%*JdLL2m& z9Le4FJAU7x_V=B`Ru&_ztN^9t7X6#oMMXrG8yF2#G~EAcyQzTJ{N%n&0VBtg8x}8H z-k8K}$4wsj`o`FrzyAA=@Kx5ghkWjM_wJ0?VKG{2y|LK!=|F}GGw0!zHx0ufwD7hT ziIfe45~sAfzACCL)BO6^Hu)6v)UI0ck1H2Vs;8+gI#IP6GYaIV$Epm%G`EIqR#^1QQ2 zu7A^k$`*l-(kZ^*q|xm~y91inRpBQG6tN;v?2>79!a&8sm7}o7(5-# zemGgV>5LYpWqS}XNn(C+!gvIl_Z^; z+S4L1f06N5q~9j;DFc7<9aI@Kiz*RvP}y2#7Q6u!&}`ThvV-OmE`jR2iuD-W(7(NU z>~#Lqnz5BtcseqG`1%9PY8ByAjwbe};6Z;BzzZFCv9c0F7lqM#P)F>HC?jUr@=O>t z6AviQ22uLv|2uB>Pg*r`$|RnZcGD=1$yu*N{| z;^0%SX|`uZIUv=2MP#;^?GW{1#OqcpI@K-{E7!k$=KCtq;F4glcx+|zCXfa6=mmE08Cp8QtHkXk)?GPyZ0$D{G5`- zrFQmHTN@NiXicg~EUdE5cxm)4vRCp#Vnk?LV`>&nuAqGP#d6}kM(%aFr-7L92T!b$ zNs`!dX%lgsmOXHd^1bj%%g-xO;Q};eyNBz%`7KalRQgH+&bxO^V)tz(tS7y(WoRhodK$TW<60%WZ!6c1ym_ z$xsJNwC9!R4dQa>cD^F-mv*MPhH8pCx2dXqNqU}87fetMSsCba@df|8N3tU+C;jKoJGSA+Ea*L{JiTm(lE1%$HF(^GDeFw64Cm+ru zksG$WEZ5b<$i?`OV)cF4>W9ev;_ z-XHqnsm2q$Uxy0%-FtYv-_=CIid5&;VBTJ)l@1+VgLGlSHlzDrbpxq2-~{dhn#whF{!^ywmR>+nMTEb1}z^&`hc zh;5nvw(`ZWM57jFiOo-amOQp$rh_uj!*{SR*<3+mWyJZvR0~z%{q;CeD^4z-m7>X7Q=r8w|BkOc&Ws5^@6E*N&MZZ+1cz?Rivx$Q4Cu^R-A~d8d6?Uw@3TU4Z_jasJi-f|Lj( z7O%fuQ%<(kP+R7f{C6dLHt)qS!q4|mv&7<}^9&y{_q(sUK>RaksfEIpV=k#M!vq7- z*V8S~*JJMVXmrrNB$N{ym13Az(`YbR!YpCyBYojbuu$mRlHabo$7W{zn;LvS)j_J! zwM3j!7o056ExDc^WZgTM5f=dPzYFJJgRJ;v}9uuzDbyR~ra+2@23{wY%esh?LR zxwl0iT0GFKuKs;O57j3;+4k+_r9IU2G|{lPEdo~@F=S7eeK0R(oRX7zVpW6IHy&gB z^>Tj1meY&QG41a2jGfQ0?#B-8d?CP+obj1ZU&l14+ge$#g4RhCyka=i|J+W0X#J{h zPiq+cMoFw&Ibuh(*6*NYnQrUTx2?|RnzmsFOa{&sQawsG^?p^0}WYC!QBN&h)MSllx*R!?|JDh9JSm zt@ec6W|(X~g{3_?Pw|SRW*gXcMM&2Ne?shuS~CA=I>AYe6>eOsaqRm{*8HU&R1uZ- z^Gx8Ha#pOpXzRFo^ufCzHlOH2M-@ROplnnlRl`{k1^7{3XoKLl50h&5OO9j5v&z? zfIF3CS$T9-swnHkKZWU$kv<5UQ2@-5kc3N0gZj2oNvtheFGO!x{c*}1%W7@AitNL! zx#UsyTRr=jsALOR3wWJxcoO z)bsagf4;nEvJ=)62WtV$E(nSeMr>*R?F?)~qM*K+Kg%my3>JbVfGu3vE9&Lq9%^H# zNDuYxt?!F7lj3G{k28bil33AHFB4zRs8@Fd#hT`DqY*eJS0qvz}&n!qQnZpx@5pW;!FlOpvI0Fuig9avQrD-%m`W z6ge%pIcTX!HmffvS9)4d{(lFudeZcwgZ~y}bznPhzst9qPnayt0v=n3j$x`GiwT9W zo!OCUxA0G$S%72JibqmxGi$${i97cvkam3b)m1<%g7eHV8m9u9-ykG5Fyp+(=#&Vp zUG10+lZ3v0HV`XpAtqJc60uRW>*rcp{V09>Hf6j;Q2&L1rNY>q=+!D}!f&vH2`0+@ z)N$O+H9gea69cF!yx+={9oj+C4TZxF2dFbImXs#pv$@zjPlX+LKm2liW{>E)e4br4c_X zvmiT(ZTM~WQN3`iUC2YeWq8K4n)2S6w#YR@zv~YzEAsxjaXk|c8-)dIxMvbHk02Db zxZM<&U}fs)88Z)t;bTSodRV&N+rQ%~fJRt#M0E{=lxUzlEOt72E7UA477Ly0Nc(5O!P* zagngv#Shigd~nZQbw@m7u9%)WPxNFi#U-@w_o6Jq#Z2PT>3ZU`>B;w)@MnpL!WLgcNQkanDBuda1I--tL_yNC9=2o|tSh`Njz= zJUU}BPk{9n(4{m6+`p|8)ZaE3YDvgdITz~iMQ1GLJn`GI(W}l{$5ghFKMA^CEw4&^)=ajQM`sI% z!+KQ1AUX~8YY7CH9e9R|yhR?(be@A&;rrf$&yfWmF9&2r4cUIBDu`L8Yfdn;kr%AJ z@!8|E70Wlz z0IS%nPY565J2(`zjDqWL5ing~j_+82^H|wK&5=OaTjVwu4yRqaHPe%PDGz}*d|7K?E_RzIB>fkf$|=#ht9&kE~R~f`n$W}Emp4Yjy=}vA%19m z?+p4aL#o+Tx8@jQT+;%!5e2|zhh=jsJQbU}cl2sm%GS@kW(5YYtQ0maMwirn;se863&SdI_M&F%u3-1cX&6zrO8=`~0+px=r)Xoo^XC_w$T5I7h)d+lqQ|CO*)t ziC~BJ>@Wj;e^L!r9l(roP?T%h+kd6Q5({aUfS@RMdTD)ye!Cydt?7 z?j3(^B;n&&Yg?>~t#>CBzI&uo24KBJS;v+W#bscEnOV(Wsz+lLmi5~TZbVIl_wuc5Sd^L2||7E`Ho5*mb%;Yy-O~6yn5$?fOgq?Ov&PZ0o0W#ff?56sW)!TELPnahDA^CRuHK`^{sVIsB{s9 z5<#C6qB~AUv>SfkuNsgVL%D1#PH(Fs68Y)4CpBfxGvrnGk=oP%)!>|AU5dtIG!7H< z0H#ygGBGWM#4fcEQPhon&Ba!xm(CA6I~0bu52xR_b$SD?z@UD2QUwuc(Cn7PIxij> zP~W9+lMSf_<$W+8bhnygL`iKQ{t;8pg|&UyrH;^5c+Jb{ZCcNyW>*lYZe4~;Z}V-w zgI}+*$y|`Wvd-Vg>Ic2SJN7Tt`gC)hJYz1&_35X6Y;Bvvt$Y5qpA0B&tLS_g$C;80 z9wB?PD0O-n<_3_~I1{GsRzmJ=p@3#fsI>MD#q?5-kS=~XfVuk|ZYTWITgI=9l|y#W zbWQpD6H#6VqJKmw(m{z>R*h$_JemI*Q92gq3qwU1`b?Fh4*V5y!ar51qpg}a$5pFv z33IEchf#e+e9vW~A)=!I>+M`wxg|d}A-cWrdG0ZcXkc4j5mMpCA9Zqhr;MNsz)rkO z7f~q?1j?T%4=V_lyFl>qP0yI|7XsEmQQ0zwT+UkD%^3CgfaU<9(zt_aXG=3(CPb51 z87G-4%Im)B=grL3dRW$98xscoZNDwSvC6~|P3N1c!(LE11P$`UE?_jw4!X1#8wWHG zD@K4CfDqMMa@I<7{D=+h*6C$HM?}L>3T!FDp6Ttsd0~L zzDaZhH%MLIRQxs?q{B^5@QKD3>w@)+FMjFj+Y;-bqR_dd(N!1p%yUc?%V#nsQz6Sn z)8_~8Yz=W~5znF*0v#$%IZ>W5KQT2vIyGNJUH7vghViBO`-03QsR&?PmK7O zf6Q3?dE(@T7>DNyqNpRW0nJ%BVD&tAr_VS#oL*JcatSV2rIHfwq}K1>PMW=y@OnP! zY^$08Gn3rgQa#k^jxl#58sF*Y#j2drf0IYj0Iz{^+hc3~QVcTHQ$8dwlV!GSh-J2# zY-b~M5rqj;Iw18dOXFp8UG!!i5a0cF;FNWoFk@l^x(K4;(Cvnyc@JV?(Xf8-{K?vV z8kF8NupW}%T=Rzsk&0XKlg>08C4@)v9UM`jS>4|r&`dDNRVlbSXqh`-^Pl*Ym#Ui3 zru^hnHmJ;O`zeH8%O{`l?O_y)M_#ve1StbQ3Zy9CPy{7>Ak_sb9q z_!KV_G@{wC)pp>c^RHghbD2^Hwxx*Yy~Dm-*zfb>9mp49W9{4q6m+)C|2uN#zdy)b zsT?K<-j8FxLkfMlvJ~dQc#zNdcF=~U)>Psvlu;IML_<6k)Ht zcGIq52o-kJ`MCrX@*$t}#`~VSRd@?1bx!qChlMJweaknBsF!F-poH-bWT7i5eo&`; zdt`|9u?7jKm%-+uIzK@Z9`O>zsv2RTlLMDBtP6aXu}Nq_)^>qX@*_G{Zs3l6ih=U9 zx#t=K<-B6=mo-cJ8dUpq8)EiAm6BhNi)H3sn$&_yP$_P-ku5 z0s_#J4kvs$u&sa3z{ia+Mb`qlRDtWlF}t!#fb3pGP!!6;@19Wb&cDG*Vvr&-F+Vv! z0KFvruJjZ9T?|TC6f{oQoS6Hk)nu9RnxjzNH6#ewHmSKArQ91x@URD?PNQAlkBAfuHaxC;+#uV$C}XGv{&z3f^)mI)i2 zep%bBo`KA-v(>~1=LHgFP?J<0a5)_3Q!;=y7wi0l$1q5jdZ@LaVU%R72TWM@nb#63 zeV7wa9D_449w15E^b|PPJR@a~TaMoX{%o zE?lhxdie0afafWw(Tj}UGTzwCPx({KWXgDlpgtkj|D=UN<(4OHGds|mP+zj6X;yM* zN&6Gnq1?N|wTxHAC$hvc^wolfT}w_}>Ar*mb^W&}kX2o|s_JWj?S4vZjF}h!r8x^< zgJ-4f6)JtuZC6f4zLZgEc}*^$QH(UK%PW!JFAU+3q%v&>Jk` zXN#A2vQLU;T5H2#7Fme*1ZteKQ4n#9c&Tc22cLL<~4C9*M5Od-$&kG{r?d@Vex_03jmBb zY*6g>Vm&T=zUqAG^VMtl7v8{d&6`pKhSjkA8oz^ls2nApU~*R{0o)o_uG-S8W!;v$ z0pD)$b*r=Wr}snKcj9hhTBg+Fz>=WPowHHG^(?cCDaEp&N_(?lQUyjKp$5t8((a%1j zx#)n$ThI4YCLr|)WpU^Y3)lrm)#wG`H`B*o3O@FHr`PZ7U5)kd1an{)+A|&DpVDr@ z4FS!~nzGEAl<$jenC?HiWGJz?gn_el!Ar}DBQ&A!gdpjkbzBc)0@q-XGTqN>)|At( zosYb~L^F^UF8TU+o;OhL{3y>hS!m5?9`)&?uZQ;Ev7cIAljd9#k}7ybO-OvdmXJP!VjkUj^fzrctPKAHDf_Rh* zncvy)fC}sxvkOMu4{f1v_!{u`edu@Np~q^;yrZArkw7?wid7`+FG!DA=jU{Sz>fe| z2)(6Pc~*7+nTHLiN|p$s2HC1D?xp_BFvRpwn=YH2JwGf8&gX4?n|Z->IXGUgytr;g z@(Iy?^#Eh0fP<@Nz}p2O_~PdW*)v*GD=!d_nJWmbpe)}(Q!o021FxT`1V*p$VMvJl zHgw1Sw+qAZ^2i%E^QZsig98#lHJBR)S6hW(-_*6ZuQ+-(==7OUJ) zfQ-8hYO1V8quBWaxYzj1q&&@ew||kVC3#z<%`j5nyh#sW58FUI-$9|#2b<_t$&XtE zaOhOHC&1>h#US;FpuUKuFRaQ5HC6#=Yho5=x(yW1Yt*kms4`@6SpJ1E$aqBK%@$CfwRyoPGjyI$bXb4te z@2+zL4xAKb=70uU_Vg=Y7~@%w`M&7;|@5ts%(U{crOb4L+{w6Z=Ahn6gMbCJZ6K7*WJH6v9{gmHF& z4QLgm(D!M=$9<^hTzf{&73SvJu^F~@cw}^UQ;w}R?5mS+@K(itBc~S@0xD0{1wYa` z_5c@qm|pZr9u(P2IPsqaO0KGUsiz=abE<0|OK~@M(yx5pIQlg)f-Qptna!8>?K77z z5Th&HNBTWT?ArUiLbC3J=-&@ky=D0w_Scz zU&C;2_;K8&xJ4*4DZ}+?wp@S4`6GCb0|v4{j|Ia|5X*8 z%1KkXgo#a**JzLl5D2=XWmhZ=wioqlU3!`V}0IjFxk(bsLXmnUb-fl?sERnVIvRhYiSE*9ESyc7v4An5rDq_IbPK0T$tese|yyl%NUpMo<*1s_KU17^NY z12O%qub} zD{Q|?yIJ`YKAxE9ptig6mev+6lHYCzw&zV8Cox z%YN+)p2IHc9iNdRg!$w6;W!Bt%l2}#?I0DAd+$D%Dr>n^1;LhRzh-in?+=pxyv8j>K;9-Ggbne-Dd*$Kpx znc@U4a%{`fid&d${O6MTF0n8578s3Pq0fHnqYew7j@}`ImXyPy5-#~}4Xm%xxJY^k zG0D1azIDv^LNUyEUO<>xU>dlb!uDSnJmj5-B%LhzyU^%FmmshU^<%1c9YN3z+~o0} z02575IWoKNk!oF70~+Dtksy9n;+H~pkIg~_d#PRx7saKlfxiQwa^z3op%j7kUufv= z`R!A0D?R9sMq;57PtGi4Zmohi;F0aHBsUy}O4(b<;ANbNtUF=#9aGNSslq11M^L1>f*MPM^}DWAobua zu=iXSB@*8YuV+ppK{;@9*Tyg*FFF5^rA~J}8u~5L2ACBtlX{Tp#*1@WE_*bviK z=hr?m%!)iS1y+Y7A{V_Z&OzkTyXfNIL!bQ#0@tVn>IsKdLTMWZgof8b45aTfjt_sD zui#=qPS>>zJnY7;ea@SIR|CBTqro;`>kmV%{(C@kt05||O{uh3K~?Rn@4GwcKFm^= z>^Q_I4UvXMCiH4o`LsYh~eG%j2e0iC5wy9))H zO`mS*-_*@h%++fxAUVt7l)Y3xhRroWx5J=U7(AF7{O*#4|1e;}>T}#$Njzu5! zT$-}No(_x(A}k!uppxjDk~DMO)w32c`!KL+6^F)T&7hqy#VcIe&q4e)`)7F0lrqkr(tev~GebYa8mjsjgc3tY z`bH6eD{P9WsRdb7RIDZEU?Yn} z(;ok@-@CNm?+GN(&csWjO#L8>Apk3^?7g8?@%I`?)0uH9^k}3)R~IGd3P5OcZb7hT zRQM|sy+=Hh9;_T~@oyCmroS2>w(7xpZ;4)NB1J&55`X0DE{K8^DDjtSSR*C6F4#l= zB65z^LcS@&?cHB|)I{L{X>=HDZe#K1dZ_!sXZNB#7`hK}E7cO)YvmE*sAg%S8b zA@lu7DCf-p)?c{XURg~GKV_aADG7v6&Vu70PY)F$S|ACNe)|_nSpq2qDSB=iI9N|G zM!#6@rYy#ZCdMvEY7NmKHTo15?MEq4Cs)XT4ccW>xX4EEfFJ!W19s*8*r7mmm=&OPR>HD8IZr43qAc+9WT4%753B3Z&`=wnG|lRdiY@uJ zEVdqa_GlE=L%wt)s-Pb4S1-SgnbVDXf^V>{`RD*!!eya;{nWc7ClKF|Gcmr_Uxb-4 z(6;jX(y^XrNCs@Y;XbCNc;$KIS#?j@7}3BU5)A`oYUCs%?k%H33(^-6duJDoT_rIT zdCoLuq1T7awmdX-$PnCTX9(Dtm1U4CUk&==YS@i0eOTmXy6tpk5>(<4#=l6CR*apq z+S#+yOQKY?VLD<$UL#ZuYm(dCcH(ecjL{CHqK|zDX{IZP#|AR-{-shit|epf`IS(S zWg)rpuNSh^kO1EZSghRpWOrrP)ZmpUh~vYcQ$|HMLb!beQkCcHc#zY3s7Rd6!n5;4 zvvCpu zIAX>il7;T0ibD;i_36@iVjn-bEw84Afru$trZY%lU7m8;VJ@Ks?=RPpGM>cJ*rSNx zo~mBHXXhNVd=k*S-H4`X!k63reSuSl7?i#7%-t7lGcDpU`dCFj=~)sma7=S51DQ!L zhF@!JQ-qliB1#EbBU^KN#iqJ?hS9d^7jKo zdZ_z?KRk|Y$(MwYb`N|@+Ch73Oj3kdU2jxSz6MBTd{OkPaSpSD9f%0xjt$gbs%Nsq zoE%Qi&2Hq;j#0*qp~t44*Pn+Ze;HEN|0RZkj91{onN%HgXCy5Q>D(h3Gd%~G;VuiX zPr#!SUK<@U8mLL6G>C((pLzjGr5Fj|YH$DZ3E!6nujFl*bu2$&b`#)lGb_}h+T zj-FB033Ebt{pvtW%g%siMKIVkEgZ;pH$cs>yN>nff>fJ$^$*P{{#XZ4tR2`WQ_r^> zWQxW)i`=e>C?!EK_L+IN=ZT=;<4qgxpS~;nUBXzDEjgTyj)hof!}g(6m=g81Km`qF zLip({pdUf(@?4;O6XbEeF1x{&oI^umE1@|e8MO6NQ&l1D*V($fmM@!YCPv$8y~z6t zylk%ndGkF#6}2y2I)Kajb5%ZK@c&3MHxP2}rWgLu1v^ri$AZ$`3P#B=A8>O-F$KJ8 z#;cBf=4G=?3s^kO3h8G=2s!Hqq25(w^TO9#`2tddye3u&(E0M}{R)_=c57ZQsl?|C zU$+{f@Ijf-nCb@^g_Uv9ACfOX6Uy)(>f2<-?z}cB^1f$cBL<;&$D#GHL?a<*hne{q z(%!pA`8YGx>(S)ZYjxt0pr4o)7zj#TgfszWYEeM5c^GK2kmIhR7^syBWT>k_v6i3E zRobS%+CX_F+$dzNf6}!|qHv#vi7xBwxi^r*hs-G}Euj8PJknxt9`sGNA?gO4Bty|` zXgk<-vd`6GnZ6x>H9xjC zj3S7Ho&$0YSPGfYe;}eS2_*EmFeQd9lMNf(#~I1hHvdSwm%5q_w@ z`Iudy@yBmaa$ehyWB|#EX`5u3eL(WL=qSlT*OcPc36Pq8<(wBAQZb|38n(`n(m=C& zx*n-8ZY_l#)sqN?AB3Y+e2_*8Pi6!(z6H&`MN(a* zs)9X|9J1O8PAZbhMdHV!+4&G4M>|bJjOhOmSvj{SshyrSK;JI-cq~5ZE@VPM-`oVH z<6@POM-ng(qB4_IK}Y`uSL+39XA5KG5}I)ipT86^Ul;Oh2B#bky>rkeErip6GXwRi7+5&{6lI9HEhD#~%ZVFSMRKzC-f4yQ0`wbN2qfkc znkd+Y!cd2=2bd+Ev)I}rR%PvQ&^xV{3gO9-4UHfSK(ExK{5(yicNwbXk`Et0On3c7 zoyZBXU7B8efJ}bIE3!{vOCR>;Idg^Ayf~!kDh?WnAh31<@uu>JPpFKQ1Jwfc23#%B zJLl;sl*an75N8JaGx!dQEw_8p7JE2u{qEdmYcd)f(hJe;TH={V@1^?2rQZolr@%cb z%z?@>puJcg+?AYvNrZw@rcKwYnZwdnUAEl07o$tz2WsCxE{x1NC=eS( zA-c~SI>>*4s5H+|TVDu}koT&+u@p(bhF)e~Hf^}dcQ8yC#LV#I?k%5Gm1^+0B#;2W zSBXIb;Sx_aarTo-fi4(RCkLYs`;YtED(*rwK%Z3b`mhZ<2p!^dn?l+nn8w{tx0vbX z)~+v0*T?))%r92GD^!IKG1*mMz~QMb#qA(_z5&^jpZt#o(&~sXRf<;WH#2seAF7E| zXv=_%4qB1}tV{3El%Yb>9uU1SZ21XejxW(TAoD2v?y)V$9n`=Cg&-4m^(k3HOb%|Z zS?KmIim&@Rq{$l)UojvqIvyT3jV(-YbWbSwmL{0&N@B@Tf;$$2ZmfKo`923~G)PAX z!WP0}7>dxvR;D05O;8RGn@}I~=LL!PQC)F2?bS=6JYNm-1KQrQ@FoXa$F2bZ>-Xna z@hiYS;9gXD=>wQ8eS1D+iAUbc-Jje&F0;m2=E7b?Iu$;0EV-?%UbBjWu$gv+9c(A* z9+aVl!?s#%Ckf)K4$vLJy{HI3IxD98AbnqxB~}H4#>Q6zHMX+*o=OC=W8SeEnqnJO zk2|O&v7$J1b&;}kLHXtwCPkKO8j04 zZaU!kQ1g#1GgSU1br0d=2BPqxXMYW^_%G0PCv?%>F?`Etq0InjjBpM8DdxKYMl6Gw z;f;9nFwG(0E(Y@fUq7Qk$D)h*YZ>-y5xU@uxCB#dJVj{^|Qnl!>gNO zUTS0B3`&*>B0Fr5!UvFW;3lZ_#x8(4rFF{21cJflc0zY)5#aIJ&CUssCGMV`Sh=+p zQ1+~6Ora@4UpZ~SlL{W&?=H0&9+0h$Gcm*s3ij!)w=azLPpw^y1RA*0O)y&NgTg<& zCN}=TLkPf#T0|dOkFtbLj7_MZhDr#98DLsMwrvL+sg*A?Y2e*hxDoAA{JDgWj5(Qw zJ@mP6hK2kSWdW7pPk-rJ{_M_3U|L{d|1yt*EOLOCun@rJ<^9%v4LhE3E=J=1}fdhyN>DkGCVHY ze3J(^wyvE_07(=V<-%pnv+Ga}Hw+4FzmsLd;4#V9wD64aI*V@9T+%cYu22CghOs1b z*wI1uhq523|C`16>GsL9l(n1)IrnKqOp_}xK+}VKqp-Piy(}M+&+n`qd$uAn5qbnW z+%Th8d+#GvY1=RoIZzd>WsD2;P#azh{{+_^Zy8QuTs9XhrX#;70aoU@w{Jm&15h?gRuxXMOqkj3AV30W6Kd?tr7Tb9Z?*@7(4X6%ElTICTI! zbQXqRT{o?$3Ol3?!ABi^vG5Eg2U*A&)MWhwNiv@s;+-A1tpEYo!gYwh7~}-o zgkXK@QH-JTatXq!azsOCXIse2Du_q8a9;DY!{>8d1h2k1R5eIEqmR)bLz%GohSjS; zm{&R_(~x>XGRemsv<|!Ophu0O^+cREPOpc26@Q?Z}TSz6-@87y8MS znL1`zvoe3=Cc|t8JdEJW^%$2?=sesfVW2#RswJ^5slr@R07tO;Ll+8)rYn8bB; zOak-7AjYK%^&UjI5UtP>Pm16ZX0uhOgxo(u^&d2$w~o2HdMC6paS7s}8uPFi8$qtb zBQNvQ?CAm_a_H1{pwq8n0L9im!B487B@qcgB-R1Mp{jWe0ALW5#zM}X1|mSmo>6t* zdW7|w`04*0R`E(5F?ZB)kUJPcnwad7nXv*Ye{$zVILH7b&miSrYBXR!?TJU|!ZvJM z=F5jlRpfwyYmgQToVwQz0?2N@+*wssU#TO-z-0|A9GDcEQ>GH^&Oo-V8jxB-w}kqU z;dc@tVy+fQb?e|Y&?4X!caFUjKg1zK?q~WQTw;*cmGrT>P*Xg&VZn&mR1-%e2pzF5 z2xx_BGZjXUvlz6+i$Zu+?|K0*XCE|h*zF;{elxiDK8fw1oD9;C0DeIcbV-M#+}YFv zTT4NH|E{TtZ zS%(<(5E4VOuq6!-8p@{&bOko4%6KG%~ z99b1IH&AG7OWq_4V$81`b&pDg1mR3ccgV+uN{C*Fr9)xpAU1mS8nRosqHe%G^k3j< z=ciF$bAK?j=_wTG&jXFBwLzi^f587&ate3Rw*}eA@67JeMc31<5S@OD?!V$GVrk|4 z3z|-d1Nogp(?0)pFHWiW@*bF4P_Bu_Fg@+ps6g|wxYQaq4x@ws?2o9@AUU+HH^P+O z*+c2?61L(25^&Liqb%;Q$*Hq6<#PL27ar?lKaVf)5^YP>Kcoh?L+lX3oa0_k;8Nxo7D_Vup7}G(!qveBIVtQ zWp0(Pf5G}&-^FaY;i{pd8!-5m3lDKAk}x`SsdY_ZV+&5Pi`Ce4#efR(^G1xVNUKV_X-9|yM|3nzV>;yZ|&ShD;z z;_!nJ>kr#a5ISrt2~L+e8r@u%2}j)ALMsINUJ^T+ex;!Zcbi$fvB2(jO|u_5+F&l)DA6p%RnNm1CE5rxyZza z5yw5u3V)mVpRcm(w&;iIuw%wL>RCYbhvA1>oa-{dK1qU{JOr zc@mYwJ3<{^;6AfMJlWB{Pw_r!Fw2}>bYe1-ruh&**JcV)-Z5^=6#>!APH+9P zpn{ke@$9dV*^`c*1=T3O+7Fvl?qrc+)*mzf8y$t9%;(1Q*oHfE&6N#$EQTTw z8sF3_@Z!_$cl#sfcYT*&$G9K`-XR1vNi1@_(U2=NcAygxiFpIE@P zmUfq?x*Hvg`mDtxpIFt5W|u{2M}uWvfVdQ4=Z6*`5d(_}*;WAR$oP9b zXaOZWf)4HBZ~Wg0b;!ls={!9QqzSFzF6DAHgSiEYKnUZr^TQ!mb)`|cDr&5MfY7f! zn(L8K3*ZFs=Rr!cn%MECwm+Y(sE0-OQ1`+SYo{BbJ0sYXf1iR77ZsgstYHK}3zK)+ zxUfZRa~=r)emOI5S&uKGjH4@v8R0kX?kdyln)HO`jGRvR zj|B$R8Hx4aLQq|BBk~OnNK=9x9~vC}nz5K9LeO0#Wu#z$_1XE8i7;XdnA7`ok<()M z+`HmPh!QmxgBbjWjcduLArZ=2dEM%jUHUXg(9a((micK&-C!UX^P-6Juz7xT)?REb zgzcep1=AUXV6^8;@-67h2rF922Cavo@mcsvh}=UqDiX}L?5hBxs`Vl5=iV|Z=Q8&Y zLMlxU?tXH7n#rc30nK{gNl~#L-BlFGyO)tpMrSl3jRfA^tKc*O!xMpRzSUo&AwFu1 zkR`FBDwakxV+gzJ!A84;Yd4eB3V`Uw)Ka8+g}UB9H{oBAv;%r5pO61`Gw*OsFQDAM^oDTFYa8wZsg6k`L2}Ct$;d?hB%_qiS7nFw+kuPPzC;PpOMgWy zZMIMfm0)a>9J{#3-8_P}jlvGmK+zg@VB7l=VZ#TYg$cO&oWCE=?eD|3OiDd*fc&FN z@Ubn@$PH#45>^1Q1HxWSH5z9A@er=cX;$ zp5oR)o}ZU54hlnmiYAwi0vX}Cx zzOK)ia-!6J#Ddaye;HB7pLe8gADlvY8j;%a8+kZP6ufDq?JvGo6dZxX;m5Fi5;+*f zLMo%s5CKtw;6VCvKld;Bf{)ql5QhMbNt8iL;G_tK;?DtwYEG?wf=BB4bxgKOI+%S= zYE0WR2Bs4U4kl?~pM*j*s+@l84`4k9)X+cOI$|?b$LlXLsx4;$t0sH^$$GpHu>VNy z5DAk{JrWna+Hh$7AjMD(#4^EIB>kLVvJ_6)d(SQPs1WXU=MSePK)3z`w3KwkLC8JL zu|DJ}>{T->?$91xu|4i$8$P}oI+?iqC$8y;Sh#hW@_#UR`XI3quaBNU<}j*{Dz<|L zDJd}Tyx>GO$?6vAShoB0pAb}QU2A0yHvxt7t3tuf4@CFfk*dZUwxwYDboIuLxI^DL z*iVI~ld!7AYc`Fc3#c ziQu&swA;D5w3i@OKET*e4D=}cavBNSd_Utb?9Izp9qLffem2xW6I@o|xagy?$u@94 zU>3DMeL2V;QWLyy8G@r?7lw%{;Mp323p1ASh#$^#L3X~90t0C9LH6i3KJ=-q;M9#! zjdWw1atPp=aG@th67^nSfuH7BU^N}(*YH^-ti}|4uwtM6RZMT6x222=g5|s>)+Y4>b*dm*$0>rb~cY zIReHQ(nBX^(@{k(i>eq zpKPTokG5T4UpQF_2ac4pVfGDzATaWVLSlu#ZP+YOA{4mzyEB~f>2VL)Z?FHT z{c!|N%8)9%HC&B=YI*jD8u z8RnWy=ACO~kpMpGO?Gw~IW2sPS zS2&UamK@DZl>(uwS8KR7Iyh=Y%ggVyl`;<C_dnplz;T9s)bWO7Nbfr&fG8wx(TT#S+bI& zc{)6xADrw(m5CzMb7+hG#H@nXFaZ>8Y zoydkv97IN;edL7AaMjFp7agt+q}S@Fw0ks0u)=@srUxMxy3Gd1?VupOet0aPxe2-} ze#OTuD&iTL?1{!f^3HG+#KCZmZ3Jo;*8v5lEF>)Nst;!XD|H}yq(oKy;x2PF(|R!5 znpPlAJTwzZRu;#h}IA#`+j`ft`kzEmCz;>5`t)uAxS~fjC~FMfa&0W9?7NzdB`1u zpEMEYSw>g7%*<6Zn7-gA$p*?zJ5g)W8_YDQ4agmVP2(jM&(<@GDLKg)d59%iv?2Cp zjKYYr>4D-jzX`euu{S$9vYbrO;S7T(tGNIke}t3yFBdhnW(>fl!ghtsV+Pnhon+E` z{NzPVrCS~P5G8`g+CYQ7T@2cDzHZlNA|sLrM9Ewbo!6zUFN(sf)xgYj)|W?(i&mHU z9q{COj@DecQSy{+*0oobhK!Jw<6od8NGo5FB)lqc;Ub83=0y)!Jax?OkC(ZxDuG`(e|h9+K%l63DuSefA?_M#_qFX{`4^K&tXQMy7n!^V_5yvtZ0+$%=QsJG^pj&*dzhCc@$?#xYf|q@f5fMSyn=d3#2m6QZ z&IYTt3!Q7h_-i5gf78B{yz(Zt?hmKeX85YC7Q zBN`p+f4KxBJ1|;Zb?*~ROH^E%JST+c)!raKzeDmSqhV?M^gS&2vDY{>>8Hrgr(PKUaPb2{U}ld_cZ@YM!5{lOD8ZG*p;;ly) zU6p$U#x%kGlT_k~8_ij_Zr+3;_!#RUP(s@;Kh=QI?-f6^14KQ;c)7oW88(lae^_J) zEz1UbDbGHWKm!W4oVY;FOL$~$xXt{sF8IQ{|6W8}~(M-KX$Z=P9!eJ|76w6o!6 zEOsH~L=F~<=ia;`H_Hos@^7MNVoW;d!RDx!LnH&D+Y(Jzfv+L6zyWlGBBD)8F!lC) z!7IlmmGMMFA04XnUeFVGz{$$lQJsgX6YmHK=TVI30}PxD&J`4cJ5;0K1XkhJqvP+p(E&P%M|C&6;a& zfHcGPZdaZ`YB*J!QQNxId+1|(Gedp@d&zgTt(bS*G@m$LK`^Fhscv8Ohk1mk1hMq< zl%16Y`Zuu0TVl>mc(}sWY*5;dezJHO;08x*!eK2~d7I}q_&fP)S z-;e6ifT}mkq7sZyU)tx$iZl}W&J}iM9pF_FBqr4_{r0v9>J1{HF0zH9bEfFzGFP}5 zC-uaGQ>#UYP2P$(>`8>GheIq}U{HN^c@yE3IJwde~a4SCW zC5Iy~QbvbqNScClRuLs_+X9O`*Cmz)Op+-4Z-W{yS-g-#h?p99!EniN z%5}juguT)P`}uf)ChDUTUtC6?DlwGMBjO^=z-sKb20l%mIOTK}I#?(AcOnuk7-YDR z0};%7CxX$_jwkm;@h^$Fo`s?-0Rf4W<9CXh-e0ratw%cWnfZ#^xOTg9V(v|xWZWSo z3THd+FcwNcXQtxV^bc|OyiUCP7+9x!{Pi(>ulYQ0x#)mcuwUVW54}Gm2C!{&AUdZ( zsMWVdJa9*?4&Ade^n`rJg+uWA_2IwVCzJoJl0u*vc&-rZOGKxs)+lU_w zdOhkG{aPft#j4Q8NC!q}clPvwTs|)p?M_Me29Y zL*7o)wQ%EoY&Dw*lwE6}C=ZaTvj!D*2=QsYp9k;YW0iAS$~2S`{}67kgut}f6v9Bo zdQehhMI&Y3!>_Cbs~*pA8WNZsLjh%nP$Q8A5{8uDL|cf=aqe7+^%dzpIJm{%wmwa{ zKi1Q0kBU#DMVJ(0vmz=Orq*xAx3Xsw#%?ga>)woX)p~5)KL^||*NT7$&`c8nx2vc4 zUS}mC5`C0J48x$+YVh3zHFy=OQ)J-HMN7=>Bz65i!__ahsVC8=p8gg?J_%SA#-DCa z71N1Eg>}dOCDKZrMP9Fly6O9ca7n*Zjp3NY&2M}Q8=mdqqd{wHhuzh-`tg+ozNr)i z`1QzpeRcgtye6y9B^e}AAZapv`{}~E0y*Uk(H7P)_RHnVSCAzY{i{8&!f9h;1pkbU z5qvq>9pdxhVjgH}eji>RKP|nCu8t_H4?E@^q{AZWOGa*w!Sl=V8=_m-|0&8YL?}CJ zDiIsQU`gS2U$Toab6exQ% zXN*~2+_BElh(_?j^VOveV3Ed`={a5{_&JAxGmSpVG20|=_5Dt42~lfN1$mh@L6=`Q z##E0%^V@+?A$-R=N`DE*vBwL#CSzJ4%EBMkv~Pi^fSy{}T(&JO5R_!NV5uJLeD)4S zXb6#nB}KlYq{u%#M7hW&s{9X1`1&Db{|%|br_c(%K%1LlK9#4fQ-@!Glm-j=T06-Q z@&%}oL3EQi^fnox(cTv9{IQWt%30v>VQrr0DOu1Mpt~O1Y^?oCUdDeQeCz)$z{Op< zPi*XwtiB+;Yfo(b1pGqGlSs@3(%vI}E}@N?mBDiBiV!>7TTPrR7y0fs3Z*-QdCL-W zldDh>-!CEgOQ!OYnG*O;^91fcaB$U$!v7c@rgfX@!EDM8vMG>|Wr%$!Z4VMqkdHpz z`F>Q9^j?9%Gf4PPm!(butm=*2coL4Mj4GiL{&fO5>e7Y9fJi|DqnmjX5aXwhB%)b% zD^J=`Y}-K{ub z(ZgCA} zS=RjG!e)0W_sXsjnQPAK_I25G{AB~zRNG{R+km|VEnxM0HC|O?a5CfMM8YQf;m#2W znp&>{tL+M3KcB9~%W`ncp5HFha}(r**6VCOWclvJ+6(AXElXYF19bO7%Y2m88TdQexINvK zkxw+3vVR-b!d3!QVO2HuBr+ma_FGqyO{ZHF?%cbC7V+G8KCPa0-m<}DlbIkaJ|&tL zJIayl*;FKR5uRCQh=z*&?ww#1Y#H%>{oO2`a2lLWl0KZDbSg%tot>akO$m(AP{`3Q zUP4n0C@3peT=}#LzWrD4N|Dd$Dn&B0Ef%ggREr+vO@{E>yXPigV-wa)1*r_lym_C|Jh6d4b&AhQhBbZxGlw`ZD!95CTsg$_-r*IYOJ1zi;Web1SA|o7oQM z7OMD?t1q9}P@zW2_tI65Ij~{9=IP4v6OE=n(rS!;I6bsK;cIz;U@?^ondlzn>os(z z^>TCE{2O1NWcgM*zC#;x=$s0@AY|*F-PM$kLk`t;0#Ex%7G2gZ`7Am&*jt`nS)myI zP1LsH(^JdOHZbeJ^G|oTf^5{|({H->7ZJ^;M;>LC4XX!=mdx;9rPO4oX6cyE;x13n ztPf{K%Swr!*cd5uRl2QrR#Md0p1f1MdBt%BY&I%~KUW#%hQ7KA74K_$@E6S$8Ye&X zXX1eEiJ7oIYMW10t6*!+EZ56V;eBo|>P#NB-(Qfj)};ywaP+w|+-80m=$* zaFuvO#^ZS>3IY-tsu*Swx9FgUSTICpbiQBl&B*ZZ4$tUg)GU>)H^e_L2pZvEIIGSq zrokm!_?v4pDbooo%NBOg&jTaPMI$+nyDNXhL$VOqj7w&uN7N)T`lk+;bVLyl*hi?B z{(vFFqq8Nq$>Ns@HDm!~Vbh!(^S#z!IT0r*kPDA4>0P+-B3l>*ytEY$T6(#AbsKPCi2hI>s+UgJ|z6!%0l*?Z~)@(s@m z<%%KeW!}XTM{drK1wVv1J(*$UGeWzxT(JcQzt*zSorCR5v5Zbj8pk))FWJ`^!VAj= zf$LDn+G&mWJkK3#zqY0UTFx`S{}=bMU%En!*8ZWugE94fjS7{UU)`=xq1{;alHff@ zp7z^z>fV-9k1p%IEdI*|GH=Yfs_b1PH)$PSK8aeUG3opHubY0CM5Dl;sVg&}ihkm5 z^OU$vh6<5osyd(MDOlB#O($8rZM3o1vnYI{si&GI39*IAV?BGOXXphr?{`VAySl2G zcLAT%PrI8*68x@SvQ5W;)j#$4rnD_@C|+PIckW)@QaiVjT%~Djd6zuhEHW$o(SAN} z0s3?SZi+YB|~|7ZAR``23E zyRhr_6-lfeFG{sCLKRl@xOZ|}dL^6=u0tVF%y*sP|8}|}q(Kcty6@L}$CDax)er9K zdBv2z(H`|`o7oVwc$)0a5M{`3_>({MUBbbsyFnqTAs@CKyg@x|CcNHG4HvG@g!r5mOLsJvR_QRes~)`l z><+?+&<8=pcG2mz2hGHA%UlJ4k{L@SI4;e2vbe z5qU4TPq`bZfU?!oWZ;DDx=Db_>XXqV$#sFf4v6e~sui+|EC@>tb}lsr zci^sTk*3VhP~bof(d)DvsB!my+VklJw%i!Fr6Tv*$0umgjPgp;XI3a4KE$5loYv(+ z&#FxA6mrtKD7NQQ-!{FPmcmHdcY)s*E^|88weUvIX1Pt?V#F;byI-59eTOq|U?7QbtQLcCKvUiTRI6M;RxrobPH-PPsg1Gmx?oO2qy_}Z;M<*EbcMm_fy4K^jw$)b?u=b(W+6(S$2@Fq&dws)R=WBa2 zU^%Nn z*)k6h=`=;;g6AOL(0Zcwp@$^yuFiJOD-GKrTv}zb?jt4@u}4b7)gsJNuh??rY@6SnO~X)e7M+-R^Gm z(mpAsb|bdiq*_I$sFT4=8136&#($^SGgMx#XqFNFP2sa=&+LI{Gf~CHhdT#8b*q@l z70w>e-7)D9`g%`oc3Wq9a0i&!6m*e`_`?pY=c zw;r!uVw7%$GuKS#m<3{Q~IjLY96tozjMQ-iTDlXe64>=fYkKgJQjrrRi9RQk*k zLZMyY*Lm9H^eD|{(IC3qqg*hByVKH~WSzO4<`xEi9&L*EA4MEerYX$$+NZ%CdG}Pk zzBeq<7C&-Y*T;UG3?mBJbKkd3$Mb$V$4QAiADf&g82`Izmy|2|rp{eF+s*%|Zpyta z?kgiJ%N3`qzS!;g{`<2Nhrz8ECeX%z1MpwsY|#6GaLf6>>-cUPx%YC0%WqO{H6T1)Xn{q~XK?ISu&>yt~Y!L0a5 z!1c|1DO`U>%2as99#lYGF(>GOw#AhCpMXvMG*FHV#+ZvheVaT_vM-1NVuEVu zV)_@Hdrs;<4pA*IxS8sU8&^%WExhJ#OzYaJYt_J5Aj^~bBg#*DlX4H;xQI3G Pa{qFmF2A&NL-cb~FK_viEdegDwiqsL=jUeD(_=Q`JQoilgbZtERli%^UB z`1r(jnw#44@hzO-g+fI97VTU0zz*a@hz@Je)zAf zUo6YV7qW1t=~nyD*S&Ag>$`kbm^ijzGc#6HX;nh(j#&K}R%7kK+Y481&hlJJ6^+v- z-C?IHht9ZWeA{yFu;0h;2VRD^-~5nmyH6xUNmAN**RP#V1&T!8KWPZ^$4bbSK96~o zNw91j|3=r6Z25@oF-zq=o1{dC^7VaJfN1EwB+lm%8dB=CHVK!jpJG&M?GKr zFO85PONNxZG^1U_)FdSL5BqXh4W%axX1BI=hD|?dDD_jS75ZV9_o{n-;HA@;e9za~ ztMbr%)>MA~0nsX3JUVX6#5b#TN_TB^A_5afC>gfeTm8&OD42^fl`?+HWLLeErObe3 z6U&$Zj;D`!UNsUmO12E4R}w81u4J*zX%rt*szir+uuv5|)so7;d!R5xS3-6C)%Wy# zAyiNzJk_+Z^nByEUJqtQMVeVX$>iTo-@KXX;Ol9Uk!*R`>floOlj226WJi&~SX^2B zz16&D!5i)#P!FUwdmOA;X(!h8%%0@it#PUUrS1nzhPqlrVA2TXbE}ems8LOMRYRNI zNz&yosT)oY<%0FAbLo4`sQkCt@dKifc6h#Ytnz~?g@M8iQA+JGRNro_o!BgElDUP` z->SU2)vk&V5P`0lWcnv~rzS9pl6_izbCt*&bb7qT7@?i%S*&YT{3p)*eiS~53c%VRAM89MB`==+P-905N|y*mV#Q3_u=TQ{^vouRE)BGqG=z>v|T zc+@rFs3SUXoOa_q+@QgU=Ba-Bl(#XtzQV=8b{m#S%{~-0eRhdgE#XV{X=P2VquLRH zRwEP}#~Ot?!aG^Aq1P;@DrlX4sDY9OLner5-s2_oRv~Kh)?nQ5a_Phs?J|5fS(W}$etDGjhkYAz&s@wzD}K`RhP#oyq)~S=(L`Nz{T*}_1Q_H?{wO$Sj*}Ni5Bg~XMgTo z)2jbbZDaw?{maire67>V_=7h`bfShFN}m$buB42V+*#1OFn=yZE#15|0@EM|dT0(} z^CI)3YWC^vc5~YWxmE5li&MSf^iJUFb~#OS=yT84hEHy3|N$xd{^B`Bv9ZvZQGIIh?qV2swqeN zxnPl>jK$ffpYu>SD5l$&Ve9G^G|TDE`hdA2CEXfQ6OYT2Tv|!KWy($-`@H?<0-Yd- z#LQ>|uX4*h_?Dv_sVvqm5-;RAEWRVbj%i6rl97=NUqxfhF#(S>4u=1oHn{>-&;SSz&`g*$2Hk~a`;f=CcI+bd{LdJRYtG8GKNxp6Z($0rwIRZVH9J_dSx>)g6 zg&xd7bOe3Ih{*QTwNSn6^L67rtp&}`%e}kw{ZQAjn^7P(Nw)vA^|o(gzG-B{~BA+DzxM?^>m+A6E@2U;SA4Q#vnM9xD>qdGJ}N z)3|J75V|OrPT<{5WIl^8Sg3i^)p+rfL#J-R)37^aD)Sy!2@hW#p@fSQaqhD!bgl2h zL6Qx2vYInl#I)`4*aFE8z*-5vJ--1*FsaRngS}o~5wqncN_rQ0*E-42a+#ya4?q2Z z!llEMuIet)F#%;en|^-l(bu6)X*XDA(!u)Aa?zY``+4_+Kq2OIyVGc5c>n7=c4990 z{3y0eWm(SVaFo0f`C34P_%KDLju3O$lzv1@B(UIBwVd(bX0)q*PA(m9_cx2xgHxd* z?~jeE*^6agGn{W;|6?qkeT3>E$&rNToe9gqv|um!+&p$6Pw1zyj>h^PFUaU2a~aJ7 zBS=Eyp2RFxmeqEugkz2Ts6fy1+br{7M?lo*92@Z}x(vYbF$O_k+*>4&kB}a1Kr@>N zAm$|-^mqjV9vAAkc1*|Z!2@JQ@*0`>fTa(W+Ln=n;8%cG4vMtt`mBm^>5WNd{eDY5 ze+{T})q+Uell&+fnMwmKraHsw5IkF6`BkWl@%J6jwV)UB!R=hdTJ#ocYHSG~m}F|& z>n&9bw40@sS511$9&;zMXLqv{An>~Bfbfbl;wPexN$n>Ide2Jco6%|tWIW3YWxUst zc~8p13Qm5yjoaB>{Pi12X8CThd3|yaZM*m3PufamRIgaRNy({IfQ~Vvnz0OjV0}b; zT~j2gQxfg!Xj|7*y)sEPm&La+Sg1P>9eMpOx?@+GNq+L&i zG|Bwb5F&fXQ@3e9-u>tbc%lD5!YVjdIo6`OShHty_{sK6dqGWdj?MGIiwTxvInP9h z?nZmfW;uyHnATXfdSUc_Q>sQz63VG*In>zjk#)5~U-8nxLg|FB21& z$J&h}f2w_)Z&puOykT90-H9mea7>|hsxSWtrGMAByaC&__q3v3NkEXL27}+Y$LrCv z(9Ro|ZgS6su!WsetDFz#R?fVZOi6k$hlf(#R=X<~4#zu@1_LEIDha07M@nWK{|SdF zzKS#!UzUXhmEU}TxECq;_KdYkJKL-LqaWN6drHtRir&;azwTz~2TU4dV^X5sJcK9o zd9dzxh00XDxwwmVAQ3B=st6|n)Oq5xoqAV&?ZA;(TjW`tN_ram+l~2hQTx>QzzMrf z7|-H@QcPxXKNV-U=~}3b$?n0+KCA8;&WA)SmGf-~d5D0bTe&5#Uo35xsiIVpRfb>X zI0{DjDppxQK1VbW1hN$rE2qeLLjM;`ybI(2P?Muz#K(ew4DM7Y~=v?l7lmBk;x;A@vLE^{}MP#t}>!$I)7U9s^5afEUn zO4NUrV=Z|is`!}rC?&*<#%y}OB#Xtlf;61M3>nQ+PttqY+RXEb%l>xJR4irZQ@EIZ zn+zU9eCF%+KN3V@Tf<^%blH$*wwYsmgfjUkO(J-L$zwfyZ88NczLPubjzKa%zY78X zw6+IxS4x`S70{h9l-mRoL~H)!0{;{^eib#Ie_ z@>>#?1GR}TFetF2KlADHR?d|ADn{Ci1zj^tNKCS{;je6*Vv0iR2&o3nN+4Q_6d*Xk z1;YAVx*EVm`8BsT@`QkL6@simL>iLC4_k6oqx1Yti&!4g;WCgEo z-PI!rr1QEuL#@ZFj2@Xw@8hB&+(`~=)h;T3C)=AUe&emBZfaq9?07} z+x)1f2@DND+59Z0_zUsuuxFFZC?A~r(d7UYebP_rn)n_X?c$}*HMp2|r{#&^_Ik}D zl!K%kn`M>cGPMXhSGTazga=x6gow4DE`l6DS;HSmKjPFGpAjHUU~g-02ny9ZOH9)f z6kB6Q<#!tpHHLEdHQTPfaP!3Dm1q-z{3t%EGIa2D<(eetm`A|kvCI#tQA-{Uj z9|{jYy$#@wwNrj`sIF-jG}Bj?|DzC47_x6S%28~dw5uiCE<)VRZJmT{xu;OjJM9R% z9da6Xop5GY&R4SK8&zn1O1$pClR0d=W2-KP%Y5p$%Rz-U0uZ`##f+D$+vbKV%PPxy zCYhisL=L}~+=FjY%QovMIR}NcnX;(($&8E{HDT_CAa(k@bixgjk(NH_v98=%Z)x`v z$U3;$BR{hyt<30MEB>%SuOBOImDlg6Z>yH$({;U9Kup`R&V4{M6S`MTfzJ-=TfsO` zD4C~ubmLy;xmt+%Ns^TGBR;~JX{*S+jB1w*x)vrbo#26YzvZ=6M$;od>TdO-QR+L> z!s__EkuJ)O(<_e#Q}Fi$^FHM7B#ET>XDRK-py81w)sq%A?Pd zn;8N|n5;kxsoAA>2O8j^g(E6bQwj|QS3kiCfxi6{0Gq43G_qK!CSp_8QWC)(i->7) zyc~iX3LV3=LRGc-Dni=}HCP9PM{$a|pn(wKILjGcbgBQq`-94@mUkaSd#CQI2{EO+ zoZF(@y5!^RvP=DWy!HTXkI$95=KZU^ZuwCr)_ToOV(B*ZvFv%QZMp1ueaB~2Za87d zmZ$2AqYWY>INN*f`TRw!OswEq%n+9iki){X&x$%t4I_s)po72-NBa}d(0V(kd zeNE!ocO~XZ7#7Lq`^6W%(CTnlrQYV zM1cqfJ>i)2bzH@Hhfb01QSJ6Bg=f|2I{mm^IK6D?i*0& zuQz;z+Gy$^C^lWcrqai4%IYkJRV_DWJJ6&}Gvg4`nA$yFbhwQ{RWoXMD%>TFHBT3L z0^RgC<4c~U8JAvmzh)?w$Sw!M@8Y0qacmFV%5TQEOC(T8Uin2RdF%HbJE=1J1{mOe z2ms@&DqeD12pcgbLPy0;G8rJ80WEL%)kbSajF}jmhS;|HpYcvTJ7i-@A94nb_)oY) zi>=|F0eP6v7UjH+z|&uP*y=TB4jR3H*nTA~`YJ+8eQT8G`I@$Q&Ce=z##^H);>JPe zk@aZTdx^R9U4LY+D(^zP2Q0f=gtA#j0b&k!dFDqQb_B^AsvWMmC48Nh)|GfMS8MZ# z)^4#IEYO)82j)vg$m=H0>98|<@Zu1o)HWIZY*x(PBuk}WN7FVZP+iyJFZ&Pm6hsM> zA!KCiBq%(anzCNZ{FR^gMc8HfXmkO8LnLtYDIa(1?oRtyv3Jl%_P{*_CGO(hlu#DOkwK+FIkUszxCXSL@{OEFQ#j~EXgFM zLFPE~I;b9`KHQ73Ext^AwVgTD>-3uOS9?!qom(*x=mo0iR+5x7=7qK1@Eqhh>R#x< zyvZ>+(p;ZTppKNBmJXhnxN*q`QAMkRacdf`8pB4|OCDSZycrrgYA4iF&_zf7AvQl@_PB$HC7_mp7v#+2oe-8oAs;rShSPaf3fIGzM=$1ve1^DUd8C6_wyPV&8>jFQ zBPO(hIXWEV=uA@1)jPeXu4$DS75EX4?;+R1gU#ho2hawtr{sapRZn>@nRhC}N;zVz z@zMv(f={hr5-j0%X}Z>@H!Jb(i6~8UpZmbI+vG)GXOI-$H$Vh&$18P+kfG2u!;kq< z3|}_{^PtfUiyw1;BvVV!|6=+w7T4Kep8%8(w8~PnYX|l@ppV+XP-jYVF6~dW6I-}` z(68~lt?YR{nEGV|foUr@_oIL}(GtCz9>;YgTdq$4?KynD6hi(#;hs#rVFhaKFcAp( zX>k99Qs>-1&6^c+9=@Ke&`voJ-#{DgMjUGE#Lv|L?}xlMg6^JV?pJQ5 zIc%q|kdmmJf;J`C$~Alk2EAO54@xK3HGv05KAvC>{+t9Pt$DCeF4FObeHFVgcYWQ& zKVZ<{0)ZNgXEWwtudTtlW?`1o;u51}%#y=MOM5NspxpZ2!HlYL{%SUB9)xyyn}LY? z03#E>T0)iEOvE0hOG(RAP9;uRA0%2tv}RhJ*fksFM0#|3ROVR6U3Yx>5&1p%D<32; zsp+~(POScC7Xaj}v!bCM&_Jz&<^iv+D3P6xXk69Rl|Ico!MYsRB3IxlT3uCIKZ)<6 z{eYiTtTH$X{Ll}wo*fKMjr34(5d*F|$^5TCcW2pAiOM|h)YO~)n#hR|dUq-ZwQ*e@ z8cBU#PXKZ8Enz1(l@T{llW?{FJI<{a2?R)L6+BulDy=z}^w66APoNtBNPqzQOLC^u zqsw;ohRJRc3DgjI7Aj*WRw#k=%MH%Se_ESj9)0LGsEPrbl%(p2TZQ(5H4@O4%%IO( z9e)4cQ0^d_dH#QcIc)ZfN*!VG`u3{)9?XR`wG6`gv(?Gx7*@$O^McE2MoE6L$)1bQ;)m_vqC!O~9 ze$YV_PsvPdv)s-4s(dyG{~nmkr%PDz%(l+EkT#3fzh~{i!zD{(`YMi(s{uT5T93td zPpQ*Uz+SAM5l}(@33!w}ZDc#KQeL2UBgxBq6XOZ6NzKk1JSD6II~O5#4fcY6(C%WE zlP&ZjKghqpx+ZDnizYDoNH3>(ko})n*Jv-ee?_H}>>)`G>g9?`8Knrc%Rgryg>4On z>E}t^iZdd4$uRl=-A^tvYwN^Va9b17|C6w?7Kk%)_qn+e|8AR%;}BtJZhgS+_{Ri# zK-l`YCuVlcZkN%#ARSDz7o_iPNrfxnQW-SA1r?gw%PM<86E!=SC&4^N!}j~^Rd8o6 zuX##X%*v6dG>_en6eUR zAS~8g7eT*s23mr*d}Ha02T$zuBYXd zCjfK@fTAK}4gk7Cu9e>;IgukJGGH%%yKFDE8tOSJo5jNhF29pnw)B#-*t}U4ps7F< z{tRf=MU1KSU>4Bqil1C?!j%(GbQXD>+k;mI*u9a>5ns80GM6zss6WPjk#Tvzq{4vV zT|UO9|{2JW&l(?_q0a^3|Kn|t;5Ipb?$Y9d)SCT zM9-!t&C<52-qphMC8TMyeKarkk1fnYc>~7~u%rTGu~f{TbwG@&C+$@`-o&!YgYu)k z#j+V0F@cSQMVnto&2scgwC?{W(1EB<_wCMwYx$G?NU~v65Ym0cxBDzyB=nBX+3h2g zr?=zT>WUHQ1926~pWZZ0ZvitWG4V=tS=Yi#{rnhLA!3@-pYZy(IsN*TCUqV=*>6{Y z60Uk&<&E(7#dU-UDaMErUMsmI-}!SXD@h|+aE7D{zZOJG&Ab~`)Bh&ygt8j z(>K%jm~zo16WE4inq4A03@*fYCMZ^Hx{i$MB$aC6n}6(SENy~71I^~M#fx9!_JFNL z{TA!2ImKTiCNGb^*MkvQC}gMalvPyUs$YV~+&?9<3ym;3ej7zAlP-sGZ9K|*XJ?Z5 z+QM_2dN)0-Yx*5#=mbGOn7W`!W&r0x+FEmje%R~nR{Wu*mE)b-VH3~xl;nI_!Mv1b z#?Fp5h#K;GC8E96pz@;V3u?47LQl7+nbCOkrK;I>+6JgywBDNR_cwJN#8yaOwW(J- z^NG&z?I!hN#1tzVy;H4KTHhV>ac5;_oM?IAXSN3qiq{rDkAxLBZkNeqEk7}2u{VBA z9%^mU7Lj^$+IjAXCf(O<;#ouKF|>X1Y*CkTS7=ekf2)th8O-{xJapzP*Ukf5I*ZBB%VJf` z1wR#wj%@4Px6T@5LAcqX#%{f__rd=Q;;jfie&fGGUbnqqNJ%U^45k`aa%@_Y*q*L# z=b#LJiQaG`jrlEs8I46kn#?$NaQXNK;8Up48g4;=9v&L`^?jf)@wU*r&7ef*k=QGe zW^t2oo(~HqnRV1Y6u7nh>!2chq2ZUZ&Yx0lePXbkx`hH2fgnc#3=Cz0_HZ>0R8?nt z)l0bi6DpVUg_gTTT+Vddw{@0dRhsDO?9+89Kk5{iR29iSU)1HIN!{5ik% zo-m|4H_~WPf7D#OFIgp_~b#8e=4tvwHIt1=~ky}-Jg@Q;$VYRTyXq5)4c;4 zwCzND)t!v>$`OG(0DTi+aPd;QvMe3ETZ?$yv02<7^pi&Bp1;u#=5e7$TOr~$RQ?Ct zr+~jzw3df^@l#fj|ABkN4at9S@2WFNkcWFPcS7b&RlLjzTBFs99fv##dEJ`B_rqGx zf4KqMP?Vu|_2#$BA28(TvQ69Rp7|{pUx@L)NS<(`{ak<{Q<`m;w>!OM`zkJfF}%DR z!$fTH&ZV;D3N;X<-hYiQz-EAQG-x*lC%sEATu9cjXQ%+6&@fZ-7C3buRa`#?lO-MkIWaMA@lfOmawSt)LsVJXGzm{6>3JGNl4=# zPdo%g4Zr;=w}iIkdTgtPC=+`M`Ebjw9lYc1-!( zz{fY+v9=-ZJ`7)_ZnMBI<{L;#A}P?qS!gmicO*JDE+XrJPaxX0AmI(NiZcO2@^IzW zE~kx)w4dz!VPGq^8ORwjokDK5fL^p($7bWqA6-T`@<|1VXE}KLnuvASIB5mzN?Lj_ zv_%HBHGn8OpkD(jigd$vV+P!`;ebs!D+kDM7SK&oEA>XtQt@=of54lu13nTfD1G%)JDJ9c^f)LW4ZItS4)V+C zcis`=ndgtW%Y(i3wXFg6HLxqwyMr-7xb$8NG8^_*L|?+##n^pK zml9hIF>)^QE(e+P+u|D=S0Hv-RY+fJPL&9e?=$e!33oSZ@EkH$R5pT1s}~L>^#23s zUbI8RWL*VjX-+WgFqDPKqX&sSFY@0L3h)?ma?v@cTzClpx?yB+y)zR?iwX$_%=u9* z?jY&GXtWribgr)@96h(L2lJI^NlB|ws3mO3hApyxf*TMz1t`LITI2xO;j_b66>IVj zw;T8M+d-mrN&JK+cI*P&Nhb^?JWr->+6Ks04T-xF*{I(miO#PqnIKc0Zl97_nanXY<9AtN;YSPNf{nq~@l$9irT)@0KC?@BMY}7P# zfh_~ddXlMNPWvcSPq@b2IcaSub(eA`6(|lI5kzU4v^ha~!=6xPFh9J@97$_zQLjS0 z!HRb156Jkz0$d+U7~L;!9FNLN=1m_^fIdliEAA(a`Q3cKDT}qC=2{kOlt)Ej7x0z_ z0<4p;ixpae`l+a}vInzY7iQ6ipoKD~?p@B4d+e1T_4Wn=&0K{F!H0k%TcyJT3|>OI zYY8@O@yNhabjxr+Rt0AB~001ASQjv$}ccY?{YD zy`}$-ie?>zRp!vydp_WTtkcxm7D1nM0H-w=a_vq+Izdx*f@nF|)N(9#p>?3DIcYmMcSpDrP zOy(B}+qTF620 z%oa~slR++=m|Iq|2Y|lejOPn(T(UEBLHP8F(5PjZ;kMxX1_G1)7l<9rA|OaOp)(Xs z%1meP5b9@DFT0e7EYZmGp62Gga}Pdv;m=`Gl5?tdeM2rG&=)fpOYa5{1S z8zmA7Is*vaH5Lr<`1HJa^z7xbV8(48K{F zxn5K29;|1;hMW!z8aS)jPrXw&fTR7N&<4O7d1TFz^BZe}<3!`>tbuJn&sBL*5lZ z|0xX(efJ2Z<(943k*>I;=&}!H4-p#<*`p{Ldw&h3DHy6B4GF{B&_)gvepw0T&oH@| zFnI0>h3v)xYzMJYxE2aQtg-a<0~pp8crP(%JlOj^d8CByzv9rD%hQ3`sL;rNJqVTn zK&%t|uZ>X9!20m6Zf#uN2ZMA30-D)z-bx7qPqch{!5hey0rh}THmZSlrWN-s!9+$!susLQ z%$cWR>Z>CW4-U9Z_tVwDbH@CT&EiB7vd6>Q_;>;iC~UdUp&YOX#gM7{!Kqaq?DiXe zt5-w!L{?g1okZ*t?B<28b`ZRsjOsLdus!|T%OJ59^(I&uOM+<*0(06hweiCI4R8{c zvItp<(yS|nsoQHB_`JF0Rl=}xNg;cz74NSDYK>su2oI<-tk`L&pFuUs)F&tQ9f#*iIRC*?_Zc*9rHYD&!4WTcu!V zb%Dg)tV0&hAb|z9Q}tjT29^jc)XLWr;HApyCYc{oUwe!9~?@CK|HR$GHKQ$T|e z4goTLE({AgeUxn8sxfRDFmmbdzb#cAdlmBhoc)Ck6U*JePGD5LcNVt=FxYzFIVkp; zzU5QaAv%@Ig73uvt6kw(EpMy59~>v=Pc>V3%754yl8~T>?9)nq@RWz<1fwhdX;^ml zfy2$Df-5KI=;~H}cp9qdt!W1r@m`Dl_2vEo1mvW*lkgHS>cuuGX~00_x)boG@dS6S zh68IFoSIFyJO_wrTW|aFAP+3LA|COnl0bk{WINUCdG)ba@sObz*%wP{3D*{6qon0I zu=-;pT$%K8dKZ!1CF}sOp{se`C>G~rt|k&FVwTnRd+0hx;dlx)5+4Y{@$^AAODOXq zA;VC___+nuJ%@XU3Vtj+V@|`DDfc=sTZb>hM9oy!qESY(NwLQZaaDM=p%|=BTk>K} z_p5pkL(N;N3x#xGH3}@1=c=T=dO1KNbLen0k)>K-^i%2wW3dJQ;6NbUVVRBs!};Qr z$2!}5k(FtADAX7ZWZ)a=%1)!2Nh{bYsY&mB1k;p{#IyuASkHUR2+98gGgW)=?R}?W zFP|8CEAxOfBw0{h||LC$mrrcj**IWciSkX9F z<}-EVXanFe3?(vbDTC794isxT6z1}KTUJ6FfD!8sC6$eNMj*)+D6o>h21!A>z{TuF zEIGc{IVRwFvb#6;VDPZt5BPUmRSWn`2RH&ev04Y}G8-96>emp{H1+|f>Np370u@{t*(sDk6#@KaaE@0EijCw@P9Q3>k7 zvRlyhVJWu=G4;5ztWUNEqMgk$Gf6K*7~?$Pi=p+fr5pf*>hw!9x27hyPamhKCW~1!B#!k zwps&RuK~W(vZ#3LuN8J;p03Ax{)y>%OOdY)9g;gWy&}`k`9D3m&Rws}V7)}_R0GP% z0J~WGiCU@F`CPhx(vRp|`f@1Bm4tNzM?%{XW+doMse^1Th(n%;=?0_w*>K{B3ZV{y z-h2bjX!vQqSuKIq!_VV4)uy1+9Vc6ExYzBbc6e1YbT>m z*Km%4XSYbL%HQoMc;jRDxet_tQ7iT{jHIFz=hoTfy&+dG{D^7pyuN`kC{FnnPfeq_`4$~(awyH!mdMo!|MY=v_U&a1^7JWzHjHkx`UY^=(m6xFx) zGv$k>Crx&lFg@t@Nz4{`%^IyHE!^03ymJuFphZR*IpWc`(pZYiarbbe2_L;XocF$& zj)K}1ozt4NnDzb24VS}Y=%~r21KV&X(;h?>Cjam^(w5@vT8cCHD5rU0OFTWC+!c4>vDNI0?x_)rsaAubWP+GSL{1j^O&n`!9BW7gTQE;`L+RA3 z@1MSHz?s*RY%;D*>u)I%(to#2eduI<&pi6iDYZ_ z9cl$pW86pa!J|~Mg1S1NshQ48zaru2&Z+}Gw_|2O?{K3c72oMcKo$(FI2E}YM*FQAEPEBvafL8_lx1qVnIe~ z6*4uGw37^+kkAlqNazGpd=_0p zs$6d zn3(l&qLUX-49M1PW=|XEi+{ z&A1$FXqRsV%A_;~Q34vka^k>5t!|V#894`?BQ18Q{ zmVKbK_@|GmjW`F$2f80k2q-W7v8gv?S{;kN#*K4W7TWlB;1iF>NJ(ndk1*HPV)idt zTS0z(JuFH)ZiE@<6;G&mI>`~{-0n5<3UX)N7pjP5g&p>G4&v;;;nYI@0f9yb#<3<` zyvK@f$IHC1xbtb7>6MNx4VFz$7Cyzuexy`fA*j2B(S@g|oI{mLLC4L@w9?+)l+!%? zHsE=ZUWwQuYVfVtxdVw)JByZ}Tdxz5Bl+m5N*@8!`A^N`>C$!^d}FU1{xAzd?}3%{r(?$=R%Cr&-q9hs_^6*r!GN z1rE8-U*IGrdUW|xc3AM|FG`Zf7mYF(eH0{)zomN7>jWs6SJk|cFzduwa#wkXd zvSdqZ7P^JpesVj$10H+wk?D1MqnA|2ccd;3_cX0w57kcM7WGg7;Oo|@0Yn6}!mYhs z<4FrixW5$J^eBTQ61YZ~8kLy#^x0DECjX0B=*odt{4GunP!;IpKGEHTx@a?n88bBM z5<%=xMb*Z&>=eS)&;Jt+Zo5tom^Kf>VYziWWr~kE))arGyEa;1VdmQY zUr$B*rN{bP?P3W(FA=7{&#%i9sKb0!Vq6k|;$EC30l;zK0BNkKH@`p!hb@-78Rl?# zRDCs;j%0Eqbg`3KLHd`1-I0tmPj5G7C|s?+rbinzT(v6n+&+OQ$Q?v~Xa?!uguYze^ z-=rd`R^N1~;5P&_;4$NZrue515e!!R*qZaiNwkNuxQC)0Px#V+2`>n2Z-=g~#Ta#O zi6)w9J-@$&bmhi#X`IaLDnMQ*%OIRli%b?&oC$vahQcufv}hH3!sx*lv|IZ!B0o?* zzLaB^4<9`_%G~Tpd&z@8yZ-_Hv`<#T-K6&sTe^WB^cC9_L_I`#>rT<2*i+v={tbT6 zn#Z?Gab`EUroKDBxiO84ev4QxvAKN;)Hv4i`HQG!r&`D#P4VZj$GZ*!-1G}ROL~30 zOQctU2IxG6+g{*wIqd{c&KlvsE-i@c#(y! zfhXSVu0|rha&1A>LWXbVdi||o^pOR1nA`9VOngdvRkzke1Ief9`l&NoO~=Q{+N~2} zNZfDDm(oE|>cbq+XRp&`xUUpxiieU*U_L_n`Ha)Eq&n>k!_Ur11ZVRKHTLQinvXmh z#{Ba7<*L=6c6U6Q>aTX;*J&-7+;Wa(y&Zp#TdfF;CSIpsbdmyur*ylBF@TyBK&1=y zQodz`*&X&=$|lD2KrInEw4^v4YwMd{SDHlRJm_yj!?IB%pipsD90vl3!{I7 zVCBg_lajtH%}(D(o8;^#5)$2h?)qtG1|9rx_k}*j{TRM9#qD^GI91~UYrqg_&XMQQ z!9QQ+v{#Ma6Itfq{2g#0`Ca$uz*^;HE8L8|beM>L^=< z1RLqVL0NPl8(uEnLrBagE)x&x3$*JIQUdp`GjlOz&&`b>C(rNY%j zrGluN-J+wbe+^3XhB`rU#Bv$aI3V=_zc*QEZr?^C&lJY%-BDqeQo=6pxgFN}NC@is z0=a*gV2f#D?3}uTN4R1z&$!U-3)&#r)dpMM#iU z_(zy~Uw&D6$UVndY`my#@l(tuNU#P=%qoXE%SU^Ip<@`jk-VhoQ_X0N--j~=Ozi9} z5gD984yOk-UO*+aSFNbSs2y}8IzS3-E$aso{bjjM>!Z5;!qks%Z5YvI%g?cl>zfV% zPRqy6)jOKnXSp9A{Oc9wYD-esVSnceAA>2C8zD~5EbBQyA5($l3Vk4uO2>!}8)Y^NnK!}BJhF9=Wcq_Q~lWg*;{1f&NkESE#%Lp z_*e*#qc}Bq=s_hC;RPv5cRxRnl3Kp&^o>alMPiCZcw9gE|A=?NKajevHSym%!c>VR z=>LT1I?SrpR_^?>mxig6CqM?7?Qp|4D#6mxo$8?Zz`c38D!53nK@(e_^74QlmbGI?aSM zd>wZR!fk4iQQ~s9*dqFl^$5+MH;G&Efl{5zqRn(+Of> zElB34gD~ufO_SZl?F68JCS3M?LLOjAu!9~4^gh6U6}$9m82t~{{lqcGzj47%DzN;> zn=K|JFF_N0!3r#8pCr`@A@?3_s@SnxK>EZs1L<3u6xJFv%3SzN;+=1R1W+Trl27+E zfH)XES?NhzVpR`%$JSry#HC-~76p{6ANzFFC3damZ|UNnMQ6=PU*hhtz?$}63gn#5 zz!k#Dmzf(FCteP#d(poBn8Dw!$S<3Bo&LHORC56LG-Gir;iq4_ibOOFCw|l?ZBUeS z9QFeaIyLb6t%>@OuFwb*ME5MZ%e>3%nEVLiB{W(%n{9@Kkm;_b!yzvbdepG5ZoAt`M#-4n#w+poNcdROjY4o_YVn(R#`Ogqe| z0Jq+|DoIo8I5Zey4~66qqXY`YD8@->V~~DPk5`2raS9YiAy09n_o;6@cAZ&Y@u}mq zwh5LNHl6Z;GI9_>|2j&Z0BBYab!Cx|b&AgJjM894>=t;ubx;eEyxH7&rjHTIz3X47 z<lKH}=7 ziM7D9$mT&pxsMW$zQ%Z)kGEHGIo=MSMXg7|<#12J)V_HL^-z8mCHIGRu7bo5kTAg? z{;LZhI1&g!EQq>&>krQP==txc=-*E*xFuAkb>2NS#A1V|?wJ!6pPv-Uh1Y2{RY?^I zp==Ov0^+@2qYU_lhSXKSCopW%IyCAmZ=4n&5-JR1!lFi$Hh%XzIck*#0tLIrjZxa) z_4d)y7B#@}v8YpRBRZA7Z{aN5hapIp2}t*v_oN8!Av{QThrW0g6}HBV4=b2#v(KKy^(-M0 zT%Vo>FGGD&jNI=o3W@elfg6Lgw3lbV3Sin@n>O?`#n=5-P!s$nc#p9Sy3?<|E1Af= z*vM(knNzr>DB*u#94j6aH+!TckB4y$mVsI59?)>Xu`E+OPWDr?Q%CeSE~_#i5?C-U zxgiobJ)YNo5*OrdT@a;zA*QD(h0E>goBqk|TF9L%jf0LWW6_kp!gHP2Q}8ALj#IR^ z&P$9drl27Q*g?n%+7$*m7AGoxq(DPq56omCNgrD_Z))dngAQu?)Ne9>Uk%(0&>{vK zq4OQoJL4!QE0RQZwUSV(Y;_sOc+hSyL1@qGdvDR_ob-WdUYf%?UcA9%d9(ZNPixuG zf+#pcSZn3GLx|P)fzlXEB-nN|Tzhj51jf&Kr=V4PH2AuyZ9KcV@mH3drbU+le6#-= zd~pnsOHkKZEuAq1GGJ*C%yd^z(GtKmIQbFyZbelttU{!aE9z(IA&9>R0uubae+eD9 z*9+{j{Zd!MhD3JV-T)?^(}`!k-35n3mK5JGCs+Ez(g8HPp24;hAE{V>VV2WRhzVQuv@D^(Esw*LI& z{sTQ4=UAg(azvILP>Bb93%d57I0uKipG>^R8u$zxMnHF?2J|7rDOyN)gDnngc)m>Q z{y8V*{W(Ax-T+E~(91~OvWR*U$=(79UgGUi*wa@C`Pt5;@=IK{SM-BDxq_YUlF-&m z8MUH>Gr-l+wi*5LQ~N?<+8;mfE7Fdkjc{*Pqs7Vp!!`>1Ul59Zfs%+F?YE03)SWJ~ zfB<|D`ar?h&6isBFrE#L>_@J#*Qe}3D|&?ZM)HHV7LofG0q96U*Cq8aPI3XSh5Xh` zbe4X9Ylh(!!gR;vf56?4$$y8tzYuX$9P?SWyCTj>OzuDuJOR4o(dju-C(R!JDni7% z-ZQ^W@5RQjI=GSwyt6o#Q#@2)B=Ap#|eu_qgs(M_FOJ@$-{DZ?h(GCo?`!ZeLV7=oTi-`bde8s0=*O zV0l}7ew`(S_4cvIGHTs3fT@dESI*v|{UAPe#Ut(}*gF0 ztd)BzD#j^a9z1zW^TfZoFliG@xHi8MDCG{2ZNTS}$VYc%C`objyAHw?6>t@7 zM$YDM;SFwmM}$o9Byv20Qp>6QC`t(8x-OCVtzlCL9pR%^MM7V;l5P$qYFC_C?4Eka zAHb^u5O|$2?xcj~R@~Ja%})Mne>ZyIFNH;ox{7-R)okFi2S}F*s9ZcEIKkQ;U9FI) z30}ctry4oU{Wriv`(Y%UDxSxUM=L`$@55z=hH{V^d88lc!mid z1WOydyb7{Q{iKRl!cdu?2yg|PJLjF0H^meRrNUI>@~md_hz@wYTqOXfOX@pP(@r#; zxOp6bxnv&9b+kqs7}wB|lDpvq)Ou@Qp?~LuY1GbK1FzTP;BMbG z-%P?sS&3ivIDJrPSJcF~+`2MvLXZ+k$VT%41vrg%q6ZL?Dv z0^RqxDEC14F~TqoG4hit}0@{?G#L>a}DW{t93& z5WyC5nJNB@D-Zx=bTQ;{Fr^1kGzaezAh>$At-hIItvCfb3G@<|$AM_p8oZW)(+Y~2 zqE^5Fg$F7d0pkvZSc^%sH&?reotwnXrad}G`gQ=pHzTcz6B3o@T}Vyyp|37z*->Y? zKLqJ&*p34dI;|4VMoKn-;L>g(f15*zM+u%9&-0+J0bvs~n=nNx>?6MtN36io+|^_V zNi?3vHSHD$mJjV%wd6XzAP>kO&rky5%@-_N>BG*n$(U~II|IH=OfO|x;6`VR*1=sr zNKYm?=>$4-o{{Z~sB2zo2i=3fawipVldD>s_FN1Pephf9u=(HU216EKAhw4{AKwB) z799(FbJodVn&_SyrTIIsFufUsm<&9MI^ni*2KMTK;D1-En3|Rbl77D11)9gmrUfI+ zZXS(G4{&Eu>o(Rmtqd+_+;+bIm+OeG#*Vphfvuv=NCS|~*$;ffx8U%mXNNh^UxQ|p zYK|^D4a1hO8)$jW^~k&i@u~F=#IeE(z?wiv+}*DaD^Cs;TrNeCkm-aq()#uVDcxAc z81vKQ?2K4iqkdKzJNT6JO$&@Uyc$}b3C-;BCcprTTYLJB*amUrsW&IIf`mG;7Aa>$ z6jVC8r+mAkMV3hzWEcjYh~+Z5urXkACoUOPPjbMYV+3uQ7KP6G{wKn=gEbx`wM=e~ zVQDdRHUn|uA`8-%i>DrD#H^gD(=LcQa3M*-m3d!N%U4fpm$O*c4VZhJ8DRzr(^s68 z1&sV0+G&qibfF7%TIHfyXH0(ML5w)nYcK)@-@k#03-qCvkzh|CB#w3eofjbP`;A@+ zg%dHLiKs3Jy4A~R{z+GaCUeqH!R`a~<$r-Ty9yurGO%iLhzK2JOCc`x)?XX8#KEF=r;9kMjH!!Y=Pld@=3W&LVqDP^HwTJ3CoSU@{Y+)106^3m<1byGo zmPw!pN{2m9d>7YgZ8BXJpr`feixMMX#d?#zp~!9cJb4fzmhfica7)7b@h1__ zCI`lrRs~`n>O&@yJ(Mx9UbzEVm>Q~pVoe1O=}>q{k_**bMb)Ji%|b>I@QrFVGL@_J zW!Fw}eCI(O9!1KaHf;V8Y2Fx?Uz955-m%4q>DDJYwkcfocmMOxLK{_9z3L_tR_@{2 zaFd!L3$+Iy)r!?(PP>JTt&3O!vnLT4ByEm01nK^;0BM57U-Fa4w{|C{1q1I$h?^6- zKvn!!4}O{_3jxzYG@0=~#OZ%!YggAHY6YYv|1KomaDx*QwD7Zr;l8(v4Zv>_Ys7q; zZ$=k$uSl8JK0CrhTsV=yo(n6Way|NvSRo!O86U^mV2allr#^l-5dvspQsU?@Irbd$ z5dnB+De4s<8ZtKCeQo+3(jxvbewf@w_W1=3;=W-lOH>tGbA(z1BZo6I(-Ss<>^o0IiO0eML9kqIN+LU6Ucn9{_qvc~(!hIw34U{ssC%ldKcp$o$%cky z{Q1$B+Ys0C4*7Tjt+Ejleps%Dq5$?PBCnrrZd?L`*QF--$I|qbb&T;J;LsqmMV^s@ z*sQw%$}0cA%C0;v#nLwF5z+2op zNdtvJBj1QrEu12^&=DjHjhnS|BIn{`CA}0Bs!164Or=XT*7F2u7SaX7M$@jxC6A`b z@H}nxzMfdTE%uf7=TJiZD7Npq%^09r#<(sV+`%#~6dk;N*DNC)I{ON(au3ZYjggdsTgR!x-53 zj{pL5+GKFvfMcEZ0OlTpX%&MtQa`^Ws7xppY+7VpC+eewP1zUwqksIG7gq+HsIC{J z-@x}Nh%2L0nqqd`Shj*MC@HTt+A9w*V$P3~yDH42)JEy&ozl*H(1tK?arVvb7xWc_ z$3baF%KdX6f|y7O!{u z9JCEWYHUgvDluHu*BQDXX}i_+$4s7H>sVFR{(i#hjO5rc^#QBo&z$(LC%U7YGhm;5 zDeLv%Wu$g)6thDpljtcf3ca`St zzwWFTWWdNOV<51~%vInUyvP-^-Br{f$a9Q^`?+@xw7A zy2pYnOk<#fyVX`Er8F&8&2c$e=%snQBRD+YiXo0UnM2n|&5R|v6zv!WM)<3mPG|ok znK{qR!@c1mx67VOo$4M2tRk8np<9dBSueiezfR2Px{eM4!pRS>Jnp#8^5dUvRgaQq z%=uanK?HNOH_`6btHacqKW8uUK&vRF7ViE~d~=ajp`Cbs?h$(MuUN#V&eHclQy+C>8l`96`mvK^c*?19d(=U7n}LI);kGMM{ z)(el-opM9kmdVnqbKL=|Q)P<_rXs<`zIXLH-nj!*_5+@7ImP3`=;e;fHT9^r3&{Dz zB||I>XsMHJYF!);Cq=XkzH`9q;7dU)D>+(`I56(*t|Jo?>QtFFWP@O;Ata;Z=^GlJnQJ6%ox* z93;GQCH8F)-;BxreU!8{bnKM6PT^YH_soIWGF=6Vu&E$u6Ev&H zZ^ggVmNZi3h8kID8i{WsG%IE30|*n_WK$Ek>m91f`p^VEw zbGD&J^-^(?Ikwad{Ump2G{3e`Z;T>L=K1YvD-O*6d7fTf0+Mz%q@pqFy`_X9Oh^g0 z*!~9NF1fIr9W|}uuL;CN?@H15M`KRjE)}n}&2}EKbV5VGs(_KxD&AZPj^nCo*J&u- zxfhPkgP_(V1%2n$Ln6B-gW}O8e?dM-2&d+rhRX8^2kj+JoNDOxiS zZ9fNH6RFGB{v9h5cE4Dy@$6?7-XoH&uR3-T=^xw6gUemsxOdOz@S!v_H;Hh1}Pm`4hcue_K{N688vHC{OBmkc?ciDi zu!}{i_S21*B_UJH zC8B6+_;y0-jgt=GT)c0UBU^r=a8aC3z4MoR(>yR0-OUz@+GLb%H~0n-a^!f4^Nb^+ zx*Jr1+ZcrT!%>1f9#SBk#TiOMSYF_-XhoQLW58Bau^;)41qd-DZL&3GS{I}6Q(pEn z_N}sOfZc=fpcWW5~t-I3IDJ ze3gZC9lboLU6wW?feRBt;omK*Dho)}V+t2$L2d+N0x7#oqyn`#L_Tvi|Mloz#D*7p z63}Ecl8kySusO`V!o4=RK47$j@dwVRQL$(m4+A_jCdB8x`kD+{qJ)3>tQ6#U2`+0P(XT2yU{vgeW{uS zcO%P>7lL+}Cw%=`O%Znt*&Wu%W=SPP|IHSpQsI>84c-02IEI&IyPK?XEk2SZ+-s^y zQ!_}q&n}Vc`?Q`WVGKqAr8Ex#Q0qVR8#vaXHmK@8=^nFBeu!dJ8Wf|7s{=|7dKBw; zhJqbF*W4;{%YsJ^kRjH{;_rfd`$a=(cTHWsMw%N^&8mC2FHa*%KJ7@#2iJJK@!8b% zl#ybp+MOykJ#V<$0{ahhiety2BTIN$l(aK1SnyIXK*IRy=M9`zF%Xws>*F&0h8co& z;EJ4WhEtpplhHrn2_rlZ;-^kQ@(?SJvJS06hvs?cSkXmtLxj6_ZnLHtrxCO_6aW*$ zrb6QEcl1Y?T{izM3(3F@ZKm)HoSJa7F_BIo>4l@USW%c-*pjFCluzKpbI;n0(XMM* z39;TT17rLmUBwHb8c5|g!WP}HPHzdda;9%TQ{{IyXd*86QvhKH3Vd$ZWTh z)?Cg(biKUw0jsWiyALV$VXmrw+jfaoYuL~AlmoiJmq*KUz);QB*$2|Ng19)n-EOelgnwm> zxaP0!?tn8#J?O_#ZL&^#2_p$*UL+cD>d6@SW1ljHNO!enI2qPN z0nNOh;=Qg})H;h3(2>oZoo?Ti<&(gTl&%7APvzc$*{$S_PuqjH?rdt!_hXwdXi}8oGH!{H`*P;ktXi zjX~~8{(@?gOq)4>#*g|i35Iz;b1uq{L_U3D%2FO}Ztq)F94^ty^r~dg;J~ zo(;!g{xzQ|XNPUlL|f$WroYMN0Y&EUqd~1@{)ODK{5L)==t$9eIDJtH(10V>eh_@^ILB77)RH|~axS%D`^xjoSPn+R;Jma|I z+y8B%OB5QjN~t@jV*1?}Dy&3VYx?f$)E&*~c;!So?*n6`lrv;ek6X(wT*FUF;rx~3 z4RP|ny})A+&n<**NQ&v}mm&uybWtBq##S7=@$fyAZ>{EAax#khKQ9dPSwGy#A0=?% ze#gFUXoh6vzDyzG}2HZkejvs%WK*Ju?w5pc^n~bp~KN&txGYpTD3X9w_SQ z)C40o^#-O+)os6YOn9Rs=-vD&!ZSeq9Uem9&}kJ<>Y4lG6Qw#^3q`8^>w5GNZ0JSF zk0~=tOrG%X2qLtB>pQf^{00+(7{d*}NNMNje?h_xq>o-qTdtX_Fr7%lki8+{WKPAe zYumFe-PJ~;%?6?ileD1T0&)yr%HoviCKtPh6gUuN9qv;0j;#f;4{X`Cwlr9vRi6_rLQzg z7<+QMXTFO5$kdqb zn_(#TcDi}`i|IS77r*UGN~tO(qU^Px*r4vyKPzXqZexM2#eQRrS1FSXr0*p0m!h9L zE5VG|WXy2V`j3e3r$Z{_n}IOO-Qu{3md^EpG3B~;Pn}- zD4Rkj*8A1JKR^6%b8mH1*^|~UTP=Mq-|U|$teSP{D%l*VUirpK9P4w`e-8GkW;n9V zgqxQk7j-8S8zV;%rcB&A>K!$bRUQ_+zM#$N8C7c#(Gpmjm^HdNZI%v$lHshQgtjff zR+a1;|Ne#n2r^E%^_^B2oHWfd!d+ zr_5malIUB)UzcmV65C7XNI=s^>WHc#5Z_Cb?|VO?W;5UvAm|Mt%M1(ekQA|H5;%Ac z;w3l0>9cMI$>5!T1DvKZ-a9smUeMcl{#rXf!$=G7g-RcCLY6 zQHQ(s>unc(rK)v9arPUpVI$~0;=AtE4W!wB= z-6c(3+?Y^gUg*aegrHS@uY5htfElQxBrA6JtF<<3`5fK!vJjv_!#>h7g#7*^UJ2$8 zxW(veh!CXmI_4alR-uKW6?UoQS0BJV64MWWL?|v4g*&Ib4e<3nzL*rTH9xgCRW#7;`c{gJz2F`0&>} zz@|>o)9F$2c?QfWs0~H1LmSvvgS}B!433eD#xsj~ZXG+J#e*kU;4IONcJn%>#i(5l znuAMn_clWr%a(_^reGLphNW=_%v#fM8wes>m2U#L-5D|k2x%}4_uel*p;g-@0Sf@z&Bti?*`6qGa`@o$`S zLU-N$j5KsF7-nlmIXhV7Y`3yXtdVm5yDRn+otrm#_2EB%+2RKUzK)fDN@K2g9jj;j zN$amrxOk`%3O`U#*sHrHgL?_qDBIlIGf9!T3t+ z;~pRj3nsn@hw&gJ6d`KEl)O{kLM6%QLI*97qbcnY2#m@5yfQK zZG5l|VkHuZ`e|A3*~+P1hwCqZhvmCdP~1>St0$ z`d9=Hw*u@DHa3wa`}$*!{?9^yhYp;@S_CU7PzFFQkeGfj{_$@2O4N5eXqB29kQi)q_``d>_nqiiU=ngHz@Udt=Eh2f$y z#>{5GdkLeI0qs=EU)TQ7*nzX{z=heokaVm}^QPdIRJA5L`Zr^1WhED!m94h!h0u(b?y0^aM_75uZerRZT;>R)gpK^bgJ7=MD JmgB13{|!4YKRf^c From 6b3a178f2a74c572ec2e90790f53291228ec4dfb Mon Sep 17 00:00:00 2001 From: Stypox Date: Tue, 25 Apr 2023 18:06:51 +0200 Subject: [PATCH 063/172] Show snackbar with feed loading errors --- .../schabi/newpipe/local/feed/FeedFragment.kt | 42 ++++++++++++------- .../schabi/newpipe/local/feed/FeedState.kt | 4 +- .../newpipe/local/feed/FeedViewModel.kt | 2 +- 3 files changed, 29 insertions(+), 19 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/local/feed/FeedFragment.kt b/app/src/main/java/org/schabi/newpipe/local/feed/FeedFragment.kt index ea9a3f36e..4f153dcf8 100644 --- a/app/src/main/java/org/schabi/newpipe/local/feed/FeedFragment.kt +++ b/app/src/main/java/org/schabi/newpipe/local/feed/FeedFragment.kt @@ -60,6 +60,7 @@ import org.schabi.newpipe.database.feed.model.FeedGroupEntity import org.schabi.newpipe.database.subscription.SubscriptionEntity import org.schabi.newpipe.databinding.FragmentFeedBinding import org.schabi.newpipe.error.ErrorInfo +import org.schabi.newpipe.error.ErrorUtil import org.schabi.newpipe.error.UserAction import org.schabi.newpipe.extractor.exceptions.AccountTerminatedException import org.schabi.newpipe.extractor.exceptions.ContentNotAvailableException @@ -453,24 +454,33 @@ class FeedFragment : BaseStateFragment() { if (t is FeedLoadService.RequestException && t.cause is ContentNotAvailableException ) { - Single.fromCallable { - NewPipeDatabase.getInstance(requireContext()).subscriptionDAO() - .getSubscription(t.subscriptionId) - }.subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe( - { subscriptionEntity -> - handleFeedNotAvailable( - subscriptionEntity, - t.cause, - errors.subList(i + 1, errors.size) - ) - }, - { throwable -> Log.e(TAG, "Unable to process", throwable) } - ) - return // this will be called on the remaining errors by handleFeedNotAvailable() + disposables.add( + Single.fromCallable { + NewPipeDatabase.getInstance(requireContext()).subscriptionDAO() + .getSubscription(t.subscriptionId) + } + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe( + { subscriptionEntity -> + handleFeedNotAvailable( + subscriptionEntity, + t.cause, + errors.subList(i + 1, errors.size) + ) + }, + { throwable -> Log.e(TAG, "Unable to process", throwable) } + ) + ) + // this will be called on the remaining errors by handleFeedNotAvailable() + return@handleItemsErrors } } + + if (errors.isNotEmpty()) { + // if no error was a ContentNotAvailableException, show a general error snackbar + ErrorUtil.showSnackbar(this, ErrorInfo(errors, UserAction.REQUESTED_FEED, "")) + } } private fun handleFeedNotAvailable( diff --git a/app/src/main/java/org/schabi/newpipe/local/feed/FeedState.kt b/app/src/main/java/org/schabi/newpipe/local/feed/FeedState.kt index 27613e83e..665ebbe43 100644 --- a/app/src/main/java/org/schabi/newpipe/local/feed/FeedState.kt +++ b/app/src/main/java/org/schabi/newpipe/local/feed/FeedState.kt @@ -13,9 +13,9 @@ sealed class FeedState { data class LoadedState( val items: List, - val oldestUpdate: OffsetDateTime? = null, + val oldestUpdate: OffsetDateTime?, val notLoadedCount: Long, - val itemsErrors: List = emptyList() + val itemsErrors: List ) : FeedState() data class ErrorState( diff --git a/app/src/main/java/org/schabi/newpipe/local/feed/FeedViewModel.kt b/app/src/main/java/org/schabi/newpipe/local/feed/FeedViewModel.kt index 58f9e9edc..728570b17 100644 --- a/app/src/main/java/org/schabi/newpipe/local/feed/FeedViewModel.kt +++ b/app/src/main/java/org/schabi/newpipe/local/feed/FeedViewModel.kt @@ -86,7 +86,7 @@ class FeedViewModel( .subscribe { (event, listFromDB, notLoadedCount, oldestUpdate) -> mutableStateLiveData.postValue( when (event) { - is IdleEvent -> FeedState.LoadedState(listFromDB.map { e -> StreamItem(e) }, oldestUpdate, notLoadedCount) + is IdleEvent -> FeedState.LoadedState(listFromDB.map { e -> StreamItem(e) }, oldestUpdate, notLoadedCount, listOf()) is ProgressEvent -> FeedState.ProgressState(event.currentProgress, event.maxProgress, event.progressMessage) is SuccessResultEvent -> FeedState.LoadedState(listFromDB.map { e -> StreamItem(e) }, oldestUpdate, notLoadedCount, event.itemsErrors) is ErrorResultEvent -> FeedState.ErrorState(event.error) From 1519527356936a1ebf4ac58154bc2e897139c519 Mon Sep 17 00:00:00 2001 From: Stypox Date: Tue, 25 Apr 2023 19:01:02 +0200 Subject: [PATCH 064/172] Fix loading feed when a channel tab is empty --- .../org/schabi/newpipe/local/feed/service/FeedLoadManager.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/schabi/newpipe/local/feed/service/FeedLoadManager.kt b/app/src/main/java/org/schabi/newpipe/local/feed/service/FeedLoadManager.kt index b55549704..c9593e537 100644 --- a/app/src/main/java/org/schabi/newpipe/local/feed/service/FeedLoadManager.kt +++ b/app/src/main/java/org/schabi/newpipe/local/feed/service/FeedLoadManager.kt @@ -165,7 +165,9 @@ class FeedLoadManager(private val context: Context) { } .flatMap { (channelTabInfo, linkHandler) -> errors.addAll(channelTabInfo.errors) - if (channelTabInfo.relatedItems.isEmpty()) { + if (channelTabInfo.relatedItems.isEmpty() && + channelTabInfo.nextPage != null + ) { val infoItemsPage = getMoreChannelTabItems( subscriptionEntity.serviceId, linkHandler, channelTabInfo.nextPage From 6f23b56b06275d5d85721ab72ad7b47306c58f84 Mon Sep 17 00:00:00 2001 From: Stypox Date: Tue, 25 Apr 2023 19:11:30 +0200 Subject: [PATCH 065/172] Use consistent name for livestreams tab in settings keys --- app/src/main/res/values/settings_keys.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/values/settings_keys.xml b/app/src/main/res/values/settings_keys.xml index d9d8e60be..51abe14fb 100644 --- a/app/src/main/res/values/settings_keys.xml +++ b/app/src/main/res/values/settings_keys.xml @@ -278,7 +278,7 @@ show_channel_tabs_videos show_channel_tabs_tracks show_channel_tabs_shorts - show_channel_tabs_live + show_channel_tabs_livestreams show_channel_tabs_channels show_channel_tabs_playlists show_channel_tabs_albums @@ -376,7 +376,7 @@ fetch_channel_tabs_videos fetch_channel_tabs_tracks fetch_channel_tabs_shorts - fetch_channel_tabs_live + fetch_channel_tabs_livestreams @string/fetch_channel_tabs_videos @string/fetch_channel_tabs_tracks From 9e55014a133b7f77f65aadb456e33d5affd97dcf Mon Sep 17 00:00:00 2001 From: Stypox Date: Tue, 25 Apr 2023 19:18:34 +0200 Subject: [PATCH 066/172] Fix wrongly themed channel header Since it is embedded in the app bar and has red as background color, it should be themed in the same way as the toolbar. --- app/src/main/res/layout/fragment_channel.xml | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/app/src/main/res/layout/fragment_channel.xml b/app/src/main/res/layout/fragment_channel.xml index cd3e371c5..f557e3396 100644 --- a/app/src/main/res/layout/fragment_channel.xml +++ b/app/src/main/res/layout/fragment_channel.xml @@ -5,10 +5,13 @@ android:layout_width="match_parent" android:layout_height="match_parent"> + + app:strokeWidth="2dp" + app:tint="@null" /> Date: Wed, 2 Aug 2023 22:45:53 +0200 Subject: [PATCH 067/172] Update NewPipeExtractor and adapt imports --- app/build.gradle | 2 +- .../newpipe/fragments/list/channel/ChannelTabFragment.java | 2 +- .../schabi/newpipe/local/subscription/SubscriptionManager.kt | 2 +- .../local/subscription/services/SubscriptionsImportService.java | 2 +- .../schabi/newpipe/player/playqueue/ChannelTabPlayQueue.java | 2 +- app/src/main/java/org/schabi/newpipe/util/ChannelTabHelper.java | 2 +- app/src/main/java/org/schabi/newpipe/util/ExtractorHelper.java | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index d73cca424..051414ba0 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -197,7 +197,7 @@ dependencies { // name and the commit hash with the commit hash of the (pushed) commit you want to test // This works thanks to JitPack: https://jitpack.io/ implementation 'com.github.TeamNewPipe:nanojson:1d9e1aea9049fc9f85e68b43ba39fe7be1c1f751' - implementation 'com.github.Theta-Dev:NewPipeExtractor:2ad496fc2b932dd89009f3892462014cb231f6ca' + implementation 'com.github.TeamNewPipe:NewPipeExtractor:95a3cc0a173bba28c179f9f9503b1010ec6bff21' implementation 'com.github.TeamNewPipe:NoNonsense-FilePicker:5.0.0' /** Checkstyle **/ diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelTabFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelTabFragment.java index 86e429bea..6b2dd20bf 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelTabFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelTabFragment.java @@ -13,7 +13,7 @@ import org.schabi.newpipe.databinding.PlaylistControlBinding; import org.schabi.newpipe.error.UserAction; import org.schabi.newpipe.extractor.InfoItem; import org.schabi.newpipe.extractor.ListExtractor; -import org.schabi.newpipe.extractor.channel.ChannelTabInfo; +import org.schabi.newpipe.extractor.channel.tabs.ChannelTabInfo; import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler; import org.schabi.newpipe.extractor.stream.StreamInfoItem; import org.schabi.newpipe.fragments.list.BaseListInfoFragment; diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionManager.kt b/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionManager.kt index 9a8b53e90..3c11ce152 100644 --- a/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionManager.kt +++ b/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionManager.kt @@ -14,7 +14,7 @@ import org.schabi.newpipe.database.subscription.SubscriptionDAO import org.schabi.newpipe.database.subscription.SubscriptionEntity import org.schabi.newpipe.extractor.Info import org.schabi.newpipe.extractor.channel.ChannelInfo -import org.schabi.newpipe.extractor.channel.ChannelTabInfo +import org.schabi.newpipe.extractor.channel.tabs.ChannelTabInfo import org.schabi.newpipe.extractor.feed.FeedInfo import org.schabi.newpipe.extractor.stream.StreamInfoItem import org.schabi.newpipe.local.feed.FeedDatabaseManager diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/services/SubscriptionsImportService.java b/app/src/main/java/org/schabi/newpipe/local/subscription/services/SubscriptionsImportService.java index 66164807d..d624e1038 100644 --- a/app/src/main/java/org/schabi/newpipe/local/subscription/services/SubscriptionsImportService.java +++ b/app/src/main/java/org/schabi/newpipe/local/subscription/services/SubscriptionsImportService.java @@ -39,7 +39,7 @@ import org.schabi.newpipe.R; import org.schabi.newpipe.database.subscription.SubscriptionEntity; import org.schabi.newpipe.extractor.NewPipe; import org.schabi.newpipe.extractor.channel.ChannelInfo; -import org.schabi.newpipe.extractor.channel.ChannelTabInfo; +import org.schabi.newpipe.extractor.channel.tabs.ChannelTabInfo; import org.schabi.newpipe.extractor.subscription.SubscriptionItem; import org.schabi.newpipe.ktx.ExceptionUtils; import org.schabi.newpipe.streams.io.SharpInputStream; diff --git a/app/src/main/java/org/schabi/newpipe/player/playqueue/ChannelTabPlayQueue.java b/app/src/main/java/org/schabi/newpipe/player/playqueue/ChannelTabPlayQueue.java index e422a5c52..a9eb2a19c 100644 --- a/app/src/main/java/org/schabi/newpipe/player/playqueue/ChannelTabPlayQueue.java +++ b/app/src/main/java/org/schabi/newpipe/player/playqueue/ChannelTabPlayQueue.java @@ -2,7 +2,7 @@ package org.schabi.newpipe.player.playqueue; import org.schabi.newpipe.extractor.Page; -import org.schabi.newpipe.extractor.channel.ChannelTabInfo; +import org.schabi.newpipe.extractor.channel.tabs.ChannelTabInfo; import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler; import org.schabi.newpipe.extractor.stream.StreamInfoItem; import org.schabi.newpipe.util.ExtractorHelper; diff --git a/app/src/main/java/org/schabi/newpipe/util/ChannelTabHelper.java b/app/src/main/java/org/schabi/newpipe/util/ChannelTabHelper.java index 5db438863..8e8d38490 100644 --- a/app/src/main/java/org/schabi/newpipe/util/ChannelTabHelper.java +++ b/app/src/main/java/org/schabi/newpipe/util/ChannelTabHelper.java @@ -6,7 +6,7 @@ import android.content.SharedPreferences; import androidx.annotation.StringRes; import org.schabi.newpipe.R; -import org.schabi.newpipe.extractor.linkhandler.ChannelTabs; +import org.schabi.newpipe.extractor.channel.tabs.ChannelTabs; import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler; import java.util.List; diff --git a/app/src/main/java/org/schabi/newpipe/util/ExtractorHelper.java b/app/src/main/java/org/schabi/newpipe/util/ExtractorHelper.java index 59a5df205..257a428fc 100644 --- a/app/src/main/java/org/schabi/newpipe/util/ExtractorHelper.java +++ b/app/src/main/java/org/schabi/newpipe/util/ExtractorHelper.java @@ -40,7 +40,7 @@ import org.schabi.newpipe.extractor.MetaInfo; import org.schabi.newpipe.extractor.NewPipe; import org.schabi.newpipe.extractor.Page; import org.schabi.newpipe.extractor.channel.ChannelInfo; -import org.schabi.newpipe.extractor.channel.ChannelTabInfo; +import org.schabi.newpipe.extractor.channel.tabs.ChannelTabInfo; import org.schabi.newpipe.extractor.comments.CommentsInfo; import org.schabi.newpipe.extractor.comments.CommentsInfoItem; import org.schabi.newpipe.extractor.kiosk.KioskInfo; From 5c7c38232347d90708ac740135d0130d82df9932 Mon Sep 17 00:00:00 2001 From: TobiGr Date: Tue, 22 Aug 2023 12:39:27 +0200 Subject: [PATCH 068/172] Add missing `@Override` annotations to setupMetadata() implementations --- .../org/schabi/newpipe/fragments/detail/DescriptionFragment.java | 1 + .../newpipe/fragments/list/channel/ChannelAboutFragment.java | 1 + 2 files changed, 2 insertions(+) diff --git a/app/src/main/java/org/schabi/newpipe/fragments/detail/DescriptionFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/detail/DescriptionFragment.java index ded4e907a..cb38d8416 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/detail/DescriptionFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/detail/DescriptionFragment.java @@ -73,6 +73,7 @@ public class DescriptionFragment extends BaseDescriptionFragment { return streamInfo.getTags(); } + @Override protected void setupMetadata(final LayoutInflater inflater, final LinearLayout layout) { if (streamInfo.getUploadDate() != null) { diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelAboutFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelAboutFragment.java index e78d5a922..4117533bd 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelAboutFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelAboutFragment.java @@ -80,6 +80,7 @@ public class ChannelAboutFragment extends BaseDescriptionFragment { return channelInfo.getTags(); } + @Override protected void setupMetadata(final LayoutInflater inflater, final LinearLayout layout) { final Context context = getContext(); From 6ab8716e695bf9595061570d5f3368d99cee1a42 Mon Sep 17 00:00:00 2001 From: TobiGr Date: Tue, 22 Aug 2023 12:37:02 +0200 Subject: [PATCH 069/172] Extract actual feed loading code into separate method Increase readability --- .../local/feed/service/FeedLoadManager.kt | 197 +++++++++--------- 1 file changed, 104 insertions(+), 93 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/local/feed/service/FeedLoadManager.kt b/app/src/main/java/org/schabi/newpipe/local/feed/service/FeedLoadManager.kt index c9593e537..b0969a769 100644 --- a/app/src/main/java/org/schabi/newpipe/local/feed/service/FeedLoadManager.kt +++ b/app/src/main/java/org/schabi/newpipe/local/feed/service/FeedLoadManager.kt @@ -1,6 +1,7 @@ package org.schabi.newpipe.local.feed.service import android.content.Context +import android.content.SharedPreferences import androidx.preference.PreferenceManager import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers import io.reactivex.rxjava3.core.Completable @@ -13,6 +14,7 @@ import io.reactivex.rxjava3.schedulers.Schedulers import org.schabi.newpipe.R import org.schabi.newpipe.database.feed.model.FeedGroupEntity import org.schabi.newpipe.database.subscription.NotificationMode +import org.schabi.newpipe.database.subscription.SubscriptionEntity import org.schabi.newpipe.extractor.Info import org.schabi.newpipe.extractor.NewPipe import org.schabi.newpipe.extractor.feed.FeedInfo @@ -108,99 +110,7 @@ class FeedLoadManager(private val context: Context) { .runOn(Schedulers.io(), PARALLEL_EXTRACTIONS * 2) .filter { !cancelSignal.get() } .map { subscriptionEntity -> - var error: Throwable? = null - val storeOriginalErrorAndRethrow = { e: Throwable -> - // keep original to prevent blockingGet() from wrapping it into RuntimeException - error = e - throw e - } - - try { - // check for and load new streams - // either by using the dedicated feed method or by getting the channel info - var originalInfo: Info? = null - var streams: List? = null - val errors = ArrayList() - - if (useFeedExtractor) { - NewPipe.getService(subscriptionEntity.serviceId) - .getFeedExtractor(subscriptionEntity.url) - ?.also { feedExtractor -> - // the user wants to use a feed extractor and there is one, use it - val feedInfo = FeedInfo.getInfo(feedExtractor) - errors.addAll(feedInfo.errors) - originalInfo = feedInfo - streams = feedInfo.relatedItems - } - } - - if (originalInfo == null) { - // use the normal channel tabs extractor if either the user wants it, or - // the current service does not have a dedicated feed extractor - - val channelInfo = getChannelInfo( - subscriptionEntity.serviceId, - subscriptionEntity.url, true - ) - .onErrorReturn(storeOriginalErrorAndRethrow) - .blockingGet() - errors.addAll(channelInfo.errors) - originalInfo = channelInfo - - streams = channelInfo.tabs - .filter { tab -> - ChannelTabHelper.fetchFeedChannelTab( - context, - defaultSharedPreferences, - tab - ) - } - .map { - Pair( - getChannelTab(subscriptionEntity.serviceId, it, true) - .onErrorReturn(storeOriginalErrorAndRethrow) - .blockingGet(), - it - ) - } - .flatMap { (channelTabInfo, linkHandler) -> - errors.addAll(channelTabInfo.errors) - if (channelTabInfo.relatedItems.isEmpty() && - channelTabInfo.nextPage != null - ) { - val infoItemsPage = getMoreChannelTabItems( - subscriptionEntity.serviceId, - linkHandler, channelTabInfo.nextPage - ) - .blockingGet() - - errors.addAll(infoItemsPage.errors) - return@flatMap infoItemsPage.items - } else { - return@flatMap channelTabInfo.relatedItems - } - } - .filterIsInstance() - } - - return@map Notification.createOnNext( - FeedUpdateInfo( - subscriptionEntity, - originalInfo!!, - streams!!, - errors, - ) - ) - } catch (e: Throwable) { - val request = "${subscriptionEntity.serviceId}:${subscriptionEntity.url}" - val wrapper = FeedLoadService.RequestException( - subscriptionEntity.uid, - request, - // do this to prevent blockingGet() from wrapping into RuntimeException - error ?: e - ) - return@map Notification.createOnError(wrapper) - } + loadStreams(subscriptionEntity, useFeedExtractor, defaultSharedPreferences) } .sequential() .observeOn(AndroidSchedulers.mainThread()) @@ -226,6 +136,107 @@ class FeedLoadManager(private val context: Context) { ) } + private fun loadStreams( + subscriptionEntity: SubscriptionEntity, + useFeedExtractor: Boolean, + defaultSharedPreferences: SharedPreferences + ): + Notification { + var error: Throwable? = null + val storeOriginalErrorAndRethrow = { e: Throwable -> + // keep original to prevent blockingGet() from wrapping it into RuntimeException + error = e + throw e + } + + try { + // check for and load new streams + // either by using the dedicated feed method or by getting the channel info + var originalInfo: Info? = null + var streams: List? = null + val errors = ArrayList() + + if (useFeedExtractor) { + NewPipe.getService(subscriptionEntity.serviceId) + .getFeedExtractor(subscriptionEntity.url) + ?.also { feedExtractor -> + // the user wants to use a feed extractor and there is one, use it + val feedInfo = FeedInfo.getInfo(feedExtractor) + errors.addAll(feedInfo.errors) + originalInfo = feedInfo + streams = feedInfo.relatedItems + } + } + + if (originalInfo == null) { + // use the normal channel tabs extractor if either the user wants it, or + // the current service does not have a dedicated feed extractor + + val channelInfo = getChannelInfo( + subscriptionEntity.serviceId, + subscriptionEntity.url, true + ) + .onErrorReturn(storeOriginalErrorAndRethrow) + .blockingGet() + errors.addAll(channelInfo.errors) + originalInfo = channelInfo + + streams = channelInfo.tabs + .filter { tab -> + ChannelTabHelper.fetchFeedChannelTab( + context, + defaultSharedPreferences, + tab + ) + } + .map { + Pair( + getChannelTab(subscriptionEntity.serviceId, it, true) + .onErrorReturn(storeOriginalErrorAndRethrow) + .blockingGet(), + it + ) + } + .flatMap { (channelTabInfo, linkHandler) -> + errors.addAll(channelTabInfo.errors) + if (channelTabInfo.relatedItems.isEmpty() && + channelTabInfo.nextPage != null + ) { + val infoItemsPage = getMoreChannelTabItems( + subscriptionEntity.serviceId, + linkHandler, channelTabInfo.nextPage + ) + .blockingGet() + + errors.addAll(infoItemsPage.errors) + return@flatMap infoItemsPage.items + } else { + return@flatMap channelTabInfo.relatedItems + } + } + .filterIsInstance() + } + + return Notification.createOnNext( + FeedUpdateInfo( + subscriptionEntity, + originalInfo!!, + streams!!, + errors, + ) + ) + } catch (e: Throwable) { + val request = "${subscriptionEntity.serviceId}:${subscriptionEntity.url}" + val wrapper = FeedLoadService.RequestException( + subscriptionEntity.uid, + request, + // do this to prevent blockingGet() from wrapping into RuntimeException + error ?: e + ) + return Notification.createOnError(wrapper) + } + } + /** * Keep the feed and the stream tables small * to reduce loading times when trying to display the feed. From 89dc44be612224eb3bfc11579f66d1f4407de853 Mon Sep 17 00:00:00 2001 From: AudricV <74829229+AudricV@users.noreply.github.com> Date: Tue, 22 Aug 2023 19:14:17 +0200 Subject: [PATCH 070/172] Always show the About tab and support having no description --- .../detail/BaseDescriptionFragment.java | 19 +++++++++++-------- .../list/channel/ChannelFragment.java | 4 +--- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/fragments/detail/BaseDescriptionFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/detail/BaseDescriptionFragment.java index 47f8598af..3b1ede432 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/detail/BaseDescriptionFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/detail/BaseDescriptionFragment.java @@ -129,10 +129,13 @@ public abstract class BaseDescriptionFragment extends BaseFragment { private void disableDescriptionSelection() { // show description content again, otherwise some links are not clickable - TextLinkifier.fromDescription(binding.detailDescriptionView, - getDescription(), HtmlCompat.FROM_HTML_MODE_LEGACY, - getService(), getStreamUrl(), - descriptionDisposables, SET_LINK_MOVEMENT_METHOD); + final Description description = getDescription(); + if (description != null) { + TextLinkifier.fromDescription(binding.detailDescriptionView, + description, HtmlCompat.FROM_HTML_MODE_LEGACY, + getService(), getStreamUrl(), + descriptionDisposables, SET_LINK_MOVEMENT_METHOD); + } binding.detailDescriptionNoteView.setVisibility(View.GONE); binding.detailDescriptionView.setTextIsSelectable(false); @@ -144,10 +147,10 @@ public abstract class BaseDescriptionFragment extends BaseFragment { } protected void addMetadataItem(final LayoutInflater inflater, - final LinearLayout layout, - final boolean linkifyContent, - @StringRes final int type, - @Nullable final String content) { + final LinearLayout layout, + final boolean linkifyContent, + @StringRes final int type, + @Nullable final String content) { if (isBlank(content)) { return; } diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java index f709fc226..6c0eb9792 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java @@ -470,9 +470,7 @@ public class ChannelFragment extends BaseStateFragment } } - final String description = currentInfo.getDescription(); - if (description != null && !description.isEmpty() - && ChannelTabHelper.showChannelTab( + if (ChannelTabHelper.showChannelTab( context, preferences, R.string.show_channel_tabs_about)) { tabAdapter.addFragment( ChannelAboutFragment.getInstance(currentInfo), From f2ee3859ab6031d821a49de8c57e64bf7483f1ce Mon Sep 17 00:00:00 2001 From: AudricV <74829229+AudricV@users.noreply.github.com> Date: Tue, 22 Aug 2023 19:15:45 +0200 Subject: [PATCH 071/172] Hide the upload date element on the About tab This empty element should be always hidden for this tab, as there is no upload date available for channels. --- .../newpipe/fragments/list/channel/ChannelAboutFragment.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelAboutFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelAboutFragment.java index 4117533bd..d1afd51a0 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelAboutFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelAboutFragment.java @@ -84,6 +84,8 @@ public class ChannelAboutFragment extends BaseDescriptionFragment { protected void setupMetadata(final LayoutInflater inflater, final LinearLayout layout) { final Context context = getContext(); + // There is no upload date available for channels, so hide the relevant UI element + binding.detailUploadDateView.setVisibility(View.GONE); if (channelInfo.getSubscriberCount() != UNKNOWN_SUBSCRIBER_COUNT) { addMetadataItem(inflater, layout, false, R.string.metadata_subscribers, From 8fbc8ffc7c57555bb617c7c5d6b3b158bf31ffa3 Mon Sep 17 00:00:00 2001 From: AudricV <74829229+AudricV@users.noreply.github.com> Date: Tue, 22 Aug 2023 19:16:10 +0200 Subject: [PATCH 072/172] Remove unneeded German translation --- app/src/main/res/values-de/strings.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 1720d2b0a..5283f1afa 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -773,7 +773,6 @@ Wiedergabelisten Kanäle Alben - Info Tabs auf den Kanalseiten Welche Tabs auf den Kanalseiten angezeigt werden \ No newline at end of file From 0d9910cbbec39cd605aba774f2714e93db33ce5b Mon Sep 17 00:00:00 2001 From: AudricV <74829229+AudricV@users.noreply.github.com> Date: Wed, 23 Aug 2023 23:23:26 +0200 Subject: [PATCH 073/172] Fix SubscriptionManagerTest tests The breakage of these tests is related to the channel tabs changes. The testRememberRecentStreams test method has been removed, as it doesn't seem to be relevant anymore to managing subscriptions. --- .../subscription/SubscriptionManagerTest.java | 41 +------------------ 1 file changed, 2 insertions(+), 39 deletions(-) diff --git a/app/src/androidTest/java/org/schabi/newpipe/local/subscription/SubscriptionManagerTest.java b/app/src/androidTest/java/org/schabi/newpipe/local/subscription/SubscriptionManagerTest.java index e71083d2c..213b679f0 100644 --- a/app/src/androidTest/java/org/schabi/newpipe/local/subscription/SubscriptionManagerTest.java +++ b/app/src/androidTest/java/org/schabi/newpipe/local/subscription/SubscriptionManagerTest.java @@ -10,19 +10,13 @@ import org.junit.Rule; import org.junit.Test; import org.schabi.newpipe.database.AppDatabase; import org.schabi.newpipe.database.feed.model.FeedGroupEntity; -import org.schabi.newpipe.database.stream.model.StreamEntity; import org.schabi.newpipe.database.subscription.SubscriptionEntity; import org.schabi.newpipe.extractor.channel.ChannelInfo; import org.schabi.newpipe.extractor.exceptions.ExtractionException; -import org.schabi.newpipe.extractor.localization.DateWrapper; -import org.schabi.newpipe.extractor.stream.StreamInfoItem; -import org.schabi.newpipe.extractor.stream.StreamType; import org.schabi.newpipe.testUtil.TestDatabase; import org.schabi.newpipe.testUtil.TrampolineSchedulerRule; import java.io.IOException; -import java.time.OffsetDateTime; -import java.util.Comparator; import java.util.List; public class SubscriptionManagerTest { @@ -58,7 +52,7 @@ public class SubscriptionManagerTest { final ChannelInfo info = ChannelInfo.getInfo("https://www.youtube.com/c/3blue1brown"); final SubscriptionEntity subscription = SubscriptionEntity.from(info); - manager.insertSubscription(subscription, info); + manager.insertSubscription(subscription); final SubscriptionEntity readSubscription = getAssertOneSubscriptionEntity(); // the uid has changed, since the uid is chosen upon inserting, but the rest should match @@ -76,7 +70,7 @@ public class SubscriptionManagerTest { final SubscriptionEntity subscription = SubscriptionEntity.from(info); subscription.setNotificationMode(0); - manager.insertSubscription(subscription, info); + manager.insertSubscription(subscription); manager.updateNotificationMode(subscription.getServiceId(), subscription.getUrl(), 1) .blockingAwait(); final SubscriptionEntity anotherSubscription = getAssertOneSubscriptionEntity(); @@ -85,35 +79,4 @@ public class SubscriptionManagerTest { assertEquals(subscription.getUrl(), anotherSubscription.getUrl()); assertEquals(1, anotherSubscription.getNotificationMode()); } - - @Test - public void testRememberRecentStreams() throws ExtractionException, IOException { - final ChannelInfo info = ChannelInfo.getInfo("https://www.youtube.com/c/Polyphia"); - final List relatedItems = List.of( - new StreamInfoItem(0, "a", "b", StreamType.VIDEO_STREAM), - new StreamInfoItem(1, "c", "d", StreamType.AUDIO_STREAM), - new StreamInfoItem(2, "e", "f", StreamType.AUDIO_LIVE_STREAM), - new StreamInfoItem(3, "g", "h", StreamType.LIVE_STREAM)); - relatedItems.forEach(item -> { - // these two fields must be non-null for the insert to succeed - item.setUploaderUrl(info.getUrl()); - item.setUploaderName(info.getName()); - // the upload date must not be too much in the past for the item to actually be inserted - item.setUploadDate(new DateWrapper(OffsetDateTime.now())); - }); - info.setRelatedItems(relatedItems); - final SubscriptionEntity subscription = SubscriptionEntity.from(info); - - manager.insertSubscription(subscription, info); - final List streams = database.streamDAO().getAll().blockingFirst(); - - assertEquals(4, streams.size()); - streams.sort(Comparator.comparing(StreamEntity::getServiceId)); - for (int i = 0; i < 4; i++) { - assertEquals(relatedItems.get(0).getServiceId(), streams.get(0).getServiceId()); - assertEquals(relatedItems.get(0).getUrl(), streams.get(0).getUrl()); - assertEquals(relatedItems.get(0).getName(), streams.get(0).getTitle()); - assertEquals(relatedItems.get(0).getStreamType(), streams.get(0).getStreamType()); - } - } } From 109d06b4bb407e0995754af418ae74cb0e159692 Mon Sep 17 00:00:00 2001 From: TobiGr Date: Sun, 10 Sep 2023 01:11:00 +0200 Subject: [PATCH 074/172] Deduplicate code to initialize ClickListeners on playlist controls Add the separate utility class PlayButtonHelper to handle the initialization of the listeners. The ClickListeners on playlist controls had different behaviours. This commit fixes that. The commit also refactors the way how the app determines whether it is started for the first time. The previous version was not clean and recent in this PR caused it to fail. --- .../fragments/detail/VideoDetailFragment.java | 10 ++- .../list/channel/ChannelTabFragment.java | 33 ++----- .../playlist/PlaylistControlViewHolder.java | 13 +++ .../list/playlist/PlaylistFragment.java | 24 ++--- .../history/StatisticsPlaylistFragment.java | 26 +++--- .../local/playlist/LocalPlaylistFragment.java | 48 ++-------- .../newpipe/settings/NewPipeSettings.java | 20 ++--- .../schabi/newpipe/util/PlayButtonHelper.java | 90 +++++++++++++++++++ 8 files changed, 147 insertions(+), 117 deletions(-) create mode 100644 app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistControlViewHolder.java create mode 100644 app/src/main/java/org/schabi/newpipe/util/PlayButtonHelper.java diff --git a/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java index def1774b7..686e102f1 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java @@ -112,6 +112,7 @@ import org.schabi.newpipe.util.StreamTypeUtil; import org.schabi.newpipe.util.ThemeHelper; import org.schabi.newpipe.util.external_communication.KoreUtils; import org.schabi.newpipe.util.external_communication.ShareUtils; +import org.schabi.newpipe.util.PlayButtonHelper; import java.util.ArrayList; import java.util.Iterator; @@ -535,9 +536,11 @@ public final class VideoDetailFragment })); binding.detailControlsBackground.setOnLongClickListener(makeOnLongClickListener(info -> - openBackgroundPlayer(true))); + openBackgroundPlayer(true) + )); binding.detailControlsPopup.setOnLongClickListener(makeOnLongClickListener(info -> - openPopupPlayer(true))); + openPopupPlayer(true) + )); binding.detailControlsDownload.setOnLongClickListener(makeOnLongClickListener(info -> NavigationHelper.openDownloads(activity))); @@ -620,8 +623,7 @@ public final class VideoDetailFragment final View.OnTouchListener controlsTouchListener = (view, motionEvent) -> { if (motionEvent.getAction() == MotionEvent.ACTION_DOWN - && PreferenceManager.getDefaultSharedPreferences(activity) - .getBoolean(getString(R.string.show_hold_to_append_key), true)) { + && PlayButtonHelper.shouldShowHoldToAppendTip(activity)) { animate(binding.touchAppendDetail, true, 250, AnimationType.ALPHA, 0, () -> animate(binding.touchAppendDetail, false, 1500, AnimationType.ALPHA, 1000)); diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelTabFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelTabFragment.java index 6b2dd20bf..27315a991 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelTabFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelTabFragment.java @@ -17,12 +17,12 @@ import org.schabi.newpipe.extractor.channel.tabs.ChannelTabInfo; import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler; import org.schabi.newpipe.extractor.stream.StreamInfoItem; import org.schabi.newpipe.fragments.list.BaseListInfoFragment; -import org.schabi.newpipe.player.PlayerType; +import org.schabi.newpipe.fragments.list.playlist.PlaylistControlViewHolder; import org.schabi.newpipe.player.playqueue.ChannelTabPlayQueue; import org.schabi.newpipe.player.playqueue.PlayQueue; import org.schabi.newpipe.util.ChannelTabHelper; import org.schabi.newpipe.util.ExtractorHelper; -import org.schabi.newpipe.util.NavigationHelper; +import org.schabi.newpipe.util.PlayButtonHelper; import java.util.List; import java.util.function.Supplier; @@ -31,7 +31,8 @@ import java.util.stream.Collectors; import icepick.State; import io.reactivex.rxjava3.core.Single; -public class ChannelTabFragment extends BaseListInfoFragment { +public class ChannelTabFragment extends BaseListInfoFragment + implements PlaylistControlViewHolder { @State protected ListLinkHandler tabHandler; @@ -39,7 +40,6 @@ public class ChannelTabFragment extends BaseListInfoFragment NavigationHelper.playOnMainPlayer(activity, getPlayQueue())); - playlistControlBinding.playlistCtrlPlayPopupButton.setOnClickListener( - view -> NavigationHelper.playOnPopupPlayer(activity, getPlayQueue(), false)); - playlistControlBinding.playlistCtrlPlayBgButton.setOnClickListener( - view -> NavigationHelper.playOnBackgroundPlayer(activity, getPlayQueue(), - false)); - - playlistControlBinding.playlistCtrlPlayPopupButton.setOnLongClickListener(view -> { - NavigationHelper.enqueueOnPlayer(activity, getPlayQueue(), PlayerType.POPUP); - return true; - }); - - playlistControlBinding.playlistCtrlPlayBgButton.setOnLongClickListener(view -> { - NavigationHelper.enqueueOnPlayer(activity, getPlayQueue(), PlayerType.AUDIO); - return true; - }); + PlayButtonHelper.initPlaylistControlClickListener( + activity, playlistControlBinding, this); } } - private PlayQueue getPlayQueue() { + public PlayQueue getPlayQueue() { final List streamItems = infoListAdapter.getItemsList().stream() .filter(StreamInfoItem.class::isInstance) .map(StreamInfoItem.class::cast) diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistControlViewHolder.java b/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistControlViewHolder.java new file mode 100644 index 000000000..2a785146c --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistControlViewHolder.java @@ -0,0 +1,13 @@ +package org.schabi.newpipe.fragments.list.playlist; + +import org.schabi.newpipe.player.playqueue.PlayQueue; + +/** + * Interface for {@code R.layout.playlist_control} view holders + * to give access to the play queue. + */ +public interface PlaylistControlViewHolder { + + PlayQueue getPlayQueue(); + +} diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java index 8dd77bed6..2b7cf9446 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java @@ -43,7 +43,6 @@ import org.schabi.newpipe.info_list.dialog.InfoItemDialog; import org.schabi.newpipe.info_list.dialog.StreamDialogDefaultEntry; import org.schabi.newpipe.local.dialog.PlaylistDialog; import org.schabi.newpipe.local.playlist.RemotePlaylistManager; -import org.schabi.newpipe.player.PlayerType; import org.schabi.newpipe.player.playqueue.PlayQueue; import org.schabi.newpipe.player.playqueue.PlaylistPlayQueue; import org.schabi.newpipe.util.ExtractorHelper; @@ -51,6 +50,7 @@ import org.schabi.newpipe.util.Localization; import org.schabi.newpipe.util.NavigationHelper; import org.schabi.newpipe.util.PicassoHelper; import org.schabi.newpipe.util.external_communication.ShareUtils; +import org.schabi.newpipe.util.PlayButtonHelper; import java.util.ArrayList; import java.util.List; @@ -64,7 +64,8 @@ import io.reactivex.rxjava3.core.Single; import io.reactivex.rxjava3.disposables.CompositeDisposable; import io.reactivex.rxjava3.disposables.Disposable; -public class PlaylistFragment extends BaseListInfoFragment { +public class PlaylistFragment extends BaseListInfoFragment + implements PlaylistControlViewHolder { private static final String PICASSO_PLAYLIST_TAG = "PICASSO_PLAYLIST_TAG"; @@ -332,25 +333,10 @@ public class PlaylistFragment extends BaseListInfoFragment - NavigationHelper.playOnMainPlayer(activity, getPlayQueue())); - playlistControlBinding.playlistCtrlPlayPopupButton.setOnClickListener(view -> - NavigationHelper.playOnPopupPlayer(activity, getPlayQueue(), false)); - playlistControlBinding.playlistCtrlPlayBgButton.setOnClickListener(view -> - NavigationHelper.playOnBackgroundPlayer(activity, getPlayQueue(), false)); - - playlistControlBinding.playlistCtrlPlayPopupButton.setOnLongClickListener(view -> { - NavigationHelper.enqueueOnPlayer(activity, getPlayQueue(), PlayerType.POPUP); - return true; - }); - - playlistControlBinding.playlistCtrlPlayBgButton.setOnLongClickListener(view -> { - NavigationHelper.enqueueOnPlayer(activity, getPlayQueue(), PlayerType.AUDIO); - return true; - }); + PlayButtonHelper.initPlaylistControlClickListener(activity, playlistControlBinding, this); } - private PlayQueue getPlayQueue() { + public PlayQueue getPlayQueue() { return getPlayQueue(0); } diff --git a/app/src/main/java/org/schabi/newpipe/local/history/StatisticsPlaylistFragment.java b/app/src/main/java/org/schabi/newpipe/local/history/StatisticsPlaylistFragment.java index a20a80ae9..1fea7e155 100644 --- a/app/src/main/java/org/schabi/newpipe/local/history/StatisticsPlaylistFragment.java +++ b/app/src/main/java/org/schabi/newpipe/local/history/StatisticsPlaylistFragment.java @@ -28,14 +28,16 @@ import org.schabi.newpipe.databinding.StatisticPlaylistControlBinding; import org.schabi.newpipe.error.ErrorInfo; import org.schabi.newpipe.error.UserAction; import org.schabi.newpipe.extractor.stream.StreamInfoItem; +import org.schabi.newpipe.fragments.list.playlist.PlaylistControlViewHolder; import org.schabi.newpipe.info_list.dialog.InfoItemDialog; +import org.schabi.newpipe.info_list.dialog.StreamDialogDefaultEntry; import org.schabi.newpipe.local.BaseLocalListFragment; import org.schabi.newpipe.player.playqueue.PlayQueue; import org.schabi.newpipe.player.playqueue.SinglePlayQueue; import org.schabi.newpipe.settings.HistorySettingsFragment; import org.schabi.newpipe.util.NavigationHelper; import org.schabi.newpipe.util.OnClickGesture; -import org.schabi.newpipe.info_list.dialog.StreamDialogDefaultEntry; +import org.schabi.newpipe.util.PlayButtonHelper; import java.util.ArrayList; import java.util.Collections; @@ -49,7 +51,8 @@ import io.reactivex.rxjava3.disposables.CompositeDisposable; import io.reactivex.rxjava3.disposables.Disposable; public class StatisticsPlaylistFragment - extends BaseLocalListFragment, Void> { + extends BaseLocalListFragment, Void> + implements PlaylistControlViewHolder { private final CompositeDisposable disposables = new CompositeDisposable(); @State Parcelable itemsListState; @@ -195,14 +198,9 @@ public class StatisticsPlaylistFragment if (itemListAdapter != null) { itemListAdapter.unsetSelectedListener(); } - if (playlistControlBinding != null) { - playlistControlBinding.playlistCtrlPlayBgButton.setOnClickListener(null); - playlistControlBinding.playlistCtrlPlayAllButton.setOnClickListener(null); - playlistControlBinding.playlistCtrlPlayPopupButton.setOnClickListener(null); - headerBinding = null; - playlistControlBinding = null; - } + headerBinding = null; + playlistControlBinding = null; if (databaseSubscription != null) { databaseSubscription.cancel(); @@ -276,12 +274,8 @@ public class StatisticsPlaylistFragment itemsListState = null; } - playlistControlBinding.playlistCtrlPlayAllButton.setOnClickListener(view -> - NavigationHelper.playOnMainPlayer(activity, getPlayQueue())); - playlistControlBinding.playlistCtrlPlayPopupButton.setOnClickListener(view -> - NavigationHelper.playOnPopupPlayer(activity, getPlayQueue(), false)); - playlistControlBinding.playlistCtrlPlayBgButton.setOnClickListener(view -> - NavigationHelper.playOnBackgroundPlayer(activity, getPlayQueue(), false)); + PlayButtonHelper.initPlaylistControlClickListener(activity, playlistControlBinding, this); + headerBinding.sortButton.setOnClickListener(view -> toggleSortMode()); hideLoading(); @@ -374,7 +368,7 @@ public class StatisticsPlaylistFragment } } - private PlayQueue getPlayQueue() { + public PlayQueue getPlayQueue() { return getPlayQueue(0); } diff --git a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java index 2a639a69f..0d8f81334 100644 --- a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java +++ b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java @@ -22,7 +22,6 @@ import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AlertDialog; -import androidx.preference.PreferenceManager; import androidx.recyclerview.widget.ItemTouchHelper; import androidx.recyclerview.widget.RecyclerView; import androidx.viewbinding.ViewBinding; @@ -42,17 +41,18 @@ import org.schabi.newpipe.databinding.PlaylistControlBinding; import org.schabi.newpipe.error.ErrorInfo; import org.schabi.newpipe.error.UserAction; import org.schabi.newpipe.extractor.stream.StreamInfoItem; +import org.schabi.newpipe.fragments.list.playlist.PlaylistControlViewHolder; import org.schabi.newpipe.info_list.dialog.InfoItemDialog; import org.schabi.newpipe.info_list.dialog.StreamDialogDefaultEntry; import org.schabi.newpipe.local.BaseLocalListFragment; import org.schabi.newpipe.local.history.HistoryRecordManager; -import org.schabi.newpipe.player.PlayerType; import org.schabi.newpipe.player.playqueue.PlayQueue; import org.schabi.newpipe.player.playqueue.SinglePlayQueue; import org.schabi.newpipe.util.Localization; import org.schabi.newpipe.util.NavigationHelper; import org.schabi.newpipe.util.OnClickGesture; import org.schabi.newpipe.util.external_communication.ShareUtils; +import org.schabi.newpipe.util.PlayButtonHelper; import java.util.ArrayList; import java.util.Collections; @@ -69,7 +69,8 @@ import io.reactivex.rxjava3.disposables.Disposable; import io.reactivex.rxjava3.schedulers.Schedulers; import io.reactivex.rxjava3.subjects.PublishSubject; -public class LocalPlaylistFragment extends BaseLocalListFragment, Void> { +public class LocalPlaylistFragment extends BaseLocalListFragment, Void> + implements PlaylistControlViewHolder { // Save the list 10 seconds after the last change occurred private static final long SAVE_DEBOUNCE_MILLIS = 10000; private static final int MINIMUM_INITIAL_DRAG_VELOCITY = 12; @@ -265,14 +266,10 @@ public class LocalPlaylistFragment extends BaseLocalListFragment { - NavigationHelper.playOnMainPlayer(activity, getPlayQueue()); - showHoldToAppendTipIfNeeded(); - }); - playlistControlBinding.playlistCtrlPlayPopupButton.setOnClickListener(view -> { - NavigationHelper.playOnPopupPlayer(activity, getPlayQueue(), false); - showHoldToAppendTipIfNeeded(); - }); - playlistControlBinding.playlistCtrlPlayBgButton.setOnClickListener(view -> { - NavigationHelper.playOnBackgroundPlayer(activity, getPlayQueue(), false); - showHoldToAppendTipIfNeeded(); - }); - playlistControlBinding.playlistCtrlPlayPopupButton.setOnLongClickListener(view -> { - NavigationHelper.enqueueOnPlayer(activity, getPlayQueue(), PlayerType.POPUP); - return true; - }); - - playlistControlBinding.playlistCtrlPlayBgButton.setOnLongClickListener(view -> { - NavigationHelper.enqueueOnPlayer(activity, getPlayQueue(), PlayerType.AUDIO); - return true; - }); + PlayButtonHelper.initPlaylistControlClickListener(activity, playlistControlBinding, this); hideLoading(); } - private void showHoldToAppendTipIfNeeded() { - if (PreferenceManager.getDefaultSharedPreferences(activity) - .getBoolean(getString(R.string.show_hold_to_append_key), true)) { - Toast.makeText(activity, R.string.hold_to_append, Toast.LENGTH_SHORT).show(); - } - } - /////////////////////////////////////////////////////////////////////////// // Fragment Error Handling /////////////////////////////////////////////////////////////////////////// @@ -853,7 +823,7 @@ public class LocalPlaylistFragment extends BaseLocalListFragment prefsKeys = PreferenceManager.getDefaultSharedPreferences(context) - .getAll().keySet(); - for (final String key: prefsKeys) { - // ACRA stores some info in the prefs during app initialization - // which happens before this method is called. Therefore ignore ACRA-related keys. - if (!key.toLowerCase().startsWith("acra")) { - isFirstRun = false; - break; - } - } - if (isFirstRun == null) { - isFirstRun = true; - } + // check if the last used preference version is set + // to determine whether this is the first app run + final int lastUsedPrefVersion = PreferenceManager.getDefaultSharedPreferences(context) + .getInt(context.getString(R.string.last_used_preferences_version), -1); + final boolean isFirstRun = lastUsedPrefVersion == -1; // first run migrations, then setDefaultValues, since the latter requires the correct types SettingMigrations.runMigrationsIfNeeded(context, isFirstRun); diff --git a/app/src/main/java/org/schabi/newpipe/util/PlayButtonHelper.java b/app/src/main/java/org/schabi/newpipe/util/PlayButtonHelper.java new file mode 100644 index 000000000..a0707c656 --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/util/PlayButtonHelper.java @@ -0,0 +1,90 @@ +package org.schabi.newpipe.util; + +import android.content.Context; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatActivity; +import androidx.preference.PreferenceManager; + +import org.schabi.newpipe.R; +import org.schabi.newpipe.databinding.PlaylistControlBinding; +import org.schabi.newpipe.fragments.list.playlist.PlaylistControlViewHolder; +import org.schabi.newpipe.player.PlayerType; + +/** + * Utility class for play buttons and their respective click listeners. + */ +public final class PlayButtonHelper { + + private PlayButtonHelper() { + // utility class + } + + /** + *

Initialize {@link android.view.View.OnClickListener OnClickListener} + * and {@link android.view.View.OnLongClickListener OnLongClickListener} for playlist control + * buttons defined in {@code R.layout.playlist_control}.

+ * + * @param activity The activity to use for the {@link android.widget.Toast Toast}. + * @param playlistControlBinding The binding of the + * {@link R.layout.playlist_control playlist control layout}. + * @param fragment The fragment to get the play queue from. + */ + public static void initPlaylistControlClickListener( + @NonNull final AppCompatActivity activity, + @NonNull final PlaylistControlBinding playlistControlBinding, + @NonNull final PlaylistControlViewHolder fragment) { + // click listener + playlistControlBinding.playlistCtrlPlayAllButton.setOnClickListener(view -> { + NavigationHelper.playOnMainPlayer(activity, fragment.getPlayQueue()); + showHoldToAppendToastIfNeeded(activity); + }); + playlistControlBinding.playlistCtrlPlayPopupButton.setOnClickListener(view -> { + NavigationHelper.playOnPopupPlayer(activity, fragment.getPlayQueue(), false); + showHoldToAppendToastIfNeeded(activity); + }); + playlistControlBinding.playlistCtrlPlayBgButton.setOnClickListener(view -> { + NavigationHelper.playOnBackgroundPlayer(activity, fragment.getPlayQueue(), false); + showHoldToAppendToastIfNeeded(activity); + }); + + // long click listener + playlistControlBinding.playlistCtrlPlayPopupButton.setOnLongClickListener(view -> { + NavigationHelper.enqueueOnPlayer(activity, fragment.getPlayQueue(), PlayerType.POPUP); + return true; + }); + playlistControlBinding.playlistCtrlPlayBgButton.setOnLongClickListener(view -> { + NavigationHelper.enqueueOnPlayer(activity, fragment.getPlayQueue(), PlayerType.AUDIO); + return true; + }); + } + + /** + *

Show the "hold to append" toast if the corresponding preference is enabled.

+ * + * @param context The context to show the toast. + */ + private static void showHoldToAppendToastIfNeeded(@NonNull final Context context) { + if (shouldShowHoldToAppendTip(context)) { + Toast.makeText(context, R.string.hold_to_append, Toast.LENGTH_SHORT).show(); + } + + } + + /** + *

Check if the "hold to append" toast should be shown.

+ * + *

+ * The tip is shown if the corresponding preference is enabled. + * This is the default behaviour. + *

+ * + * @param context The context to get the preference. + * @return {@code true} if the tip should be shown, {@code false} otherwise. + */ + public static boolean shouldShowHoldToAppendTip(@NonNull final Context context) { + return PreferenceManager.getDefaultSharedPreferences(context) + .getBoolean(context.getString(R.string.show_hold_to_append_key), true); + } +} From 57eaa1bbe1c837531d5bcfe6de41e130e61b97c3 Mon Sep 17 00:00:00 2001 From: TobiGr Date: Mon, 18 Sep 2023 15:01:17 +0200 Subject: [PATCH 075/172] Apply review Co-Authored-By: Audric V <74829229+AudricV@users.noreply.github.com> --- .../detail/BaseDescriptionFragment.java | 4 ++-- .../fragments/detail/DescriptionFragment.java | 9 +++++++- .../fragments/list/BaseListInfoFragment.java | 2 -- .../list/channel/ChannelAboutFragment.java | 9 +++++++- .../list/channel/ChannelFragment.java | 12 +++++----- .../list/channel/ChannelTabFragment.java | 10 +++++++- .../playlist/PlaylistControlViewHolder.java | 2 -- .../local/feed/service/FeedLoadManager.kt | 3 +-- .../playqueue/AbstractInfoPlayQueue.java | 23 +++++++++++-------- .../schabi/newpipe/util/ExtractorHelper.java | 8 +++---- .../schabi/newpipe/util/PlayButtonHelper.java | 10 ++++---- .../main/res/layout/fragment_channel_tab.xml | 2 +- 12 files changed, 58 insertions(+), 36 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/fragments/detail/BaseDescriptionFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/detail/BaseDescriptionFragment.java index 3b1ede432..ae334b761 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/detail/BaseDescriptionFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/detail/BaseDescriptionFragment.java @@ -34,7 +34,7 @@ import java.util.List; import io.reactivex.rxjava3.disposables.CompositeDisposable; public abstract class BaseDescriptionFragment extends BaseFragment { - final CompositeDisposable descriptionDisposables = new CompositeDisposable(); + private final CompositeDisposable descriptionDisposables = new CompositeDisposable(); protected FragmentDescriptionBinding binding; @Override @@ -75,7 +75,7 @@ public abstract class BaseDescriptionFragment extends BaseFragment { protected abstract int getServiceId(); /** - * Get the URL of the described video. Used for generating description links. + * Get the URL of the described video or audio, used to generate description links. * @return stream URL */ @Nullable diff --git a/app/src/main/java/org/schabi/newpipe/fragments/detail/DescriptionFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/detail/DescriptionFragment.java index cb38d8416..92219883b 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/detail/DescriptionFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/detail/DescriptionFragment.java @@ -52,6 +52,9 @@ public class DescriptionFragment extends BaseDescriptionFragment { @Override protected int getServiceId() { + if (streamInfo == null) { + return -1; + } return streamInfo.getServiceId(); } @@ -76,13 +79,17 @@ public class DescriptionFragment extends BaseDescriptionFragment { @Override protected void setupMetadata(final LayoutInflater inflater, final LinearLayout layout) { - if (streamInfo.getUploadDate() != null) { + if (streamInfo != null && streamInfo.getUploadDate() != null) { binding.detailUploadDateView.setText(Localization .localizeUploadDate(activity, streamInfo.getUploadDate().offsetDateTime())); } else { binding.detailUploadDateView.setVisibility(View.GONE); } + if (streamInfo == null) { + return; + } + addMetadataItem(inflater, layout, false, R.string.metadata_category, streamInfo.getCategory()); diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListInfoFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListInfoFragment.java index d30dadfd1..e7e9f5aad 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListInfoFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListInfoFragment.java @@ -233,8 +233,6 @@ public abstract class BaseListInfoFragment } @Override - public void onAttach(final @NonNull Context context) { + public void onAttach(@NonNull final Context context) { super.onAttach(context); subscriptionManager = new SubscriptionManager(activity); } @@ -138,7 +138,7 @@ public class ChannelFragment extends BaseStateFragment return binding.getRoot(); } - @Override // called from onViewCreated in {@link BaseFragment#onViewCreated} + @Override // called from onViewCreated in BaseFragment.onViewCreated protected void initViews(final View rootView, final Bundle savedInstanceState) { super.initViews(rootView, savedInstanceState); @@ -202,7 +202,7 @@ public class ChannelFragment extends BaseStateFragment } @Override - public void onPrepareOptionsMenu(final @NonNull Menu menu) { + public void onPrepareOptionsMenu(@NonNull final Menu menu) { super.onPrepareOptionsMenu(menu); menuRssButton = menu.findItem(R.id.menu_item_rss); menuNotifyButton = menu.findItem(R.id.menu_item_notify); @@ -210,7 +210,7 @@ public class ChannelFragment extends BaseStateFragment } @Override - public boolean onOptionsItemSelected(final MenuItem item) { + public boolean onOptionsItemSelected(@NonNull final MenuItem item) { switch (item.getItemId()) { case R.id.menu_item_notify: final boolean value = !item.isChecked(); @@ -561,8 +561,8 @@ public class ChannelFragment extends BaseStateFragment .subscribe(result -> { isLoading.set(false); handleResult(result); - }, throwable -> showError(new ErrorInfo(throwable, UserAction.REQUESTED_STREAM, - url == null ? "no url" : url, serviceId))); + }, throwable -> showError(new ErrorInfo(throwable, UserAction.REQUESTED_CHANNEL, + url == null ? "No URL" : url, serviceId))); } @Override diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelTabFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelTabFragment.java index 27315a991..8712ab4d9 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelTabFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelTabFragment.java @@ -34,12 +34,15 @@ import io.reactivex.rxjava3.core.Single; public class ChannelTabFragment extends BaseListInfoFragment implements PlaylistControlViewHolder { + // states must be protected and not private for IcePick being able to access them @State protected ListLinkHandler tabHandler; @State protected String channelName; private PlaylistControlBinding playlistControlBinding; + + @NonNull public static ChannelTabFragment getInstance(final int serviceId, final ListLinkHandler tabHandler, final String channelName) { @@ -99,11 +102,16 @@ public class ChannelTabFragment extends BaseListInfoFragment { + ): Notification { var error: Throwable? = null val storeOriginalErrorAndRethrow = { e: Throwable -> // keep original to prevent blockingGet() from wrapping it into RuntimeException diff --git a/app/src/main/java/org/schabi/newpipe/player/playqueue/AbstractInfoPlayQueue.java b/app/src/main/java/org/schabi/newpipe/player/playqueue/AbstractInfoPlayQueue.java index a0fc88eae..33ec390a5 100644 --- a/app/src/main/java/org/schabi/newpipe/player/playqueue/AbstractInfoPlayQueue.java +++ b/app/src/main/java/org/schabi/newpipe/player/playqueue/AbstractInfoPlayQueue.java @@ -29,9 +29,12 @@ abstract class AbstractInfoPlayQueue> protected AbstractInfoPlayQueue(final T info) { this(info.getServiceId(), info.getUrl(), info.getNextPage(), - info.getRelatedItems().stream().filter(StreamInfoItem.class::isInstance) - .map(StreamInfoItem.class::cast).collect( - Collectors.toList()), 0); + info.getRelatedItems() + .stream() + .filter(StreamInfoItem.class::isInstance) + .map(StreamInfoItem.class::cast) + .collect(Collectors.toList()), + 0); } protected AbstractInfoPlayQueue(final int serviceId, @@ -76,10 +79,11 @@ abstract class AbstractInfoPlayQueue> } nextPage = result.getNextPage(); - append(extractListItems(result.getRelatedItems().stream() + append(extractListItems(result.getRelatedItems() + .stream() .filter(StreamInfoItem.class::isInstance) - .map(StreamInfoItem.class::cast).collect( - Collectors.toList()))); + .map(StreamInfoItem.class::cast) + .collect(Collectors.toList()))); fetchReactor.dispose(); fetchReactor = null; @@ -114,10 +118,11 @@ abstract class AbstractInfoPlayQueue> } nextPage = result.getNextPage(); - append(extractListItems(result.getItems().stream() + append(extractListItems(result.getItems() + .stream() .filter(StreamInfoItem.class::isInstance) - .map(StreamInfoItem.class::cast).collect( - Collectors.toList()))); + .map(StreamInfoItem.class::cast) + .collect(Collectors.toList()))); fetchReactor.dispose(); fetchReactor = null; diff --git a/app/src/main/java/org/schabi/newpipe/util/ExtractorHelper.java b/app/src/main/java/org/schabi/newpipe/util/ExtractorHelper.java index 257a428fc..07d0f516d 100644 --- a/app/src/main/java/org/schabi/newpipe/util/ExtractorHelper.java +++ b/app/src/main/java/org/schabi/newpipe/util/ExtractorHelper.java @@ -135,10 +135,10 @@ public final class ExtractorHelper { ChannelTabInfo.getInfo(NewPipe.getService(serviceId), listLinkHandler))); } - public static Single> getMoreChannelTabItems(final int serviceId, - final ListLinkHandler - listLinkHandler, - final Page nextPage) { + public static Single> getMoreChannelTabItems( + final int serviceId, + final ListLinkHandler listLinkHandler, + final Page nextPage) { checkServiceId(serviceId); return Single.fromCallable(() -> ChannelTabInfo.getMoreItems(NewPipe.getService(serviceId), diff --git a/app/src/main/java/org/schabi/newpipe/util/PlayButtonHelper.java b/app/src/main/java/org/schabi/newpipe/util/PlayButtonHelper.java index a0707c656..9727c8083 100644 --- a/app/src/main/java/org/schabi/newpipe/util/PlayButtonHelper.java +++ b/app/src/main/java/org/schabi/newpipe/util/PlayButtonHelper.java @@ -22,13 +22,13 @@ public final class PlayButtonHelper { } /** - *

Initialize {@link android.view.View.OnClickListener OnClickListener} + * Initialize {@link android.view.View.OnClickListener OnClickListener} * and {@link android.view.View.OnLongClickListener OnLongClickListener} for playlist control - * buttons defined in {@code R.layout.playlist_control}.

+ * buttons defined in {@link R.layout#playlist_control}. * * @param activity The activity to use for the {@link android.widget.Toast Toast}. * @param playlistControlBinding The binding of the - * {@link R.layout.playlist_control playlist control layout}. + * {@link R.layout#playlist_control playlist control layout}. * @param fragment The fragment to get the play queue from. */ public static void initPlaylistControlClickListener( @@ -61,7 +61,7 @@ public final class PlayButtonHelper { } /** - *

Show the "hold to append" toast if the corresponding preference is enabled.

+ * Show the "hold to append" toast if the corresponding preference is enabled. * * @param context The context to show the toast. */ @@ -73,7 +73,7 @@ public final class PlayButtonHelper { } /** - *

Check if the "hold to append" toast should be shown.

+ * Check if the "hold to append" toast should be shown. * *

* The tip is shown if the corresponding preference is enabled. diff --git a/app/src/main/res/layout/fragment_channel_tab.xml b/app/src/main/res/layout/fragment_channel_tab.xml index dd114cb77..62795c7da 100644 --- a/app/src/main/res/layout/fragment_channel_tab.xml +++ b/app/src/main/res/layout/fragment_channel_tab.xml @@ -47,4 +47,4 @@ android:layout_alignParentTop="true" android:background="?attr/toolbar_shadow" /> - \ No newline at end of file + From 64da7a06c02647d856402f89d7115a83a50ade04 Mon Sep 17 00:00:00 2001 From: TobiGr Date: Mon, 18 Sep 2023 15:52:29 +0200 Subject: [PATCH 076/172] Fix previous ActionBar title visible for a few miliseconds when opening ChannelFragment --- .../schabi/newpipe/fragments/list/channel/ChannelFragment.java | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java index 2c6189880..c1345180b 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java @@ -146,6 +146,7 @@ public class ChannelFragment extends BaseStateFragment binding.viewPager.setAdapter(tabAdapter); binding.tabLayout.setupWithViewPager(binding.viewPager); + setTitle(name); binding.channelTitleView.setText(name); if (!PicassoHelper.getShouldLoadImages()) { // do not waste space for the banner if it is not going to be loaded From 031b893196cf9e1ce5016b9a836f8476bd142cde Mon Sep 17 00:00:00 2001 From: TobiGr Date: Mon, 18 Sep 2023 15:55:41 +0200 Subject: [PATCH 077/172] Remove unused content not supported TextView --- app/src/main/res/layout/fragment_channel_videos.xml | 9 --------- 1 file changed, 9 deletions(-) diff --git a/app/src/main/res/layout/fragment_channel_videos.xml b/app/src/main/res/layout/fragment_channel_videos.xml index 9e2257539..77d14b020 100644 --- a/app/src/main/res/layout/fragment_channel_videos.xml +++ b/app/src/main/res/layout/fragment_channel_videos.xml @@ -49,15 +49,6 @@ android:text="@string/empty_view_no_videos" android:textSize="24sp" /> - - From 8f83e39970c7d7601f9ea697e2b25ce2831a2938 Mon Sep 17 00:00:00 2001 From: TobiGr Date: Tue, 29 Aug 2023 15:33:03 +0200 Subject: [PATCH 078/172] Fix three memory leaks Add documentation to BaseFragment.initViews(View, Bundle) and BaseFragment.initListeners() --- .../java/org/schabi/newpipe/BaseFragment.java | 20 +++++++++++++++++++ .../newpipe/fragments/BaseStateFragment.java | 2 ++ .../newpipe/fragments/MainFragment.java | 6 ++++++ .../subscription/SubscriptionFragment.kt | 5 +++++ 4 files changed, 33 insertions(+) diff --git a/app/src/main/java/org/schabi/newpipe/BaseFragment.java b/app/src/main/java/org/schabi/newpipe/BaseFragment.java index 19a99009b..5dde2a747 100644 --- a/app/src/main/java/org/schabi/newpipe/BaseFragment.java +++ b/app/src/main/java/org/schabi/newpipe/BaseFragment.java @@ -80,9 +80,29 @@ public abstract class BaseFragment extends Fragment { // Init //////////////////////////////////////////////////////////////////////////*/ + /** + * This method is called in {@link #onViewCreated(View, Bundle)} to initialize the views. + * + *

+ * {@link #initListeners()} is called after this method to initialize the corresponding + * listeners. + *

+ * @param rootView The inflated view for this fragment + * (provided by {@link #onViewCreated(View, Bundle)}) + * @param savedInstanceState The saved state of this fragment + * (provided by {@link #onViewCreated(View, Bundle)}) + */ protected void initViews(final View rootView, final Bundle savedInstanceState) { } + /** + * Initialize the listeners for this fragment. + * + *

+ * This method is called after {@link #initViews(View, Bundle)} + * in {@link #onViewCreated(View, Bundle)}. + *

+ */ protected void initListeners() { } diff --git a/app/src/main/java/org/schabi/newpipe/fragments/BaseStateFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/BaseStateFragment.java index 85603d337..a3d3d8b60 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/BaseStateFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/BaseStateFragment.java @@ -80,6 +80,8 @@ public abstract class BaseStateFragment extends BaseFragment implements ViewC if (errorPanelHelper != null) { errorPanelHelper.dispose(); } + emptyStateView = null; + emptyStateMessageView = null; } protected void onRetryButtonClicked() { diff --git a/app/src/main/java/org/schabi/newpipe/fragments/MainFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/MainFragment.java index e1b61ea7c..023642955 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/MainFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/MainFragment.java @@ -139,6 +139,12 @@ public class MainFragment extends BaseFragment implements TabLayout.OnTabSelecte } } + @Override + public void onDestroyView() { + super.onDestroyView(); + binding = null; + } + /*////////////////////////////////////////////////////////////////////////// // Menu //////////////////////////////////////////////////////////////////////////*/ diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionFragment.kt b/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionFragment.kt index da1eba225..dda4326e9 100644 --- a/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionFragment.kt +++ b/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionFragment.kt @@ -115,6 +115,11 @@ class SubscriptionFragment : BaseStateFragment() { feedGroupsCarouselState = feedGroupsCarousel.onSaveInstanceState() } + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } + override fun onDestroy() { super.onDestroy() disposables.dispose() From 992bb5d7be034e57a1daed1a9c398491fc5ddf33 Mon Sep 17 00:00:00 2001 From: Stypox Date: Tue, 19 Sep 2023 15:33:40 +0200 Subject: [PATCH 079/172] Simplify retrieveMediaFormatFromContentTypeHeader Also check for nullity --- .../newpipe/util/StreamItemAdapterTest.kt | 12 ++++++---- .../newpipe/util/StreamItemAdapter.java | 23 +++++++++++-------- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/app/src/androidTest/java/org/schabi/newpipe/util/StreamItemAdapterTest.kt b/app/src/androidTest/java/org/schabi/newpipe/util/StreamItemAdapterTest.kt index 13c27aec9..9b8ee211e 100644 --- a/app/src/androidTest/java/org/schabi/newpipe/util/StreamItemAdapterTest.kt +++ b/app/src/androidTest/java/org/schabi/newpipe/util/StreamItemAdapterTest.kt @@ -196,7 +196,7 @@ class StreamItemAdapterTest { @Test fun retrieveMediaFormatFromContentTypeHeader() { - val streams = getIncompleteAudioStreams(10) + val streams = getIncompleteAudioStreams(12) val wrapper = StreamInfoWrapper(streams, context) val retrieveMediaFormat = { stream: AudioStream, response: Response -> StreamInfoWrapper.retrieveMediaFormatFromContentTypeHeader(stream, wrapper, response) @@ -209,18 +209,20 @@ class StreamItemAdapterTest { helper.assertInvalidResponse(getResponse(mapOf(Pair("Content-Type", "mp3"))), 3) helper.assertInvalidResponse(getResponse(mapOf(Pair("Content-Type", "audio/mpeg"))), 4) helper.assertInvalidResponse(getResponse(mapOf(Pair("Content-Type", "audio/aif"))), 5) + helper.assertInvalidResponse(getResponse(mapOf(Pair("Content-Type", "whatever"))), 6) + helper.assertInvalidResponse(getResponse(mapOf()), 7) helper.assertValidResponse( - getResponse(mapOf(Pair("Content-Type", "audio/flac"))), 6, MediaFormat.FLAC + getResponse(mapOf(Pair("Content-Type", "audio/flac"))), 8, MediaFormat.FLAC ) helper.assertValidResponse( - getResponse(mapOf(Pair("Content-Type", "audio/wav"))), 7, MediaFormat.WAV + getResponse(mapOf(Pair("Content-Type", "audio/wav"))), 9, MediaFormat.WAV ) helper.assertValidResponse( - getResponse(mapOf(Pair("Content-Type", "audio/opus"))), 8, MediaFormat.OPUS + getResponse(mapOf(Pair("Content-Type", "audio/opus"))), 10, MediaFormat.OPUS ) helper.assertValidResponse( - getResponse(mapOf(Pair("Content-Type", "audio/aiff"))), 9, MediaFormat.AIFF + getResponse(mapOf(Pair("Content-Type", "audio/aiff"))), 11, MediaFormat.AIFF ) } diff --git a/app/src/main/java/org/schabi/newpipe/util/StreamItemAdapter.java b/app/src/main/java/org/schabi/newpipe/util/StreamItemAdapter.java index d5b73d0b6..2eeb14b1b 100644 --- a/app/src/main/java/org/schabi/newpipe/util/StreamItemAdapter.java +++ b/app/src/main/java/org/schabi/newpipe/util/StreamItemAdapter.java @@ -27,7 +27,6 @@ import org.schabi.newpipe.extractor.stream.VideoStream; import org.schabi.newpipe.extractor.utils.Utils; import java.io.Serializable; -import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -400,17 +399,21 @@ public class StreamItemAdapter extends BaseA @NonNull final Response response) { // try to get the format by content type // some mime types are not unique for every format, those are omitted - final List formats = MediaFormat.getAllFromMimeType( - response.getHeader("Content-Type")); - final List uniqueFormats = new ArrayList<>(formats.size()); - for (int i = 0; i < formats.size(); i++) { - final MediaFormat format = formats.get(i); - if (uniqueFormats.stream().filter(f -> f.id == format.id).count() == 0) { - uniqueFormats.add(format); + final String contentTypeHeader = response.getHeader("Content-Type"); + if (contentTypeHeader == null) { + return false; + } + + @Nullable MediaFormat foundFormat = null; + for (final MediaFormat format : MediaFormat.getAllFromMimeType(contentTypeHeader)) { + if (foundFormat == null) { + foundFormat = format; + } else if (foundFormat.id != format.id) { + return false; } } - if (uniqueFormats.size() == 1) { - streamsWrapper.setFormat(stream, uniqueFormats.get(0)); + if (foundFormat != null) { + streamsWrapper.setFormat(stream, foundFormat); return true; } return false; From 6c848b4766d6fc9549b9c78e13b01c24d4e019db Mon Sep 17 00:00:00 2001 From: TacoTheDank Date: Tue, 19 Sep 2023 16:30:09 -0400 Subject: [PATCH 080/172] Update Google Material library --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 051414ba0..831b758b9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -229,7 +229,7 @@ dependencies { implementation 'androidx.viewpager2:viewpager2:1.1.0-beta01' implementation "androidx.work:work-runtime-ktx:${androidxWorkVersion}" implementation "androidx.work:work-rxjava3:${androidxWorkVersion}" - implementation 'com.google.android.material:material:1.6.1' + implementation 'com.google.android.material:material:1.9.0' /** Third-party libraries **/ // Instance state boilerplate elimination From b1faed586d446b98bd49bfc60837c0bb176fe7a0 Mon Sep 17 00:00:00 2001 From: TacoTheDank Date: Tue, 19 Sep 2023 16:32:37 -0400 Subject: [PATCH 081/172] Replace MathUtils.clamp with Kotlin coerceIn --- .../schabi/newpipe/local/feed/FeedFragment.kt | 3 +-- .../gesture/MainPlayerGestureListener.kt | 3 +-- .../gesture/PopupPlayerGestureListener.kt | 19 ++++++++++--------- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/local/feed/FeedFragment.kt b/app/src/main/java/org/schabi/newpipe/local/feed/FeedFragment.kt index 4f153dcf8..83882d35f 100644 --- a/app/src/main/java/org/schabi/newpipe/local/feed/FeedFragment.kt +++ b/app/src/main/java/org/schabi/newpipe/local/feed/FeedFragment.kt @@ -38,7 +38,6 @@ import android.view.ViewGroup import android.widget.Button import androidx.appcompat.app.AlertDialog import androidx.core.content.edit -import androidx.core.math.MathUtils import androidx.core.os.bundleOf import androidx.core.view.isVisible import androidx.lifecycle.ViewModelProvider @@ -589,7 +588,7 @@ class FeedFragment : BaseStateFragment() { // state until the user scrolls them out of the visible area which causes a update/bind-call groupAdapter.notifyItemRangeChanged( 0, - MathUtils.clamp(highlightCount, lastNewItemsCount, groupAdapter.itemCount) + highlightCount.coerceIn(lastNewItemsCount, groupAdapter.itemCount) ) if (highlightCount > 0) { diff --git a/app/src/main/java/org/schabi/newpipe/player/gesture/MainPlayerGestureListener.kt b/app/src/main/java/org/schabi/newpipe/player/gesture/MainPlayerGestureListener.kt index 0d28f2f58..8acd70413 100644 --- a/app/src/main/java/org/schabi/newpipe/player/gesture/MainPlayerGestureListener.kt +++ b/app/src/main/java/org/schabi/newpipe/player/gesture/MainPlayerGestureListener.kt @@ -7,7 +7,6 @@ import android.view.View.OnTouchListener import android.widget.ProgressBar import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.content.res.AppCompatResources -import androidx.core.math.MathUtils import androidx.core.view.isVisible import org.schabi.newpipe.MainActivity import org.schabi.newpipe.R @@ -113,7 +112,7 @@ class MainPlayerGestureListener( // Update progress bar val oldBrightness = layoutParams.screenBrightness - bar.progress = (bar.max * MathUtils.clamp(oldBrightness, 0f, 1f)).toInt() + bar.progress = (bar.max * oldBrightness.coerceIn(0f, 1f)).toInt() bar.incrementProgressBy(distanceY.toInt()) // Update brightness diff --git a/app/src/main/java/org/schabi/newpipe/player/gesture/PopupPlayerGestureListener.kt b/app/src/main/java/org/schabi/newpipe/player/gesture/PopupPlayerGestureListener.kt index a540c0ab0..23edcaeb8 100644 --- a/app/src/main/java/org/schabi/newpipe/player/gesture/PopupPlayerGestureListener.kt +++ b/app/src/main/java/org/schabi/newpipe/player/gesture/PopupPlayerGestureListener.kt @@ -4,7 +4,7 @@ import android.util.Log import android.view.MotionEvent import android.view.View import android.view.ViewConfiguration -import androidx.core.math.MathUtils +import androidx.core.view.isVisible import org.schabi.newpipe.MainActivity import org.schabi.newpipe.ktx.AnimationType import org.schabi.newpipe.ktx.animate @@ -235,14 +235,16 @@ class PopupPlayerGestureListener( isMoving = true val diffX = (movingEvent.rawX - initialEvent.rawX) - val posX = MathUtils.clamp( - initialPopupX + diffX, - 0f, (playerUi.screenWidth - playerUi.popupLayoutParams.width).toFloat() + val posX = (initialPopupX + diffX).coerceIn( + 0f, + (playerUi.screenWidth - playerUi.popupLayoutParams.width).toFloat() + .coerceAtLeast(0f) ) val diffY = (movingEvent.rawY - initialEvent.rawY) - val posY = MathUtils.clamp( - initialPopupY + diffY, - 0f, (playerUi.screenHeight - playerUi.popupLayoutParams.height).toFloat() + val posY = (initialPopupY + diffY).coerceIn( + 0f, + (playerUi.screenHeight - playerUi.popupLayoutParams.height).toFloat() + .coerceAtLeast(0f) ) playerUi.popupLayoutParams.x = posX.toInt() @@ -251,8 +253,7 @@ class PopupPlayerGestureListener( // -- Determine if the ClosingOverlayView (red X) has to be shown or hidden -- val showClosingOverlayView: Boolean = playerUi.isInsideClosingRadius(movingEvent) // Check if an view is in expected state and if not animate it into the correct state - val expectedVisibility = if (showClosingOverlayView) View.VISIBLE else View.GONE - if (binding.closingOverlay.visibility != expectedVisibility) { + if (binding.closingOverlay.isVisible != showClosingOverlayView) { binding.closingOverlay.animate(showClosingOverlayView, 200) } From 748c2babe9c34e533ed7fe97693d284f5d752fd1 Mon Sep 17 00:00:00 2001 From: TobiGr Date: Wed, 20 Sep 2023 15:41:21 +0200 Subject: [PATCH 082/172] Add comments and annotations --- .../newpipe/fragments/list/search/SearchFragment.java | 6 ++++++ .../schabi/newpipe/player/playqueue/SinglePlayQueue.java | 8 ++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java index 26a283229..4bae6f1ca 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java @@ -167,6 +167,10 @@ public class SearchFragment extends BaseListFragment items, final int index) { + public SinglePlayQueue(@NonNull final List items, final int index) { super(index, playQueueItemsOf(items)); } - private static List playQueueItemsOf(final List items) { + private static List playQueueItemsOf(@NonNull final List items) { final List playQueueItems = new ArrayList<>(items.size()); for (final StreamInfoItem item : items) { playQueueItems.add(new PlayQueueItem(item)); @@ -39,5 +41,7 @@ public final class SinglePlayQueue extends PlayQueue { @Override public void fetch() { + // Item was already passed in constructor. + // No further items need to be fetched as this is a PlayQueue with only one item } } From 8bf2d996ea681271447e115cd3d535358e453e0c Mon Sep 17 00:00:00 2001 From: TobiGr Date: Wed, 20 Sep 2023 15:41:57 +0200 Subject: [PATCH 083/172] Reorder the modifiers to comply with the Java Language Specification. --- .../java/us/shandian/giga/get/DownloadInitializer.java | 8 ++++---- .../main/java/us/shandian/giga/io/CircularFileWriter.java | 8 ++++---- .../java/us/shandian/giga/service/DownloadManager.java | 6 +++--- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/us/shandian/giga/get/DownloadInitializer.java b/app/src/main/java/us/shandian/giga/get/DownloadInitializer.java index 1d5a93588..84e968b43 100644 --- a/app/src/main/java/us/shandian/giga/get/DownloadInitializer.java +++ b/app/src/main/java/us/shandian/giga/get/DownloadInitializer.java @@ -18,10 +18,10 @@ import static org.schabi.newpipe.BuildConfig.DEBUG; import static us.shandian.giga.get.DownloadMission.ERROR_HTTP_FORBIDDEN; public class DownloadInitializer extends Thread { - private final static String TAG = "DownloadInitializer"; - final static int mId = 0; - private final static int RESERVE_SPACE_DEFAULT = 5 * 1024 * 1024;// 5 MiB - private final static int RESERVE_SPACE_MAXIMUM = 150 * 1024 * 1024;// 150 MiB + private static final String TAG = "DownloadInitializer"; + static final int mId = 0; + private static final int RESERVE_SPACE_DEFAULT = 5 * 1024 * 1024;// 5 MiB + private static final int RESERVE_SPACE_MAXIMUM = 150 * 1024 * 1024;// 150 MiB private final DownloadMission mMission; private HttpURLConnection mConn; diff --git a/app/src/main/java/us/shandian/giga/io/CircularFileWriter.java b/app/src/main/java/us/shandian/giga/io/CircularFileWriter.java index dbceeb091..4473fa7f9 100644 --- a/app/src/main/java/us/shandian/giga/io/CircularFileWriter.java +++ b/app/src/main/java/us/shandian/giga/io/CircularFileWriter.java @@ -11,10 +11,10 @@ import java.util.Objects; public class CircularFileWriter extends SharpStream { - private final static int QUEUE_BUFFER_SIZE = 8 * 1024;// 8 KiB - private final static int COPY_BUFFER_SIZE = 128 * 1024; // 128 KiB - private final static int NOTIFY_BYTES_INTERVAL = 64 * 1024;// 64 KiB - private final static int THRESHOLD_AUX_LENGTH = 15 * 1024 * 1024;// 15 MiB + private static final int QUEUE_BUFFER_SIZE = 8 * 1024;// 8 KiB + private static final int COPY_BUFFER_SIZE = 128 * 1024; // 128 KiB + private static final int NOTIFY_BYTES_INTERVAL = 64 * 1024;// 64 KiB + private static final int THRESHOLD_AUX_LENGTH = 15 * 1024 * 1024;// 15 MiB private final OffsetChecker callback; diff --git a/app/src/main/java/us/shandian/giga/service/DownloadManager.java b/app/src/main/java/us/shandian/giga/service/DownloadManager.java index 7c248c2b6..9b90fa14b 100644 --- a/app/src/main/java/us/shandian/giga/service/DownloadManager.java +++ b/app/src/main/java/us/shandian/giga/service/DownloadManager.java @@ -30,9 +30,9 @@ public class DownloadManager { enum NetworkState {Unavailable, Operating, MeteredOperating} - public final static int SPECIAL_NOTHING = 0; - public final static int SPECIAL_PENDING = 1; - public final static int SPECIAL_FINISHED = 2; + public static final int SPECIAL_NOTHING = 0; + public static final int SPECIAL_PENDING = 1; + public static final int SPECIAL_FINISHED = 2; public static final String TAG_AUDIO = "audio"; public static final String TAG_VIDEO = "video"; From 0acc3532c9cc29ca8b38375a65d878c095f7a376 Mon Sep 17 00:00:00 2001 From: TobiGr Date: Wed, 20 Sep 2023 15:42:09 +0200 Subject: [PATCH 084/172] Remove useless override --- .../org/schabi/newpipe/local/bookmark/BookmarkFragment.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java b/app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java index 0df84d6c0..7ae0563a5 100644 --- a/app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java +++ b/app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java @@ -91,11 +91,6 @@ public final class BookmarkFragment extends BaseLocalListFragment Date: Mon, 18 Sep 2023 05:08:53 +0530 Subject: [PATCH 085/172] Bump AGP to 8.1.1 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index c14a1fcd7..f1c861c9f 100644 --- a/build.gradle +++ b/build.gradle @@ -7,7 +7,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:8.0.2' + classpath 'com.android.tools.build:gradle:8.1.1' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // NOTE: Do not place your application dependencies here; they belong From a1f2b7f8e83e0427a099d7c12b3fc416d96616f7 Mon Sep 17 00:00:00 2001 From: Isira Seneviratne Date: Mon, 18 Sep 2023 05:14:15 +0530 Subject: [PATCH 086/172] Switch to Files.createDirectories() --- .../schabi/newpipe/streams/io/StoredDirectoryHelper.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/streams/io/StoredDirectoryHelper.java b/app/src/main/java/org/schabi/newpipe/streams/io/StoredDirectoryHelper.java index 1b74c90a5..53dc5cf2a 100644 --- a/app/src/main/java/org/schabi/newpipe/streams/io/StoredDirectoryHelper.java +++ b/app/src/main/java/org/schabi/newpipe/streams/io/StoredDirectoryHelper.java @@ -180,9 +180,12 @@ public class StoredDirectoryHelper { */ public boolean mkdirs() { if (docTree == null) { - // TODO: Use Files.createDirectories() when AGP 8.1 is available: - // https://issuetracker.google.com/issues/282544786 - return Files.exists(ioTree) || ioTree.toFile().mkdirs(); + try { + Files.createDirectories(ioTree); + } catch (final IOException e) { + Log.e(TAG, "Error while creating directories at " + ioTree, e); + } + return Files.exists(ioTree); } if (docTree.exists()) { From 779ea19222647065199e99d29b6780916491ac4c Mon Sep 17 00:00:00 2001 From: TobiGr Date: Wed, 20 Sep 2023 19:41:45 +0200 Subject: [PATCH 087/172] Fix doc formatting --- .../org/schabi/newpipe/streams/io/StoredDirectoryHelper.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/streams/io/StoredDirectoryHelper.java b/app/src/main/java/org/schabi/newpipe/streams/io/StoredDirectoryHelper.java index 53dc5cf2a..74fc74c76 100644 --- a/app/src/main/java/org/schabi/newpipe/streams/io/StoredDirectoryHelper.java +++ b/app/src/main/java/org/schabi/newpipe/streams/io/StoredDirectoryHelper.java @@ -170,8 +170,8 @@ public class StoredDirectoryHelper { /** * Only using Java I/O. Creates the directory named by this abstract pathname, including any - * necessary but nonexistent parent directories. Note that if this - * operation fails it may have succeeded in creating some of the necessary + * necessary but nonexistent parent directories. + * Note that if this operation fails it may have succeeded in creating some of the necessary * parent directories. * * @return true if and only if the directory was created, From 2a1b506d98273785605527eedbb06cddae9f24eb Mon Sep 17 00:00:00 2001 From: TobiGr Date: Mon, 18 Sep 2023 03:11:28 +0200 Subject: [PATCH 088/172] Improved accessibility of player interfaces --- .../newpipe/player/PlayQueueActivity.java | 14 ++++--- .../newpipe/player/ui/VideoPlayerUi.java | 35 +++++++++++++++-- .../activity_player_queue_control.xml | 14 +++---- .../main/res/layout/fragment_video_detail.xml | 5 ++- app/src/main/res/layout/play_queue_item.xml | 1 + app/src/main/res/layout/player.xml | 39 ++++++++++++------- .../res/layout/player_popup_close_overlay.xml | 1 + app/src/main/res/values/strings.xml | 11 ++++++ 8 files changed, 86 insertions(+), 34 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/player/PlayQueueActivity.java b/app/src/main/java/org/schabi/newpipe/player/PlayQueueActivity.java index 4baadf69f..defc8ba21 100644 --- a/app/src/main/java/org/schabi/newpipe/player/PlayQueueActivity.java +++ b/app/src/main/java/org/schabi/newpipe/player/PlayQueueActivity.java @@ -16,6 +16,7 @@ import android.view.MenuItem; import android.view.SubMenu; import android.view.View; import android.view.ViewGroup; +import android.widget.ImageButton; import android.widget.SeekBar; import androidx.annotation.Nullable; @@ -531,18 +532,19 @@ public final class PlayQueueActivity extends AppCompatActivity //////////////////////////////////////////////////////////////////////////// private void onStateChanged(final int state) { + final ImageButton playPauseButton = queueControlBinding.controlPlayPause; switch (state) { case Player.STATE_PAUSED: - queueControlBinding.controlPlayPause - .setImageResource(R.drawable.ic_play_arrow); + playPauseButton.setImageResource(R.drawable.ic_play_arrow); + playPauseButton.setContentDescription(getString(R.string.play)); break; case Player.STATE_PLAYING: - queueControlBinding.controlPlayPause - .setImageResource(R.drawable.ic_pause); + playPauseButton.setImageResource(R.drawable.ic_pause); + playPauseButton.setContentDescription(getString(R.string.pause)); break; case Player.STATE_COMPLETED: - queueControlBinding.controlPlayPause - .setImageResource(R.drawable.ic_replay); + playPauseButton.setImageResource(R.drawable.ic_replay); + playPauseButton.setContentDescription(getString(R.string.replay)); break; default: break; diff --git a/app/src/main/java/org/schabi/newpipe/player/ui/VideoPlayerUi.java b/app/src/main/java/org/schabi/newpipe/player/ui/VideoPlayerUi.java index 2638ff041..119c43b95 100644 --- a/app/src/main/java/org/schabi/newpipe/player/ui/VideoPlayerUi.java +++ b/app/src/main/java/org/schabi/newpipe/player/ui/VideoPlayerUi.java @@ -41,6 +41,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.content.res.AppCompatResources; import androidx.appcompat.view.ContextThemeWrapper; +import androidx.appcompat.widget.AppCompatImageButton; import androidx.appcompat.widget.PopupMenu; import androidx.core.graphics.BitmapCompat; import androidx.core.graphics.Insets; @@ -103,6 +104,9 @@ public abstract class VideoPlayerUi extends PlayerUi implements SeekBar.OnSeekBa // other constants (TODO remove playback speeds and use normal menu for popup, too) private static final float[] PLAYBACK_SPEEDS = {0.5f, 0.75f, 1.0f, 1.25f, 1.5f, 1.75f, 2.0f}; + private enum PlayButtonAction { + PLAY, PAUSE, REPLAY + } /*////////////////////////////////////////////////////////////////////////// // Views @@ -755,6 +759,29 @@ public abstract class VideoPlayerUi extends PlayerUi implements SeekBar.OnSeekBa // only MainPlayerUi can be in fullscreen, so overridden there return false; } + + /** + * Update the play/pause button ({@link R.id.playPauseButton}) to reflect the action + * that will be performed when the button is clicked.. + * @param action the action that is performed when the play/pause button is clicked + */ + private void updatePlayPauseButton(final PlayButtonAction action) { + final AppCompatImageButton button = binding.playPauseButton; + switch (action) { + case PLAY: + button.setContentDescription(context.getString(R.string.play)); + button.setImageResource(R.drawable.ic_play_arrow); + break; + case PAUSE: + button.setContentDescription(context.getString(R.string.pause)); + button.setImageResource(R.drawable.ic_pause); + break; + case REPLAY: + button.setContentDescription(context.getString(R.string.replay)); + button.setImageResource(R.drawable.ic_replay); + break; + } + } //endregion @@ -785,7 +812,7 @@ public abstract class VideoPlayerUi extends PlayerUi implements SeekBar.OnSeekBa animate(binding.loadingPanel, true, 0); animate(binding.surfaceForeground, true, 100); - binding.playPauseButton.setImageResource(R.drawable.ic_play_arrow); + updatePlayPauseButton(PlayButtonAction.PLAY); animatePlayButtons(false, 100); binding.getRoot().setKeepScreenOn(false); } @@ -806,7 +833,7 @@ public abstract class VideoPlayerUi extends PlayerUi implements SeekBar.OnSeekBa animate(binding.playPauseButton, false, 80, AnimationType.SCALE_AND_ALPHA, 0, () -> { - binding.playPauseButton.setImageResource(R.drawable.ic_pause); + updatePlayPauseButton(PlayButtonAction.PAUSE); animatePlayButtons(true, 200); if (!isAnyListViewOpen()) { binding.playPauseButton.requestFocus(); @@ -836,7 +863,7 @@ public abstract class VideoPlayerUi extends PlayerUi implements SeekBar.OnSeekBa animate(binding.playPauseButton, false, 80, AnimationType.SCALE_AND_ALPHA, 0, () -> { - binding.playPauseButton.setImageResource(R.drawable.ic_play_arrow); + updatePlayPauseButton(PlayButtonAction.PLAY); animatePlayButtons(true, 200); if (!isAnyListViewOpen()) { binding.playPauseButton.requestFocus(); @@ -860,7 +887,7 @@ public abstract class VideoPlayerUi extends PlayerUi implements SeekBar.OnSeekBa animate(binding.playPauseButton, false, 0, AnimationType.SCALE_AND_ALPHA, 0, () -> { - binding.playPauseButton.setImageResource(R.drawable.ic_replay); + updatePlayPauseButton(PlayButtonAction.REPLAY); animatePlayButtons(true, DEFAULT_CONTROLS_DURATION); }); diff --git a/app/src/main/res/layout-land/activity_player_queue_control.xml b/app/src/main/res/layout-land/activity_player_queue_control.xml index 7d3b43ecc..a5df5e566 100644 --- a/app/src/main/res/layout-land/activity_player_queue_control.xml +++ b/app/src/main/res/layout-land/activity_player_queue_control.xml @@ -123,7 +123,7 @@ android:scaleType="fitCenter" android:src="@drawable/exo_controls_rewind" android:tint="?attr/colorAccent" - tools:ignore="ContentDescription" /> + android:contentDescription="@string/rewind" /> + android:contentDescription="@string/pause" /> + android:contentDescription="@string/forward" /> + android:contentDescription="@string/previous_stream" /> + android:contentDescription="@string/notification_action_repeat" /> + android:contentDescription="@string/notification_action_shuffle" /> + android:contentDescription="@string/next_stream" /> diff --git a/app/src/main/res/layout/fragment_video_detail.xml b/app/src/main/res/layout/fragment_video_detail.xml index 9aaf6d8d6..1a4711581 100644 --- a/app/src/main/res/layout/fragment_video_detail.xml +++ b/app/src/main/res/layout/fragment_video_detail.xml @@ -614,7 +614,8 @@ android:gravity="center_vertical" android:paddingLeft="@dimen/video_item_search_padding" android:paddingRight="@dimen/video_item_search_padding" - android:scaleType="fitCenter" /> + android:scaleType="fitCenter" + tools:ignore="ContentDescription" /> + tools:ignore="RtlHardcoded" /> diff --git a/app/src/main/res/layout/player.xml b/app/src/main/res/layout/player.xml index 89f1ed88e..99b514bb0 100644 --- a/app/src/main/res/layout/player.xml +++ b/app/src/main/res/layout/player.xml @@ -115,7 +115,8 @@ android:src="@drawable/ic_close" android:visibility="gone" app:tint="@color/white" - tools:ignore="ContentDescription,RtlHardcoded" /> + android:contentDescription="@string/close" + tools:ignore="RtlHardcoded" /> + android:contentDescription="@string/open_play_queue" + tools:ignore="RtlHardcoded" /> + android:contentDescription="@string/chapters" + tools:ignore="RtlHardcoded" /> + android:contentDescription="@string/more_options" + tools:ignore="RtlHardcoded" /> @@ -368,9 +372,10 @@ android:padding="@dimen/player_main_buttons_padding" android:scaleType="fitCenter" android:src="@drawable/ic_fullscreen" + android:contentDescription="@string/toggle_fullscreen" android:visibility="gone" app:tint="@color/white" - tools:ignore="ContentDescription,RtlHardcoded" + tools:ignore="RtlHardcoded" tools:visibility="visible" /> @@ -493,8 +498,9 @@ android:scaleType="fitCenter" android:src="@drawable/ic_fullscreen" android:visibility="gone" + android:contentDescription="@string/toggle_screen_orientation" app:tint="@color/white" - tools:ignore="ContentDescription,RtlHardcoded" + tools:ignore="RtlHardcoded" tools:visibility="visible" /> @@ -517,8 +523,8 @@ android:focusable="true" android:scaleType="fitCenter" android:src="@drawable/ic_previous" - app:tint="@color/white" - tools:ignore="ContentDescription" /> + android:contentDescription="@string/previous_stream" + app:tint="@color/white" /> + android:contentDescription="@string/pause" + app:tint="@color/white" /> + android:contentDescription="@string/next_stream" + app:tint="@color/white" /> @@ -595,7 +601,8 @@ android:scaleType="fitXY" android:src="@drawable/exo_controls_repeat_off" android:tint="?attr/colorAccent" - tools:ignore="ContentDescription,RtlHardcoded" /> + android:contentDescription="@string/notification_action_repeat" + tools:ignore="RtlHardcoded" /> + android:contentDescription="@string/notification_action_shuffle" + tools:ignore="RtlHardcoded" /> + android:contentDescription="@string/add_to_playlist" + tools:ignore="RtlHardcoded" /> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index e6fb35a16..e5bbffaff 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -811,4 +811,15 @@ About Channel tabs What tabs are shown on the channel pages + Open play queue + Toggle fullscreen + Toggle screen orientation + Previous stream + Next stream + Play + Replay + More options + Duration + Rewind + Forward \ No newline at end of file From af2375948de932dde1ac3e186ab40c60f86d531f Mon Sep 17 00:00:00 2001 From: Stypox Date: Mon, 1 May 2023 23:11:48 +0200 Subject: [PATCH 089/172] Support obtaining multiple images from the extractor --- app/build.gradle | 2 +- .../org/schabi/newpipe/QueueItemMenuUtil.java | 2 +- .../database/playlist/PlaylistStreamEntry.kt | 3 +- .../playlist/model/PlaylistRemoteEntity.java | 7 +- .../database/stream/StreamStatisticsEntry.kt | 3 +- .../database/stream/model/StreamEntity.kt | 10 ++- .../subscription/SubscriptionEntity.java | 7 +- .../fragments/detail/DescriptionFragment.java | 3 +- .../fragments/detail/VideoDetailFragment.java | 25 +++--- .../list/channel/ChannelAboutFragment.java | 5 +- .../list/channel/ChannelFragment.java | 13 ++- .../list/playlist/PlaylistFragment.java | 5 +- .../dialog/StreamDialogDefaultEntry.java | 2 +- .../holder/ChannelMiniInfoItemHolder.java | 2 +- .../holder/CommentsMiniInfoItemHolder.java | 2 +- .../holder/PlaylistMiniInfoItemHolder.java | 2 +- .../holder/StreamMiniInfoItemHolder.java | 2 +- .../subscription/SubscriptionFragment.kt | 3 +- .../local/subscription/SubscriptionManager.kt | 10 ++- .../local/subscription/item/ChannelItem.kt | 2 +- .../org/schabi/newpipe/player/Player.java | 13 +-- .../player/mediaitem/ExceptionTag.java | 3 +- .../player/mediaitem/StreamInfoTag.java | 3 +- .../mediasession/PlayQueueNavigator.java | 4 +- .../player/playqueue/PlayQueueItem.java | 16 ++-- .../playqueue/PlayQueueItemBuilder.java | 2 +- .../newpipe/player/ui/MainPlayerUi.java | 2 +- .../newpipe/player/ui/VideoPlayerUi.java | 2 +- .../schabi/newpipe/util/PicassoHelper.java | 87 ++++++++++++++++--- .../external_communication/ShareUtils.java | 25 ++++++ 30 files changed, 190 insertions(+), 77 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 831b758b9..aa7ac8720 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -197,7 +197,7 @@ dependencies { // name and the commit hash with the commit hash of the (pushed) commit you want to test // This works thanks to JitPack: https://jitpack.io/ implementation 'com.github.TeamNewPipe:nanojson:1d9e1aea9049fc9f85e68b43ba39fe7be1c1f751' - implementation 'com.github.TeamNewPipe:NewPipeExtractor:95a3cc0a173bba28c179f9f9503b1010ec6bff21' + implementation 'com.github.TeamNewPipe:NewPipeExtractor:3be76a6406d59f1fd8eedf5fab6552e6c2a3da76' implementation 'com.github.TeamNewPipe:NoNonsense-FilePicker:5.0.0' /** Checkstyle **/ diff --git a/app/src/main/java/org/schabi/newpipe/QueueItemMenuUtil.java b/app/src/main/java/org/schabi/newpipe/QueueItemMenuUtil.java index 3255489b0..e6177f6a3 100644 --- a/app/src/main/java/org/schabi/newpipe/QueueItemMenuUtil.java +++ b/app/src/main/java/org/schabi/newpipe/QueueItemMenuUtil.java @@ -75,7 +75,7 @@ public final class QueueItemMenuUtil { return true; case R.id.menu_item_share: shareText(context, item.getTitle(), item.getUrl(), - item.getThumbnailUrl()); + item.getThumbnails()); return true; case R.id.menu_item_download: fetchStreamInfoAndSaveToDatabase(context, item.getServiceId(), item.getUrl(), diff --git a/app/src/main/java/org/schabi/newpipe/database/playlist/PlaylistStreamEntry.kt b/app/src/main/java/org/schabi/newpipe/database/playlist/PlaylistStreamEntry.kt index d2543ae6d..3b6bc9593 100644 --- a/app/src/main/java/org/schabi/newpipe/database/playlist/PlaylistStreamEntry.kt +++ b/app/src/main/java/org/schabi/newpipe/database/playlist/PlaylistStreamEntry.kt @@ -7,6 +7,7 @@ import org.schabi.newpipe.database.playlist.model.PlaylistStreamEntity import org.schabi.newpipe.database.stream.model.StreamEntity import org.schabi.newpipe.database.stream.model.StreamStateEntity import org.schabi.newpipe.extractor.stream.StreamInfoItem +import org.schabi.newpipe.util.PicassoHelper data class PlaylistStreamEntry( @Embedded @@ -28,7 +29,7 @@ data class PlaylistStreamEntry( item.duration = streamEntity.duration item.uploaderName = streamEntity.uploader item.uploaderUrl = streamEntity.uploaderUrl - item.thumbnailUrl = streamEntity.thumbnailUrl + item.thumbnails = PicassoHelper.urlToImageList(streamEntity.thumbnailUrl) return item } diff --git a/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistRemoteEntity.java b/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistRemoteEntity.java index 2e9a15d7d..640b6d1fa 100644 --- a/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistRemoteEntity.java +++ b/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistRemoteEntity.java @@ -11,6 +11,7 @@ import androidx.room.PrimaryKey; import org.schabi.newpipe.database.playlist.PlaylistLocalItem; import org.schabi.newpipe.extractor.playlist.PlaylistInfo; import org.schabi.newpipe.util.Constants; +import org.schabi.newpipe.util.PicassoHelper; import static org.schabi.newpipe.database.LocalItem.LocalItemType.PLAYLIST_REMOTE_ITEM; import static org.schabi.newpipe.database.playlist.model.PlaylistRemoteEntity.REMOTE_PLAYLIST_NAME; @@ -69,8 +70,7 @@ public class PlaylistRemoteEntity implements PlaylistLocalItem { @Ignore public PlaylistRemoteEntity(final PlaylistInfo info) { this(info.getServiceId(), info.getName(), info.getUrl(), - info.getThumbnailUrl() == null - ? info.getUploaderAvatarUrl() : info.getThumbnailUrl(), + PicassoHelper.choosePreferredImage(info.getThumbnails()), info.getUploaderName(), info.getStreamCount()); } @@ -84,7 +84,8 @@ public class PlaylistRemoteEntity implements PlaylistLocalItem { && getStreamCount() == info.getStreamCount() && TextUtils.equals(getName(), info.getName()) && TextUtils.equals(getUrl(), info.getUrl()) - && TextUtils.equals(getThumbnailUrl(), info.getThumbnailUrl()) + && TextUtils.equals(getThumbnailUrl(), + PicassoHelper.choosePreferredImage(info.getThumbnails())) && TextUtils.equals(getUploader(), info.getUploaderName()); } diff --git a/app/src/main/java/org/schabi/newpipe/database/stream/StreamStatisticsEntry.kt b/app/src/main/java/org/schabi/newpipe/database/stream/StreamStatisticsEntry.kt index dc0db59d8..a268f8bbf 100644 --- a/app/src/main/java/org/schabi/newpipe/database/stream/StreamStatisticsEntry.kt +++ b/app/src/main/java/org/schabi/newpipe/database/stream/StreamStatisticsEntry.kt @@ -7,6 +7,7 @@ import org.schabi.newpipe.database.history.model.StreamHistoryEntity import org.schabi.newpipe.database.stream.model.StreamEntity import org.schabi.newpipe.database.stream.model.StreamStateEntity.STREAM_PROGRESS_MILLIS import org.schabi.newpipe.extractor.stream.StreamInfoItem +import org.schabi.newpipe.util.PicassoHelper import java.time.OffsetDateTime class StreamStatisticsEntry( @@ -30,7 +31,7 @@ class StreamStatisticsEntry( item.duration = streamEntity.duration item.uploaderName = streamEntity.uploader item.uploaderUrl = streamEntity.uploaderUrl - item.thumbnailUrl = streamEntity.thumbnailUrl + item.thumbnails = PicassoHelper.urlToImageList(streamEntity.thumbnailUrl) return item } diff --git a/app/src/main/java/org/schabi/newpipe/database/stream/model/StreamEntity.kt b/app/src/main/java/org/schabi/newpipe/database/stream/model/StreamEntity.kt index c56f91949..8b7639bbd 100644 --- a/app/src/main/java/org/schabi/newpipe/database/stream/model/StreamEntity.kt +++ b/app/src/main/java/org/schabi/newpipe/database/stream/model/StreamEntity.kt @@ -13,6 +13,7 @@ import org.schabi.newpipe.extractor.stream.StreamInfo import org.schabi.newpipe.extractor.stream.StreamInfoItem import org.schabi.newpipe.extractor.stream.StreamType import org.schabi.newpipe.player.playqueue.PlayQueueItem +import org.schabi.newpipe.util.PicassoHelper import java.io.Serializable import java.time.OffsetDateTime @@ -67,7 +68,7 @@ data class StreamEntity( constructor(item: StreamInfoItem) : this( serviceId = item.serviceId, url = item.url, title = item.name, streamType = item.streamType, duration = item.duration, uploader = item.uploaderName, - uploaderUrl = item.uploaderUrl, thumbnailUrl = item.thumbnailUrl, viewCount = item.viewCount, + uploaderUrl = item.uploaderUrl, thumbnailUrl = PicassoHelper.choosePreferredImage(item.thumbnails), viewCount = item.viewCount, textualUploadDate = item.textualUploadDate, uploadDate = item.uploadDate?.offsetDateTime(), isUploadDateApproximation = item.uploadDate?.isApproximation ) @@ -76,7 +77,7 @@ data class StreamEntity( constructor(info: StreamInfo) : this( serviceId = info.serviceId, url = info.url, title = info.name, streamType = info.streamType, duration = info.duration, uploader = info.uploaderName, - uploaderUrl = info.uploaderUrl, thumbnailUrl = info.thumbnailUrl, viewCount = info.viewCount, + uploaderUrl = info.uploaderUrl, thumbnailUrl = PicassoHelper.choosePreferredImage(info.thumbnails), viewCount = info.viewCount, textualUploadDate = info.textualUploadDate, uploadDate = info.uploadDate?.offsetDateTime(), isUploadDateApproximation = info.uploadDate?.isApproximation ) @@ -85,7 +86,8 @@ data class StreamEntity( constructor(item: PlayQueueItem) : this( serviceId = item.serviceId, url = item.url, title = item.title, streamType = item.streamType, duration = item.duration, uploader = item.uploader, - uploaderUrl = item.uploaderUrl, thumbnailUrl = item.thumbnailUrl + uploaderUrl = item.uploaderUrl, + thumbnailUrl = PicassoHelper.choosePreferredImage(item.thumbnails) ) fun toStreamInfoItem(): StreamInfoItem { @@ -93,7 +95,7 @@ data class StreamEntity( item.duration = duration item.uploaderName = uploader item.uploaderUrl = uploaderUrl - item.thumbnailUrl = thumbnailUrl + item.thumbnails = PicassoHelper.urlToImageList(thumbnailUrl) if (viewCount != null) item.viewCount = viewCount as Long item.textualUploadDate = textualUploadDate diff --git a/app/src/main/java/org/schabi/newpipe/database/subscription/SubscriptionEntity.java b/app/src/main/java/org/schabi/newpipe/database/subscription/SubscriptionEntity.java index 0e4bda490..a455cf258 100644 --- a/app/src/main/java/org/schabi/newpipe/database/subscription/SubscriptionEntity.java +++ b/app/src/main/java/org/schabi/newpipe/database/subscription/SubscriptionEntity.java @@ -10,6 +10,7 @@ import androidx.room.PrimaryKey; import org.schabi.newpipe.extractor.channel.ChannelInfo; import org.schabi.newpipe.extractor.channel.ChannelInfoItem; import org.schabi.newpipe.util.Constants; +import org.schabi.newpipe.util.PicassoHelper; import static org.schabi.newpipe.database.subscription.SubscriptionEntity.SUBSCRIPTION_SERVICE_ID; import static org.schabi.newpipe.database.subscription.SubscriptionEntity.SUBSCRIPTION_TABLE; @@ -57,8 +58,8 @@ public class SubscriptionEntity { final SubscriptionEntity result = new SubscriptionEntity(); result.setServiceId(info.getServiceId()); result.setUrl(info.getUrl()); - result.setData(info.getName(), info.getAvatarUrl(), info.getDescription(), - info.getSubscriberCount()); + result.setData(info.getName(), PicassoHelper.choosePreferredImage(info.getAvatars()), + info.getDescription(), info.getSubscriberCount()); return result; } @@ -138,7 +139,7 @@ public class SubscriptionEntity { @Ignore public ChannelInfoItem toChannelInfoItem() { final ChannelInfoItem item = new ChannelInfoItem(getServiceId(), getUrl(), getName()); - item.setThumbnailUrl(getAvatarUrl()); + item.setThumbnails(PicassoHelper.urlToImageList(getAvatarUrl())); item.setSubscriberCount(getSubscriberCount()); item.setDescription(getDescription()); return item; diff --git a/app/src/main/java/org/schabi/newpipe/fragments/detail/DescriptionFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/detail/DescriptionFragment.java index 92219883b..e7f257665 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/detail/DescriptionFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/detail/DescriptionFragment.java @@ -17,6 +17,7 @@ import org.schabi.newpipe.extractor.stream.StreamInfo; import org.schabi.newpipe.util.Localization; import java.util.List; +import org.schabi.newpipe.util.PicassoHelper; import icepick.State; @@ -113,7 +114,7 @@ public class DescriptionFragment extends BaseDescriptionFragment { addMetadataItem(inflater, layout, true, R.string.metadata_host, streamInfo.getHost()); addMetadataItem(inflater, layout, true, R.string.metadata_thumbnail_url, - streamInfo.getThumbnailUrl()); + PicassoHelper.choosePreferredImage(streamInfo.getThumbnails())); } private void addPrivacyMetadataItem(final LayoutInflater inflater, final LinearLayout layout) { diff --git a/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java index 686e102f1..2e6f493a3 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java @@ -71,6 +71,7 @@ import org.schabi.newpipe.error.ErrorInfo; import org.schabi.newpipe.error.ErrorUtil; import org.schabi.newpipe.error.ReCaptchaActivity; import org.schabi.newpipe.error.UserAction; +import org.schabi.newpipe.extractor.Image; import org.schabi.newpipe.extractor.InfoItem; import org.schabi.newpipe.extractor.NewPipe; import org.schabi.newpipe.extractor.exceptions.ContentNotSupportedException; @@ -483,7 +484,7 @@ public final class VideoDetailFragment }); binding.detailControlsShare.setOnClickListener(makeOnClickListener(info -> ShareUtils.shareText(requireContext(), info.getName(), info.getUrl(), - info.getThumbnailUrl()))); + info.getThumbnails()))); binding.detailControlsOpenInBrowser.setOnClickListener(makeOnClickListener(info -> ShareUtils.openUrlInBrowser(requireContext(), info.getUrl()))); binding.detailControlsPlayWithKodi.setOnClickListener(makeOnClickListener(info -> @@ -723,7 +724,7 @@ public final class VideoDetailFragment final boolean isPlayerStopped = !isPlayerAvailable() || player.isStopped(); if (playQueueItem != null && isPlayerStopped) { updateOverlayData(playQueueItem.getTitle(), - playQueueItem.getUploader(), playQueueItem.getThumbnailUrl()); + playQueueItem.getUploader(), playQueueItem.getThumbnails()); } } @@ -1536,13 +1537,13 @@ public final class VideoDetailFragment binding.detailSecondaryControlPanel.setVisibility(View.GONE); checkUpdateProgressInfo(info); - PicassoHelper.loadDetailsThumbnail(info.getThumbnailUrl()).tag(PICASSO_VIDEO_DETAILS_TAG) + PicassoHelper.loadDetailsThumbnail(info.getThumbnails()).tag(PICASSO_VIDEO_DETAILS_TAG) .into(binding.detailThumbnailImageView); showMetaInfoInTextView(info.getMetaInfo(), binding.detailMetaInfoTextView, binding.detailMetaInfoSeparator, disposables); if (!isPlayerAvailable() || player.isStopped()) { - updateOverlayData(info.getName(), info.getUploaderName(), info.getThumbnailUrl()); + updateOverlayData(info.getName(), info.getUploaderName(), info.getThumbnails()); } if (!info.getErrors().isEmpty()) { @@ -1587,7 +1588,7 @@ public final class VideoDetailFragment binding.detailUploaderTextView.setVisibility(View.GONE); } - PicassoHelper.loadAvatar(info.getUploaderAvatarUrl()).tag(PICASSO_VIDEO_DETAILS_TAG) + PicassoHelper.loadAvatar(info.getUploaderAvatars()).tag(PICASSO_VIDEO_DETAILS_TAG) .into(binding.detailSubChannelThumbnailView); binding.detailSubChannelThumbnailView.setVisibility(View.VISIBLE); binding.detailUploaderThumbnailView.setVisibility(View.GONE); @@ -1619,10 +1620,10 @@ public final class VideoDetailFragment binding.detailUploaderTextView.setVisibility(View.GONE); } - PicassoHelper.loadAvatar(info.getSubChannelAvatarUrl()).tag(PICASSO_VIDEO_DETAILS_TAG) + PicassoHelper.loadAvatar(info.getSubChannelAvatars()).tag(PICASSO_VIDEO_DETAILS_TAG) .into(binding.detailSubChannelThumbnailView); binding.detailSubChannelThumbnailView.setVisibility(View.VISIBLE); - PicassoHelper.loadAvatar(info.getUploaderAvatarUrl()).tag(PICASSO_VIDEO_DETAILS_TAG) + PicassoHelper.loadAvatar(info.getUploaderAvatars()).tag(PICASSO_VIDEO_DETAILS_TAG) .into(binding.detailUploaderThumbnailView); binding.detailUploaderThumbnailView.setVisibility(View.VISIBLE); } @@ -1797,7 +1798,7 @@ public final class VideoDetailFragment return; } - updateOverlayData(info.getName(), info.getUploaderName(), info.getThumbnailUrl()); + updateOverlayData(info.getName(), info.getUploaderName(), info.getThumbnails()); if (currentInfo != null && info.getUrl().equals(currentInfo.getUrl())) { return; } @@ -1826,7 +1827,7 @@ public final class VideoDetailFragment if (currentInfo != null) { updateOverlayData(currentInfo.getName(), currentInfo.getUploaderName(), - currentInfo.getThumbnailUrl()); + currentInfo.getThumbnails()); } updateOverlayPlayQueueButtonVisibility(); } @@ -2191,7 +2192,7 @@ public final class VideoDetailFragment playerHolder.stopService(); setInitialData(0, null, "", null); currentInfo = null; - updateOverlayData(null, null, null); + updateOverlayData(null, null, List.of()); } /*////////////////////////////////////////////////////////////////////////// @@ -2373,11 +2374,11 @@ public final class VideoDetailFragment private void updateOverlayData(@Nullable final String overlayTitle, @Nullable final String uploader, - @Nullable final String thumbnailUrl) { + @NonNull final List thumbnails) { binding.overlayTitleTextView.setText(isEmpty(overlayTitle) ? "" : overlayTitle); binding.overlayChannelTextView.setText(isEmpty(uploader) ? "" : uploader); binding.overlayThumbnail.setImageDrawable(null); - PicassoHelper.loadDetailsThumbnail(thumbnailUrl).tag(PICASSO_VIDEO_DETAILS_TAG) + PicassoHelper.loadDetailsThumbnail(thumbnails).tag(PICASSO_VIDEO_DETAILS_TAG) .into(binding.overlayThumbnail); } diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelAboutFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelAboutFragment.java index 543fd80f3..eebd12d20 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelAboutFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelAboutFragment.java @@ -17,6 +17,7 @@ import org.schabi.newpipe.extractor.stream.Description; import org.schabi.newpipe.fragments.detail.BaseDescriptionFragment; import org.schabi.newpipe.util.DeviceUtils; import org.schabi.newpipe.util.Localization; +import org.schabi.newpipe.util.PicassoHelper; import java.util.List; @@ -100,8 +101,8 @@ public class ChannelAboutFragment extends BaseDescriptionFragment { } addMetadataItem(inflater, layout, true, R.string.metadata_avatar_url, - channelInfo.getAvatarUrl()); + PicassoHelper.choosePreferredImage(channelInfo.getAvatars())); addMetadataItem(inflater, layout, true, R.string.metadata_banner_url, - channelInfo.getBannerUrl()); + PicassoHelper.choosePreferredImage(channelInfo.getBanners())); } } diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java index c1345180b..6b2c71337 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java @@ -1,6 +1,5 @@ package org.schabi.newpipe.fragments.list.channel; -import static org.schabi.newpipe.extractor.utils.Utils.isBlank; import static org.schabi.newpipe.ktx.TextViewUtils.animateTextColor; import static org.schabi.newpipe.ktx.ViewUtils.animate; import static org.schabi.newpipe.ktx.ViewUtils.animateBackgroundColor; @@ -234,7 +233,7 @@ public class ChannelFragment extends BaseStateFragment case R.id.menu_item_share: if (currentInfo != null) { ShareUtils.shareText(requireContext(), name, currentInfo.getOriginalUrl(), - currentInfo.getAvatarUrl()); + currentInfo.getAvatars()); } break; default: @@ -355,7 +354,7 @@ public class ChannelFragment extends BaseStateFragment channel.setServiceId(info.getServiceId()); channel.setUrl(info.getUrl()); channel.setData(info.getName(), - info.getAvatarUrl(), + PicassoHelper.choosePreferredImage(info.getAvatars()), info.getDescription(), info.getSubscriberCount()); channelSubscription = null; @@ -579,17 +578,17 @@ public class ChannelFragment extends BaseStateFragment currentInfo = result; setInitialData(result.getServiceId(), result.getOriginalUrl(), result.getName()); - if (PicassoHelper.getShouldLoadImages() && !isBlank(result.getBannerUrl())) { - PicassoHelper.loadBanner(result.getBannerUrl()).tag(PICASSO_CHANNEL_TAG) + if (PicassoHelper.getShouldLoadImages() && !result.getBanners().isEmpty()) { + PicassoHelper.loadBanner(result.getBanners()).tag(PICASSO_CHANNEL_TAG) .into(binding.channelBannerImage); } else { // do not waste space for the banner, if the user disabled images or there is not one binding.channelBannerImage.setImageDrawable(null); } - PicassoHelper.loadAvatar(result.getAvatarUrl()).tag(PICASSO_CHANNEL_TAG) + PicassoHelper.loadAvatar(result.getAvatars()).tag(PICASSO_CHANNEL_TAG) .into(binding.channelAvatarView); - PicassoHelper.loadAvatar(result.getParentChannelAvatarUrl()).tag(PICASSO_CHANNEL_TAG) + PicassoHelper.loadAvatar(result.getParentChannelAvatars()).tag(PICASSO_CHANNEL_TAG) .into(binding.subChannelAvatarView); binding.channelTitleView.setText(result.getName()); diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java index 2b7cf9446..9b3f693e1 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java @@ -234,7 +234,7 @@ public class PlaylistFragment extends BaseListInfoFragment ShareUtils.shareText(fragment.requireContext(), item.getName(), item.getUrl(), - item.getThumbnailUrl())), + item.getThumbnails())), /** * Opens a {@link DownloadDialog} after fetching some stream info. diff --git a/app/src/main/java/org/schabi/newpipe/info_list/holder/ChannelMiniInfoItemHolder.java b/app/src/main/java/org/schabi/newpipe/info_list/holder/ChannelMiniInfoItemHolder.java index 3b375d6eb..d971a6a6d 100644 --- a/app/src/main/java/org/schabi/newpipe/info_list/holder/ChannelMiniInfoItemHolder.java +++ b/app/src/main/java/org/schabi/newpipe/info_list/holder/ChannelMiniInfoItemHolder.java @@ -56,7 +56,7 @@ public class ChannelMiniInfoItemHolder extends InfoItemHolder { itemAdditionalDetailView.setText(getDetailLine(item)); } - PicassoHelper.loadAvatar(item.getThumbnailUrl()).into(itemThumbnailView); + PicassoHelper.loadAvatar(item.getThumbnails()).into(itemThumbnailView); itemView.setOnClickListener(view -> { if (itemBuilder.getOnChannelSelectedListener() != null) { diff --git a/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentsMiniInfoItemHolder.java b/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentsMiniInfoItemHolder.java index 1c8db26d6..d69be077d 100644 --- a/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentsMiniInfoItemHolder.java +++ b/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentsMiniInfoItemHolder.java @@ -97,7 +97,7 @@ public class CommentsMiniInfoItemHolder extends InfoItemHolder { } final CommentsInfoItem item = (CommentsInfoItem) infoItem; - PicassoHelper.loadAvatar(item.getUploaderAvatarUrl()).into(itemThumbnailView); + PicassoHelper.loadAvatar(item.getUploaderAvatars()).into(itemThumbnailView); if (PicassoHelper.getShouldLoadImages()) { itemThumbnailView.setVisibility(View.VISIBLE); itemRoot.setPadding(commentVerticalPadding, commentVerticalPadding, diff --git a/app/src/main/java/org/schabi/newpipe/info_list/holder/PlaylistMiniInfoItemHolder.java b/app/src/main/java/org/schabi/newpipe/info_list/holder/PlaylistMiniInfoItemHolder.java index bf5f57db3..62c7c27eb 100644 --- a/app/src/main/java/org/schabi/newpipe/info_list/holder/PlaylistMiniInfoItemHolder.java +++ b/app/src/main/java/org/schabi/newpipe/info_list/holder/PlaylistMiniInfoItemHolder.java @@ -46,7 +46,7 @@ public class PlaylistMiniInfoItemHolder extends InfoItemHolder { .localizeStreamCountMini(itemStreamCountView.getContext(), item.getStreamCount())); itemUploaderView.setText(item.getUploaderName()); - PicassoHelper.loadPlaylistThumbnail(item.getThumbnailUrl()).into(itemThumbnailView); + PicassoHelper.loadPlaylistThumbnail(item.getThumbnails()).into(itemThumbnailView); itemView.setOnClickListener(view -> { if (itemBuilder.getOnPlaylistSelectedListener() != null) { diff --git a/app/src/main/java/org/schabi/newpipe/info_list/holder/StreamMiniInfoItemHolder.java b/app/src/main/java/org/schabi/newpipe/info_list/holder/StreamMiniInfoItemHolder.java index 6dd06e47f..796ea63b3 100644 --- a/app/src/main/java/org/schabi/newpipe/info_list/holder/StreamMiniInfoItemHolder.java +++ b/app/src/main/java/org/schabi/newpipe/info_list/holder/StreamMiniInfoItemHolder.java @@ -87,7 +87,7 @@ public class StreamMiniInfoItemHolder extends InfoItemHolder { } // Default thumbnail is shown on error, while loading and if the url is empty - PicassoHelper.loadThumbnail(item.getThumbnailUrl()).into(itemThumbnailView); + PicassoHelper.loadThumbnail(item.getThumbnails()).into(itemThumbnailView); itemView.setOnClickListener(view -> { if (itemBuilder.getOnStreamSelectedListener() != null) { diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionFragment.kt b/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionFragment.kt index dda4326e9..f428a7c1d 100644 --- a/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionFragment.kt +++ b/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionFragment.kt @@ -58,6 +58,7 @@ import org.schabi.newpipe.streams.io.NoFileManagerSafeGuard import org.schabi.newpipe.streams.io.StoredFileHelper import org.schabi.newpipe.util.NavigationHelper import org.schabi.newpipe.util.OnClickGesture +import org.schabi.newpipe.util.PicassoHelper import org.schabi.newpipe.util.ServiceHelper import org.schabi.newpipe.util.ThemeHelper.getGridSpanCountChannels import org.schabi.newpipe.util.external_communication.ShareUtils @@ -342,7 +343,7 @@ class SubscriptionFragment : BaseStateFragment() { when (i) { 0 -> ShareUtils.shareText( requireContext(), selectedItem.name, selectedItem.url, - selectedItem.thumbnailUrl + PicassoHelper.choosePreferredImage(selectedItem.thumbnails) ) 1 -> ShareUtils.openUrlInBrowser(requireContext(), selectedItem.url) 2 -> deleteChannel(selectedItem) diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionManager.kt b/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionManager.kt index 3c11ce152..a74ff305c 100644 --- a/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionManager.kt +++ b/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionManager.kt @@ -19,6 +19,7 @@ import org.schabi.newpipe.extractor.feed.FeedInfo import org.schabi.newpipe.extractor.stream.StreamInfoItem import org.schabi.newpipe.local.feed.FeedDatabaseManager import org.schabi.newpipe.util.ExtractorHelper +import org.schabi.newpipe.util.PicassoHelper class SubscriptionManager(context: Context) { private val database = NewPipeDatabase.getInstance(context) @@ -71,7 +72,12 @@ class SubscriptionManager(context: Context) { subscriptionTable.getSubscription(info.serviceId, info.url) .flatMapCompletable { Completable.fromRunnable { - it.setData(info.name, info.avatarUrl, info.description, info.subscriberCount) + it.setData( + info.name, + PicassoHelper.choosePreferredImage(info.avatars), + info.description, + info.subscriberCount + ) subscriptionTable.update(it) } } @@ -99,7 +105,7 @@ class SubscriptionManager(context: Context) { } else if (info is ChannelInfo) { subscriptionEntity.setData( info.name, - info.avatarUrl, + PicassoHelper.choosePreferredImage(info.avatars), info.description, info.subscriberCount ) diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/item/ChannelItem.kt b/app/src/main/java/org/schabi/newpipe/local/subscription/item/ChannelItem.kt index bee2e910a..07a4f11ff 100644 --- a/app/src/main/java/org/schabi/newpipe/local/subscription/item/ChannelItem.kt +++ b/app/src/main/java/org/schabi/newpipe/local/subscription/item/ChannelItem.kt @@ -39,7 +39,7 @@ class ChannelItem( itemChannelDescriptionView.text = infoItem.description } - PicassoHelper.loadAvatar(infoItem.thumbnailUrl).into(itemThumbnailView) + PicassoHelper.loadAvatar(infoItem.thumbnails).into(itemThumbnailView) gesturesListener?.run { viewHolder.root.setOnClickListener { selected(infoItem) } diff --git a/app/src/main/java/org/schabi/newpipe/player/Player.java b/app/src/main/java/org/schabi/newpipe/player/Player.java index 1a323176c..3ad03891e 100644 --- a/app/src/main/java/org/schabi/newpipe/player/Player.java +++ b/app/src/main/java/org/schabi/newpipe/player/Player.java @@ -87,6 +87,7 @@ import org.schabi.newpipe.error.ErrorInfo; import org.schabi.newpipe.error.ErrorUtil; import org.schabi.newpipe.error.UserAction; import org.schabi.newpipe.extractor.stream.AudioStream; +import org.schabi.newpipe.extractor.Image; import org.schabi.newpipe.extractor.stream.StreamInfo; import org.schabi.newpipe.extractor.stream.StreamType; import org.schabi.newpipe.extractor.stream.VideoStream; @@ -805,10 +806,10 @@ public final class Player implements PlaybackListener, Listener { }; } - private void loadCurrentThumbnail(final String url) { + private void loadCurrentThumbnail(final List thumbnails) { if (DEBUG) { - Log.d(TAG, "Thumbnail - loadCurrentThumbnail() called with url = [" - + (url == null ? "null" : url) + "]"); + Log.d(TAG, "Thumbnail - loadCurrentThumbnail() called with thumbnails = [" + + thumbnails.size() + "]"); } // first cancel any previous loading @@ -817,12 +818,12 @@ public final class Player implements PlaybackListener, Listener { // Unset currentThumbnail, since it is now outdated. This ensures it is not used in media // session metadata while the new thumbnail is being loaded by Picasso. onThumbnailLoaded(null); - if (isNullOrEmpty(url)) { + if (thumbnails.isEmpty()) { return; } // scale down the notification thumbnail for performance - PicassoHelper.loadScaledDownThumbnail(context, url) + PicassoHelper.loadScaledDownThumbnail(context, thumbnails) .tag(PICASSO_PLAYER_THUMBNAIL_TAG) .into(currentThumbnailTarget); } @@ -1792,7 +1793,7 @@ public final class Player implements PlaybackListener, Listener { maybeAutoQueueNextStream(info); - loadCurrentThumbnail(info.getThumbnailUrl()); + loadCurrentThumbnail(info.getThumbnails()); registerStreamViewed(); notifyMetadataUpdateToListeners(); diff --git a/app/src/main/java/org/schabi/newpipe/player/mediaitem/ExceptionTag.java b/app/src/main/java/org/schabi/newpipe/player/mediaitem/ExceptionTag.java index ebedf8c71..5a5360b34 100644 --- a/app/src/main/java/org/schabi/newpipe/player/mediaitem/ExceptionTag.java +++ b/app/src/main/java/org/schabi/newpipe/player/mediaitem/ExceptionTag.java @@ -3,6 +3,7 @@ package org.schabi.newpipe.player.mediaitem; import org.schabi.newpipe.extractor.stream.StreamInfo; import org.schabi.newpipe.extractor.stream.StreamType; import org.schabi.newpipe.player.playqueue.PlayQueueItem; +import org.schabi.newpipe.util.PicassoHelper; import java.util.List; import java.util.Optional; @@ -74,7 +75,7 @@ public final class ExceptionTag implements MediaItemTag { @Override public String getThumbnailUrl() { - return item.getThumbnailUrl(); + return PicassoHelper.choosePreferredImage(item.getThumbnails()); } @Override diff --git a/app/src/main/java/org/schabi/newpipe/player/mediaitem/StreamInfoTag.java b/app/src/main/java/org/schabi/newpipe/player/mediaitem/StreamInfoTag.java index 689f5c72b..eb3abec1f 100644 --- a/app/src/main/java/org/schabi/newpipe/player/mediaitem/StreamInfoTag.java +++ b/app/src/main/java/org/schabi/newpipe/player/mediaitem/StreamInfoTag.java @@ -6,6 +6,7 @@ import org.schabi.newpipe.extractor.stream.AudioStream; import org.schabi.newpipe.extractor.stream.StreamInfo; import org.schabi.newpipe.extractor.stream.StreamType; import org.schabi.newpipe.extractor.stream.VideoStream; +import org.schabi.newpipe.util.PicassoHelper; import java.util.Collections; import java.util.List; @@ -95,7 +96,7 @@ public final class StreamInfoTag implements MediaItemTag { @Override public String getThumbnailUrl() { - return streamInfo.getThumbnailUrl(); + return PicassoHelper.choosePreferredImage(streamInfo.getThumbnails()); } @Override diff --git a/app/src/main/java/org/schabi/newpipe/player/mediasession/PlayQueueNavigator.java b/app/src/main/java/org/schabi/newpipe/player/mediasession/PlayQueueNavigator.java index 2e54b1129..327c2befe 100644 --- a/app/src/main/java/org/schabi/newpipe/player/mediasession/PlayQueueNavigator.java +++ b/app/src/main/java/org/schabi/newpipe/player/mediasession/PlayQueueNavigator.java @@ -20,6 +20,7 @@ import com.google.android.exoplayer2.util.Util; import org.schabi.newpipe.player.Player; import org.schabi.newpipe.player.playqueue.PlayQueue; import org.schabi.newpipe.player.playqueue.PlayQueueItem; +import org.schabi.newpipe.util.PicassoHelper; import java.util.ArrayList; import java.util.Collections; @@ -137,7 +138,8 @@ public class PlayQueueNavigator implements MediaSessionConnector.QueueNavigator .putLong(MediaMetadataCompat.METADATA_KEY_NUM_TRACKS, player.getPlayQueue().size()); descBuilder.setExtras(additionalMetadata); - final Uri thumbnailUri = Uri.parse(item.getThumbnailUrl()); + final Uri thumbnailUri = Uri.parse( + PicassoHelper.choosePreferredImage(item.getThumbnails())); if (thumbnailUri != null) { descBuilder.setIconUri(thumbnailUri); } diff --git a/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueItem.java b/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueItem.java index bf31ea9b1..759c51267 100644 --- a/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueItem.java +++ b/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueItem.java @@ -3,12 +3,14 @@ package org.schabi.newpipe.player.playqueue; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import org.schabi.newpipe.extractor.Image; import org.schabi.newpipe.extractor.stream.StreamInfo; import org.schabi.newpipe.extractor.stream.StreamInfoItem; import org.schabi.newpipe.extractor.stream.StreamType; import org.schabi.newpipe.util.ExtractorHelper; import java.io.Serializable; +import java.util.List; import io.reactivex.rxjava3.core.Single; import io.reactivex.rxjava3.schedulers.Schedulers; @@ -24,7 +26,7 @@ public class PlayQueueItem implements Serializable { private final int serviceId; private final long duration; @NonNull - private final String thumbnailUrl; + private final List thumbnails; @NonNull private final String uploader; private final String uploaderUrl; @@ -38,7 +40,7 @@ public class PlayQueueItem implements Serializable { PlayQueueItem(@NonNull final StreamInfo info) { this(info.getName(), info.getUrl(), info.getServiceId(), info.getDuration(), - info.getThumbnailUrl(), info.getUploaderName(), + info.getThumbnails(), info.getUploaderName(), info.getUploaderUrl(), info.getStreamType()); if (info.getStartPosition() > 0) { @@ -48,20 +50,20 @@ public class PlayQueueItem implements Serializable { PlayQueueItem(@NonNull final StreamInfoItem item) { this(item.getName(), item.getUrl(), item.getServiceId(), item.getDuration(), - item.getThumbnailUrl(), item.getUploaderName(), + item.getThumbnails(), item.getUploaderName(), item.getUploaderUrl(), item.getStreamType()); } @SuppressWarnings("ParameterNumber") private PlayQueueItem(@Nullable final String name, @Nullable final String url, final int serviceId, final long duration, - @Nullable final String thumbnailUrl, @Nullable final String uploader, + final List thumbnails, @Nullable final String uploader, final String uploaderUrl, @NonNull final StreamType streamType) { this.title = name != null ? name : EMPTY_STRING; this.url = url != null ? url : EMPTY_STRING; this.serviceId = serviceId; this.duration = duration; - this.thumbnailUrl = thumbnailUrl != null ? thumbnailUrl : EMPTY_STRING; + this.thumbnails = thumbnails; this.uploader = uploader != null ? uploader : EMPTY_STRING; this.uploaderUrl = uploaderUrl; this.streamType = streamType; @@ -88,8 +90,8 @@ public class PlayQueueItem implements Serializable { } @NonNull - public String getThumbnailUrl() { - return thumbnailUrl; + public List getThumbnails() { + return thumbnails; } @NonNull diff --git a/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueItemBuilder.java b/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueItemBuilder.java index e7aeb9638..19101a31d 100644 --- a/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueItemBuilder.java +++ b/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueItemBuilder.java @@ -33,7 +33,7 @@ public class PlayQueueItemBuilder { holder.itemDurationView.setVisibility(View.GONE); } - PicassoHelper.loadThumbnail(item.getThumbnailUrl()).into(holder.itemThumbnailView); + PicassoHelper.loadThumbnail(item.getThumbnails()).into(holder.itemThumbnailView); holder.itemRoot.setOnClickListener(view -> { if (onItemClickListener != null) { diff --git a/app/src/main/java/org/schabi/newpipe/player/ui/MainPlayerUi.java b/app/src/main/java/org/schabi/newpipe/player/ui/MainPlayerUi.java index 92e38a6a2..03f90a344 100644 --- a/app/src/main/java/org/schabi/newpipe/player/ui/MainPlayerUi.java +++ b/app/src/main/java/org/schabi/newpipe/player/ui/MainPlayerUi.java @@ -740,7 +740,7 @@ public final class MainPlayerUi extends VideoPlayerUi implements View.OnLayoutCh String videoUrl = player.getVideoUrl(); videoUrl += ("&t=" + seconds); ShareUtils.shareText(context, currentItem.getTitle(), - videoUrl, currentItem.getThumbnailUrl()); + videoUrl, currentItem.getThumbnails()); } } }; diff --git a/app/src/main/java/org/schabi/newpipe/player/ui/VideoPlayerUi.java b/app/src/main/java/org/schabi/newpipe/player/ui/VideoPlayerUi.java index 119c43b95..b51aaa638 100644 --- a/app/src/main/java/org/schabi/newpipe/player/ui/VideoPlayerUi.java +++ b/app/src/main/java/org/schabi/newpipe/player/ui/VideoPlayerUi.java @@ -226,7 +226,7 @@ public abstract class VideoPlayerUi extends PlayerUi implements SeekBar.OnSeekBa final PlayQueueItem currentItem = player.getCurrentItem(); if (currentItem != null) { ShareUtils.shareText(context, currentItem.getTitle(), - player.getVideoUrlAtCurrentTime(), currentItem.getThumbnailUrl()); + player.getVideoUrlAtCurrentTime(), currentItem.getThumbnails()); } })); binding.share.setOnLongClickListener(v -> { diff --git a/app/src/main/java/org/schabi/newpipe/util/PicassoHelper.java b/app/src/main/java/org/schabi/newpipe/util/PicassoHelper.java index ece0c7e87..5f3876d78 100644 --- a/app/src/main/java/org/schabi/newpipe/util/PicassoHelper.java +++ b/app/src/main/java/org/schabi/newpipe/util/PicassoHelper.java @@ -1,13 +1,14 @@ package org.schabi.newpipe.util; import static org.schabi.newpipe.MainActivity.DEBUG; -import static org.schabi.newpipe.extractor.utils.Utils.isBlank; +import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty; import android.annotation.SuppressLint; import android.content.Context; import android.graphics.Bitmap; import android.util.Log; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.graphics.BitmapCompat; @@ -19,9 +20,13 @@ import com.squareup.picasso.RequestCreator; import com.squareup.picasso.Transformation; import org.schabi.newpipe.R; +import org.schabi.newpipe.extractor.Image; +import org.schabi.newpipe.extractor.Image.ResolutionLevel; import java.io.File; import java.io.IOException; +import java.util.Comparator; +import java.util.List; import java.util.concurrent.TimeUnit; import okhttp3.OkHttpClient; @@ -42,6 +47,7 @@ public final class PicassoHelper { private static Picasso picassoInstance; private static boolean shouldLoadImages; + private static ResolutionLevel preferredResolutionLevel = ResolutionLevel.HIGH; public static void init(final Context context) { picassoCache = new LruCache(10 * 1024 * 1024); @@ -96,20 +102,33 @@ public final class PicassoHelper { } + public static RequestCreator loadAvatar(final List images) { + return loadImageDefault(images, R.drawable.placeholder_person); + } + public static RequestCreator loadAvatar(final String url) { return loadImageDefault(url, R.drawable.placeholder_person); } + public static RequestCreator loadThumbnail(final List images) { + return loadImageDefault(images, R.drawable.placeholder_thumbnail_video); + } + public static RequestCreator loadThumbnail(final String url) { return loadImageDefault(url, R.drawable.placeholder_thumbnail_video); } - public static RequestCreator loadDetailsThumbnail(final String url) { - return loadImageDefault(url, R.drawable.placeholder_thumbnail_video, false); + public static RequestCreator loadDetailsThumbnail(final List images) { + return loadImageDefault(choosePreferredImage(images), + R.drawable.placeholder_thumbnail_video, false); } - public static RequestCreator loadBanner(final String url) { - return loadImageDefault(url, R.drawable.placeholder_channel_banner); + public static RequestCreator loadBanner(final List images) { + return loadImageDefault(images, R.drawable.placeholder_channel_banner); + } + + public static RequestCreator loadPlaylistThumbnail(final List images) { + return loadImageDefault(images, R.drawable.placeholder_thumbnail_playlist); } public static RequestCreator loadPlaylistThumbnail(final String url) { @@ -125,9 +144,10 @@ public final class PicassoHelper { } - public static RequestCreator loadScaledDownThumbnail(final Context context, final String url) { + public static RequestCreator loadScaledDownThumbnail(final Context context, + final List images) { // scale down the notification thumbnail for performance - return PicassoHelper.loadThumbnail(url) + return PicassoHelper.loadThumbnail(images) .transform(new Transformation() { @Override public Bitmap transform(final Bitmap source) { @@ -180,13 +200,20 @@ public final class PicassoHelper { } - private static RequestCreator loadImageDefault(final String url, final int placeholderResId) { + private static RequestCreator loadImageDefault(final List images, + final int placeholderResId) { + return loadImageDefault(choosePreferredImage(images), placeholderResId); + } + + private static RequestCreator loadImageDefault(final String url, + final int placeholderResId) { return loadImageDefault(url, placeholderResId, true); } - private static RequestCreator loadImageDefault(final String url, final int placeholderResId, + private static RequestCreator loadImageDefault(@Nullable final String url, + final int placeholderResId, final boolean showPlaceholderWhileLoading) { - if (!shouldLoadImages || isBlank(url)) { + if (isNullOrEmpty(url)) { return picassoInstance .load((String) null) .placeholder(placeholderResId) // show placeholder when no image should load @@ -201,4 +228,44 @@ public final class PicassoHelper { return requestCreator; } } + + @Nullable + public static String choosePreferredImage(final List images) { + if (!shouldLoadImages) { + return null; + } + + final Comparator comparator; + switch (preferredResolutionLevel) { + case HIGH: + comparator = Comparator.comparingInt(Image::getHeight).reversed(); + break; + default: + case UNKNOWN: + case MEDIUM: + comparator = Comparator.comparingInt(image -> Math.abs(image.getHeight() - 450)); + break; + case LOW: + comparator = Comparator.comparingInt(Image::getHeight); + break; + } + + return images.stream() + .filter(image -> image.getEstimatedResolutionLevel() != ResolutionLevel.UNKNOWN) + .min(comparator) + .map(Image::getUrl) + .orElseGet(() -> images.stream() + .findAny() + .map(Image::getUrl) + .orElse(null)); + } + + @NonNull + public static List urlToImageList(@Nullable final String url) { + if (url == null) { + return List.of(); + } else { + return List.of(new Image(url, -1, -1, ResolutionLevel.UNKNOWN)); + } + } } diff --git a/app/src/main/java/org/schabi/newpipe/util/external_communication/ShareUtils.java b/app/src/main/java/org/schabi/newpipe/util/external_communication/ShareUtils.java index 118b77026..f14f22069 100644 --- a/app/src/main/java/org/schabi/newpipe/util/external_communication/ShareUtils.java +++ b/app/src/main/java/org/schabi/newpipe/util/external_communication/ShareUtils.java @@ -23,10 +23,12 @@ import androidx.core.content.FileProvider; import org.schabi.newpipe.BuildConfig; import org.schabi.newpipe.R; +import org.schabi.newpipe.extractor.Image; import org.schabi.newpipe.util.PicassoHelper; import java.io.File; import java.io.FileOutputStream; +import java.util.List; public final class ShareUtils { private static final String TAG = ShareUtils.class.getSimpleName(); @@ -261,6 +263,29 @@ public final class ShareUtils { openAppChooser(context, shareIntent, false); } + /** + * Open the android share sheet to share a content. + * + *

+ * For Android 10+ users, a content preview is shown, which includes the title of the shared + * content and an image preview the content, if its URL is not null or empty and its + * corresponding image is in the image cache. + *

+ * + * @param context the context to use + * @param title the title of the content + * @param content the content to share + * @param images a set of possible {@link Image}s of the subject, among which to choose with + * {@link PicassoHelper#choosePreferredImage(List)} since that's likely to + * provide an image that is in Picasso's cache + */ + public static void shareText(@NonNull final Context context, + @NonNull final String title, + final String content, + final List images) { + shareText(context, title, content, PicassoHelper.choosePreferredImage(images)); + } + /** * Open the android share sheet to share a content. * From 0a8f28b1c6f804de22a1ee81fdc284e7725ef8cc Mon Sep 17 00:00:00 2001 From: Stypox Date: Tue, 2 May 2023 11:08:32 +0200 Subject: [PATCH 090/172] Add image quality preference --- app/src/main/java/org/schabi/newpipe/App.java | 8 ++++--- .../database/playlist/PlaylistStreamEntry.kt | 2 +- .../playlist/model/PlaylistRemoteEntity.java | 2 +- .../database/stream/StreamStatisticsEntry.kt | 2 +- .../database/stream/model/StreamEntity.kt | 2 +- .../subscription/SubscriptionEntity.java | 2 +- .../fragments/detail/DescriptionFragment.java | 2 +- .../fragments/detail/VideoDetailFragment.java | 2 +- .../list/channel/ChannelAboutFragment.java | 2 +- .../list/channel/ChannelFragment.java | 6 ++--- .../list/playlist/PlaylistFragment.java | 2 +- .../newpipe/info_list/StreamSegmentItem.kt | 2 +- .../holder/ChannelMiniInfoItemHolder.java | 2 +- .../holder/CommentsMiniInfoItemHolder.java | 4 ++-- .../holder/PlaylistMiniInfoItemHolder.java | 2 +- .../holder/StreamMiniInfoItemHolder.java | 2 +- .../newpipe/local/feed/item/StreamItem.kt | 2 +- .../feed/notifications/NotificationHelper.kt | 2 +- .../local/holder/LocalPlaylistItemHolder.java | 2 +- .../holder/LocalPlaylistStreamItemHolder.java | 2 +- .../LocalStatisticStreamItemHolder.java | 2 +- .../holder/RemotePlaylistItemHolder.java | 2 +- .../subscription/SubscriptionFragment.kt | 2 +- .../local/subscription/SubscriptionManager.kt | 2 +- .../local/subscription/item/ChannelItem.kt | 2 +- .../item/PickerSubscriptionItem.kt | 2 +- .../org/schabi/newpipe/player/Player.java | 2 +- .../player/mediaitem/ExceptionTag.java | 2 +- .../player/mediaitem/StreamInfoTag.java | 2 +- .../mediasession/PlayQueueNavigator.java | 2 +- .../playqueue/PlayQueueItemBuilder.java | 2 +- .../SeekbarPreviewThumbnailHolder.java | 2 +- .../settings/ContentSettingsFragment.java | 9 ++++--- .../settings/DebugSettingsFragment.java | 2 +- .../settings/SelectChannelFragment.java | 2 +- .../settings/SelectPlaylistFragment.java | 2 +- .../newpipe/settings/SettingMigrations.java | 17 ++++++++++++- .../external_communication/ShareUtils.java | 4 ++-- .../util/{ => image}/PicassoHelper.java | 22 +++++++---------- .../util/image/PreferredImageQuality.java | 24 +++++++++++++++++++ app/src/main/res/values-ar/strings.xml | 2 -- app/src/main/res/values-as/strings.xml | 2 -- app/src/main/res/values-az/strings.xml | 2 -- app/src/main/res/values-b+ast/strings.xml | 2 -- app/src/main/res/values-b+uz+Latn/strings.xml | 2 -- app/src/main/res/values-be/strings.xml | 2 -- app/src/main/res/values-bg/strings.xml | 2 -- app/src/main/res/values-bn-rBD/strings.xml | 2 -- app/src/main/res/values-bn-rIN/strings.xml | 2 -- app/src/main/res/values-bn/strings.xml | 2 -- app/src/main/res/values-bs/strings.xml | 2 -- app/src/main/res/values-ca/strings.xml | 2 -- app/src/main/res/values-ckb/strings.xml | 2 -- app/src/main/res/values-cs/strings.xml | 2 -- app/src/main/res/values-da/strings.xml | 2 -- app/src/main/res/values-de/strings.xml | 2 -- app/src/main/res/values-el/strings.xml | 2 -- app/src/main/res/values-en-rGB/strings.xml | 1 - app/src/main/res/values-eo/strings.xml | 2 -- app/src/main/res/values-es/strings.xml | 2 -- app/src/main/res/values-et/strings.xml | 2 -- app/src/main/res/values-eu/strings.xml | 2 -- app/src/main/res/values-fa/strings.xml | 2 -- app/src/main/res/values-fi/strings.xml | 2 -- app/src/main/res/values-fil/strings.xml | 2 -- app/src/main/res/values-fr/strings.xml | 2 -- app/src/main/res/values-gl/strings.xml | 2 -- app/src/main/res/values-he/strings.xml | 2 -- app/src/main/res/values-hi/strings.xml | 2 -- app/src/main/res/values-hr/strings.xml | 2 -- app/src/main/res/values-hu/strings.xml | 2 -- app/src/main/res/values-ia/strings.xml | 1 - app/src/main/res/values-in/strings.xml | 2 -- app/src/main/res/values-is/strings.xml | 2 -- app/src/main/res/values-it/strings.xml | 2 -- app/src/main/res/values-ja/strings.xml | 2 -- app/src/main/res/values-jv/strings.xml | 2 -- app/src/main/res/values-ka/strings.xml | 2 -- app/src/main/res/values-kmr/strings.xml | 2 -- app/src/main/res/values-ko/strings.xml | 2 -- app/src/main/res/values-ku/strings.xml | 3 --- app/src/main/res/values-lt/strings.xml | 2 -- app/src/main/res/values-lv/strings.xml | 2 -- app/src/main/res/values-mk/strings.xml | 2 -- app/src/main/res/values-ml/strings.xml | 2 -- app/src/main/res/values-ms/strings.xml | 2 -- app/src/main/res/values-nb-rNO/strings.xml | 2 -- app/src/main/res/values-ne/strings.xml | 2 -- app/src/main/res/values-nl-rBE/strings.xml | 2 -- app/src/main/res/values-nl/strings.xml | 2 -- app/src/main/res/values-oc/strings.xml | 1 - app/src/main/res/values-or/strings.xml | 2 -- app/src/main/res/values-pa-rPK/strings.xml | 1 - app/src/main/res/values-pa/strings.xml | 2 -- app/src/main/res/values-pl/strings.xml | 2 -- app/src/main/res/values-pt-rBR/strings.xml | 2 -- app/src/main/res/values-pt-rPT/strings.xml | 2 -- app/src/main/res/values-pt/strings.xml | 2 -- app/src/main/res/values-ro/strings.xml | 2 -- app/src/main/res/values-ru/strings.xml | 2 -- app/src/main/res/values-sc/strings.xml | 2 -- app/src/main/res/values-sk/strings.xml | 2 -- app/src/main/res/values-sl/strings.xml | 2 -- app/src/main/res/values-so/strings.xml | 2 -- app/src/main/res/values-sq/strings.xml | 2 -- app/src/main/res/values-sr/strings.xml | 2 -- app/src/main/res/values-sv/strings.xml | 2 -- app/src/main/res/values-ta/strings.xml | 2 -- app/src/main/res/values-te/strings.xml | 2 -- app/src/main/res/values-th/strings.xml | 2 -- app/src/main/res/values-tr/strings.xml | 2 -- app/src/main/res/values-uk/strings.xml | 2 -- app/src/main/res/values-und/strings.xml | 1 - app/src/main/res/values-ur/strings.xml | 2 -- app/src/main/res/values-vi/strings.xml | 2 -- app/src/main/res/values-zh-rCN/strings.xml | 2 -- app/src/main/res/values-zh-rHK/strings.xml | 2 -- app/src/main/res/values-zh-rTW/strings.xml | 2 -- app/src/main/res/values/settings_keys.xml | 22 +++++++++++++++-- app/src/main/res/values/strings.xml | 8 +++++-- app/src/main/res/xml/content_settings.xml | 12 ++++++---- 121 files changed, 132 insertions(+), 220 deletions(-) rename app/src/main/java/org/schabi/newpipe/util/{ => image}/PicassoHelper.java (94%) create mode 100644 app/src/main/java/org/schabi/newpipe/util/image/PreferredImageQuality.java diff --git a/app/src/main/java/org/schabi/newpipe/App.java b/app/src/main/java/org/schabi/newpipe/App.java index f4410a31b..b394c7039 100644 --- a/app/src/main/java/org/schabi/newpipe/App.java +++ b/app/src/main/java/org/schabi/newpipe/App.java @@ -20,9 +20,10 @@ import org.schabi.newpipe.extractor.downloader.Downloader; import org.schabi.newpipe.ktx.ExceptionUtils; import org.schabi.newpipe.settings.NewPipeSettings; import org.schabi.newpipe.util.Localization; -import org.schabi.newpipe.util.PicassoHelper; +import org.schabi.newpipe.util.image.PicassoHelper; import org.schabi.newpipe.util.ServiceHelper; import org.schabi.newpipe.util.StateSaver; +import org.schabi.newpipe.util.image.PreferredImageQuality; import java.io.IOException; import java.io.InterruptedIOException; @@ -99,8 +100,9 @@ public class App extends Application { // Initialize image loader final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); PicassoHelper.init(this); - PicassoHelper.setShouldLoadImages( - prefs.getBoolean(getString(R.string.download_thumbnail_key), true)); + PicassoHelper.setPreferredImageQuality(PreferredImageQuality.fromPreferenceKey(this, + prefs.getString(getString(R.string.image_quality_key), + getString(R.string.image_quality_default)))); PicassoHelper.setIndicatorsEnabled(MainActivity.DEBUG && prefs.getBoolean(getString(R.string.show_image_indicators_key), false)); diff --git a/app/src/main/java/org/schabi/newpipe/database/playlist/PlaylistStreamEntry.kt b/app/src/main/java/org/schabi/newpipe/database/playlist/PlaylistStreamEntry.kt index 3b6bc9593..e7db1d603 100644 --- a/app/src/main/java/org/schabi/newpipe/database/playlist/PlaylistStreamEntry.kt +++ b/app/src/main/java/org/schabi/newpipe/database/playlist/PlaylistStreamEntry.kt @@ -7,7 +7,7 @@ import org.schabi.newpipe.database.playlist.model.PlaylistStreamEntity import org.schabi.newpipe.database.stream.model.StreamEntity import org.schabi.newpipe.database.stream.model.StreamStateEntity import org.schabi.newpipe.extractor.stream.StreamInfoItem -import org.schabi.newpipe.util.PicassoHelper +import org.schabi.newpipe.util.image.PicassoHelper data class PlaylistStreamEntry( @Embedded diff --git a/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistRemoteEntity.java b/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistRemoteEntity.java index 640b6d1fa..569f6721c 100644 --- a/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistRemoteEntity.java +++ b/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistRemoteEntity.java @@ -11,7 +11,7 @@ import androidx.room.PrimaryKey; import org.schabi.newpipe.database.playlist.PlaylistLocalItem; import org.schabi.newpipe.extractor.playlist.PlaylistInfo; import org.schabi.newpipe.util.Constants; -import org.schabi.newpipe.util.PicassoHelper; +import org.schabi.newpipe.util.image.PicassoHelper; import static org.schabi.newpipe.database.LocalItem.LocalItemType.PLAYLIST_REMOTE_ITEM; import static org.schabi.newpipe.database.playlist.model.PlaylistRemoteEntity.REMOTE_PLAYLIST_NAME; diff --git a/app/src/main/java/org/schabi/newpipe/database/stream/StreamStatisticsEntry.kt b/app/src/main/java/org/schabi/newpipe/database/stream/StreamStatisticsEntry.kt index a268f8bbf..6d005351d 100644 --- a/app/src/main/java/org/schabi/newpipe/database/stream/StreamStatisticsEntry.kt +++ b/app/src/main/java/org/schabi/newpipe/database/stream/StreamStatisticsEntry.kt @@ -7,7 +7,7 @@ import org.schabi.newpipe.database.history.model.StreamHistoryEntity import org.schabi.newpipe.database.stream.model.StreamEntity import org.schabi.newpipe.database.stream.model.StreamStateEntity.STREAM_PROGRESS_MILLIS import org.schabi.newpipe.extractor.stream.StreamInfoItem -import org.schabi.newpipe.util.PicassoHelper +import org.schabi.newpipe.util.image.PicassoHelper import java.time.OffsetDateTime class StreamStatisticsEntry( diff --git a/app/src/main/java/org/schabi/newpipe/database/stream/model/StreamEntity.kt b/app/src/main/java/org/schabi/newpipe/database/stream/model/StreamEntity.kt index 8b7639bbd..bb2c0e0d7 100644 --- a/app/src/main/java/org/schabi/newpipe/database/stream/model/StreamEntity.kt +++ b/app/src/main/java/org/schabi/newpipe/database/stream/model/StreamEntity.kt @@ -13,7 +13,7 @@ import org.schabi.newpipe.extractor.stream.StreamInfo import org.schabi.newpipe.extractor.stream.StreamInfoItem import org.schabi.newpipe.extractor.stream.StreamType import org.schabi.newpipe.player.playqueue.PlayQueueItem -import org.schabi.newpipe.util.PicassoHelper +import org.schabi.newpipe.util.image.PicassoHelper import java.io.Serializable import java.time.OffsetDateTime diff --git a/app/src/main/java/org/schabi/newpipe/database/subscription/SubscriptionEntity.java b/app/src/main/java/org/schabi/newpipe/database/subscription/SubscriptionEntity.java index a455cf258..1f1722814 100644 --- a/app/src/main/java/org/schabi/newpipe/database/subscription/SubscriptionEntity.java +++ b/app/src/main/java/org/schabi/newpipe/database/subscription/SubscriptionEntity.java @@ -10,7 +10,7 @@ import androidx.room.PrimaryKey; import org.schabi.newpipe.extractor.channel.ChannelInfo; import org.schabi.newpipe.extractor.channel.ChannelInfoItem; import org.schabi.newpipe.util.Constants; -import org.schabi.newpipe.util.PicassoHelper; +import org.schabi.newpipe.util.image.PicassoHelper; import static org.schabi.newpipe.database.subscription.SubscriptionEntity.SUBSCRIPTION_SERVICE_ID; import static org.schabi.newpipe.database.subscription.SubscriptionEntity.SUBSCRIPTION_TABLE; diff --git a/app/src/main/java/org/schabi/newpipe/fragments/detail/DescriptionFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/detail/DescriptionFragment.java index e7f257665..ff1a01466 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/detail/DescriptionFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/detail/DescriptionFragment.java @@ -17,7 +17,7 @@ import org.schabi.newpipe.extractor.stream.StreamInfo; import org.schabi.newpipe.util.Localization; import java.util.List; -import org.schabi.newpipe.util.PicassoHelper; +import org.schabi.newpipe.util.image.PicassoHelper; import icepick.State; diff --git a/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java index 2e6f493a3..0314c2540 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java @@ -108,7 +108,7 @@ import org.schabi.newpipe.util.ListHelper; import org.schabi.newpipe.util.Localization; import org.schabi.newpipe.util.NavigationHelper; import org.schabi.newpipe.util.PermissionHelper; -import org.schabi.newpipe.util.PicassoHelper; +import org.schabi.newpipe.util.image.PicassoHelper; import org.schabi.newpipe.util.StreamTypeUtil; import org.schabi.newpipe.util.ThemeHelper; import org.schabi.newpipe.util.external_communication.KoreUtils; diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelAboutFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelAboutFragment.java index eebd12d20..5ea25bf15 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelAboutFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelAboutFragment.java @@ -17,7 +17,7 @@ import org.schabi.newpipe.extractor.stream.Description; import org.schabi.newpipe.fragments.detail.BaseDescriptionFragment; import org.schabi.newpipe.util.DeviceUtils; import org.schabi.newpipe.util.Localization; -import org.schabi.newpipe.util.PicassoHelper; +import org.schabi.newpipe.util.image.PicassoHelper; import java.util.List; diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java index 6b2c71337..7436f50fd 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java @@ -48,8 +48,8 @@ import org.schabi.newpipe.util.Constants; import org.schabi.newpipe.util.ExtractorHelper; import org.schabi.newpipe.util.Localization; import org.schabi.newpipe.util.NavigationHelper; -import org.schabi.newpipe.util.PicassoHelper; import org.schabi.newpipe.util.StateSaver; +import org.schabi.newpipe.util.image.PicassoHelper; import org.schabi.newpipe.util.ThemeHelper; import org.schabi.newpipe.util.external_communication.ShareUtils; @@ -147,7 +147,7 @@ public class ChannelFragment extends BaseStateFragment setTitle(name); binding.channelTitleView.setText(name); - if (!PicassoHelper.getShouldLoadImages()) { + if (!PicassoHelper.shouldLoadImages()) { // do not waste space for the banner if it is not going to be loaded binding.channelBannerImage.setImageDrawable(null); } @@ -578,7 +578,7 @@ public class ChannelFragment extends BaseStateFragment currentInfo = result; setInitialData(result.getServiceId(), result.getOriginalUrl(), result.getName()); - if (PicassoHelper.getShouldLoadImages() && !result.getBanners().isEmpty()) { + if (PicassoHelper.shouldLoadImages() && !result.getBanners().isEmpty()) { PicassoHelper.loadBanner(result.getBanners()).tag(PICASSO_CHANNEL_TAG) .into(binding.channelBannerImage); } else { diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java index 9b3f693e1..e82a984d5 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java @@ -48,7 +48,7 @@ import org.schabi.newpipe.player.playqueue.PlaylistPlayQueue; import org.schabi.newpipe.util.ExtractorHelper; import org.schabi.newpipe.util.Localization; import org.schabi.newpipe.util.NavigationHelper; -import org.schabi.newpipe.util.PicassoHelper; +import org.schabi.newpipe.util.image.PicassoHelper; import org.schabi.newpipe.util.external_communication.ShareUtils; import org.schabi.newpipe.util.PlayButtonHelper; diff --git a/app/src/main/java/org/schabi/newpipe/info_list/StreamSegmentItem.kt b/app/src/main/java/org/schabi/newpipe/info_list/StreamSegmentItem.kt index 5fc8aa684..1e52d3168 100644 --- a/app/src/main/java/org/schabi/newpipe/info_list/StreamSegmentItem.kt +++ b/app/src/main/java/org/schabi/newpipe/info_list/StreamSegmentItem.kt @@ -8,7 +8,7 @@ import com.xwray.groupie.Item import org.schabi.newpipe.R import org.schabi.newpipe.extractor.stream.StreamSegment import org.schabi.newpipe.util.Localization -import org.schabi.newpipe.util.PicassoHelper +import org.schabi.newpipe.util.image.PicassoHelper class StreamSegmentItem( private val item: StreamSegment, diff --git a/app/src/main/java/org/schabi/newpipe/info_list/holder/ChannelMiniInfoItemHolder.java b/app/src/main/java/org/schabi/newpipe/info_list/holder/ChannelMiniInfoItemHolder.java index d971a6a6d..7afc05c6c 100644 --- a/app/src/main/java/org/schabi/newpipe/info_list/holder/ChannelMiniInfoItemHolder.java +++ b/app/src/main/java/org/schabi/newpipe/info_list/holder/ChannelMiniInfoItemHolder.java @@ -13,7 +13,7 @@ import org.schabi.newpipe.extractor.channel.ChannelInfoItem; import org.schabi.newpipe.extractor.utils.Utils; import org.schabi.newpipe.info_list.InfoItemBuilder; import org.schabi.newpipe.local.history.HistoryRecordManager; -import org.schabi.newpipe.util.PicassoHelper; +import org.schabi.newpipe.util.image.PicassoHelper; import org.schabi.newpipe.util.Localization; public class ChannelMiniInfoItemHolder extends InfoItemHolder { diff --git a/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentsMiniInfoItemHolder.java b/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentsMiniInfoItemHolder.java index d69be077d..69e1bf5f6 100644 --- a/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentsMiniInfoItemHolder.java +++ b/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentsMiniInfoItemHolder.java @@ -31,7 +31,7 @@ import org.schabi.newpipe.local.history.HistoryRecordManager; import org.schabi.newpipe.util.DeviceUtils; import org.schabi.newpipe.util.Localization; import org.schabi.newpipe.util.NavigationHelper; -import org.schabi.newpipe.util.PicassoHelper; +import org.schabi.newpipe.util.image.PicassoHelper; import org.schabi.newpipe.util.external_communication.ShareUtils; import org.schabi.newpipe.util.text.CommentTextOnTouchListener; import org.schabi.newpipe.util.text.TextLinkifier; @@ -98,7 +98,7 @@ public class CommentsMiniInfoItemHolder extends InfoItemHolder { final CommentsInfoItem item = (CommentsInfoItem) infoItem; PicassoHelper.loadAvatar(item.getUploaderAvatars()).into(itemThumbnailView); - if (PicassoHelper.getShouldLoadImages()) { + if (PicassoHelper.shouldLoadImages()) { itemThumbnailView.setVisibility(View.VISIBLE); itemRoot.setPadding(commentVerticalPadding, commentVerticalPadding, commentVerticalPadding, commentVerticalPadding); diff --git a/app/src/main/java/org/schabi/newpipe/info_list/holder/PlaylistMiniInfoItemHolder.java b/app/src/main/java/org/schabi/newpipe/info_list/holder/PlaylistMiniInfoItemHolder.java index 62c7c27eb..c9216d9a9 100644 --- a/app/src/main/java/org/schabi/newpipe/info_list/holder/PlaylistMiniInfoItemHolder.java +++ b/app/src/main/java/org/schabi/newpipe/info_list/holder/PlaylistMiniInfoItemHolder.java @@ -9,7 +9,7 @@ import org.schabi.newpipe.extractor.InfoItem; import org.schabi.newpipe.extractor.playlist.PlaylistInfoItem; import org.schabi.newpipe.info_list.InfoItemBuilder; import org.schabi.newpipe.local.history.HistoryRecordManager; -import org.schabi.newpipe.util.PicassoHelper; +import org.schabi.newpipe.util.image.PicassoHelper; import org.schabi.newpipe.util.Localization; public class PlaylistMiniInfoItemHolder extends InfoItemHolder { diff --git a/app/src/main/java/org/schabi/newpipe/info_list/holder/StreamMiniInfoItemHolder.java b/app/src/main/java/org/schabi/newpipe/info_list/holder/StreamMiniInfoItemHolder.java index 796ea63b3..01f3be6b3 100644 --- a/app/src/main/java/org/schabi/newpipe/info_list/holder/StreamMiniInfoItemHolder.java +++ b/app/src/main/java/org/schabi/newpipe/info_list/holder/StreamMiniInfoItemHolder.java @@ -16,7 +16,7 @@ import org.schabi.newpipe.ktx.ViewUtils; import org.schabi.newpipe.local.history.HistoryRecordManager; import org.schabi.newpipe.util.DependentPreferenceHelper; import org.schabi.newpipe.util.Localization; -import org.schabi.newpipe.util.PicassoHelper; +import org.schabi.newpipe.util.image.PicassoHelper; import org.schabi.newpipe.util.StreamTypeUtil; import org.schabi.newpipe.views.AnimatedProgressBar; diff --git a/app/src/main/java/org/schabi/newpipe/local/feed/item/StreamItem.kt b/app/src/main/java/org/schabi/newpipe/local/feed/item/StreamItem.kt index d795dcb08..4a071d6df 100644 --- a/app/src/main/java/org/schabi/newpipe/local/feed/item/StreamItem.kt +++ b/app/src/main/java/org/schabi/newpipe/local/feed/item/StreamItem.kt @@ -18,8 +18,8 @@ import org.schabi.newpipe.extractor.stream.StreamType.POST_LIVE_AUDIO_STREAM import org.schabi.newpipe.extractor.stream.StreamType.POST_LIVE_STREAM import org.schabi.newpipe.extractor.stream.StreamType.VIDEO_STREAM import org.schabi.newpipe.util.Localization -import org.schabi.newpipe.util.PicassoHelper import org.schabi.newpipe.util.StreamTypeUtil +import org.schabi.newpipe.util.image.PicassoHelper import java.util.concurrent.TimeUnit import java.util.function.Consumer diff --git a/app/src/main/java/org/schabi/newpipe/local/feed/notifications/NotificationHelper.kt b/app/src/main/java/org/schabi/newpipe/local/feed/notifications/NotificationHelper.kt index 782f5ee47..9f7553e1f 100644 --- a/app/src/main/java/org/schabi/newpipe/local/feed/notifications/NotificationHelper.kt +++ b/app/src/main/java/org/schabi/newpipe/local/feed/notifications/NotificationHelper.kt @@ -22,7 +22,7 @@ import org.schabi.newpipe.R import org.schabi.newpipe.extractor.stream.StreamInfoItem import org.schabi.newpipe.local.feed.service.FeedUpdateInfo import org.schabi.newpipe.util.NavigationHelper -import org.schabi.newpipe.util.PicassoHelper +import org.schabi.newpipe.util.image.PicassoHelper /** * Helper for everything related to show notifications about new streams to the user. diff --git a/app/src/main/java/org/schabi/newpipe/local/holder/LocalPlaylistItemHolder.java b/app/src/main/java/org/schabi/newpipe/local/holder/LocalPlaylistItemHolder.java index 240ca0462..336f5cfe3 100644 --- a/app/src/main/java/org/schabi/newpipe/local/holder/LocalPlaylistItemHolder.java +++ b/app/src/main/java/org/schabi/newpipe/local/holder/LocalPlaylistItemHolder.java @@ -8,7 +8,7 @@ import org.schabi.newpipe.database.playlist.PlaylistDuplicatesEntry; import org.schabi.newpipe.database.playlist.PlaylistMetadataEntry; import org.schabi.newpipe.local.LocalItemBuilder; import org.schabi.newpipe.local.history.HistoryRecordManager; -import org.schabi.newpipe.util.PicassoHelper; +import org.schabi.newpipe.util.image.PicassoHelper; import org.schabi.newpipe.util.Localization; import java.time.format.DateTimeFormatter; diff --git a/app/src/main/java/org/schabi/newpipe/local/holder/LocalPlaylistStreamItemHolder.java b/app/src/main/java/org/schabi/newpipe/local/holder/LocalPlaylistStreamItemHolder.java index c98a8b60b..89a714fd7 100644 --- a/app/src/main/java/org/schabi/newpipe/local/holder/LocalPlaylistStreamItemHolder.java +++ b/app/src/main/java/org/schabi/newpipe/local/holder/LocalPlaylistStreamItemHolder.java @@ -16,7 +16,7 @@ import org.schabi.newpipe.local.LocalItemBuilder; import org.schabi.newpipe.local.history.HistoryRecordManager; import org.schabi.newpipe.util.DependentPreferenceHelper; import org.schabi.newpipe.util.Localization; -import org.schabi.newpipe.util.PicassoHelper; +import org.schabi.newpipe.util.image.PicassoHelper; import org.schabi.newpipe.util.ServiceHelper; import org.schabi.newpipe.views.AnimatedProgressBar; diff --git a/app/src/main/java/org/schabi/newpipe/local/holder/LocalStatisticStreamItemHolder.java b/app/src/main/java/org/schabi/newpipe/local/holder/LocalStatisticStreamItemHolder.java index 41f2df1d0..150a35eb5 100644 --- a/app/src/main/java/org/schabi/newpipe/local/holder/LocalStatisticStreamItemHolder.java +++ b/app/src/main/java/org/schabi/newpipe/local/holder/LocalStatisticStreamItemHolder.java @@ -16,7 +16,7 @@ import org.schabi.newpipe.local.LocalItemBuilder; import org.schabi.newpipe.local.history.HistoryRecordManager; import org.schabi.newpipe.util.DependentPreferenceHelper; import org.schabi.newpipe.util.Localization; -import org.schabi.newpipe.util.PicassoHelper; +import org.schabi.newpipe.util.image.PicassoHelper; import org.schabi.newpipe.util.ServiceHelper; import org.schabi.newpipe.views.AnimatedProgressBar; diff --git a/app/src/main/java/org/schabi/newpipe/local/holder/RemotePlaylistItemHolder.java b/app/src/main/java/org/schabi/newpipe/local/holder/RemotePlaylistItemHolder.java index 70987a6fc..d14c1a231 100644 --- a/app/src/main/java/org/schabi/newpipe/local/holder/RemotePlaylistItemHolder.java +++ b/app/src/main/java/org/schabi/newpipe/local/holder/RemotePlaylistItemHolder.java @@ -8,7 +8,7 @@ import org.schabi.newpipe.database.playlist.model.PlaylistRemoteEntity; import org.schabi.newpipe.local.LocalItemBuilder; import org.schabi.newpipe.local.history.HistoryRecordManager; import org.schabi.newpipe.util.Localization; -import org.schabi.newpipe.util.PicassoHelper; +import org.schabi.newpipe.util.image.PicassoHelper; import org.schabi.newpipe.util.ServiceHelper; import java.time.format.DateTimeFormatter; diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionFragment.kt b/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionFragment.kt index f428a7c1d..f84d9865f 100644 --- a/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionFragment.kt +++ b/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionFragment.kt @@ -58,10 +58,10 @@ import org.schabi.newpipe.streams.io.NoFileManagerSafeGuard import org.schabi.newpipe.streams.io.StoredFileHelper import org.schabi.newpipe.util.NavigationHelper import org.schabi.newpipe.util.OnClickGesture -import org.schabi.newpipe.util.PicassoHelper import org.schabi.newpipe.util.ServiceHelper import org.schabi.newpipe.util.ThemeHelper.getGridSpanCountChannels import org.schabi.newpipe.util.external_communication.ShareUtils +import org.schabi.newpipe.util.image.PicassoHelper import java.text.SimpleDateFormat import java.util.Date import java.util.Locale diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionManager.kt b/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionManager.kt index a74ff305c..70bac6168 100644 --- a/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionManager.kt +++ b/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionManager.kt @@ -19,7 +19,7 @@ import org.schabi.newpipe.extractor.feed.FeedInfo import org.schabi.newpipe.extractor.stream.StreamInfoItem import org.schabi.newpipe.local.feed.FeedDatabaseManager import org.schabi.newpipe.util.ExtractorHelper -import org.schabi.newpipe.util.PicassoHelper +import org.schabi.newpipe.util.image.PicassoHelper class SubscriptionManager(context: Context) { private val database = NewPipeDatabase.getInstance(context) diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/item/ChannelItem.kt b/app/src/main/java/org/schabi/newpipe/local/subscription/item/ChannelItem.kt index 07a4f11ff..bc39dafe6 100644 --- a/app/src/main/java/org/schabi/newpipe/local/subscription/item/ChannelItem.kt +++ b/app/src/main/java/org/schabi/newpipe/local/subscription/item/ChannelItem.kt @@ -9,7 +9,7 @@ import org.schabi.newpipe.R import org.schabi.newpipe.extractor.channel.ChannelInfoItem import org.schabi.newpipe.util.Localization import org.schabi.newpipe.util.OnClickGesture -import org.schabi.newpipe.util.PicassoHelper +import org.schabi.newpipe.util.image.PicassoHelper class ChannelItem( private val infoItem: ChannelInfoItem, diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/item/PickerSubscriptionItem.kt b/app/src/main/java/org/schabi/newpipe/local/subscription/item/PickerSubscriptionItem.kt index aadb2fc73..3a4c6e41b 100644 --- a/app/src/main/java/org/schabi/newpipe/local/subscription/item/PickerSubscriptionItem.kt +++ b/app/src/main/java/org/schabi/newpipe/local/subscription/item/PickerSubscriptionItem.kt @@ -10,7 +10,7 @@ import org.schabi.newpipe.database.subscription.SubscriptionEntity import org.schabi.newpipe.databinding.PickerSubscriptionItemBinding import org.schabi.newpipe.ktx.AnimationType import org.schabi.newpipe.ktx.animate -import org.schabi.newpipe.util.PicassoHelper +import org.schabi.newpipe.util.image.PicassoHelper data class PickerSubscriptionItem( val subscriptionEntity: SubscriptionEntity, diff --git a/app/src/main/java/org/schabi/newpipe/player/Player.java b/app/src/main/java/org/schabi/newpipe/player/Player.java index 3ad03891e..49e72328e 100644 --- a/app/src/main/java/org/schabi/newpipe/player/Player.java +++ b/app/src/main/java/org/schabi/newpipe/player/Player.java @@ -118,7 +118,7 @@ import org.schabi.newpipe.player.ui.VideoPlayerUi; import org.schabi.newpipe.util.DependentPreferenceHelper; import org.schabi.newpipe.util.ListHelper; import org.schabi.newpipe.util.NavigationHelper; -import org.schabi.newpipe.util.PicassoHelper; +import org.schabi.newpipe.util.image.PicassoHelper; import org.schabi.newpipe.util.SerializedCache; import org.schabi.newpipe.util.StreamTypeUtil; diff --git a/app/src/main/java/org/schabi/newpipe/player/mediaitem/ExceptionTag.java b/app/src/main/java/org/schabi/newpipe/player/mediaitem/ExceptionTag.java index 5a5360b34..9ec6513dc 100644 --- a/app/src/main/java/org/schabi/newpipe/player/mediaitem/ExceptionTag.java +++ b/app/src/main/java/org/schabi/newpipe/player/mediaitem/ExceptionTag.java @@ -3,7 +3,7 @@ package org.schabi.newpipe.player.mediaitem; import org.schabi.newpipe.extractor.stream.StreamInfo; import org.schabi.newpipe.extractor.stream.StreamType; import org.schabi.newpipe.player.playqueue.PlayQueueItem; -import org.schabi.newpipe.util.PicassoHelper; +import org.schabi.newpipe.util.image.PicassoHelper; import java.util.List; import java.util.Optional; diff --git a/app/src/main/java/org/schabi/newpipe/player/mediaitem/StreamInfoTag.java b/app/src/main/java/org/schabi/newpipe/player/mediaitem/StreamInfoTag.java index eb3abec1f..a96f49f2f 100644 --- a/app/src/main/java/org/schabi/newpipe/player/mediaitem/StreamInfoTag.java +++ b/app/src/main/java/org/schabi/newpipe/player/mediaitem/StreamInfoTag.java @@ -6,7 +6,7 @@ import org.schabi.newpipe.extractor.stream.AudioStream; import org.schabi.newpipe.extractor.stream.StreamInfo; import org.schabi.newpipe.extractor.stream.StreamType; import org.schabi.newpipe.extractor.stream.VideoStream; -import org.schabi.newpipe.util.PicassoHelper; +import org.schabi.newpipe.util.image.PicassoHelper; import java.util.Collections; import java.util.List; diff --git a/app/src/main/java/org/schabi/newpipe/player/mediasession/PlayQueueNavigator.java b/app/src/main/java/org/schabi/newpipe/player/mediasession/PlayQueueNavigator.java index 327c2befe..3e0736f82 100644 --- a/app/src/main/java/org/schabi/newpipe/player/mediasession/PlayQueueNavigator.java +++ b/app/src/main/java/org/schabi/newpipe/player/mediasession/PlayQueueNavigator.java @@ -20,7 +20,7 @@ import com.google.android.exoplayer2.util.Util; import org.schabi.newpipe.player.Player; import org.schabi.newpipe.player.playqueue.PlayQueue; import org.schabi.newpipe.player.playqueue.PlayQueueItem; -import org.schabi.newpipe.util.PicassoHelper; +import org.schabi.newpipe.util.image.PicassoHelper; import java.util.ArrayList; import java.util.Collections; diff --git a/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueItemBuilder.java b/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueItemBuilder.java index 19101a31d..066f92c26 100644 --- a/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueItemBuilder.java +++ b/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueItemBuilder.java @@ -6,7 +6,7 @@ import android.view.MotionEvent; import android.view.View; import org.schabi.newpipe.util.Localization; -import org.schabi.newpipe.util.PicassoHelper; +import org.schabi.newpipe.util.image.PicassoHelper; import org.schabi.newpipe.util.ServiceHelper; public class PlayQueueItemBuilder { diff --git a/app/src/main/java/org/schabi/newpipe/player/seekbarpreview/SeekbarPreviewThumbnailHolder.java b/app/src/main/java/org/schabi/newpipe/player/seekbarpreview/SeekbarPreviewThumbnailHolder.java index 50ffa2f2a..26065de15 100644 --- a/app/src/main/java/org/schabi/newpipe/player/seekbarpreview/SeekbarPreviewThumbnailHolder.java +++ b/app/src/main/java/org/schabi/newpipe/player/seekbarpreview/SeekbarPreviewThumbnailHolder.java @@ -14,7 +14,7 @@ import androidx.collection.SparseArrayCompat; import com.google.common.base.Stopwatch; import org.schabi.newpipe.extractor.stream.Frameset; -import org.schabi.newpipe.util.PicassoHelper; +import org.schabi.newpipe.util.image.PicassoHelper; import java.util.Comparator; import java.util.List; diff --git a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java index ee34f01dd..2297e3e93 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java @@ -31,8 +31,9 @@ import org.schabi.newpipe.extractor.localization.Localization; import org.schabi.newpipe.streams.io.NoFileManagerSafeGuard; import org.schabi.newpipe.streams.io.StoredFileHelper; import org.schabi.newpipe.util.NavigationHelper; -import org.schabi.newpipe.util.PicassoHelper; +import org.schabi.newpipe.util.image.PicassoHelper; import org.schabi.newpipe.util.ZipHelper; +import org.schabi.newpipe.util.image.PreferredImageQuality; import java.io.File; import java.io.IOException; @@ -105,9 +106,11 @@ public class ContentSettingsFragment extends BasePreferenceFragment { .getPreferredContentCountry(requireContext()); initialLanguage = defaultPreferences.getString(getString(R.string.app_language_key), "en"); - findPreference(getString(R.string.download_thumbnail_key)).setOnPreferenceChangeListener( + final Preference imageQualityPreference = requirePreference(R.string.image_quality_key); + imageQualityPreference.setOnPreferenceChangeListener( (preference, newValue) -> { - PicassoHelper.setShouldLoadImages((Boolean) newValue); + PicassoHelper.setPreferredImageQuality(PreferredImageQuality + .fromPreferenceKey(requireContext(), (String) newValue)); try { PicassoHelper.clearCache(preference.getContext()); Toast.makeText(preference.getContext(), diff --git a/app/src/main/java/org/schabi/newpipe/settings/DebugSettingsFragment.java b/app/src/main/java/org/schabi/newpipe/settings/DebugSettingsFragment.java index 0f4c9765e..d78ade49d 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/DebugSettingsFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/DebugSettingsFragment.java @@ -10,7 +10,7 @@ import org.schabi.newpipe.error.ErrorInfo; import org.schabi.newpipe.error.ErrorUtil; import org.schabi.newpipe.error.UserAction; import org.schabi.newpipe.local.feed.notifications.NotificationWorker; -import org.schabi.newpipe.util.PicassoHelper; +import org.schabi.newpipe.util.image.PicassoHelper; import java.util.Optional; diff --git a/app/src/main/java/org/schabi/newpipe/settings/SelectChannelFragment.java b/app/src/main/java/org/schabi/newpipe/settings/SelectChannelFragment.java index 0f25be630..37335421d 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/SelectChannelFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/SelectChannelFragment.java @@ -19,7 +19,7 @@ import org.schabi.newpipe.R; import org.schabi.newpipe.database.subscription.SubscriptionEntity; import org.schabi.newpipe.error.ErrorUtil; import org.schabi.newpipe.local.subscription.SubscriptionManager; -import org.schabi.newpipe.util.PicassoHelper; +import org.schabi.newpipe.util.image.PicassoHelper; import org.schabi.newpipe.util.ThemeHelper; import java.util.List; diff --git a/app/src/main/java/org/schabi/newpipe/settings/SelectPlaylistFragment.java b/app/src/main/java/org/schabi/newpipe/settings/SelectPlaylistFragment.java index e8491d52c..147d20a36 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/SelectPlaylistFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/SelectPlaylistFragment.java @@ -25,7 +25,7 @@ import org.schabi.newpipe.error.ErrorUtil; import org.schabi.newpipe.error.UserAction; import org.schabi.newpipe.local.playlist.LocalPlaylistManager; import org.schabi.newpipe.local.playlist.RemotePlaylistManager; -import org.schabi.newpipe.util.PicassoHelper; +import org.schabi.newpipe.util.image.PicassoHelper; import java.util.List; import java.util.Vector; diff --git a/app/src/main/java/org/schabi/newpipe/settings/SettingMigrations.java b/app/src/main/java/org/schabi/newpipe/settings/SettingMigrations.java index 215caaa38..b7bafde75 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/SettingMigrations.java +++ b/app/src/main/java/org/schabi/newpipe/settings/SettingMigrations.java @@ -128,6 +128,20 @@ public final class SettingMigrations { } }; + public static final Migration MIGRATION_5_6 = new Migration(5, 6) { + @Override + protected void migrate(@NonNull final Context context) { + final boolean loadImages = sp.getBoolean("download_thumbnail_key", true); + + sp.edit() + .putString(context.getString(R.string.image_quality_key), + context.getString(loadImages + ? R.string.image_quality_default + : R.string.image_quality_none_key)) + .apply(); + } + }; + /** * List of all implemented migrations. *

@@ -140,12 +154,13 @@ public final class SettingMigrations { MIGRATION_2_3, MIGRATION_3_4, MIGRATION_4_5, + MIGRATION_5_6, }; /** * Version number for preferences. Must be incremented every time a migration is necessary. */ - private static final int VERSION = 5; + private static final int VERSION = 6; public static void runMigrationsIfNeeded(@NonNull final Context context, diff --git a/app/src/main/java/org/schabi/newpipe/util/external_communication/ShareUtils.java b/app/src/main/java/org/schabi/newpipe/util/external_communication/ShareUtils.java index f14f22069..8150d4030 100644 --- a/app/src/main/java/org/schabi/newpipe/util/external_communication/ShareUtils.java +++ b/app/src/main/java/org/schabi/newpipe/util/external_communication/ShareUtils.java @@ -24,7 +24,7 @@ import androidx.core.content.FileProvider; import org.schabi.newpipe.BuildConfig; import org.schabi.newpipe.R; import org.schabi.newpipe.extractor.Image; -import org.schabi.newpipe.util.PicassoHelper; +import org.schabi.newpipe.util.image.PicassoHelper; import java.io.File; import java.io.FileOutputStream; @@ -251,7 +251,7 @@ public final class ShareUtils { // If loading of images has been disabled, don't try to generate a content preview if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && !TextUtils.isEmpty(imagePreviewUrl) - && PicassoHelper.getShouldLoadImages()) { + && PicassoHelper.shouldLoadImages()) { final ClipData clipData = generateClipDataForImagePreview(context, imagePreviewUrl); if (clipData != null) { diff --git a/app/src/main/java/org/schabi/newpipe/util/PicassoHelper.java b/app/src/main/java/org/schabi/newpipe/util/image/PicassoHelper.java similarity index 94% rename from app/src/main/java/org/schabi/newpipe/util/PicassoHelper.java rename to app/src/main/java/org/schabi/newpipe/util/image/PicassoHelper.java index 5f3876d78..3177e83f4 100644 --- a/app/src/main/java/org/schabi/newpipe/util/PicassoHelper.java +++ b/app/src/main/java/org/schabi/newpipe/util/image/PicassoHelper.java @@ -1,4 +1,4 @@ -package org.schabi.newpipe.util; +package org.schabi.newpipe.util.image; import static org.schabi.newpipe.MainActivity.DEBUG; import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty; @@ -46,8 +46,7 @@ public final class PicassoHelper { @SuppressLint("StaticFieldLeak") private static Picasso picassoInstance; - private static boolean shouldLoadImages; - private static ResolutionLevel preferredResolutionLevel = ResolutionLevel.HIGH; + private static PreferredImageQuality preferredImageQuality = PreferredImageQuality.MEDIUM; public static void init(final Context context) { picassoCache = new LruCache(10 * 1024 * 1024); @@ -93,12 +92,12 @@ public final class PicassoHelper { picassoInstance.setIndicatorsEnabled(enabled); // useful for debugging } - public static void setShouldLoadImages(final boolean shouldLoadImages) { - PicassoHelper.shouldLoadImages = shouldLoadImages; + public static void setPreferredImageQuality(final PreferredImageQuality preferredImageQuality) { + PicassoHelper.preferredImageQuality = preferredImageQuality; } - public static boolean getShouldLoadImages() { - return shouldLoadImages; + public static boolean shouldLoadImages() { + return preferredImageQuality != PreferredImageQuality.NONE; } @@ -231,17 +230,14 @@ public final class PicassoHelper { @Nullable public static String choosePreferredImage(final List images) { - if (!shouldLoadImages) { - return null; - } - final Comparator comparator; - switch (preferredResolutionLevel) { + switch (preferredImageQuality) { + case NONE: + return null; case HIGH: comparator = Comparator.comparingInt(Image::getHeight).reversed(); break; default: - case UNKNOWN: case MEDIUM: comparator = Comparator.comparingInt(image -> Math.abs(image.getHeight() - 450)); break; diff --git a/app/src/main/java/org/schabi/newpipe/util/image/PreferredImageQuality.java b/app/src/main/java/org/schabi/newpipe/util/image/PreferredImageQuality.java new file mode 100644 index 000000000..9f17082ea --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/util/image/PreferredImageQuality.java @@ -0,0 +1,24 @@ +package org.schabi.newpipe.util.image; + +import android.content.Context; + +import org.schabi.newpipe.R; + +public enum PreferredImageQuality { + NONE, + LOW, + MEDIUM, + HIGH; + + public static PreferredImageQuality fromPreferenceKey(final Context context, final String key) { + if (context.getString(R.string.image_quality_none_key).equals(key)) { + return NONE; + } else if (context.getString(R.string.image_quality_low_key).equals(key)) { + return LOW; + } else if (context.getString(R.string.image_quality_high_key).equals(key)) { + return HIGH; + } else { + return MEDIUM; // default to medium + } + } +} diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index d0cf90db4..0c9f2c74c 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -243,7 +243,6 @@ الإشارات المرجعية استعمال التقديم السريع الغير دقيق خاصية التقديم الغير دقيق تسمح للمشغل بالقفز خلال الفديو بشكل أسرع مع دقة قفز أقل. خاصية القفز ل5، 15 او 25 لا تعمل مع القفز الغير دقيق - تحميل الصور المصغرة تم إفراغ مساحة ذاكرة التخزين المؤقتة الخاصة بالصور الملف لا يوجد مثل هذا المجلد @@ -260,7 +259,6 @@ عملية التصدير جارية … إستيراد ملف معرفك, soundcloud.com/هويتك - قم بإيقاف تشغيله لمنع تحميل الصور المصغرة وحفظ البيانات واستخدام الذاكرة. تمسح التغييرات كلاً من ذاكرة التخزين المؤقت للصورة الموجودة في الذاكرة والموجودة على القرص امسح البيانات الوصفيّة المخزّنة مؤقّتًا إزالة جميع بيانات صفحات الويب المخزنة مؤقّتًا تم محو ذاكرة التخزين المؤقتّة للبيانات الوصفيّة diff --git a/app/src/main/res/values-as/strings.xml b/app/src/main/res/values-as/strings.xml index 93e9e363e..fc9d5b2b6 100644 --- a/app/src/main/res/values-as/strings.xml +++ b/app/src/main/res/values-as/strings.xml @@ -62,7 +62,6 @@ লোড ব্যৱধানৰ আকাৰ সলনি কৰক (বৰ্তমানে %s) । এটা কম মানে প্ৰাৰম্ভিক ভিডিঅ\' লোডিং দ্ৰুত কৰিব পাৰে। পৰিৱৰ্তনৰ বাবে এটা খেলুৱৈ পুনৰাৰম্ভৰ প্ৰয়োজন থাম্বনেইলত থকা মূল ৰং অনুসৰি এণ্ড্ৰইডক জাননীৰ ৰং কাষ্টমাইজ কৰিবলৈ কওক (মন কৰিব যে এইটো সকলো ডিভাইচতে উপলব্ধ নহয়) সক্ৰিয় প্লেয়াৰৰ queue সলনি কৰা হ’ব - থাম্বনেইল লোড কৰক মন্তব্য দেখুৱাওক বিৱৰণ দেখুৱাওক মেটা তথ্য দেখুৱাওক @@ -96,6 +95,5 @@ ভিডিঅ\'ৰ বিৱৰণ আৰু অতিৰিক্ত তথ্য লুকুৱাবলৈ বন্ধ কৰক মন্তব্য লুকুৱাবলৈ বন্ধ কৰক \'পৰৱৰ্তী\' আৰু \'সাদৃশ্য থকা\' ভিডিঅ\' দেখুৱাওক - থাম্বনেইলসমূহ লোড কৰা, তথ্য আৰু মেমৰি ব্যৱহাৰ সংৰক্ষণ কৰা ৰোধ কৰিবলে বন্ধ কৰক। পৰিবৰ্তনসমূহে ইন-মেমৰি আৰু অন-ডিস্ক কেশ্ব দুয়োটা পৰিষ্কাৰ কৰে ষ্ট্ৰিমৰ সৃষ্টিকৰ্তা, ষ্ট্ৰিমৰ বিষয়বস্তু বা এটা সন্ধান অনুৰোধৰ বিষয়ে অতিৰিক্ত তথ্যৰ সৈতে মেটা তথ্যৰ বাকচসমূহ লুকুৱাবলৈ বন্ধ কৰক \ No newline at end of file diff --git a/app/src/main/res/values-az/strings.xml b/app/src/main/res/values-az/strings.xml index a238758af..06273f9cf 100644 --- a/app/src/main/res/values-az/strings.xml +++ b/app/src/main/res/values-az/strings.xml @@ -136,7 +136,6 @@ \nOnu görmək istəyirsinizsə, tənzimləmələrdə \"%1$s\" seçimini aktivləşdirin. YouTube potensial yetkin məzmunu gizlədən \"Məhdud Rejim\" təmin edir \"PeerTube\" nümunələri - Miniatürləri yüklə Yığcam bildirişdə göstərmək üçün ən çoxu üç fəaliyyət seçə bilərsiniz! Həmişə yenilə Axın @@ -287,7 +286,6 @@ Səs yayımı tapılmadı Digər tətbiqlərin üzərində göstərməyə icazə ver İlkin tənzimləmələri qaytarmaq istəyirsiniz\? - Miniatürləri yükləməyi, məlumata qənaət və yaddaş istifadəsin azaltmaq üçün söndür. Dəyişikliklər həm yaddaşdaxilində, həm də diskdə təsvir keşini təmizləyir Növbətini növbələ Təkrar Cəhd Et Cari oynatma yayımı bildirişini konfiqurasiya et diff --git a/app/src/main/res/values-b+ast/strings.xml b/app/src/main/res/values-b+ast/strings.xml index f9c6109e6..b9a57f1c2 100644 --- a/app/src/main/res/values-b+ast/strings.xml +++ b/app/src/main/res/values-b+ast/strings.xml @@ -206,8 +206,6 @@ \n3. Anicia sesión cuando se te pida \n4. Copia la URL del perfil al que te redirixeron. soundcloud.com/LaToID - Cargar les miniatures - Desactiva esta opción pa eviar la carga de miniatures y aforrar datos y usu de memoria. Los cambeos llimpien la caché d\'imáxenes temporal y permanente. Minimizar al cambiar d\'aplicación Minimizar al reproductor en segundu planu Minimizar al reproductor en ventanu diff --git a/app/src/main/res/values-b+uz+Latn/strings.xml b/app/src/main/res/values-b+uz+Latn/strings.xml index affa805e6..76924b0d4 100644 --- a/app/src/main/res/values-b+uz+Latn/strings.xml +++ b/app/src/main/res/values-b+uz+Latn/strings.xml @@ -24,10 +24,8 @@ Barcha keshlangan veb-sahifa ma\'lumotlarini olib tashlash Keshlangan metadatalarni o\'chirish Rasm keshi o\'chirildi - Eskizlarni yuklash, ma\'lumotlarni tejash va xotiradan foydalanishni oldini olish uchun o\'chirib qo\'ying. O\'zgarishlar xotiradagi va diskdagi rasm keshini tozalaydi. sharhlarni yashirishni o\'chirish Izohlarni ko\'rsatish - Eskizlarni yuklang Aktiv ijro etish navbati almashtiriladi Bir ijro etishdan boshqasiga o\'tish sizning navbatingizni almashtirishi mumkin Navbatni tozalashdan oldin tasdiqlashni so\'rash diff --git a/app/src/main/res/values-be/strings.xml b/app/src/main/res/values-be/strings.xml index 979553372..e176d2bc9 100644 --- a/app/src/main/res/values-be/strings.xml +++ b/app/src/main/res/values-be/strings.xml @@ -55,8 +55,6 @@ Запамінаць памер і становішча ўсплываючага акна Хуткі пошук пазіцыі Недакладны пошук дазваляе плэеру знаходзіць пазіцыі хутчэй са зніжанай дакладнасцю. Пошук цягам 5, 15 ці 25 секунд пры гэтым немажлівы - Загружаць мініяцюры - Адключыце, каб не загружаць мініяцюры і зэканоміць трафік і памяць. Змена налады ачысьціць кэш малюнкаў Кэш малюнкаў ачышчаны Ачысціць кэш метададзеных Выдаліць усе загружаныя дадзеныя вэб-старонак diff --git a/app/src/main/res/values-bg/strings.xml b/app/src/main/res/values-bg/strings.xml index 24bf7a764..59091553d 100644 --- a/app/src/main/res/values-bg/strings.xml +++ b/app/src/main/res/values-bg/strings.xml @@ -151,7 +151,6 @@ Добавяне към Използвай бързо, но неточно превъртане По-бързо превъртане с по-ниска прецизност. Превъртане с по 5, 15 или 25 секунди няма да работи с тази опция - Зареждай миниатюри Кеш-паметта с изображения е изтрита Изтрий кешираните метаданни Премахни всички метаданни за уебстраници от кеш-паметта @@ -205,7 +204,6 @@ Прочетете нашата политика за поверителност Лицензът на NewPipe Липсва стрийм плейър (можете да изтеглите VLC, за да пуснете стрийма). - Изключете, за да спрете зареждането на всички миниатюри, спестявайки трафик и памет. При промяна на тази настройка, текущата кеш-памет на изображенията ще бъде изтрита Показвай подсказка при избор на фоновия режим или режим в прозорец от екрана за „Детайли“ към видео Изтрива историята на възпроизвежданите стриймове и позицията на възпроизвеждането Не са намерени видео стриймове diff --git a/app/src/main/res/values-bn-rBD/strings.xml b/app/src/main/res/values-bn-rBD/strings.xml index 4e6655e45..e660cb7bd 100644 --- a/app/src/main/res/values-bn-rBD/strings.xml +++ b/app/src/main/res/values-bn-rBD/strings.xml @@ -140,8 +140,6 @@ দ্রুত-ফরওয়ার্ড/-পুনরায় সন্ধান সময়কাল মন্তব্যসমূহ লুকাতে বন্ধ করুন মন্তব্যসমূহ দেখাও - থাম্বনেইল লোড করো - থাম্বনেইল প্রদর্শন বন্ধ করার মাধ্যমে, ডাটা এবং মেমোরি সংরক্ষণ করুন। অপশনটি‌ পরিবর্তনে ইন-মেমোরি এবং অন-ডিস্ক ইমেজ ক্যাশ উভয়ই মুছে যাবে। ছবির ক্যাশ মোছা হয়েছে সব ক্যাশড ওয়েবপেজ ডেটা মুছে ফেলো ক্যাশ করা মেটাডেটা মোছ diff --git a/app/src/main/res/values-bn-rIN/strings.xml b/app/src/main/res/values-bn-rIN/strings.xml index 162dfde39..1f664ce26 100644 --- a/app/src/main/res/values-bn-rIN/strings.xml +++ b/app/src/main/res/values-bn-rIN/strings.xml @@ -79,10 +79,8 @@ সব ক্যাশড ওয়েবপেজ ডেটা মুছে ফেলো ক্যাশ করা মেটাডেটা মুছো ছবির ক্যাশ মুছে ফেলা হয়েছে - থাম্বনেইল প্রদর্শন বন্ধ করার মাধ্যমে, ডাটা এবং মেমোরি সংরক্ষণ করুন। অপশনটি‌ পরিবর্তনে ইন-মেমোরি এবং অন-ডিস্ক ইমেজ ক্যাশ উভয়ই মুছে যাবে মতামত প্রদর্শন বন্ধ করতে অপশনটি বন্ধ করুন মতামত প্রদর্শন করুন - থাম্বনেইল লোড করুন দ্রুত-ফরওয়ার্ড/-পুনরায় সন্ধান সময়কাল অনির্দিষ্ট সন্ধান প্লেয়ারকে আরো দ্রুত গতিতে সন্ধান করার সুবিধা দেয়, কিন্তু এটি সম্পূর্ণ নির্ভুল নাও হতে পারে ৷ ৫, ১৫ ও ২৫ সেকেন্ডের জন্য এটা কাজ করবে না ৷ দ্রুত টানা ব্যাবহার করুন diff --git a/app/src/main/res/values-bn/strings.xml b/app/src/main/res/values-bn/strings.xml index 6c3cca7a1..d3f3a845b 100644 --- a/app/src/main/res/values-bn/strings.xml +++ b/app/src/main/res/values-bn/strings.xml @@ -225,10 +225,8 @@ সব ক্যাশড ওয়েবপেজ ডেটা মুছে ফেলো ক্যাশ করা মেটাডেটা মুছো ছবির ক্যাশ মুছে ফেলা হয়েছে - থাম্বনেইল প্রদর্শন বন্ধ করার মাধ্যমে, ডাটা এবং মেমোরি সংরক্ষণ করুন। অপশনটি‌ পরিবর্তনে ইন-মেমোরি এবং অন-ডিস্ক ইমেজ ক্যাশ উভয়ই মুছে যাবে মতামত প্রদর্শন বন্ধ করতে অপশনটি বন্ধ করুন মতামত প্রদর্শন করুন - থাম্বনেইল লোড করুন দ্রুত-ফরওয়ার্ড/-পুনরায় সন্ধান সময়কাল অনির্দিষ্ট সন্ধান, চালককে আরো দ্রুত গতিতে সন্ধান করার সুবিধা দেয়, কিন্তু এটি সম্পূর্ণ নির্ভুল নাও হতে পারে ৷ ৫, ১৫ ও ২৫ সেকেন্ডের জন্য এটা কাজ করবে না। দ্রুত টানা ব্যাবহার করুন diff --git a/app/src/main/res/values-bs/strings.xml b/app/src/main/res/values-bs/strings.xml index 50dcf839c..4921a6aa8 100644 --- a/app/src/main/res/values-bs/strings.xml +++ b/app/src/main/res/values-bs/strings.xml @@ -73,7 +73,6 @@ Prebacivanje sa jednog pokretača na drugi bi van moglo zamijeniti pokretni red Isključite da sakrijete komentare Pitajte za potvrdu prije isčišćavanja reda - Isključite kako bi ste spriječili učitavanje sličica, sto če vam spasiti korištenje podataka i memorije. Promjene čiste slike oboje u memoriji i predmešiju na disku Prikažite komentare Pokažite \'Sljedeće\' i \'Slične\' video zapise Prikažite opis @@ -115,5 +114,4 @@ Pokrenite s KODI-jem Vrijeme premotavanja naprijed/nazad Aktivni pokretni red će biti zamijenjen - Učitajte sličice \ No newline at end of file diff --git a/app/src/main/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml index 010823e43..bd3a5c61b 100644 --- a/app/src/main/res/values-ca/strings.xml +++ b/app/src/main/res/values-ca/strings.xml @@ -121,7 +121,6 @@ Recorda la darrera mida i posició del reproductor emergent Cerca ràpida poc precisa La cerca poc precisa permet que el reproductor cerqui una posició més ràpidament amb menys precisió. Cerques de 5, 15 o 25 segons no funcionaran - Carrega les miniatures S\'ha eliminat la memòria cau d\'imatges Elimina les metadades de la memòria cau S\'ha esborrat la memòria cau de metadades @@ -217,7 +216,6 @@ Toca \"Cerca\" per començar. Elimina l\'àudio en algunes resolucions Reproductor d\'àudio extern - Desactiveu-ho per no guardar miniatures i estalviar dades i memòria. Canviant aquesta opció, s\'eliminarà la memòria cau d\'imatges tant de la memòria com de l\'emmagatzematge Emmagatzema les cerques localment Crea un historial de vídeos visualitzats Reprèn la reproducció diff --git a/app/src/main/res/values-ckb/strings.xml b/app/src/main/res/values-ckb/strings.xml index f761323f9..bae9fb822 100644 --- a/app/src/main/res/values-ckb/strings.xml +++ b/app/src/main/res/values-ckb/strings.xml @@ -16,7 +16,6 @@ پڕۆژەی نیوپایپ زانیارییە تایبەتییەکانت بە وردی دەپارێزێت. هەروەها به‌رنامه‌كه‌ هیچ زانایارییەکت بەبێ ئاگاداری تۆ بەکارنابات. \n‫سیاسەتی تایبەتی نیوپایپ بە وردی ڕوونکردنەوەت دەداتێ لەسەر ئەو زانیاریانەی وەریاندەگرێت و بەکاریاندەبات. ناتوانرێت لە بیرگەی دەرەکیدا داببەزێنرێت . شوێنی فۆڵده‌ری دابه‌زاندنەکان ڕێکبخرێتەوە؟ - ناکارای بكه‌ بۆ وەستاندنی باركردنی وێنۆچكه‌كان، داتا دەپارێزێت و کەمتر بیرگە بەکاردەبات, گۆڕینی ئه‌مه‌ ده‌بێته‌ هۆی سڕینه‌وه‌یان له‌سه‌ر بیرگه‌ی مۆبایله‌كه‌ت ئایا مەبەستت ئه‌مه‌یه‌ \"%1$s\"؟ ماوەی نوێكردنه‌وه‌ی فیید هێڵەکی @@ -111,7 +110,6 @@ زمان دەگۆڕدرێت لەدوای داگیرساندنەوەی به‌رنامه‌كه‌ لادانی سەیرکراو پیشاندانی نیشانەکەری شوێنی کارپێکەر لە خشتەکاندا - باركردنی وێنۆچكه‌كان شوێنەکان لە خشتەکاندا به‌ژداریت بەهۆی گۆڕانکاری لە شێوەی ژێرنووسکردنەکە. پێویستە به‌رنامه‌كه‌ دابگیرسێنیته‌وه‌ diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index 1eb38085c..dab312d3b 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -251,8 +251,6 @@ Vynutit hlášení nedoručitelných výjimek Rx mimo životnost fragmentu nebo aktivity po odstranění Použít rychlé nepřesné hledání Nepřesné hledání umožní přehrávači posouvat se rychleji, ale se sníženou přesností. Posouvání po 5, 15 nebo 25 vteřinách s tímto nefunguje - Načítat náhledy - Vypnutím zabráníte načítání miniatur, ukládání dat a spotřebě paměti. Změny vymažou mezipaměť obrázků v paměti i na disku Mezipaměť obrázků vymazána Vymazat metadata v mezipaměti Odstranit všechna data webových stránek v mezipaměti diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml index 0bd7e9875..ef6197414 100644 --- a/app/src/main/res/values-da/strings.xml +++ b/app/src/main/res/values-da/strings.xml @@ -57,8 +57,6 @@ Husk sidste størrelse og placering af pop op-afspiller Brug hurtig og upræcis søgning Upræcis søgning lader afspilleren finde placeringer hurtigere, men mindre præcist. Søgninger på 5, 15 eller 25 sekunder fungerer ikke med denne indstilling slået til - Indlæs miniaturebilleder - Slå fra for at undgå indlæsning af billeder, hvorved der spares data og hukommelse. Ændringer sletter billedcachen i både ram og lager Billedcache slettet Slet metadata-cachen Slet alle websidedata fra cachen diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 5283f1afa..e9b710c63 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -253,7 +253,6 @@ Beachte, dass diese Aktion das Netzwerk stark belasten kann. \n \nMöchtest du fortfahren\? - Vorschaubilder laden Bilder-Cache gelöscht Zwischengespeicherte (Metadaten) löschen Alle zwischengespeicherten Website-Daten entfernen @@ -270,7 +269,6 @@ Geschwindigkeit Tonhöhe Entkoppeln (kann zu Verzerrungen führen) - Ausschalten, um das Laden von Vorschaubildern zu verhindern, was Daten- und Speicherverbrauch spart. Änderungen löschen den Bildzwischenspeicher sowohl im Arbeitsspeicher als auch auf dem internen Speicher Nächsten Stream automatisch einreihen Wiedergabe durch Anhängen eines verwandten Streams an die Warteschlange (ohne Wiederholungsschleife) fortsetzen Wiedergabeliste mit Lesezeichen versehen diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index 094ac0ccd..ced70b787 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -90,8 +90,6 @@ Ενθύμηση του τελευταίου μεγέθους και θέσης του παραθύρου Χρήση γρήγορης ανακριβούς αναζήτησης Η μην ακριβής αναζήτηση επιτρέπει στην εφαρμογή να αναζητεί θέσεις στο βίντεο γρηγορότερα με μειωμένη ακρίβεια. Δε λειτουργεί για διαστήματα των 5, 15 ή 25 δευτερολέπτων - Φόρτωση μικρογραφιών - Με την απενεργοποίηση δε φορτώνονται οι μικρογραφίες, εξοικονομώντας δεδομένα και μνήμη. Οι αλλαγές σβήνουν τις προσωρινά αποθηκευμένες εικόνες στη μνήμη και στον δίσκο Εκκαθαρίστηκε η προσωρινή μνήμη εικόνων Εκκαθάριση προσωρινά αποθηκευμένων μεταδεδομένων Αφαίρεση όλων των προσωρινά αποθηκευμένων δεδομένων ιστοσελίδων diff --git a/app/src/main/res/values-en-rGB/strings.xml b/app/src/main/res/values-en-rGB/strings.xml index c8cc728b5..808aa2573 100644 --- a/app/src/main/res/values-en-rGB/strings.xml +++ b/app/src/main/res/values-en-rGB/strings.xml @@ -76,7 +76,6 @@ Behaviour Select your favourite PeerTube instances Continue playing after interruptions (e.g. phone calls) - Turn off to prevent loading thumbnails, saving data and memory usage. Changes clear both in-memory and on-disc image cache. Published on %1$s Report this error via e-mail Select your favorite night theme – %s diff --git a/app/src/main/res/values-eo/strings.xml b/app/src/main/res/values-eo/strings.xml index a3a7a6af4..2d0951db4 100644 --- a/app/src/main/res/values-eo/strings.xml +++ b/app/src/main/res/values-eo/strings.xml @@ -80,7 +80,6 @@ Memori lastan grandon kaj pozicion de ŝprucfenestro Uzi rapidan malekzaktan serĉon Malekzakta serĉo permesas ke, la ludilo serĉi poziciojn pli rapide sed kun malpli ekzakto. Serĉi por 5, 15 aŭ 25 sekundoj ne funckias kun ĉi tio opcio - Ŝarĝi bildetojn Ne povis konstrui la dosierujon de elŝuto Enhavo limigita al aĝo Nuna @@ -181,7 +180,6 @@ \n2. Iru tien: %1$s \n3. Ensalutu kiam oni petas vin \n4. Kopiu la ligilon de profilo ke oni kondikis vin. - Malŝaltu por malebligi ŝarĝajn bildetojn por konservi datumuzadon kaj memoruzadon. Ŝanĝoj vakigi ambaŭ en memoran kaj en diskan bildkaŝmemoron Bildokaŝmemoro vakigis Vakigi kaŝmemorigitajn metadatumojn Vakigi tutajn kaŝmemorigitajn retpaĝajn datumojn diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index d1d7fdcd4..6ffadca81 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -288,8 +288,6 @@ Esta operación puede causar un uso intensivo de la red. \n \n¿Quieres continuar\? - Cargar miniaturas - Desactivar para evitar la carga de miniaturas y ahorrar datos y memoria. Se vaciará la caché de imágenes en la memoria volátil y en el disco Se vació la caché de imágenes Vaciar metadatos en memoria caché Quitar todos los datos guardados de páginas web diff --git a/app/src/main/res/values-et/strings.xml b/app/src/main/res/values-et/strings.xml index b55870c75..ab478ec11 100644 --- a/app/src/main/res/values-et/strings.xml +++ b/app/src/main/res/values-et/strings.xml @@ -55,8 +55,6 @@ Pea hüpikakna viimane suurus ja asukoht meeles Kasuta ebatäpset kerimist Ebatäpne kerimine lubab meediamängijal otsida asukohta kiiremini täpsuse arvel. Sellega ei tööta 5, 15 või 25 sekundi kaupa kerimine - Laadi pisipildid - Lülita välja, et keelata pisipiltide laadimist, andmete salvestamist ja mälukasutust. Muutmine puhastab vahemälu nii kettal kui ka mälus Pildid kustutati vahemälust Kustuta metaandmed vahemälust Kustuta veebilehtede andmed vahemälust diff --git a/app/src/main/res/values-eu/strings.xml b/app/src/main/res/values-eu/strings.xml index c8d16b698..6003de6fd 100644 --- a/app/src/main/res/values-eu/strings.xml +++ b/app/src/main/res/values-eu/strings.xml @@ -211,7 +211,6 @@ Gogoko erreprodukzio-zerrendak Gehitu hona Erabili bilaketa azkar ez zehatza - Kargatu iruditxoak Irudien cachea ezabatuta Ezabatu cacheko metadatuak Kendu cachetik webguneen datu guztiak @@ -307,7 +306,6 @@ Desaktibatu (distortsioa sor lezake) Ezarpenak ere inportatu nahi dituzu? Bilaketa ez zehatzak posizioak azkarrago baina prezisio gutxiagoz bilatzea ahalbidetzen du. 5, 15 edo 25 segundo bilatzea ez du honekin funtzionatzen - Desgaitu koadro txikiak ez kargatzeko, datuak eta memoria aurreztuz. Aldaketak memoria eta diskoko irudien cacheak garbituko ditu NewPipe Software Librea eta Copyleft da: Erabili, ikertu, partekatu eta hobetu dezakezu. Zehazki, elkarbanatzea eta aldatzea Free Software Foundation-ek argitaratutako GNU General Public License-ren 3. bertsioa edo berriagoren baten terminoen arabera egiteko baimena duzu. Behartu aktibitatearen bizitza ziklotik kanpo baztertu eta gero entregatu ezin diren Rx salbuespenen inguruko txostena NewPipe pribatutasun politika diff --git a/app/src/main/res/values-fa/strings.xml b/app/src/main/res/values-fa/strings.xml index 3d8e8da9b..35db56515 100644 --- a/app/src/main/res/values-fa/strings.xml +++ b/app/src/main/res/values-fa/strings.xml @@ -96,7 +96,6 @@ تنها برخی دستگاه‌ها توانایی پخش ویدیوهای 2K و 4K را دارند قالب ویدیویی پیش‌گزیده سیاه - بار کردن بندانگشتی‌ها قرار دادن خودکار جریان بعدی در صف پیشنهادهای جستجو گزینش پیشنهادها برای نمایش هنگام جست‌وجو @@ -270,7 +269,6 @@ پخش ادامه یابد ذخیره محلی نتایج جستجو صف پخش در حال پایان (بدون تکرار) را با افزودن یک جریان مرتبط ادامه دهید - برای پیش‌گیری از بار کردن بندانگشتی‌ها و ذخیرهٔ داده و فضای ذخیره، خاموش کنید. تغییرات، انبارهٔ تصاویر روی حافظه و دیسک را پاک می‌کند ادامه پخش بازگرداندن آخرین موقعیت پخش موقعیت در فهرست‌ها diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml index 641e55b21..397f2fef0 100644 --- a/app/src/main/res/values-fi/strings.xml +++ b/app/src/main/res/values-fi/strings.xml @@ -196,8 +196,6 @@ Lisää soittolistaan Käytä nopeampaa epätarkkaa pikakelausta Epätarkka kelaus mahdollistaa videon kelauksen nopeammin huonommalla tarkkuudella. Kelaaminen 5, 15 tai 25 sekunnin hyppäyksin ei toimi tämän kanssa - Lataa esikatselukuvat - Poista käytöstä estääksesi esikatselukuvien lataus. Tämä säästää dataa ja vähentää muistin käyttöä. Asetuksen muuttaminen poistaa muistissa ja levyllä olevan kuvavälimuistin Kuvavälimuisti tyhjennetty Poista tallennettu metatieto Poista kaikki tallennettu sivutieto diff --git a/app/src/main/res/values-fil/strings.xml b/app/src/main/res/values-fil/strings.xml index 4cafaff85..0fb7a0a1d 100644 --- a/app/src/main/res/values-fil/strings.xml +++ b/app/src/main/res/values-fil/strings.xml @@ -48,7 +48,6 @@ Pangalawang action button Pangatlong action button Pinapayagan ng di-saktong seek ang player na mag-seek sa mga posisyon nang mabilis ngunit na may pinababang kasaktuhan. Di ito gagana sa pag-seek nang 5, 15, o 25 segundo. - Patayin para mapigilan ang pag-load sa mga thumbnail, para makatipid ng data at paggamit sa memory. Lilinisin ang parehong image cache na nasa memory at nasa disk Piliin ang mga mungkahing ipapakita habang naghahanap Patayin para itago ang paglalarawan ng video at karagdagang impormasyon I-edit ang bawat action sa abiso sa baba sa pamamagitan ng pagpindot sa mga ito. Pumili ng hanggang tatlong ipapakita sa siksik na abiso gamit ang mga checkbox sa kanan @@ -70,7 +69,6 @@ Kumpirmahin muna bago linisin ang pila Maaaring mapalitan ang pila mo kung magpapalit ka ng player Papalitan ang aktibong pila sa player - I-load ang mga thumbnail Ipakita ang paglalarawan Ipakita ang meta info Patayin para itago ang mga meta infobox na may karagdagang impormasyon tungkol sa creator ng stream, laman nito o ng hinanap diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index b899ec7f8..51f258166 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -244,8 +244,6 @@ Zoomer Utiliser la recherche rapide approximative Permet au lecteur d’accéder plus rapidement à une position au détriment de la précision. Se déplacer de 5, 15 ou 25 secondes est impossible avec cette option - Charger les miniatures - Désactivez pour empêcher le chargement des miniatures afin de réduire l’utilisation de la bande passante et de la mémoire. La modification de cette option vide le cache en mémoire vive et sur le disque Images en cache effacées Effacer les métadonnées en cache Efface toutes les données des pages Web en cache diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml index 98d3d472b..8b5aaa497 100644 --- a/app/src/main/res/values-gl/strings.xml +++ b/app/src/main/res/values-gl/strings.xml @@ -55,8 +55,6 @@ Lembrar o tamaño e a posición anteriores do «popup» Usar un salto inexacto mais inexacto A busca inexacta permite ao reprodutor procurar posicións máis rápidas con precisión reducida. A busca de 5, 15 ou 25 segundos non funciona con isto - Carregar miniaturas - Desactíveo para evitar a carga de miniaturas e poupar datos e memoria. Modificar esta opción limpa a caché de imaxes da memoria e do disco A caché de imaxes foi limpada Os metadatos da caché foron eliminados Eliminar todos os datos de páxinas en caché diff --git a/app/src/main/res/values-he/strings.xml b/app/src/main/res/values-he/strings.xml index 5c55d0bad..4dec4c819 100644 --- a/app/src/main/res/values-he/strings.xml +++ b/app/src/main/res/values-he/strings.xml @@ -268,8 +268,6 @@ קצב שימוש בחיפוש מהיר ולא מדויק חיפוש גס מאפשר לנגן לחפש נקודת זמן מהר יותר, ברמת דיוק נמוכה יותר. חיפוש של 5, 15 או 25 שניות לא עובד עם ההגדרה הזאת - טעינת תמונות ממוזערות - כיבוי האפשרות מונע את טעינת התמונות הממוזערות, חוסך בתקשורת נתונים ובניצולת הזיכרון. שינויים באפשרות זו מוחקים את המטמון בזיכרון ובכונן הסרת כל נתוני העמודים שבמטמון הוספת התזרים הבא לרשימת הנגינה אוטומטית להמשיך תור נגינה סופית (בלתי מחזורית) על ידי הוספת תזרים קשור diff --git a/app/src/main/res/values-hi/strings.xml b/app/src/main/res/values-hi/strings.xml index a2bbaf672..80ab6209c 100644 --- a/app/src/main/res/values-hi/strings.xml +++ b/app/src/main/res/values-hi/strings.xml @@ -245,10 +245,8 @@ ऑटो-जनरेटेड हीप डंप करने के दौरान मेमोरी लीक मॉनिटरिंग ऐप को अनुत्तरदायी बना सकता है Out-of-Lifecycle त्रुटियों की रिपोर्ट करें - थंमनेल लोड करें तेज और अनिश्चित तलाश का प्रयोग करें अनिश्चित खोज से प्लेयर में कम सटीकता से लेकिन तेजी से वीडियो पोजीशन्स की तलाश कर सकता हैं। 5, 15 या 25 सेकंड की तलाश में यह काम नहीं करता - डेटा खपत, मेमोरी उपयोग की बचत और थंमनेल लोड होने से रोकने के लिए बंद करें। इस बदलाव से इन-मेमोरी और ऑन-डिस्क छवि कैश दोनों मिट जाते हैं चित्र कैश मिटाया गया कैश मेटाडेटा मिटाएं कैश किए गए सभी वेबपेज का डेटा हटाएं diff --git a/app/src/main/res/values-hr/strings.xml b/app/src/main/res/values-hr/strings.xml index 80b734fcd..c625955f7 100644 --- a/app/src/main/res/values-hr/strings.xml +++ b/app/src/main/res/values-hr/strings.xml @@ -218,7 +218,6 @@ Prikaži informacije Zabilježene playliste Dodaj u - Učitaj sličice Slikovna predmemorija obrisana Izbriši metapodatke iz predmemorije Kanali @@ -312,7 +311,6 @@ Dostupna je nova verzija za NewPipe! Preuzimanje nije uspjelo Prikaži pogrešku - Isključi za sprečavanje učitavanja sličica, čime se štedi korištenje podataka i memorije. Promjene čiste predmemoriju slika radne memorije i diska Izbriši sve podatke web-stranica iz predmemorije Metapodaci su izbrisani Automatski dodaj sljedeći stream u popisa izvođenja diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml index 9f3ddf9cf..26f4ee3cf 100644 --- a/app/src/main/res/values-hu/strings.xml +++ b/app/src/main/res/values-hu/strings.xml @@ -136,8 +136,6 @@ Hozzáadás ehhez Gyorsabb, de pontatlan tekerés használata A pontatlan tekerés lehetővé teszi, hogy gyorsabban ugorjon a pozíciókra, de kisebb pontossággal. Az 5, 15, vagy 25 másodperces tekerés nem működik ebben a módban - Bélyegképek betöltése - Kapcsolja ki, hogy a megelőzze a bélyegképek betöltését, így csökkentve az adat- és memóriahasználatot. A megváltoztatása törli a memóriában és a meghajtón lévő képgyorsítótárat A bélyegkép gyorsítótár törölve Gyorsítótárazott metaadatok törlése Minden gyorsítótárazott weboldaladat törlése diff --git a/app/src/main/res/values-ia/strings.xml b/app/src/main/res/values-ia/strings.xml index d4ae5b455..512598eaa 100644 --- a/app/src/main/res/values-ia/strings.xml +++ b/app/src/main/res/values-ia/strings.xml @@ -227,7 +227,6 @@ Interne Aperir con Suggestiones de recerca remote - Cargar miniaturas Monstrante resultatos pro: %s Solmente alicun apparatos pote reproducer videos 2K/4K Initiar le reproductor principal in schermo plen diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index 292430861..b68b36a47 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -132,8 +132,6 @@ Notifikasi NewPipe Riwayat Riwayat - Muat thumbnail - Matikan agar thumbnail tidak dimuat, menghemat penggunaan data dan memori. Perubahan menghapus cache gambar baik di memori dan disk Cache gambar dihapus Hapus cache metadata Hapus semua data cache halaman web diff --git a/app/src/main/res/values-is/strings.xml b/app/src/main/res/values-is/strings.xml index e27217971..98f73e294 100644 --- a/app/src/main/res/values-is/strings.xml +++ b/app/src/main/res/values-is/strings.xml @@ -177,7 +177,6 @@ Nota hraða en ónákvæma leit Lengd skrefs Biðja um staðfestingu áður en röð er hreinsuð - Sækja smámyndir Sýna ummæli Sjálfvirk biðröð Hreinsa gögn @@ -613,7 +612,6 @@ Stærð forhleðslu Breyta stærð forhleðslu (nú %s). Lægra gildi gæti flýtt fyrir upphaflegu hleðslu myndbands. Breytingar krefjast endurræsingar spilara Biðröð spilarans verður skipt út - Slökktu á til að hlaða ekki niður smámyndum til að spara bandbreidd og vinnsluminni. Breytingar eyða myndskyndiminni í bæði vinnsluminni og geymslu Slökktu á til að fela lýsigagnareiti með viðbótarupplýsingum um straumhöfund, straumefni eða leitarbeiðni Fjarlæga öll síðugögn úr skyndiminni Bæta svipuðum straumum við biðröðina þegar síðasta er spilað og endurspilun er ekki virkjuð diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 05604e998..48cc84328 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -287,8 +287,6 @@ Tieni presente che questa operazione può consumare una grande quantità di traffico dati. \n \nVuoi continuare? - Carica copertine - Disabilita per prevenire il caricamento delle copertine, risparmiando dati e memoria. La modifica di questa opzione cancellerà la cache delle immagini in memoria e sul disco Cache immagini svuotata Svuota la cache dei metadati Elimina i dati delle pagine web memorizzati nella cache diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 0eeeaf8dd..8fa73a002 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -196,7 +196,6 @@ 動画をダウンロード 情報を表示 ブックマークしたプレイリスト - サムネイルを読み込む 画像キャッシュを消去しました キャッシュを消去 アプリ内のキャッシュデータをすべて削除します @@ -254,7 +253,6 @@ プライバシーポリシーを確認 おおまかなシーク おおまかなシークを使用することで精度が下がる代わりに高速にシークができます。5 秒、15 秒または 25 秒間隔のシークはできません - サムネイルの読み込みと保存を無効化します。(このオプションを切り替えるとメモリとディスク上の画像キャッシュが消去されます) キューに関連動画を追加して再生を続ける (繰り返ししない場合) すべての再生履歴を削除しますか? すべての検索履歴を削除しますか? diff --git a/app/src/main/res/values-jv/strings.xml b/app/src/main/res/values-jv/strings.xml index 2f68f9bc9..7f71a2f41 100644 --- a/app/src/main/res/values-jv/strings.xml +++ b/app/src/main/res/values-jv/strings.xml @@ -10,11 +10,9 @@ Antri otomatis stream bare Sampah metadata wes dibusak Busak kabeh sampah ora kanggo - Pateni ben gambar cilik ora ketok, ora boros data lan memori. Iku bakal ngresiki sampah gambar. Sampah gambar wes resik Pateni gawe ngumpetke komentar Duduhke komentar - Duduhke gambar cilik Durasi cepet maju/mundure Eling-eling ukuran lan posisi ngambang terakhir Eling-eling ukuran lan posisi ngambang diff --git a/app/src/main/res/values-ka/strings.xml b/app/src/main/res/values-ka/strings.xml index 89c2193da..47e105183 100644 --- a/app/src/main/res/values-ka/strings.xml +++ b/app/src/main/res/values-ka/strings.xml @@ -42,7 +42,6 @@ არაზუსტი ძიება საშუალებას აძლევს მოთამაშეს უფრო სწრაფად მოიძიოს პოზიციები შემცირებული სიზუსტით. 5, 15 ან 25 წამის ძიება ამით არ მუშაობს სწრაფი წინსვლა/-გადახვევა ძიების ხანგრძლივობა ერთი მოთამაშიდან მეორეზე გადართვამ შესაძლოა შეცვალოს თქვენი რიგი - გამორთეთ ესკიზების ჩატვირთვის თავიდან ასაცილებლად, მონაცემთა დაზოგვისა და მეხსიერების გამოყენების თავიდან ასაცილებლად. იცვლება როგორც მეხსიერებაში, ასევე დისკზე გამოსახულების ქეშის გასუფთავება ძიების შეთავაზებები წაშალეთ ყველა ქეშირებული ვებგვერდის მონაცემები შემდეგი ნაკადის ავტომატური შეყვანა @@ -107,7 +106,6 @@ შავი დამახსოვრება ამომხტარი ფანჯრის თვისებები აქტიური მოთამაშის რიგი შეიცვლება - ჩატვირთეთ ესკიზები კომენტარების ჩვენება გამორთეთ კომენტარების დასამალად \"შემდეგი\" და \"მსგავსი\" ვიდეოების ჩვენება diff --git a/app/src/main/res/values-kmr/strings.xml b/app/src/main/res/values-kmr/strings.xml index 41f2742ab..b7478aa58 100644 --- a/app/src/main/res/values-kmr/strings.xml +++ b/app/src/main/res/values-kmr/strings.xml @@ -242,8 +242,6 @@ Vîdyoyên \'Pêş\' û \'Bi vî rengî\' nîşan bidin Zivirandin da ku şîroveyan veşêrin Şîroveyan nîşan bide - Ji bo pêşîgirtina li barkirina nîgarkêşan, daneya daneyê û karanîna bîranînê xilas bibe vemirînin. Guherandinên kaşeya wêneyê hem di bîra û hem jî li ser dîskê paqij dikin. - Nîgarên barkêş Dê rêza lîstikvanê çalak were guhertin Guhertina ji lîstikvanek bi yeke din dibe ku dewsa dorê we bigire Berî paqijkirina dorê ji pejirandinê bipirsin diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index 127db9bcb..30c381bcf 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -278,8 +278,6 @@ 경고: 데이터가 많이 소모될 수 있습니다. \n \n계속하시겠습니까\? - 썸네일 로드하기 - 동영상 썸네일을 로드하지 않으며, 데이터와 메모리 사용을 최대한 줄입니다. 이 옵션을 선택 시 모든 메모리 캐시와 저장소 캐시를 삭제합니다 이미지 캐시 지워짐 캐시된 메타데이터 지우기 캐시된 모든 웹페이지 데이터 지우기 diff --git a/app/src/main/res/values-ku/strings.xml b/app/src/main/res/values-ku/strings.xml index 8d1ffbab8..fc7e85616 100644 --- a/app/src/main/res/values-ku/strings.xml +++ b/app/src/main/res/values-ku/strings.xml @@ -53,9 +53,6 @@ ڕه‌ش بیرهاتنه‌وه‌ی شوێن و قه‌باره‌ی په‌نجه‌ره‌ بیرهاتنه‌وه‌ی كۆتا قه‌باره‌ و شوێنی په‌نجه‌ره‌ی بچووك - باركردنی وێنۆچكه‌كان - ناچالاكی بكه‌ بۆ ڕاگرتنی وێنۆچكه‌كان له‌ باركردن و پاشه‌كه‌وتبوون له‌سه‌ر بیرگه‌ی ئامێره‌كه‌ت. -\nگۆڕینی ئه‌مه‌ ده‌بێته‌ هۆی سڕینه‌وه‌یان له‌سه‌ر بیرگه‌ی مۆبایله‌كه‌ت. پاشماوه‌ی وێنۆچكه‌كان سڕایه‌وه‌ بەکارهێنانی گەڕانی ناوردی خێرا خاوێنکردنەوەی پاشماوەی داتا diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml index 1c8ba59ae..58b25709b 100644 --- a/app/src/main/res/values-lt/strings.xml +++ b/app/src/main/res/values-lt/strings.xml @@ -374,8 +374,6 @@ Atstatyti paskutinį atkūrimo laiką Tęsti atkūrimą Rodyti aprašymą - Norėdami taupyti duomenų srautą, atminties naudojimą išjunkite. Pakeitimai išvalys duomenis atmintyje ir diske - Įkelti miniatiūras Aktyvaus grotuvo eilė bus pakeista Perjungimas iš vieno grotuvo į kitą gali pakeisti jūsų eilę Prieš išvalant eilę prašyti patvirtinimo diff --git a/app/src/main/res/values-lv/strings.xml b/app/src/main/res/values-lv/strings.xml index c8d3221eb..a613dd70a 100644 --- a/app/src/main/res/values-lv/strings.xml +++ b/app/src/main/res/values-lv/strings.xml @@ -517,8 +517,6 @@ Rādīt \'Nākošos\' un \'Līdzīgos\' videoklipus Izslēdziet, lai paslēptu komentārus Rādīt komentārus - Izslēdziet, ja vēlaties nelādēt video attēlus, ietaupot datus un atmiņu. Opcija notīra kešatmiņu, izdzēšot visus saglabātos video attēlus - Ielādēt video attēlus Tagadējā atskaņošanas rinda tiks aizvietota Mainoties vienam video uz citu, iespējams, notīrīsies jūsu atskaņošanas rinda Prasīt apstiprinājumu, pirms notīrīt atskaņošanas rindu diff --git a/app/src/main/res/values-mk/strings.xml b/app/src/main/res/values-mk/strings.xml index 524c82aef..e39172c72 100644 --- a/app/src/main/res/values-mk/strings.xml +++ b/app/src/main/res/values-mk/strings.xml @@ -55,8 +55,6 @@ Запамти ја последната големина и место на прозорчето Брзо, непрецизно премотување Со непрецизното премотување се пребарува побрзо, но со намалена презицност. - Прочитај мали видео-сликички - Оневозможете, за да не се читаат малите видео-сликички за штедење на меморија и интернет. Промената на оваа опцијата ќе ја избрише кеш-меморијата. Кешираните слики се избришани Избришете ги кешираните мета-податоци Избришете ги сите кеш-податоци од веб-страни diff --git a/app/src/main/res/values-ml/strings.xml b/app/src/main/res/values-ml/strings.xml index 29769acae..d03ae0a38 100644 --- a/app/src/main/res/values-ml/strings.xml +++ b/app/src/main/res/values-ml/strings.xml @@ -331,10 +331,8 @@ കാഷെ ആയ ഡേറ്റ നീക്കംചെയ്യുക കാഷെ ആയ മെറ്റാഡേറ്റ തുടച്ചുനീക്കി ഇമേജ് കാചെ തുടച്ചുമാറ്റി - ലഘുചിങ്ങൾ ലോഡ് ചെയ്യാതിരിക്കാനും ഡേറ്റയും മെമ്മറിയും ലാഭിക്കാനുമായി ഓഫ്ചെയ്യുക. എസ് ഡീ കാർഡിലെയും മെമ്മറിയിലെയും കാച്ചേ ക്ലിയർ ചെയ്യും കമന്റുകൾ മറയ്ക്കാനായി ഓഫ് ചെയ്യുക കമന്റുകൾ കാണിക്കുക - ലഘുചിത്രങ്ങൾ ലോഡ്‌ ചെയ്യുക ഫാസ്റ്റ്-ഫോർവേർഡ്/റീവൈൻഡ് സമയദൈർഘ്യം Inexact seek ഉപയോഗിക്കുക കുറഞ്ഞ കൃത്യതയോടെ സീക് ചെയ്യാൻ ഇൻ എക്സക്ട് സഹായിക്കുന്നു. 5,15,25 സെക്കൻഡ് സീക്‌ ഈ മോഡിൽ പ്രവർത്തിക്കുകയില്ല diff --git a/app/src/main/res/values-ms/strings.xml b/app/src/main/res/values-ms/strings.xml index 648849205..d9e4f12ef 100644 --- a/app/src/main/res/values-ms/strings.xml +++ b/app/src/main/res/values-ms/strings.xml @@ -57,8 +57,6 @@ Mengingat saiz dan posisi popup terakhir Gunakan tinjau laju tidak tepat Membolehkan pemain untuk meninjau ke posisi lebih laju dengan kurang ketepatan. Mencari 5, 15 atau 25 saat tidak berfungsi dengan ini - Muatkan thumbnail - Matikan untuk mengelakkan pemuatan thumbnail, menjimat penggunaan data dan ingatan. Perubahan akan menghapus cache imej dari ingatan dan disk Cache imej dihapuskan Hapuskan cache metadata Hapuskan semua cache data halaman web diff --git a/app/src/main/res/values-nb-rNO/strings.xml b/app/src/main/res/values-nb-rNO/strings.xml index da6193e90..1637fe1f7 100644 --- a/app/src/main/res/values-nb-rNO/strings.xml +++ b/app/src/main/res/values-nb-rNO/strings.xml @@ -257,7 +257,6 @@ Eksporterer… Importer fil Forrige eksport - Last miniatyrbilder Bildehurtiglager tømt Tøm hurtiglagret metadata Fjern all hurtiglagret nettsidedata @@ -304,7 +303,6 @@ \n3. Logg inn når forespurt \n4. Kopier profil-nettadressen du ble videresendt til. Unøyaktig spoling lar spilleren søke posisjoner raskere med redusert presisjon. Å søke i 5, 15 eller 25 sekunder fungerer ikke med dette - Skru av for å stoppe innlasting av miniatyrbilder, noe som sparer data- og minnebruk. Endring av dette vil tømme både disk- og minne-hurtiglager Fortsett fullendt (ikke-repeterende) avspillingskø ved å legge til en relatert strøm Overvåkning av minnelekkasjer kan forårsake at appen ikke svarer under heap dumping Rapporter feil utenfor livssyklusen diff --git a/app/src/main/res/values-ne/strings.xml b/app/src/main/res/values-ne/strings.xml index 05c82808e..d1d0d15b0 100644 --- a/app/src/main/res/values-ne/strings.xml +++ b/app/src/main/res/values-ne/strings.xml @@ -56,10 +56,8 @@ पछिल्लो आकार र पपअप को स्थिति सम्झना तेज \'inexact\' खोज्न प्रयोग गर्नुहोस \'Inexact\' प्लेयर कम सटीक छिटो स्थितिहरू गर्न खोज्न अनुमति दिन्छ खोज्छन्। 5, 15 वा 25 सेकेन्ड को लागि खोजी यो काम गर्दैन। - थम्बनेल लोड टिप्पणीहरू देखाऊ टिप्पणीहरू लुकाउन, बन्द गर्नुहोस - डाटा र स्मृति उपयोग सुरक्षित गर्न, थम्बनेलहरू लोड रोक्न, बन्द गर्नुहोस। परिवर्तनहरू दुवै मा-स्मृति र-डिस्क छवि क्यास खाली गर्छ। छवि क्यास सखाप क्यास मेटाडाटा हटाउ सबै क्यास वेबपेज डाटा हटाउ diff --git a/app/src/main/res/values-nl-rBE/strings.xml b/app/src/main/res/values-nl-rBE/strings.xml index bf77f9da3..0d582f6de 100644 --- a/app/src/main/res/values-nl-rBE/strings.xml +++ b/app/src/main/res/values-nl-rBE/strings.xml @@ -55,8 +55,6 @@ Onthoud laatste grootte en positie van pop-up Snel, minder exact spoelen gebruiken Minder exact spoelen laat de speler sneller posities zoeken met verminderde precisie. 5, 15 en 25 seconden werken niet - Miniatuurvoorbeelden laden - Schakel dit uit voor het laden van miniatuurvoorbeelden te verhinderen; dit bespaart mobiele gegevens en geheugen. Het wijzigen van deze instelling wist het geheugen en de afbeeldingscache Afbeeldingscache gewist Gecachete metagegevens wissen Alle gecachete webpagina-gegevens wissen diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index b6622c210..e5b7f0f82 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -284,8 +284,6 @@ Let op: deze actie kan veel MB’s van je mobiele netwerk gebruiken. \n \nWil je doorgaan? - Miniatuurvoorbeelden laden - Schakel dit uit om het laden van miniatuurvoorbeelden te verhinderen; dit bespaart mobiele data en geheugen. Het wijzigen van deze instelling wist het geheugen en de afbeeldingscache Afbeeldingscache gewist Gecachete metagegevens wissen Alle gecachete webpagina-gegevens wissen diff --git a/app/src/main/res/values-oc/strings.xml b/app/src/main/res/values-oc/strings.xml index d440d8a89..6341e6700 100644 --- a/app/src/main/res/values-oc/strings.xml +++ b/app/src/main/res/values-oc/strings.xml @@ -58,7 +58,6 @@ Utilzar la recèrca rapida inexacta La recèrca inexacta permet a l\'utilizaire de recercar mai rapidament una posicion amb mens de precision Durada d\'avançada/reculada rapida - Cargar las miniaturas Afichar los comentaris Desactivar per afichar pas mai los comentaris Apondre la vidèo seguenta dins la coa de lectura diff --git a/app/src/main/res/values-or/strings.xml b/app/src/main/res/values-or/strings.xml index 084f21ca2..519a0f199 100644 --- a/app/src/main/res/values-or/strings.xml +++ b/app/src/main/res/values-or/strings.xml @@ -101,7 +101,6 @@ ଏକ ଧାଡି ସଫା କରିବା ପୂର୍ବରୁ ନିଶ୍ଚିତକରଣ ମାଗନ୍ତୁ ଗୋଟିଏ ଖେଳାଳୀରୁ ଅନ୍ୟ ଖେଳାଳୀକୁ ପରିବର୍ତ୍ତନ କରିବା ଆପଣଙ୍କ ଧାଡି ବଦଳାଇପାରେ ସକ୍ରିୟ ପ୍ଲେୟାର କ୍ୟୁ ବଦଳାଯିବ - ଥମ୍ୱନେଲ୍ ଲୋଡ୍ କରନ୍ତୁ \'ପରବର୍ତ୍ତୀ\' ଏବଂ \'ସମାନ\' ଭିଡିଓଗୁଡିକ ଦେଖାନ୍ତୁ ବର୍ଣ୍ଣନା ଦେଖାନ୍ତୁ ପ୍ରତିଛବି କ୍ୟାଚ୍ ପୋଛି ଦିଆଗଲା @@ -149,7 +148,6 @@ ଵିଡ଼ିଓ ଓ ଅଡ଼ିଓ ମିନି ପ୍ଲେୟାରରେ ଭିଡିଓ ଆରମ୍ଭ କରନ୍ତୁ ନାହିଁ, କିନ୍ତୁ ଅଟୋ ଘୂର୍ଣ୍ଣନ ବନ୍ଦ ହୋଇଗଲେ ସିଧାସଳଖ ଫୁଲ୍ ସ୍କ୍ରିନ୍ ମୋଡ୍ କୁ ଯାଆନ୍ତୁ। ଫୁଲ୍ ସ୍କ୍ରିନ୍ ଛାଡି ଆପଣ ଏପର୍ଯ୍ୟନ୍ତ ମିନି ପ୍ଲେୟାରକୁ ପ୍ରବେଶ କରିପାରିବେ ଏହା ଉପରେ ଟ୍ୟାପ୍ କରି ନିମ୍ନରେ ପ୍ରତ୍ୟେକ ବିଜ୍ଞପ୍ତି କାର୍ଯ୍ୟ ସଂପାଦନ କରନ୍ତୁ। ଡାହାଣରେ ଥିବା ଚେକ୍ ବକ୍ସ ବ୍ୟବହାର କରି କମ୍ପାକ୍ଟ ବିଜ୍ଞପ୍ତିରେ ଦେଖାଯିବାକୁ ସେମାନଙ୍କ ମଧ୍ୟରୁ ତିନୋଟି ପର୍ଯ୍ୟନ୍ତ ଚୟନ କରନ୍ତୁ - ଥମ୍ବନେଲ ଲୋଡିଂ, ଡାଟା ଏବଂ ମେମୋରୀ ବ୍ୟବହାରକୁ ରୋକିବା ପାଇଁ ବନ୍ଦ କରନ୍ତୁ । ପରିବର୍ତ୍ତନଗୁଡ଼ିକ ଉଭୟ ଇନ-ମେମୋରୀ ଏବଂ ଅନ୍-ଡିସ୍କ ଇମେଜ୍ କ୍ୟାଚ୍ ସଫା କରେ ଷ୍ଟ୍ରିମ୍ ସୃଷ୍ଟିକର୍ତ୍ତା, ଷ୍ଟ୍ରିମ୍ ବିଷୟବସ୍ତୁ କିମ୍ବା ଏକ ସନ୍ଧାନ ଅନୁରୋଧ ବିଷୟରେ ଅତିରିକ୍ତ ସୂଚନା ସହିତ ମେଟା ସୂଚନା ବାକ୍ସଗୁଡ଼ିକୁ ଲୁଚାଇବାକୁ ବନ୍ଦ କରନ୍ତୁ ପିଲାମାନଙ୍କ ପାଇଁ ସମ୍ଭବତ content ଅନୁପଯୁକ୍ତ ବିଷୟବସ୍ତୁ ଦେଖାନ୍ତୁ କାରଣ ଏହାର ବୟସ ସୀମା ଅଛି (ଯେପରିକି 18+) ଏହି ଭିଡିଓ ବୟସ-ସୀମିତ ଅଟେ । diff --git a/app/src/main/res/values-pa-rPK/strings.xml b/app/src/main/res/values-pa-rPK/strings.xml index 534ac790f..0233bbc8b 100644 --- a/app/src/main/res/values-pa-rPK/strings.xml +++ b/app/src/main/res/values-pa-rPK/strings.xml @@ -38,7 +38,6 @@ گوڑی اگے لنگھاؤݨ یا پچھے کرن دی سماں معد سرگرم پکیئر کتار جاوےگا - تھمنیل لوڈ کرو کتار نوں خالی کرن توں پہلاں تصویر کرن لئی پچھو ٹپݨیاں وکھاؤݨا روکݨ لئی ایسنوں بند کرو ٹپݨیاں دِکھاؤ diff --git a/app/src/main/res/values-pa/strings.xml b/app/src/main/res/values-pa/strings.xml index a10ddd125..253a87740 100644 --- a/app/src/main/res/values-pa/strings.xml +++ b/app/src/main/res/values-pa/strings.xml @@ -55,8 +55,6 @@ ਪੌਪ-ਅਪ ਦਾ ਆਖਰੀ ਅਕਾਰ ਅਤੇ ਸਥਿਤੀ ਯਾਦ ਰੱਖੋ ਤੇਜ਼ ਪਰ ਅਸਪੱਸ਼ਟ ਸੀਕ ਵਰਤੋ ਅਸਪੱਸ਼ਟ ਸੀਕ ਵੀਡੀਓ ਨੂੰ ਤੇਜ਼ ਪਰ ਅਣ-ਸਟੀਕ ਢੰਗ ਨਾਲ ਅੱਗੇ-ਪਿੱਛੇ ਲਿਜਾਂਦਾ ਹੈ । ਇਸ ਨਾਲ ਅੱਗੇ-ਪਿੱਛੇ 5,15 ਜਾਂ 25 ਸਕਿੰਟ ਜਾਣਾ ਕੰਮ ਨਹੀਂ ਕਰੇਗਾ - ਥੰਮਨੇਲ ਲੋਡ ਕਰੋ - ਡਾਟਾ ਤੇ ਮੈਮੋਰੀ ਖਪਤ ਦੀ ਬੱਚਤ ਅਤੇ ਥੰਮਨੇਲ ਲੋਡ ਹੋਣ ਤੋਂ ਰੋਕਣ ਲਈ ਬੰਦ ਕਰੋ। ਇਸ ਵਿਚ ਤਬਦੀਲੀ ਕਰਨ ਨਾਲ ਇਨ-ਮੈਮੋਰੀ ਅਤੇ ਆਨ-ਡਿਸਕ ਚਿੱਤਰ ਕੈਸ਼ੇ ਦੋਵੇਂ ਮਿਟ ਜਾਣਗੇ ਚਿੱਤਰ cache ਮਿਟਾ ਦਿੱਤੀ ਗਈ ਹੈ ਕੈਸ਼ ਕੀਤਾ ਮੈਟਾ-ਡਾਟਾ ਮਿਟਾਓ ਸਾਰੇ ਕੈਸ਼ ਕੀਤੇ ਵੈੱਬ-ਪੇਜਾਂ ਦਾ ਡਾਟਾ ਮਿਟਾਓ diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 613433f5e..b250901ff 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -254,8 +254,6 @@ Wymuś raportowanie niedostarczonych wyjątków Rx poza cyklem życia fragmentu lub aktywności po usunięciu Używaj szybkiego, niedokładnego przewijania Niedokładne przewijanie umożliwia szybsze przewijanie ze zmniejszoną dokładnością. Przewijanie o 5, 15 lub 25 sekund nie działa w tym przypadku - Wczytuj miniatury - Wyłącz, aby nie wczytywać miniatur, oszczędzając dane i zużycie pamięci. Zmiana tej opcji czyści pamięć podręczną obrazów Wyczyszczono pamięć podręczną miniatur Wyczyść pamięć podręczną metadanych Usuwa całą pamięć podręczną stron diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 831adfe9e..c344fa826 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -284,14 +284,12 @@ Tenha em mente que esta operação poderá consumir muitos dados. \n \nVocê deseja continuar\? - Carregar miniaturas Cache de imagens limpo Limpar cache de metadados Remove todos os dados de páginas em cache Cache de metadados limpo Controles de velocidade de reprodução Velocidade - Desative para não carregar miniaturas e economizar no uso de dados e memória. A alteração limpa todo o cache de imagens em memória e em disco Afinação Desvincular (pode causar distorção) Ação de \'abrir\' preferida diff --git a/app/src/main/res/values-pt-rPT/strings.xml b/app/src/main/res/values-pt-rPT/strings.xml index 24a8185db..dc3c8e48c 100644 --- a/app/src/main/res/values-pt-rPT/strings.xml +++ b/app/src/main/res/values-pt-rPT/strings.xml @@ -137,7 +137,6 @@ Mostrar resoluções mais altas Sem subscritores Utilizar reprodutor de áudio externo - Desative para parar o carregamento de miniaturas, poupar dados e utilização da memória. As alterações limpam a cache de imagens do disco e da memória Será que queria dizer \"%1$s\"\? Mostrar uma notificação para pedir a atualização da aplicação se existir uma nova versão Enfileirar @@ -442,7 +441,6 @@ Formato padrão de áudio O ficheiro não existe ou não tem permissões para ler e/ou escrever O nome do grupo está vazio - Carregar miniaturas Partilhar com Tempo após a última atualização antes de a subscrição ser considerada desatualizada - %s Pesquisar diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index 87b475a8b..c3c981fad 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -204,8 +204,6 @@ Adicionar a Utilizar pesquisa rápida Este tipo de pesquisa e mais rápida mas reduz a precisão. Procurar por 5, 15 ou 25 segundos não funciona corretamente - Carregar miniaturas - Desative para parar o carregamento de miniaturas, poupar dados e utilização da memória. As alterações limpam a cache de imagens do disco e da memória Cache de imagens limpa País padrão para conteúdo Depuração diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index ad379c5ca..0a6920b6b 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -181,8 +181,6 @@ Salvare în Folosește parcurgerea rapidă inexactă Derularea inexactă permite player-ului să deruleze mai rapid, cu o precizie redusă. Derularea timp de 5, 15 sau 25 de secunde nu funcționează cu aceasta - Încarcă miniaturi - Dezactivați pentru a preveni încărcarea miniaturilor, economisirea datelor și utilizarea memoriei. Modificările șterg atât memoria cache a imaginilor în memorie, cât și pe disc Datele cache de imagini au fost șterse Șterge cache-ul pentru metadata Șterge cache-ul pentru datele de pagini web diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index f033b6cf6..4b03f15c7 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -298,8 +298,6 @@ Это действие может вызвать большой расход трафика. \n \nПродолжить? - Загружать миниатюры - Отключите, чтобы не загружать миниатюры и сэкономить трафик и память. Изменение настройки очистит кэш изображений Кэш изображений очищен Очистить кэш метаданных Кэш метаданных очищен diff --git a/app/src/main/res/values-sc/strings.xml b/app/src/main/res/values-sc/strings.xml index 2f44a8664..7846eb274 100644 --- a/app/src/main/res/values-sc/strings.xml +++ b/app/src/main/res/values-sc/strings.xml @@ -473,10 +473,8 @@ Boga totu sos datos de sa pàgina web in sa memòria temporànea Iscantzella sos metadatos in sa memòria temporànea Memòria temporànea de sas immàgines isboidada - Istuda pro prevènnere su carrigamentu de sas miniaduras, su sarvamentu de sos datos e s\'impreu de sa memòria. Sas modìficas ant a isbodiare siat sa memòria temporànea de sa memòria siat cussa de su discu Istuda pro cuare sos cummentos Ammustra sos cummentos - Càrriga sas miniaduras Longària de s\'avantzamentu e de sa torrada in segus lestros Su moimentu inesatu permitit a su riproduidore de si mòere cara a una positzione in manera prus lestra ma prus pagu pretzisa. Su de si mòere de 5, 15 o 25 segundos non funtzionat, cun custa optzione Imprea su moimentu inesatu lestru diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml index 6e218e16c..51f9eb490 100644 --- a/app/src/main/res/values-sk/strings.xml +++ b/app/src/main/res/values-sk/strings.xml @@ -246,8 +246,6 @@ Zväčšiť Používať rýchly posun Rýchly posun umožňuje prejsť na novú pozíciu rýchlejšie, ale s menšou presnosťou. Posun o 5, 15 alebo 25 sekúnd v tomto prípade nie je možný - Načítanie miniatúr - Vypnutím tejto funkcie sa nebudú vytvárať miniatúry a tým sa ušetrí miesto a pamäť. Zmena nastavení spôsobuje vyčistenie vyrovnávacej pamäte Vyrovnávacia pamäť obrázkov vymazaná Vymazať metadáta uložené vo vyrovnávacej pamäti Odstrániť všetky údaje webových stránok vo vyrovnávacej pamäti diff --git a/app/src/main/res/values-sl/strings.xml b/app/src/main/res/values-sl/strings.xml index 7e89a1ed5..be6027620 100644 --- a/app/src/main/res/values-sl/strings.xml +++ b/app/src/main/res/values-sl/strings.xml @@ -198,7 +198,6 @@ Ustvari Opusti Preimenuj - Naloži sličice Jezik aplikacije Uporabi SAF Vprašaj kam shraniti @@ -309,7 +308,6 @@ Predpomnjeni metapodatki so bili odstranjeni Prikaži meta informacije Onemogoči da se ustavi prikazovanje komentarjev - Izklopite, če želite preprečiti nalaganje sličic, s tem bo varčeval na podatkih in uporabi spomina. Spremembe bodo izbrisale predpomnilnik v spominu in na disku Dejavna vrsta bo zamenjana Preklop na drugi predvajanik lahko zamenja vašo čakalno vrsto Vprašaj za potrditev pred čiščenjem vrste diff --git a/app/src/main/res/values-so/strings.xml b/app/src/main/res/values-so/strings.xml index b2ec76d77..b3f4051c4 100644 --- a/app/src/main/res/values-so/strings.xml +++ b/app/src/main/res/values-so/strings.xml @@ -401,10 +401,8 @@ Tirtir waxyaabaha K/G ah ee boga website-ka Tirtir faahfaahinada yaryar kaydkii kumeelgaadhka ahaa ee sawirka waa la tirtiray - Xidh si aad u joojiso soo bandhiga galka muuqaalada, adigoo yaraynaya isticmalka khadka iyo maskaxda aalada. Wax ka baddalkan wuxuu nadiifin doonaa waxa kaydka hore iyo ka caadiga ah kumeelgaadh ahaan ugu jira Xidh si aad uqariso faallooyinka Tus faallooyinka - Soodhig galalka Hormada daareha hadda wax shidaya waa la baddali doonaa Kala baddalka daareha waxay badali kartaa hormada sidaas darteed waydii in la xaqiijiyo intaan hormada la tirtirin Xaqiijinta tirtirka hormada diff --git a/app/src/main/res/values-sq/strings.xml b/app/src/main/res/values-sq/strings.xml index 41d9f22ad..5bfe72573 100644 --- a/app/src/main/res/values-sq/strings.xml +++ b/app/src/main/res/values-sq/strings.xml @@ -18,7 +18,6 @@ Luaj me Kodi Audio E zezë - Ngarko pamjet miniaturë Sugjerimet e kërkimit Të shikuarat Ruaji videot e shikuara @@ -487,7 +486,6 @@ Depoja e të dhënave meta u boshatis Boshatis depon e të gjitha të dhënave të faqeve të internetit Boshatis depon e të dhënave meta - Fikeni për të ndaluar shfaqjen e pamjeve statike, duke kursyer internet dhe memorje. Ndryshimet boshatisin depon e imazheve në memorje dhe në disk Depoja e imazheve u boshatis Fikeni për të fshehur komentet Shfaq komentet diff --git a/app/src/main/res/values-sr/strings.xml b/app/src/main/res/values-sr/strings.xml index 208b7f6e9..b31ee604b 100644 --- a/app/src/main/res/values-sr/strings.xml +++ b/app/src/main/res/values-sr/strings.xml @@ -201,8 +201,6 @@ Задржи за стављање у ред Користи брзо, непрецизно премотавање Непрецизно премотавање омогућава плејеру да брже долази до позиције уз смањену прецизност. Премотавање за 5, 15 или 25 секунди са овом опцијом не ради - Учитај сличице - Искључите да спречите преузимање сличица, смањујући утрошак преноса података и меморије. Изменом ће се очистити и меморијски и диск кеш Очишћен кеш са сликама Уклони кеширане метаподатке Уклања све податке кешираних веб-страна diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index 01b503d3f..02e472e4d 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -193,8 +193,6 @@ Bokmärkta Spellistor Lägg till i Använd snabb icke-exakt sökning - Läs in miniatyrbilder - Stäng av för att förhindra att miniatyrbilder läses in, vilket sparar data- och minnesanvändning. Ändringarna rensar både bildcacheminnet i minnet och på disken Cacheminnet för bilder rensat Debug Alltid diff --git a/app/src/main/res/values-ta/strings.xml b/app/src/main/res/values-ta/strings.xml index 0a4f30670..0383d7197 100644 --- a/app/src/main/res/values-ta/strings.xml +++ b/app/src/main/res/values-ta/strings.xml @@ -50,7 +50,6 @@ கருமை திரைமேல் பண்புகளை நினைவுகொள் திரைமேல் நிலையின் கடைசி அளவையும் இடத்தையும் நினைவுகொள் - சிறுபடத்தைக் இறக்கு பட பதுக்ககம் அழிக்கப்பட்டது மேல்நிலைத்தரவின் பதுக்ககம் அழிக்கப்பட்டது பதுக்ககப்படுத்திய வலைப்பக்கத் தரவை நீக்கு @@ -264,7 +263,6 @@ ப.ல இயக்கியைச் சிதை - சிறுபடங்களேற்றுவதை தவிர்த்து தரவு மற்றும் நினைவகப் பயன்பாட்டைச் சேமிக்க அணை. மாற்றங்கள் நினைவகத்துள் மற்றும் வட்டின்மீதுள்ள பிடிதரவைத் துடைக்கும் பட்டியல்களில் இயக்கக குறியட நிலைகாட்டிகளைக் காட்டு துணையியக்கியில் காணொளிகளை துவக்காதே, ஆனால் தானாக சுழற்றல் பூட்டப்பட்டிருந்தால் நேரடியாக முழுதிரைக்குத் திரும்பு. முழுதிரையை வெளியேறி நீங்கள் இன்னும் துணையியக்கியை அணுகலாம் உரலியை அங்கீகரக்க முடியவில்லை. மற்றொரு செயலியில் திறக்கவா\? diff --git a/app/src/main/res/values-te/strings.xml b/app/src/main/res/values-te/strings.xml index 2351be263..86f3e17c2 100644 --- a/app/src/main/res/values-te/strings.xml +++ b/app/src/main/res/values-te/strings.xml @@ -165,13 +165,11 @@ అధిక స్పష్టతను చూపుము నలుపు పాప్అప్ లక్షణాలను గుర్తుంచుకో - సూక్ష్మచిత్రాలను లోడ్ చేయండి వ్యాఖ్యలను చూపించు వ్యాఖ్యలను దాచడాన్ని ఆఫ్ చేయండి %sలో మీకు నచ్చిన సందర్భాలను కనుగొనండి పీర్‌ట్యూబ్ ఉదాహరణలు మూడవ చర్య బటన్ - థంబ్‌నెయిల్‌లను లోడ్ చేయడం, డేటాను సేవ్ చేయడం మరియు మెమరీ వినియోగాన్ని నిరోధించడానికి ఆఫ్ చేయండి. మార్పులు ఇన్-మెమరీ మరియు ఆన్-డిస్క్ ఇమేజ్ కాష్ రెండింటినీ క్లియర్ చేస్తాయి ఖచ్చితమైన శోధన తగ్గిన ఖచ్చితత్వంతో వేగంగా స్థానాలను పొందేందుకు ఆటగాడిని అనుమతిస్తుంది. 5, 15 లేదా 25 సెకన్ల పాటు కోరడం దీనితో పని చేయదు వేగవంతమైన ఖచ్చితమైన శోధనను ఉపయోగించండి జోడించండి diff --git a/app/src/main/res/values-th/strings.xml b/app/src/main/res/values-th/strings.xml index 2b31bb988..17f20c1e4 100644 --- a/app/src/main/res/values-th/strings.xml +++ b/app/src/main/res/values-th/strings.xml @@ -56,10 +56,8 @@ จำขนาดและตำแหน่งสุดท้ายของป๊อปอัพ ใช้การข้ามที่ไม่แม่นยำ การข้ามช่วงที่ไม่แม่นยำจะทำให้เลื่อนไปยังตำแหน่งเวลาที่ต้องการได้เร็วขึ้น แต่จะลดความแม่นยำในการลากตำแหน่งลง - โหลดภาพขนาดย่อ แสดงความคิดเห็น ปิดใช้งานเพื่อซ่อนความคิดเห็น - ปิดเพื่อป้องกันการโหลดรูปขนาดย่อ ลดการใช้ข้อมูลและหน่วยความจำ การเปลี่ยนแปลงล้างแคชภาพในหน่วยความจำและบนดิสก์ ล้างแคชของรูปภาพแล้ว ลบข้อมูลเว็บเพจที่แคชไว้ทั้งหมด คิววีดีโอถัดไปโดยอัตโนมัติ diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index 2400a8bd5..28bc92347 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -280,8 +280,6 @@ Bu sürecin ağa yük olabileceğini unutmayın. \n \nSürdürmek istiyor musunuz\? - Küçük resimleri yükle - Küçük resimlerin yüklenmesini önleyerek veri ve hafıza kullanımından tasarruf etmek için kapatın. Değişiklikler, hem bellek içi hem de diskteki resim önbelleğini temizler Resim önbelleği silindi Önbelleğe alınmış üstverileri temizle Önbelleğe alınmış tüm web sayfası verilerini kaldır diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 25b3a43d2..0b024c861 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -292,8 +292,6 @@ Майте на увазі: ця операція може потребувати багато трафіку. \n \nБажаєте продовжити\? - Завантажувати ескізи - Вимкніть для запобігання завантаженню ескізів, що заощадить трафік і внутрішню пам\'ять. Зміни призведуть до очищення кешу зображень Кеш зображень стерто Стерти кеш метаданих Видалити всі кешовані дані вебсторінок diff --git a/app/src/main/res/values-und/strings.xml b/app/src/main/res/values-und/strings.xml index f22a117c5..94e4f9dd6 100644 --- a/app/src/main/res/values-und/strings.xml +++ b/app/src/main/res/values-und/strings.xml @@ -118,7 +118,6 @@ کتار نوں خالی کرن توں پہلاں تصویر کرن لئی پچھو پلیئر بدلݨ نال تہاڈی بدل سکدی اے سرگرم پکیئر کتار جاوےگا - تھمنیل لوڈ کرو وہروا دِکھاؤ کھوج دا اتیت ڈیٹا پٹاؤ diff --git a/app/src/main/res/values-ur/strings.xml b/app/src/main/res/values-ur/strings.xml index c05fc095c..9632f5ff4 100644 --- a/app/src/main/res/values-ur/strings.xml +++ b/app/src/main/res/values-ur/strings.xml @@ -55,8 +55,6 @@ پچھلی جسامت اور پوپ اپ کا مقام یاد رکھیں بالواسطہ رسائی استعمال کریں بالواسطہ تلاش مشکلات کو کم کر کے پلیئر کو تیز رفتاری سے مقامات تک رسائی کرنے دیتی ہے۔ 5 ، 15 یا 25 سیکنڈ کی تلاش اس کے ساتھ کام نہیں کرتی ہے: - نظرِ انگشتی لوڈ کریں - ڈیٹا کی بچت اور میموری کے استعمال کو روکنے کیلئے تھمب نیل کو بند کریں۔ تبدیلیاں میموری اور آن ڈسک ایمیج کیشے کو صاف کریں گی تصویری کیشے کی صفائی ہوئی کیشے میٹا ڈیٹا کو صاف کریں ویب پیج کے سبھی کیشے ڈیٹا کو ہٹا دیں diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index 871fb9c12..9609943ca 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -133,8 +133,6 @@ Thêm vào Sử dụng tìm kiếm nhanh không chính xác Tua không chính xác cho phép trình phát tua đến các vị trí nhanh hơn với độ chính xác bị giảm. Tua 5, 15 hay 25 giây không dùng được với chế độ này - Tải hình thu nhỏ - Tắt để ngăn chặn việc tải các hình thu nhỏ, việc này sẽ tiết kiệm lưu lượng mạng và bộ nhớ. Các thay đổi sẽ xóa bộ nhớ đệm hình ảnh cả trong RAM và trong bộ nhớ Đã xóa bộ nhớ cache hình ảnh Xóa siêu dữ liệu đã lưu vào bộ nhớ cache Xóa tất cả dữ liệu trang web được lưu trong bộ nhớ cache diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 9a888c74d..d1d91dcd2 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -46,7 +46,6 @@ 仅一次 添加至 文件 - 加载封面 清空播放历史 最小化至后台播放 @@ -310,7 +309,6 @@ 该操作消耗大量流量, \n \n你想继续吗? - 关闭可禁止加载封面,节省流量和内存使用。切换该选项将立即清除内存与存储中的图片缓存 清空图像缓存成功 清空已缓存的元数据 清空已缓存的网页数据 diff --git a/app/src/main/res/values-zh-rHK/strings.xml b/app/src/main/res/values-zh-rHK/strings.xml index b465d887d..91f2f3fc8 100644 --- a/app/src/main/res/values-zh-rHK/strings.xml +++ b/app/src/main/res/values-zh-rHK/strings.xml @@ -159,7 +159,6 @@ 撳下面嘅掣去更改對應嘅通知動作。用右手邊嘅格仔剔選最多三個,擺喺精簡通知度 精簡通知最多淨係擺到三個動作! 循環播放 - 載入縮圖 顯示留言 關閉去隱藏留言 搜尋紀錄 @@ -168,7 +167,6 @@ 顯示描述 抹除咗影像快取 移除所有網頁嘅快取資料 - 關閉佢去避免載入條片嘅縮圖,慳返啲數據同埋用少啲 RAM。更改會抹走記憶體以及磁碟機上面嘅影像快取 粗略嘅快轉允許播放器比較籠統咁快轉去其他位置。快轉 5、15 或 25 秒就太仔細,做唔到 播放器 預設嘅國家內容 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 8eb964406..225e4562f 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -278,8 +278,6 @@ \n2. 移至此網址: %1$s \n3. 當被提示時登入帳號 \n4. 複製您被重新導向到的個人設定檔網址。 - 載入縮圖 - 關閉以防止載入縮圖,減少數據和儲存空間的用量。改變時將清除記憶體和磁碟上的縮圖快取 已抹除圖片快取 抹除已快取的中介資料 移除所有已快取的網頁資料 diff --git a/app/src/main/res/values/settings_keys.xml b/app/src/main/res/values/settings_keys.xml index 51abe14fb..19188bb6c 100644 --- a/app/src/main/res/values/settings_keys.xml +++ b/app/src/main/res/values/settings_keys.xml @@ -396,8 +396,6 @@ clear_cookie - download_thumbnail_key - cache_wipe_key clear_play_history clear_playback_states @@ -1433,4 +1431,24 @@ media_tunneling_device_blacklist_version use_exoplayer_decoder_fallback_key always_use_exoplayer_set_output_surface_workaround_key + + + image_quality_key + image_quality_none + image_quality_low + image_quality_medium + image_quality_high + @string/image_quality_medium_key + + @string/image_quality_none + @string/image_quality_low + @string/image_quality_medium + @string/image_quality_high + + + @string/image_quality_none_key + @string/image_quality_low_key + @string/image_quality_medium_key + @string/image_quality_high_key + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index e5bbffaff..705a84aab 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -85,8 +85,6 @@ The active player queue will be replaced Ignore hardware media button events Useful, for instance, if you are using a headset with broken physical buttons - Load thumbnails - Turn off to prevent loading thumbnails, saving data and memory usage. Changes clear both in-memory and on-disk image cache Show comments Turn off to hide comments Show \'Next\' and \'Similar\' videos @@ -822,4 +820,10 @@ Duration Rewind Forward + Image quality + Choose the quality of images and whether to load images at all, to reduce data and memory usage. Changes clear both in-memory and on-disk image cache — %s + Do not load images + Low quality + Medium quality + High quality \ No newline at end of file diff --git a/app/src/main/res/xml/content_settings.xml b/app/src/main/res/xml/content_settings.xml index 73a849af7..45f187452 100644 --- a/app/src/main/res/xml/content_settings.xml +++ b/app/src/main/res/xml/content_settings.xml @@ -85,11 +85,13 @@ app:singleLineTitle="false" app:iconSpaceReserved="false" /> - From 35073c780d21cba874893b5f75d9e9d99236a1e8 Mon Sep 17 00:00:00 2001 From: Stypox Date: Tue, 2 May 2023 12:30:27 +0200 Subject: [PATCH 091/172] Implement better image selection strategy --- app/src/main/java/org/schabi/newpipe/App.java | 3 +- .../database/playlist/PlaylistStreamEntry.kt | 4 +- .../playlist/model/PlaylistRemoteEntity.java | 6 +- .../database/stream/StreamStatisticsEntry.kt | 4 +- .../database/stream/model/StreamEntity.kt | 10 +- .../subscription/SubscriptionEntity.java | 6 +- .../fragments/detail/DescriptionFragment.java | 4 +- .../list/channel/ChannelAboutFragment.java | 6 +- .../list/channel/ChannelFragment.java | 7 +- .../holder/CommentsMiniInfoItemHolder.java | 3 +- .../subscription/SubscriptionFragment.kt | 4 +- .../local/subscription/SubscriptionManager.kt | 6 +- .../player/mediaitem/ExceptionTag.java | 4 +- .../player/mediaitem/StreamInfoTag.java | 4 +- .../mediasession/PlayQueueNavigator.java | 4 +- .../settings/ContentSettingsFragment.java | 3 +- .../external_communication/ShareUtils.java | 7 +- .../newpipe/util/image/ImageStrategy.java | 115 ++++++++++++++++++ .../newpipe/util/image/PicassoHelper.java | 50 +------- 19 files changed, 161 insertions(+), 89 deletions(-) create mode 100644 app/src/main/java/org/schabi/newpipe/util/image/ImageStrategy.java diff --git a/app/src/main/java/org/schabi/newpipe/App.java b/app/src/main/java/org/schabi/newpipe/App.java index b394c7039..ee352ae4a 100644 --- a/app/src/main/java/org/schabi/newpipe/App.java +++ b/app/src/main/java/org/schabi/newpipe/App.java @@ -20,6 +20,7 @@ import org.schabi.newpipe.extractor.downloader.Downloader; import org.schabi.newpipe.ktx.ExceptionUtils; import org.schabi.newpipe.settings.NewPipeSettings; import org.schabi.newpipe.util.Localization; +import org.schabi.newpipe.util.image.ImageStrategy; import org.schabi.newpipe.util.image.PicassoHelper; import org.schabi.newpipe.util.ServiceHelper; import org.schabi.newpipe.util.StateSaver; @@ -100,7 +101,7 @@ public class App extends Application { // Initialize image loader final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); PicassoHelper.init(this); - PicassoHelper.setPreferredImageQuality(PreferredImageQuality.fromPreferenceKey(this, + ImageStrategy.setPreferredImageQuality(PreferredImageQuality.fromPreferenceKey(this, prefs.getString(getString(R.string.image_quality_key), getString(R.string.image_quality_default)))); PicassoHelper.setIndicatorsEnabled(MainActivity.DEBUG diff --git a/app/src/main/java/org/schabi/newpipe/database/playlist/PlaylistStreamEntry.kt b/app/src/main/java/org/schabi/newpipe/database/playlist/PlaylistStreamEntry.kt index e7db1d603..47dc1d06a 100644 --- a/app/src/main/java/org/schabi/newpipe/database/playlist/PlaylistStreamEntry.kt +++ b/app/src/main/java/org/schabi/newpipe/database/playlist/PlaylistStreamEntry.kt @@ -7,7 +7,7 @@ import org.schabi.newpipe.database.playlist.model.PlaylistStreamEntity import org.schabi.newpipe.database.stream.model.StreamEntity import org.schabi.newpipe.database.stream.model.StreamStateEntity import org.schabi.newpipe.extractor.stream.StreamInfoItem -import org.schabi.newpipe.util.image.PicassoHelper +import org.schabi.newpipe.util.image.ImageStrategy data class PlaylistStreamEntry( @Embedded @@ -29,7 +29,7 @@ data class PlaylistStreamEntry( item.duration = streamEntity.duration item.uploaderName = streamEntity.uploader item.uploaderUrl = streamEntity.uploaderUrl - item.thumbnails = PicassoHelper.urlToImageList(streamEntity.thumbnailUrl) + item.thumbnails = ImageStrategy.urlToImageList(streamEntity.thumbnailUrl) return item } diff --git a/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistRemoteEntity.java b/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistRemoteEntity.java index 569f6721c..5e8977821 100644 --- a/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistRemoteEntity.java +++ b/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistRemoteEntity.java @@ -11,7 +11,7 @@ import androidx.room.PrimaryKey; import org.schabi.newpipe.database.playlist.PlaylistLocalItem; import org.schabi.newpipe.extractor.playlist.PlaylistInfo; import org.schabi.newpipe.util.Constants; -import org.schabi.newpipe.util.image.PicassoHelper; +import org.schabi.newpipe.util.image.ImageStrategy; import static org.schabi.newpipe.database.LocalItem.LocalItemType.PLAYLIST_REMOTE_ITEM; import static org.schabi.newpipe.database.playlist.model.PlaylistRemoteEntity.REMOTE_PLAYLIST_NAME; @@ -70,7 +70,7 @@ public class PlaylistRemoteEntity implements PlaylistLocalItem { @Ignore public PlaylistRemoteEntity(final PlaylistInfo info) { this(info.getServiceId(), info.getName(), info.getUrl(), - PicassoHelper.choosePreferredImage(info.getThumbnails()), + ImageStrategy.choosePreferredImage(info.getThumbnails()), info.getUploaderName(), info.getStreamCount()); } @@ -85,7 +85,7 @@ public class PlaylistRemoteEntity implements PlaylistLocalItem { && TextUtils.equals(getName(), info.getName()) && TextUtils.equals(getUrl(), info.getUrl()) && TextUtils.equals(getThumbnailUrl(), - PicassoHelper.choosePreferredImage(info.getThumbnails())) + ImageStrategy.choosePreferredImage(info.getThumbnails())) && TextUtils.equals(getUploader(), info.getUploaderName()); } diff --git a/app/src/main/java/org/schabi/newpipe/database/stream/StreamStatisticsEntry.kt b/app/src/main/java/org/schabi/newpipe/database/stream/StreamStatisticsEntry.kt index 6d005351d..81e17b720 100644 --- a/app/src/main/java/org/schabi/newpipe/database/stream/StreamStatisticsEntry.kt +++ b/app/src/main/java/org/schabi/newpipe/database/stream/StreamStatisticsEntry.kt @@ -7,7 +7,7 @@ import org.schabi.newpipe.database.history.model.StreamHistoryEntity import org.schabi.newpipe.database.stream.model.StreamEntity import org.schabi.newpipe.database.stream.model.StreamStateEntity.STREAM_PROGRESS_MILLIS import org.schabi.newpipe.extractor.stream.StreamInfoItem -import org.schabi.newpipe.util.image.PicassoHelper +import org.schabi.newpipe.util.image.ImageStrategy import java.time.OffsetDateTime class StreamStatisticsEntry( @@ -31,7 +31,7 @@ class StreamStatisticsEntry( item.duration = streamEntity.duration item.uploaderName = streamEntity.uploader item.uploaderUrl = streamEntity.uploaderUrl - item.thumbnails = PicassoHelper.urlToImageList(streamEntity.thumbnailUrl) + item.thumbnails = ImageStrategy.urlToImageList(streamEntity.thumbnailUrl) return item } diff --git a/app/src/main/java/org/schabi/newpipe/database/stream/model/StreamEntity.kt b/app/src/main/java/org/schabi/newpipe/database/stream/model/StreamEntity.kt index bb2c0e0d7..4eecc9373 100644 --- a/app/src/main/java/org/schabi/newpipe/database/stream/model/StreamEntity.kt +++ b/app/src/main/java/org/schabi/newpipe/database/stream/model/StreamEntity.kt @@ -13,7 +13,7 @@ import org.schabi.newpipe.extractor.stream.StreamInfo import org.schabi.newpipe.extractor.stream.StreamInfoItem import org.schabi.newpipe.extractor.stream.StreamType import org.schabi.newpipe.player.playqueue.PlayQueueItem -import org.schabi.newpipe.util.image.PicassoHelper +import org.schabi.newpipe.util.image.ImageStrategy import java.io.Serializable import java.time.OffsetDateTime @@ -68,7 +68,7 @@ data class StreamEntity( constructor(item: StreamInfoItem) : this( serviceId = item.serviceId, url = item.url, title = item.name, streamType = item.streamType, duration = item.duration, uploader = item.uploaderName, - uploaderUrl = item.uploaderUrl, thumbnailUrl = PicassoHelper.choosePreferredImage(item.thumbnails), viewCount = item.viewCount, + uploaderUrl = item.uploaderUrl, thumbnailUrl = ImageStrategy.choosePreferredImage(item.thumbnails), viewCount = item.viewCount, textualUploadDate = item.textualUploadDate, uploadDate = item.uploadDate?.offsetDateTime(), isUploadDateApproximation = item.uploadDate?.isApproximation ) @@ -77,7 +77,7 @@ data class StreamEntity( constructor(info: StreamInfo) : this( serviceId = info.serviceId, url = info.url, title = info.name, streamType = info.streamType, duration = info.duration, uploader = info.uploaderName, - uploaderUrl = info.uploaderUrl, thumbnailUrl = PicassoHelper.choosePreferredImage(info.thumbnails), viewCount = info.viewCount, + uploaderUrl = info.uploaderUrl, thumbnailUrl = ImageStrategy.choosePreferredImage(info.thumbnails), viewCount = info.viewCount, textualUploadDate = info.textualUploadDate, uploadDate = info.uploadDate?.offsetDateTime(), isUploadDateApproximation = info.uploadDate?.isApproximation ) @@ -87,7 +87,7 @@ data class StreamEntity( serviceId = item.serviceId, url = item.url, title = item.title, streamType = item.streamType, duration = item.duration, uploader = item.uploader, uploaderUrl = item.uploaderUrl, - thumbnailUrl = PicassoHelper.choosePreferredImage(item.thumbnails) + thumbnailUrl = ImageStrategy.choosePreferredImage(item.thumbnails) ) fun toStreamInfoItem(): StreamInfoItem { @@ -95,7 +95,7 @@ data class StreamEntity( item.duration = duration item.uploaderName = uploader item.uploaderUrl = uploaderUrl - item.thumbnails = PicassoHelper.urlToImageList(thumbnailUrl) + item.thumbnails = ImageStrategy.urlToImageList(thumbnailUrl) if (viewCount != null) item.viewCount = viewCount as Long item.textualUploadDate = textualUploadDate diff --git a/app/src/main/java/org/schabi/newpipe/database/subscription/SubscriptionEntity.java b/app/src/main/java/org/schabi/newpipe/database/subscription/SubscriptionEntity.java index 1f1722814..3fb474423 100644 --- a/app/src/main/java/org/schabi/newpipe/database/subscription/SubscriptionEntity.java +++ b/app/src/main/java/org/schabi/newpipe/database/subscription/SubscriptionEntity.java @@ -10,7 +10,7 @@ import androidx.room.PrimaryKey; import org.schabi.newpipe.extractor.channel.ChannelInfo; import org.schabi.newpipe.extractor.channel.ChannelInfoItem; import org.schabi.newpipe.util.Constants; -import org.schabi.newpipe.util.image.PicassoHelper; +import org.schabi.newpipe.util.image.ImageStrategy; import static org.schabi.newpipe.database.subscription.SubscriptionEntity.SUBSCRIPTION_SERVICE_ID; import static org.schabi.newpipe.database.subscription.SubscriptionEntity.SUBSCRIPTION_TABLE; @@ -58,7 +58,7 @@ public class SubscriptionEntity { final SubscriptionEntity result = new SubscriptionEntity(); result.setServiceId(info.getServiceId()); result.setUrl(info.getUrl()); - result.setData(info.getName(), PicassoHelper.choosePreferredImage(info.getAvatars()), + result.setData(info.getName(), ImageStrategy.choosePreferredImage(info.getAvatars()), info.getDescription(), info.getSubscriberCount()); return result; } @@ -139,7 +139,7 @@ public class SubscriptionEntity { @Ignore public ChannelInfoItem toChannelInfoItem() { final ChannelInfoItem item = new ChannelInfoItem(getServiceId(), getUrl(), getName()); - item.setThumbnails(PicassoHelper.urlToImageList(getAvatarUrl())); + item.setThumbnails(ImageStrategy.urlToImageList(getAvatarUrl())); item.setSubscriberCount(getSubscriberCount()); item.setDescription(getDescription()); return item; diff --git a/app/src/main/java/org/schabi/newpipe/fragments/detail/DescriptionFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/detail/DescriptionFragment.java index ff1a01466..60a2a2ed3 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/detail/DescriptionFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/detail/DescriptionFragment.java @@ -17,7 +17,7 @@ import org.schabi.newpipe.extractor.stream.StreamInfo; import org.schabi.newpipe.util.Localization; import java.util.List; -import org.schabi.newpipe.util.image.PicassoHelper; +import org.schabi.newpipe.util.image.ImageStrategy; import icepick.State; @@ -114,7 +114,7 @@ public class DescriptionFragment extends BaseDescriptionFragment { addMetadataItem(inflater, layout, true, R.string.metadata_host, streamInfo.getHost()); addMetadataItem(inflater, layout, true, R.string.metadata_thumbnail_url, - PicassoHelper.choosePreferredImage(streamInfo.getThumbnails())); + ImageStrategy.choosePreferredImage(streamInfo.getThumbnails())); } private void addPrivacyMetadataItem(final LayoutInflater inflater, final LinearLayout layout) { diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelAboutFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelAboutFragment.java index 5ea25bf15..9a035d0ab 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelAboutFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelAboutFragment.java @@ -17,7 +17,7 @@ import org.schabi.newpipe.extractor.stream.Description; import org.schabi.newpipe.fragments.detail.BaseDescriptionFragment; import org.schabi.newpipe.util.DeviceUtils; import org.schabi.newpipe.util.Localization; -import org.schabi.newpipe.util.image.PicassoHelper; +import org.schabi.newpipe.util.image.ImageStrategy; import java.util.List; @@ -101,8 +101,8 @@ public class ChannelAboutFragment extends BaseDescriptionFragment { } addMetadataItem(inflater, layout, true, R.string.metadata_avatar_url, - PicassoHelper.choosePreferredImage(channelInfo.getAvatars())); + ImageStrategy.choosePreferredImage(channelInfo.getAvatars())); addMetadataItem(inflater, layout, true, R.string.metadata_banner_url, - PicassoHelper.choosePreferredImage(channelInfo.getBanners())); + ImageStrategy.choosePreferredImage(channelInfo.getBanners())); } } diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java index 7436f50fd..3ece760ca 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java @@ -49,6 +49,7 @@ import org.schabi.newpipe.util.ExtractorHelper; import org.schabi.newpipe.util.Localization; import org.schabi.newpipe.util.NavigationHelper; import org.schabi.newpipe.util.StateSaver; +import org.schabi.newpipe.util.image.ImageStrategy; import org.schabi.newpipe.util.image.PicassoHelper; import org.schabi.newpipe.util.ThemeHelper; import org.schabi.newpipe.util.external_communication.ShareUtils; @@ -147,7 +148,7 @@ public class ChannelFragment extends BaseStateFragment setTitle(name); binding.channelTitleView.setText(name); - if (!PicassoHelper.shouldLoadImages()) { + if (!ImageStrategy.shouldLoadImages()) { // do not waste space for the banner if it is not going to be loaded binding.channelBannerImage.setImageDrawable(null); } @@ -354,7 +355,7 @@ public class ChannelFragment extends BaseStateFragment channel.setServiceId(info.getServiceId()); channel.setUrl(info.getUrl()); channel.setData(info.getName(), - PicassoHelper.choosePreferredImage(info.getAvatars()), + ImageStrategy.choosePreferredImage(info.getAvatars()), info.getDescription(), info.getSubscriberCount()); channelSubscription = null; @@ -578,7 +579,7 @@ public class ChannelFragment extends BaseStateFragment currentInfo = result; setInitialData(result.getServiceId(), result.getOriginalUrl(), result.getName()); - if (PicassoHelper.shouldLoadImages() && !result.getBanners().isEmpty()) { + if (ImageStrategy.shouldLoadImages() && !result.getBanners().isEmpty()) { PicassoHelper.loadBanner(result.getBanners()).tag(PICASSO_CHANNEL_TAG) .into(binding.channelBannerImage); } else { diff --git a/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentsMiniInfoItemHolder.java b/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentsMiniInfoItemHolder.java index 69e1bf5f6..d6a08e6cb 100644 --- a/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentsMiniInfoItemHolder.java +++ b/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentsMiniInfoItemHolder.java @@ -31,6 +31,7 @@ import org.schabi.newpipe.local.history.HistoryRecordManager; import org.schabi.newpipe.util.DeviceUtils; import org.schabi.newpipe.util.Localization; import org.schabi.newpipe.util.NavigationHelper; +import org.schabi.newpipe.util.image.ImageStrategy; import org.schabi.newpipe.util.image.PicassoHelper; import org.schabi.newpipe.util.external_communication.ShareUtils; import org.schabi.newpipe.util.text.CommentTextOnTouchListener; @@ -98,7 +99,7 @@ public class CommentsMiniInfoItemHolder extends InfoItemHolder { final CommentsInfoItem item = (CommentsInfoItem) infoItem; PicassoHelper.loadAvatar(item.getUploaderAvatars()).into(itemThumbnailView); - if (PicassoHelper.shouldLoadImages()) { + if (ImageStrategy.shouldLoadImages()) { itemThumbnailView.setVisibility(View.VISIBLE); itemRoot.setPadding(commentVerticalPadding, commentVerticalPadding, commentVerticalPadding, commentVerticalPadding); diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionFragment.kt b/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionFragment.kt index f84d9865f..ac82d5c91 100644 --- a/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionFragment.kt +++ b/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionFragment.kt @@ -61,7 +61,7 @@ import org.schabi.newpipe.util.OnClickGesture import org.schabi.newpipe.util.ServiceHelper import org.schabi.newpipe.util.ThemeHelper.getGridSpanCountChannels import org.schabi.newpipe.util.external_communication.ShareUtils -import org.schabi.newpipe.util.image.PicassoHelper +import org.schabi.newpipe.util.image.ImageStrategy import java.text.SimpleDateFormat import java.util.Date import java.util.Locale @@ -343,7 +343,7 @@ class SubscriptionFragment : BaseStateFragment() { when (i) { 0 -> ShareUtils.shareText( requireContext(), selectedItem.name, selectedItem.url, - PicassoHelper.choosePreferredImage(selectedItem.thumbnails) + ImageStrategy.choosePreferredImage(selectedItem.thumbnails) ) 1 -> ShareUtils.openUrlInBrowser(requireContext(), selectedItem.url) 2 -> deleteChannel(selectedItem) diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionManager.kt b/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionManager.kt index 70bac6168..cfd5196be 100644 --- a/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionManager.kt +++ b/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionManager.kt @@ -19,7 +19,7 @@ import org.schabi.newpipe.extractor.feed.FeedInfo import org.schabi.newpipe.extractor.stream.StreamInfoItem import org.schabi.newpipe.local.feed.FeedDatabaseManager import org.schabi.newpipe.util.ExtractorHelper -import org.schabi.newpipe.util.image.PicassoHelper +import org.schabi.newpipe.util.image.ImageStrategy class SubscriptionManager(context: Context) { private val database = NewPipeDatabase.getInstance(context) @@ -74,7 +74,7 @@ class SubscriptionManager(context: Context) { Completable.fromRunnable { it.setData( info.name, - PicassoHelper.choosePreferredImage(info.avatars), + ImageStrategy.choosePreferredImage(info.avatars), info.description, info.subscriberCount ) @@ -105,7 +105,7 @@ class SubscriptionManager(context: Context) { } else if (info is ChannelInfo) { subscriptionEntity.setData( info.name, - PicassoHelper.choosePreferredImage(info.avatars), + ImageStrategy.choosePreferredImage(info.avatars), info.description, info.subscriberCount ) diff --git a/app/src/main/java/org/schabi/newpipe/player/mediaitem/ExceptionTag.java b/app/src/main/java/org/schabi/newpipe/player/mediaitem/ExceptionTag.java index 9ec6513dc..95a4f74af 100644 --- a/app/src/main/java/org/schabi/newpipe/player/mediaitem/ExceptionTag.java +++ b/app/src/main/java/org/schabi/newpipe/player/mediaitem/ExceptionTag.java @@ -3,7 +3,7 @@ package org.schabi.newpipe.player.mediaitem; import org.schabi.newpipe.extractor.stream.StreamInfo; import org.schabi.newpipe.extractor.stream.StreamType; import org.schabi.newpipe.player.playqueue.PlayQueueItem; -import org.schabi.newpipe.util.image.PicassoHelper; +import org.schabi.newpipe.util.image.ImageStrategy; import java.util.List; import java.util.Optional; @@ -75,7 +75,7 @@ public final class ExceptionTag implements MediaItemTag { @Override public String getThumbnailUrl() { - return PicassoHelper.choosePreferredImage(item.getThumbnails()); + return ImageStrategy.choosePreferredImage(item.getThumbnails()); } @Override diff --git a/app/src/main/java/org/schabi/newpipe/player/mediaitem/StreamInfoTag.java b/app/src/main/java/org/schabi/newpipe/player/mediaitem/StreamInfoTag.java index a96f49f2f..e24a93615 100644 --- a/app/src/main/java/org/schabi/newpipe/player/mediaitem/StreamInfoTag.java +++ b/app/src/main/java/org/schabi/newpipe/player/mediaitem/StreamInfoTag.java @@ -6,7 +6,7 @@ import org.schabi.newpipe.extractor.stream.AudioStream; import org.schabi.newpipe.extractor.stream.StreamInfo; import org.schabi.newpipe.extractor.stream.StreamType; import org.schabi.newpipe.extractor.stream.VideoStream; -import org.schabi.newpipe.util.image.PicassoHelper; +import org.schabi.newpipe.util.image.ImageStrategy; import java.util.Collections; import java.util.List; @@ -96,7 +96,7 @@ public final class StreamInfoTag implements MediaItemTag { @Override public String getThumbnailUrl() { - return PicassoHelper.choosePreferredImage(streamInfo.getThumbnails()); + return ImageStrategy.choosePreferredImage(streamInfo.getThumbnails()); } @Override diff --git a/app/src/main/java/org/schabi/newpipe/player/mediasession/PlayQueueNavigator.java b/app/src/main/java/org/schabi/newpipe/player/mediasession/PlayQueueNavigator.java index 3e0736f82..f925bff16 100644 --- a/app/src/main/java/org/schabi/newpipe/player/mediasession/PlayQueueNavigator.java +++ b/app/src/main/java/org/schabi/newpipe/player/mediasession/PlayQueueNavigator.java @@ -20,7 +20,7 @@ import com.google.android.exoplayer2.util.Util; import org.schabi.newpipe.player.Player; import org.schabi.newpipe.player.playqueue.PlayQueue; import org.schabi.newpipe.player.playqueue.PlayQueueItem; -import org.schabi.newpipe.util.image.PicassoHelper; +import org.schabi.newpipe.util.image.ImageStrategy; import java.util.ArrayList; import java.util.Collections; @@ -139,7 +139,7 @@ public class PlayQueueNavigator implements MediaSessionConnector.QueueNavigator descBuilder.setExtras(additionalMetadata); final Uri thumbnailUri = Uri.parse( - PicassoHelper.choosePreferredImage(item.getThumbnails())); + ImageStrategy.choosePreferredImage(item.getThumbnails())); if (thumbnailUri != null) { descBuilder.setIconUri(thumbnailUri); } diff --git a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java index 2297e3e93..c7d107acb 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java @@ -31,6 +31,7 @@ import org.schabi.newpipe.extractor.localization.Localization; import org.schabi.newpipe.streams.io.NoFileManagerSafeGuard; import org.schabi.newpipe.streams.io.StoredFileHelper; import org.schabi.newpipe.util.NavigationHelper; +import org.schabi.newpipe.util.image.ImageStrategy; import org.schabi.newpipe.util.image.PicassoHelper; import org.schabi.newpipe.util.ZipHelper; import org.schabi.newpipe.util.image.PreferredImageQuality; @@ -109,7 +110,7 @@ public class ContentSettingsFragment extends BasePreferenceFragment { final Preference imageQualityPreference = requirePreference(R.string.image_quality_key); imageQualityPreference.setOnPreferenceChangeListener( (preference, newValue) -> { - PicassoHelper.setPreferredImageQuality(PreferredImageQuality + ImageStrategy.setPreferredImageQuality(PreferredImageQuality .fromPreferenceKey(requireContext(), (String) newValue)); try { PicassoHelper.clearCache(preference.getContext()); diff --git a/app/src/main/java/org/schabi/newpipe/util/external_communication/ShareUtils.java b/app/src/main/java/org/schabi/newpipe/util/external_communication/ShareUtils.java index 8150d4030..fc057de41 100644 --- a/app/src/main/java/org/schabi/newpipe/util/external_communication/ShareUtils.java +++ b/app/src/main/java/org/schabi/newpipe/util/external_communication/ShareUtils.java @@ -24,6 +24,7 @@ import androidx.core.content.FileProvider; import org.schabi.newpipe.BuildConfig; import org.schabi.newpipe.R; import org.schabi.newpipe.extractor.Image; +import org.schabi.newpipe.util.image.ImageStrategy; import org.schabi.newpipe.util.image.PicassoHelper; import java.io.File; @@ -251,7 +252,7 @@ public final class ShareUtils { // If loading of images has been disabled, don't try to generate a content preview if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && !TextUtils.isEmpty(imagePreviewUrl) - && PicassoHelper.shouldLoadImages()) { + && ImageStrategy.shouldLoadImages()) { final ClipData clipData = generateClipDataForImagePreview(context, imagePreviewUrl); if (clipData != null) { @@ -276,14 +277,14 @@ public final class ShareUtils { * @param title the title of the content * @param content the content to share * @param images a set of possible {@link Image}s of the subject, among which to choose with - * {@link PicassoHelper#choosePreferredImage(List)} since that's likely to + * {@link ImageStrategy#choosePreferredImage(List)} since that's likely to * provide an image that is in Picasso's cache */ public static void shareText(@NonNull final Context context, @NonNull final String title, final String content, final List images) { - shareText(context, title, content, PicassoHelper.choosePreferredImage(images)); + shareText(context, title, content, ImageStrategy.choosePreferredImage(images)); } /** diff --git a/app/src/main/java/org/schabi/newpipe/util/image/ImageStrategy.java b/app/src/main/java/org/schabi/newpipe/util/image/ImageStrategy.java new file mode 100644 index 000000000..5de0b52f4 --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/util/image/ImageStrategy.java @@ -0,0 +1,115 @@ +package org.schabi.newpipe.util.image; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import org.schabi.newpipe.extractor.Image; + +import java.util.Comparator; +import java.util.List; + +public final class ImageStrategy { + + // the height thresholds also used by the extractor (TODO move them to the extractor) + private static final int LOW_MEDIUM = 175; + private static final int MEDIUM_HIGH = 720; + + private static PreferredImageQuality preferredImageQuality = PreferredImageQuality.MEDIUM; + + private ImageStrategy() { + } + + public static void setPreferredImageQuality(final PreferredImageQuality preferredImageQuality) { + ImageStrategy.preferredImageQuality = preferredImageQuality; + } + + public static boolean shouldLoadImages() { + return preferredImageQuality != PreferredImageQuality.NONE; + } + + + private static double estimatePixelCount(final Image image, + final double widthOverHeight, + final boolean unknownsLast) { + if (image.getHeight() == Image.HEIGHT_UNKNOWN) { + if (image.getWidth() == Image.WIDTH_UNKNOWN) { + switch (image.getEstimatedResolutionLevel()) { + case LOW: + return unknownsLast + ? (LOW_MEDIUM - 1) * (LOW_MEDIUM - 1) * widthOverHeight + : 0; + case MEDIUM: + return unknownsLast + ? (MEDIUM_HIGH - 1) * (MEDIUM_HIGH - 1) * widthOverHeight + : LOW_MEDIUM * LOW_MEDIUM * widthOverHeight; + case HIGH: + return unknownsLast + ? 1e20 // less than 1e21 to prefer over fully unknown image sizes + : MEDIUM_HIGH * MEDIUM_HIGH * widthOverHeight; + default: + case UNKNOWN: + // images whose size is completely unknown will be avoided when possible + return unknownsLast ? 1e21 : -1; + } + + } else { + return image.getWidth() * image.getWidth() / widthOverHeight; + } + + } else if (image.getWidth() == Image.WIDTH_UNKNOWN) { + return image.getHeight() * image.getHeight() * widthOverHeight; + + } else { + return image.getHeight() * image.getWidth(); + } + } + + @Nullable + public static String choosePreferredImage(@NonNull final List images) { + if (preferredImageQuality == PreferredImageQuality.NONE) { + return null; // do not load images + } + + final double widthOverHeight = images.stream() + .filter(image -> image.getHeight() != Image.HEIGHT_UNKNOWN + && image.getWidth() != Image.WIDTH_UNKNOWN) + .mapToDouble(image -> ((double) image.getWidth()) / image.getHeight()) + .findFirst() + .orElse(1.0); + + final Comparator comparator; + switch (preferredImageQuality) { + case LOW: + comparator = Comparator.comparingDouble( + image -> estimatePixelCount(image, widthOverHeight, true)); + break; + default: + case MEDIUM: + comparator = Comparator.comparingDouble(image -> { + final double pixelCount = estimatePixelCount(image, widthOverHeight, true); + final double mediumHeight = (LOW_MEDIUM + MEDIUM_HIGH) / 2.0; + return Math.abs(pixelCount - mediumHeight * mediumHeight * widthOverHeight); + }); + break; + case HIGH: + comparator = Comparator.comparingDouble( + image -> estimatePixelCount(image, widthOverHeight, false)) + .reversed(); + break; + } + + return images.stream() + .min(comparator) + .map(Image::getUrl) + .orElse(null); + } + + @NonNull + public static List urlToImageList(@Nullable final String url) { + if (url == null) { + return List.of(); + } else { + return List.of(new Image(url, -1, -1, Image.ResolutionLevel.UNKNOWN)); + } + } +} diff --git a/app/src/main/java/org/schabi/newpipe/util/image/PicassoHelper.java b/app/src/main/java/org/schabi/newpipe/util/image/PicassoHelper.java index 3177e83f4..ccf7c3737 100644 --- a/app/src/main/java/org/schabi/newpipe/util/image/PicassoHelper.java +++ b/app/src/main/java/org/schabi/newpipe/util/image/PicassoHelper.java @@ -2,13 +2,13 @@ package org.schabi.newpipe.util.image; import static org.schabi.newpipe.MainActivity.DEBUG; import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty; +import static org.schabi.newpipe.util.image.ImageStrategy.choosePreferredImage; import android.annotation.SuppressLint; import android.content.Context; import android.graphics.Bitmap; import android.util.Log; -import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.graphics.BitmapCompat; @@ -21,11 +21,9 @@ import com.squareup.picasso.Transformation; import org.schabi.newpipe.R; import org.schabi.newpipe.extractor.Image; -import org.schabi.newpipe.extractor.Image.ResolutionLevel; import java.io.File; import java.io.IOException; -import java.util.Comparator; import java.util.List; import java.util.concurrent.TimeUnit; @@ -46,7 +44,6 @@ public final class PicassoHelper { @SuppressLint("StaticFieldLeak") private static Picasso picassoInstance; - private static PreferredImageQuality preferredImageQuality = PreferredImageQuality.MEDIUM; public static void init(final Context context) { picassoCache = new LruCache(10 * 1024 * 1024); @@ -92,14 +89,6 @@ public final class PicassoHelper { picassoInstance.setIndicatorsEnabled(enabled); // useful for debugging } - public static void setPreferredImageQuality(final PreferredImageQuality preferredImageQuality) { - PicassoHelper.preferredImageQuality = preferredImageQuality; - } - - public static boolean shouldLoadImages() { - return preferredImageQuality != PreferredImageQuality.NONE; - } - public static RequestCreator loadAvatar(final List images) { return loadImageDefault(images, R.drawable.placeholder_person); @@ -227,41 +216,4 @@ public final class PicassoHelper { return requestCreator; } } - - @Nullable - public static String choosePreferredImage(final List images) { - final Comparator comparator; - switch (preferredImageQuality) { - case NONE: - return null; - case HIGH: - comparator = Comparator.comparingInt(Image::getHeight).reversed(); - break; - default: - case MEDIUM: - comparator = Comparator.comparingInt(image -> Math.abs(image.getHeight() - 450)); - break; - case LOW: - comparator = Comparator.comparingInt(Image::getHeight); - break; - } - - return images.stream() - .filter(image -> image.getEstimatedResolutionLevel() != ResolutionLevel.UNKNOWN) - .min(comparator) - .map(Image::getUrl) - .orElseGet(() -> images.stream() - .findAny() - .map(Image::getUrl) - .orElse(null)); - } - - @NonNull - public static List urlToImageList(@Nullable final String url) { - if (url == null) { - return List.of(); - } else { - return List.of(new Image(url, -1, -1, ResolutionLevel.UNKNOWN)); - } - } } From 4f7d2067368c058314a7b7cd176486b861a07134 Mon Sep 17 00:00:00 2001 From: Stypox Date: Tue, 2 May 2023 18:56:02 +0200 Subject: [PATCH 092/172] Display all thumbnails in description tab --- .../detail/BaseDescriptionFragment.java | 75 +++++++++++++++++++ .../fragments/detail/DescriptionFragment.java | 10 ++- .../list/channel/ChannelAboutFragment.java | 9 +-- app/src/main/res/values-ar/strings.xml | 1 - app/src/main/res/values-az/strings.xml | 1 - app/src/main/res/values-be/strings.xml | 1 - app/src/main/res/values-bg/strings.xml | 1 - app/src/main/res/values-bn/strings.xml | 1 - app/src/main/res/values-ca/strings.xml | 1 - app/src/main/res/values-ckb/strings.xml | 1 - app/src/main/res/values-cs/strings.xml | 1 - app/src/main/res/values-da/strings.xml | 1 - app/src/main/res/values-de/strings.xml | 1 - app/src/main/res/values-el/strings.xml | 1 - app/src/main/res/values-es/strings.xml | 1 - app/src/main/res/values-et/strings.xml | 1 - app/src/main/res/values-eu/strings.xml | 1 - app/src/main/res/values-fa/strings.xml | 1 - app/src/main/res/values-fi/strings.xml | 1 - app/src/main/res/values-fil/strings.xml | 1 - app/src/main/res/values-fr/strings.xml | 1 - app/src/main/res/values-gl/strings.xml | 1 - app/src/main/res/values-he/strings.xml | 1 - app/src/main/res/values-hi/strings.xml | 1 - app/src/main/res/values-hr/strings.xml | 1 - app/src/main/res/values-hu/strings.xml | 1 - app/src/main/res/values-in/strings.xml | 1 - app/src/main/res/values-is/strings.xml | 1 - app/src/main/res/values-it/strings.xml | 1 - app/src/main/res/values-ja/strings.xml | 1 - app/src/main/res/values-ka/strings.xml | 1 - app/src/main/res/values-ko/strings.xml | 1 - app/src/main/res/values-lt/strings.xml | 1 - app/src/main/res/values-lv/strings.xml | 1 - app/src/main/res/values-ml/strings.xml | 1 - app/src/main/res/values-nb-rNO/strings.xml | 1 - app/src/main/res/values-nl/strings.xml | 1 - app/src/main/res/values-or/strings.xml | 1 - app/src/main/res/values-pa/strings.xml | 1 - app/src/main/res/values-pl/strings.xml | 1 - app/src/main/res/values-pt-rBR/strings.xml | 1 - app/src/main/res/values-pt-rPT/strings.xml | 1 - app/src/main/res/values-pt/strings.xml | 1 - app/src/main/res/values-ro/strings.xml | 1 - app/src/main/res/values-ru/strings.xml | 1 - app/src/main/res/values-sc/strings.xml | 1 - app/src/main/res/values-sk/strings.xml | 1 - app/src/main/res/values-so/strings.xml | 1 - app/src/main/res/values-sq/strings.xml | 1 - app/src/main/res/values-sr/strings.xml | 1 - app/src/main/res/values-sv/strings.xml | 1 - app/src/main/res/values-tr/strings.xml | 1 - app/src/main/res/values-uk/strings.xml | 1 - app/src/main/res/values-vi/strings.xml | 1 - app/src/main/res/values-zh-rCN/strings.xml | 1 - app/src/main/res/values-zh-rHK/strings.xml | 1 - app/src/main/res/values-zh-rTW/strings.xml | 1 - app/src/main/res/values/strings.xml | 8 +- 58 files changed, 91 insertions(+), 65 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/fragments/detail/BaseDescriptionFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/detail/BaseDescriptionFragment.java index ae334b761..2bd5906bc 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/detail/BaseDescriptionFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/detail/BaseDescriptionFragment.java @@ -4,7 +4,13 @@ import static android.text.TextUtils.isEmpty; import static org.schabi.newpipe.extractor.utils.Utils.isBlank; import static org.schabi.newpipe.util.text.TextLinkifier.SET_LINK_MOVEMENT_METHOD; +import android.graphics.Typeface; import android.os.Bundle; +import android.text.SpannableStringBuilder; +import android.text.Spanned; +import android.text.method.LinkMovementMethod; +import android.text.style.ClickableSpan; +import android.text.style.StyleSpan; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -23,10 +29,12 @@ 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.Image; import org.schabi.newpipe.extractor.StreamingService; import org.schabi.newpipe.extractor.stream.Description; import org.schabi.newpipe.util.NavigationHelper; import org.schabi.newpipe.util.external_communication.ShareUtils; +import org.schabi.newpipe.util.image.ImageStrategy; import org.schabi.newpipe.util.text.TextLinkifier; import java.util.List; @@ -176,6 +184,73 @@ public abstract class BaseDescriptionFragment extends BaseFragment { layout.addView(itemBinding.getRoot()); } + private String imageSizeToText(final int heightOrWidth) { + if (heightOrWidth < 0) { + return "?"; + } else { + return String.valueOf(heightOrWidth); + } + } + + protected void addImagesMetadataItem(final LayoutInflater inflater, + final LinearLayout layout, + @StringRes final int type, + final List images) { + final String preferredImageUrl = ImageStrategy.choosePreferredImage(images); + if (preferredImageUrl == null) { + return; // null will be returned in case there is no image + } + + final ItemMetadataBinding itemBinding = + ItemMetadataBinding.inflate(inflater, layout, false); + itemBinding.metadataTypeView.setText(type); + + final SpannableStringBuilder urls = new SpannableStringBuilder(); + for (final Image image : images) { + if (urls.length() != 0) { + urls.append(", "); + } + final int entryBegin = urls.length(); + + if (image.getHeight() != Image.HEIGHT_UNKNOWN + || image.getWidth() != Image.WIDTH_UNKNOWN + // if even the resolution level is unknown, ?x? will be shown + || image.getEstimatedResolutionLevel() == Image.ResolutionLevel.UNKNOWN) { + urls.append(imageSizeToText(image.getHeight())); + urls.append('x'); + urls.append(imageSizeToText(image.getWidth())); + } else { + switch (image.getEstimatedResolutionLevel()) { + case LOW: + urls.append(getString(R.string.image_quality_low)); + break; + case MEDIUM: + urls.append(getString(R.string.image_quality_medium)); + break; + case HIGH: + urls.append(getString(R.string.image_quality_high)); + break; + } + } + + urls.setSpan(new ClickableSpan() { + @Override + public void onClick(@NonNull final View widget) { + ShareUtils.openUrlInBrowser(requireContext(), image.getUrl()); + } + }, entryBegin, urls.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + + if (preferredImageUrl.equals(image.getUrl())) { + urls.setSpan(new StyleSpan(Typeface.BOLD), entryBegin, urls.length(), + Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + } + } + + itemBinding.metadataContentView.setText(urls); + itemBinding.metadataContentView.setMovementMethod(LinkMovementMethod.getInstance()); + layout.addView(itemBinding.getRoot()); + } + private void addTagsMetadataItem(final LayoutInflater inflater, final LinearLayout layout) { final List tags = getTags(); diff --git a/app/src/main/java/org/schabi/newpipe/fragments/detail/DescriptionFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/detail/DescriptionFragment.java index 60a2a2ed3..ada12fc8e 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/detail/DescriptionFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/detail/DescriptionFragment.java @@ -17,7 +17,6 @@ import org.schabi.newpipe.extractor.stream.StreamInfo; import org.schabi.newpipe.util.Localization; import java.util.List; -import org.schabi.newpipe.util.image.ImageStrategy; import icepick.State; @@ -113,8 +112,13 @@ public class DescriptionFragment extends BaseDescriptionFragment { streamInfo.getSupportInfo()); addMetadataItem(inflater, layout, true, R.string.metadata_host, streamInfo.getHost()); - addMetadataItem(inflater, layout, true, R.string.metadata_thumbnail_url, - ImageStrategy.choosePreferredImage(streamInfo.getThumbnails())); + + addImagesMetadataItem(inflater, layout, R.string.metadata_thumbnails, + streamInfo.getThumbnails()); + addImagesMetadataItem(inflater, layout, R.string.metadata_uploader_avatars, + streamInfo.getUploaderAvatars()); + addImagesMetadataItem(inflater, layout, R.string.metadata_subchannel_avatars, + streamInfo.getSubChannelAvatars()); } private void addPrivacyMetadataItem(final LayoutInflater inflater, final LinearLayout layout) { diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelAboutFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelAboutFragment.java index 9a035d0ab..56418800d 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelAboutFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelAboutFragment.java @@ -17,7 +17,6 @@ import org.schabi.newpipe.extractor.stream.Description; import org.schabi.newpipe.fragments.detail.BaseDescriptionFragment; import org.schabi.newpipe.util.DeviceUtils; import org.schabi.newpipe.util.Localization; -import org.schabi.newpipe.util.image.ImageStrategy; import java.util.List; @@ -100,9 +99,9 @@ public class ChannelAboutFragment extends BaseDescriptionFragment { Localization.localizeNumber(context, channelInfo.getSubscriberCount())); } - addMetadataItem(inflater, layout, true, R.string.metadata_avatar_url, - ImageStrategy.choosePreferredImage(channelInfo.getAvatars())); - addMetadataItem(inflater, layout, true, R.string.metadata_banner_url, - ImageStrategy.choosePreferredImage(channelInfo.getBanners())); + addImagesMetadataItem(inflater, layout, R.string.metadata_avatars, + channelInfo.getAvatars()); + addImagesMetadataItem(inflater, layout, R.string.metadata_banners, + channelInfo.getBanners()); } } diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index 0c9f2c74c..78b59d4f9 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -642,7 +642,6 @@ خاص غير مدرج عامة - رابط الصورة المصغرة المضيف الدعم اللغة diff --git a/app/src/main/res/values-az/strings.xml b/app/src/main/res/values-az/strings.xml index 06273f9cf..1b8109b41 100644 --- a/app/src/main/res/values-az/strings.xml +++ b/app/src/main/res/values-az/strings.xml @@ -629,7 +629,6 @@ Sahib Siyahıdan kənar Şəxsi - Miniatür URL Yaş həddi Dil İctimai diff --git a/app/src/main/res/values-be/strings.xml b/app/src/main/res/values-be/strings.xml index e176d2bc9..f79db16a8 100644 --- a/app/src/main/res/values-be/strings.xml +++ b/app/src/main/res/values-be/strings.xml @@ -698,7 +698,6 @@ Тэгі Ліцэнзія Хост - URL мініяцюры Не ў спісе Прыватная , diff --git a/app/src/main/res/values-bg/strings.xml b/app/src/main/res/values-bg/strings.xml index 59091553d..56dfb9a9a 100644 --- a/app/src/main/res/values-bg/strings.xml +++ b/app/src/main/res/values-bg/strings.xml @@ -422,7 +422,6 @@ Поддръжка Сървър Публичен - Миниатюра линк Език на интерфейса Спри звука пост-обработката diff --git a/app/src/main/res/values-bn/strings.xml b/app/src/main/res/values-bn/strings.xml index d3f3a845b..24eed9eb0 100644 --- a/app/src/main/res/values-bn/strings.xml +++ b/app/src/main/res/values-bn/strings.xml @@ -548,7 +548,6 @@ প্রক্রিয়াকরণ ফিডে ত্রুটি ওয়েবসাইট খুলুন অ্যাকাউন্ট ধ্বংসকৃত - প্রতিচ্ছবি সংযোগ বয়সসীমা অভ্যন্তরীণ ব্যক্তিগত diff --git a/app/src/main/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml index bd3a5c61b..8ee3d6df4 100644 --- a/app/src/main/res/values-ca/strings.xml +++ b/app/src/main/res/values-ca/strings.xml @@ -600,7 +600,6 @@ Privat Descatalogat Públic - URL de la miniatura Amfitrió Suport Idioma diff --git a/app/src/main/res/values-ckb/strings.xml b/app/src/main/res/values-ckb/strings.xml index bae9fb822..841edef63 100644 --- a/app/src/main/res/values-ckb/strings.xml +++ b/app/src/main/res/values-ckb/strings.xml @@ -588,7 +588,6 @@ تایبەتی خشتەنەکراو گشتی - بەستەری وێنۆچکە هۆست پشتگیری زمان diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index dab312d3b..1864f3c65 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -613,7 +613,6 @@ Soukromé Neuvedeno v seznamu Veřejné - URL miniatury Server Podpora Jazyk diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml index ef6197414..59e112918 100644 --- a/app/src/main/res/values-da/strings.xml +++ b/app/src/main/res/values-da/strings.xml @@ -669,7 +669,6 @@ \nAktiver systemet mappevælger (SAF), hvis du vil downloade til et eksternt SD-kort Originaltekster fra tjenester vil være synlige i stream-emner Ingen videostreams er tilgængelige for eksterne afspillere - URL til miniaturebillede Fra Tablet-tilstand Denne video er kun tilgængelig for YouTube Music Premium-medlemmer, så den kan ikke streames eller downloades af NewPipe. diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index e9b710c63..01aa2de34 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -615,7 +615,6 @@ Schlagwörter Kategorie Nicht gelistet - Vorschaubild-URL Server Unterstützung Abonnenten diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index ced70b787..ddbc4c28b 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -602,7 +602,6 @@ Ιδιωτικό Εκτός λίστας Δημόσιο - URL εικονιδίου Υποστήριξη Γλώσσα Όριο ηλικίας diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 6ffadca81..781325886 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -614,7 +614,6 @@ Privado No listado Público - URL de la miniatura Soporte Lenguaje Límite de edad diff --git a/app/src/main/res/values-et/strings.xml b/app/src/main/res/values-et/strings.xml index ab478ec11..de29df8d3 100644 --- a/app/src/main/res/values-et/strings.xml +++ b/app/src/main/res/values-et/strings.xml @@ -584,7 +584,6 @@ Sisemine Privaatne Avalik - Pisipildi URL Kasutajatugi Keel Vanusepiir diff --git a/app/src/main/res/values-eu/strings.xml b/app/src/main/res/values-eu/strings.xml index 6003de6fd..fa2c885ed 100644 --- a/app/src/main/res/values-eu/strings.xml +++ b/app/src/main/res/values-eu/strings.xml @@ -624,7 +624,6 @@ Kontua ezabatu da Jario azkarrak ez du honi buruz informazio gehiagorik ematen. Adin muga - Miniaturaren URL-a Barnekoa Zerrendatu gabea Ostalaria diff --git a/app/src/main/res/values-fa/strings.xml b/app/src/main/res/values-fa/strings.xml index 35db56515..341b34102 100644 --- a/app/src/main/res/values-fa/strings.xml +++ b/app/src/main/res/values-fa/strings.xml @@ -567,7 +567,6 @@ حالت رایانک گشودن پایگاه وب حساب از بین رفت - نشانی بندانگشتی کرانهٔ عمر موارد مرتبط نمایش شرح diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml index 397f2fef0..34a38ec33 100644 --- a/app/src/main/res/values-fi/strings.xml +++ b/app/src/main/res/values-fi/strings.xml @@ -595,7 +595,6 @@ Tämä video on ikärajoitettu. \nYouTuben uusien ikärajoitusperiaatteiden mukaisesti NewPipella ei ole pääsyä videoon eikä sitä voida toistaa. Yöteema - Pienoiskuvakkeen osoite Poista käytöstä tekstinvalinta kuvauskentän sisältä Voit nyt valita tekstin kuvauskentän sisältä. Huomioithan, että valintatilan aikana sivu voi vilkkua ja linkit eivät ehkä ole klikattavia. %s tuo tämän syyn: diff --git a/app/src/main/res/values-fil/strings.xml b/app/src/main/res/values-fil/strings.xml index 0fb7a0a1d..28b344af3 100644 --- a/app/src/main/res/values-fil/strings.xml +++ b/app/src/main/res/values-fil/strings.xml @@ -157,7 +157,6 @@ Lisensya Wika Pribado - URL ng Thumbnail Hindi nakalista Nakapatay Bago at patok diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 51f258166..bab3f6f47 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -616,7 +616,6 @@ Privé Non répertorié Public - URL de la miniature Hôte Support Langue diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml index 8b5aaa497..957415790 100644 --- a/app/src/main/res/values-gl/strings.xml +++ b/app/src/main/res/values-gl/strings.xml @@ -547,7 +547,6 @@ Interno Privado Público - URL da miniatura Apoio Idioma Límite de idade diff --git a/app/src/main/res/values-he/strings.xml b/app/src/main/res/values-he/strings.xml index 4dec4c819..6d067e5e5 100644 --- a/app/src/main/res/values-he/strings.xml +++ b/app/src/main/res/values-he/strings.xml @@ -622,7 +622,6 @@ פרטי לא מופיע ברשימות ציבורי - כתובת תמונה ממוזערת אירוח תמיכה שפה diff --git a/app/src/main/res/values-hi/strings.xml b/app/src/main/res/values-hi/strings.xml index 80ab6209c..5d2d3be10 100644 --- a/app/src/main/res/values-hi/strings.xml +++ b/app/src/main/res/values-hi/strings.xml @@ -616,7 +616,6 @@ ऐप को क्रैश करें श्रेणी आपसे पूछा जाएगा कि प्रत्येक डाउनलोड को कहां सहेजना है - थंमनेल यूआरएल ऑफ़ हमेशा अपडेट करें विवरण में पाठ का चयन अक्षम करें diff --git a/app/src/main/res/values-hr/strings.xml b/app/src/main/res/values-hr/strings.xml index c625955f7..cea08931d 100644 --- a/app/src/main/res/values-hr/strings.xml +++ b/app/src/main/res/values-hr/strings.xml @@ -616,7 +616,6 @@ Privatno Nenavedeno Javno - URL sličice Poslužitelj Podrška Jezik diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml index 26f4ee3cf..264eb2c86 100644 --- a/app/src/main/res/values-hu/strings.xml +++ b/app/src/main/res/values-hu/strings.xml @@ -605,7 +605,6 @@ Licenc Korhatár Kiszolgáló - Bélyegkép URL Nyilvános Nem listázott Ki diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index b68b36a47..9961a71c6 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -592,7 +592,6 @@ Privasi Tidak didaftar Publik - Alamat URL gambar mini/thumbnail Host Dukungan Bahasa diff --git a/app/src/main/res/values-is/strings.xml b/app/src/main/res/values-is/strings.xml index 98f73e294..50d8b2220 100644 --- a/app/src/main/res/values-is/strings.xml +++ b/app/src/main/res/values-is/strings.xml @@ -485,7 +485,6 @@ Frá %s Reikningi lokað Aldurstakmark - Vefslóð smámyndar Fest ummæli Spjaldtölvuhamur Virkt diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 48cc84328..5408fe7ec 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -612,7 +612,6 @@ Privato Non in elenco Pubblico - URL copertina Host Supporto Lingua diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 8fa73a002..65280130d 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -600,7 +600,6 @@ 言語 サポート ホスト - サムネイルの URL ウェブサイトを開く ダウンロードのたびに保存する場所を尋ねます ダウンロードフォルダーがまだ設定されていません。今すぐデフォルトのフォルダーを選択してください diff --git a/app/src/main/res/values-ka/strings.xml b/app/src/main/res/values-ka/strings.xml index 47e105183..0c663ac49 100644 --- a/app/src/main/res/values-ka/strings.xml +++ b/app/src/main/res/values-ka/strings.xml @@ -565,7 +565,6 @@ Ასაკობრივი შეზღუდვა Ენა მასპინძელი - მინიატურების URL საჯარო დამალული პირადი diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index 30c381bcf..057118bef 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -625,7 +625,6 @@ 창작자의 마음 비공개 비공개 - 썸네일 URL 호스트 이제 이 채널을 구독했습니다 알림 받기 diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml index 58b25709b..b6264fbf5 100644 --- a/app/src/main/res/values-lt/strings.xml +++ b/app/src/main/res/values-lt/strings.xml @@ -617,7 +617,6 @@ Viešas Privatus Neįtrauktas į sąrašą - Paveikslėlio URL Serveris Pagalba Kalba diff --git a/app/src/main/res/values-lv/strings.xml b/app/src/main/res/values-lv/strings.xml index a613dd70a..c312062b1 100644 --- a/app/src/main/res/values-lv/strings.xml +++ b/app/src/main/res/values-lv/strings.xml @@ -653,7 +653,6 @@ Zemas kvalitātes (mazāks) Privātums Sarakstā neiekļauts - Video attēla URL Uzņēmums Attālinātie meklēšanas ieteikumi Atzīmēt kā skatītu diff --git a/app/src/main/res/values-ml/strings.xml b/app/src/main/res/values-ml/strings.xml index d03ae0a38..3687a325e 100644 --- a/app/src/main/res/values-ml/strings.xml +++ b/app/src/main/res/values-ml/strings.xml @@ -609,7 +609,6 @@ സ്വകാര്യം ലിസ്റ്റ് ചെയ്യപ്പെടാത്തത് പൊതുവായത് - ചെറുചിത്രം URL ഹോസ്റ്റ് പിന്തുണ ഭാഷ diff --git a/app/src/main/res/values-nb-rNO/strings.xml b/app/src/main/res/values-nb-rNO/strings.xml index 1637fe1f7..ae503b551 100644 --- a/app/src/main/res/values-nb-rNO/strings.xml +++ b/app/src/main/res/values-nb-rNO/strings.xml @@ -621,7 +621,6 @@ Privat Ulistet Offentlig - Miniatyrbilde-nettadresse Tjener Støtte Språk diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index e5b7f0f82..564ca873a 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -600,7 +600,6 @@ Privé Niet vermeld Openbaar - Miniatuur-URL Host Ondersteuning Taal diff --git a/app/src/main/res/values-or/strings.xml b/app/src/main/res/values-or/strings.xml index 519a0f199..fdbe665a5 100644 --- a/app/src/main/res/values-or/strings.xml +++ b/app/src/main/res/values-or/strings.xml @@ -419,7 +419,6 @@ ଟୋଗଲ୍ ସେବା, ବର୍ତ୍ତମାନ ମନୋନୀତ: ଫେରସ୍ତ କର ଓଭର୍ ରାଇଟ୍ କରନ୍ତୁ - ଥମ୍ବନେଲ୍ URL ହୋଷ୍ଟ ସାର୍ଵଜନୀନ ତାଲିକାଭୁକ୍ତ ନୁହେଁ diff --git a/app/src/main/res/values-pa/strings.xml b/app/src/main/res/values-pa/strings.xml index 253a87740..521931aae 100644 --- a/app/src/main/res/values-pa/strings.xml +++ b/app/src/main/res/values-pa/strings.xml @@ -441,7 +441,6 @@ ਨਿੱਜੀ (ਪ੍ਰਾਈਵੇਟ) ਗੈਰ-ਸੂਚੀਬੱਧ ਜਨਤਕ - ਥੰਮਨੇਲ URL ਮੇਜ਼ਬਾਨ ਸਹਾਇਤਾ ਭਾਸ਼ਾ/ਬੋਲੀ diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index b250901ff..9df249f39 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -619,7 +619,6 @@ Wewnętrzny Prywatny Publiczny - Adres URL miniatury Host Wsparcie Język diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index c344fa826..7fec3d54c 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -613,7 +613,6 @@ Não Listado Público Limite de Idade - URL da Miniatura Hospedado em Suporte Idioma diff --git a/app/src/main/res/values-pt-rPT/strings.xml b/app/src/main/res/values-pt-rPT/strings.xml index dc3c8e48c..c7897a4a1 100644 --- a/app/src/main/res/values-pt-rPT/strings.xml +++ b/app/src/main/res/values-pt-rPT/strings.xml @@ -617,7 +617,6 @@ Privado Não listado Público - URL da miniatura Servidor Apoio Idioma diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index c3c981fad..efa6060d8 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -630,7 +630,6 @@ Privado Não listado Público - URL da miniatura Servidor Apoio Idioma diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index 0a6920b6b..5d69144df 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -618,7 +618,6 @@ Privat Nelistat Public - URL miniatură Gazdă Sprijin Limbă diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 4b03f15c7..f54c0318e 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -629,7 +629,6 @@ Приватная Не в списке Публичная - URL миниатюры Сервер Доступность В быстром режиме обновления подробности об этом не предоставляются. diff --git a/app/src/main/res/values-sc/strings.xml b/app/src/main/res/values-sc/strings.xml index 7846eb274..1e915a3c0 100644 --- a/app/src/main/res/values-sc/strings.xml +++ b/app/src/main/res/values-sc/strings.xml @@ -602,7 +602,6 @@ No elencadu Privadu Pùblicu - URL de sa miniadura Istrangiadore Suportu Limba diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml index 51f9eb490..9d6117bb9 100644 --- a/app/src/main/res/values-sk/strings.xml +++ b/app/src/main/res/values-sk/strings.xml @@ -611,7 +611,6 @@ Interné Súkromné Nezaradené - URL miniatúry Verejné Hostiteľ Podpora diff --git a/app/src/main/res/values-so/strings.xml b/app/src/main/res/values-so/strings.xml index b3f4051c4..f36983526 100644 --- a/app/src/main/res/values-so/strings.xml +++ b/app/src/main/res/values-so/strings.xml @@ -602,7 +602,6 @@ Gaar ah Aan liistada kujirin Lawada arko - Tixraaca galka Martigaliye Taageero Luuqada diff --git a/app/src/main/res/values-sq/strings.xml b/app/src/main/res/values-sq/strings.xml index 5bfe72573..ab5b914fe 100644 --- a/app/src/main/res/values-sq/strings.xml +++ b/app/src/main/res/values-sq/strings.xml @@ -587,7 +587,6 @@ Private E palistuar Publike - URL e pamjes statike Mundësuesi Mbështetje Gjuha diff --git a/app/src/main/res/values-sr/strings.xml b/app/src/main/res/values-sr/strings.xml index b31ee604b..ddb07544b 100644 --- a/app/src/main/res/values-sr/strings.xml +++ b/app/src/main/res/values-sr/strings.xml @@ -612,7 +612,6 @@ лично ненаведено јавно - УРЛ сличице Домаћин Подршка Језик diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index 02e472e4d..939f5aa5c 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -628,7 +628,6 @@ Aktuellt Natt-tema Aviseringar för videohashningsframsteg - Miniatyrbild-webbadress Inaktivera medietunnel om du upplever en svart skärm eller att videouppspelningen hackar. Inaktivera medietunnel Hjärtmärkt av innehållsskaparen diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index 28bc92347..52f4d7697 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -601,7 +601,6 @@ Gizli Listelenmemiş Herkese Açık - Küçük Resim URL\'si Konakçı Destek Dil diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 0b024c861..d65e1e435 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -618,7 +618,6 @@ Публічне Приватне Поза списком - URL мініатюри Власник Підтримка Мова diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index 9609943ca..7f38d3c34 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -596,7 +596,6 @@ Riêng tư Chưa được liệt kê Công khai - URL hình thu nhỏ Nơi chứa Hỗ trợ Ngôn ngữ diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index d1d91dcd2..b663b1953 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -593,7 +593,6 @@ 私享 未分类 公开 - 缩略图 URL 所在服务器 支持 语言 diff --git a/app/src/main/res/values-zh-rHK/strings.xml b/app/src/main/res/values-zh-rHK/strings.xml index 91f2f3fc8..01eb91a8c 100644 --- a/app/src/main/res/values-zh-rHK/strings.xml +++ b/app/src/main/res/values-zh-rHK/strings.xml @@ -508,7 +508,6 @@ 分類 標籤 公開設定 - 縮圖 URL 公開 憑網址瀏覽 置頂留言 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 225e4562f..18d67f34f 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -592,7 +592,6 @@ 私人 未列出 公開 - 縮圖 URL 主機 支援 語言 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 705a84aab..2ccc6a412 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -753,9 +753,11 @@ Language Support Host - Thumbnail URL - Avatar URL - Banner URL + Thumbnails + Uploader avatars + Sub-channel avatars + Avatars + Banners Public Unlisted Private From 8d463b95777ecddca14ff16e5cf9a6a5fd6ae968 Mon Sep 17 00:00:00 2001 From: Stypox Date: Tue, 2 May 2023 20:10:52 +0200 Subject: [PATCH 093/172] Further improve image resolution strategy Now using multiple comparison steps instead of magic values --- .../newpipe/util/image/ImageStrategy.java | 108 ++++++++++-------- .../util/image/PreferredImageQuality.java | 15 +++ 2 files changed, 73 insertions(+), 50 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/util/image/ImageStrategy.java b/app/src/main/java/org/schabi/newpipe/util/image/ImageStrategy.java index 5de0b52f4..89e63af3f 100644 --- a/app/src/main/java/org/schabi/newpipe/util/image/ImageStrategy.java +++ b/app/src/main/java/org/schabi/newpipe/util/image/ImageStrategy.java @@ -1,5 +1,8 @@ package org.schabi.newpipe.util.image; +import static org.schabi.newpipe.extractor.Image.HEIGHT_UNKNOWN; +import static org.schabi.newpipe.extractor.Image.WIDTH_UNKNOWN; + import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -10,9 +13,10 @@ import java.util.List; public final class ImageStrategy { - // the height thresholds also used by the extractor (TODO move them to the extractor) - private static final int LOW_MEDIUM = 175; - private static final int MEDIUM_HIGH = 720; + // when preferredImageQuality is LOW or MEDIUM, images are sorted by how close their preferred + // image quality is to these values (H stands for "Height") + private static final int BEST_LOW_H = 75; + private static final int BEST_MEDIUM_H = 250; private static PreferredImageQuality preferredImageQuality = PreferredImageQuality.MEDIUM; @@ -28,35 +32,18 @@ public final class ImageStrategy { } - private static double estimatePixelCount(final Image image, - final double widthOverHeight, - final boolean unknownsLast) { - if (image.getHeight() == Image.HEIGHT_UNKNOWN) { - if (image.getWidth() == Image.WIDTH_UNKNOWN) { - switch (image.getEstimatedResolutionLevel()) { - case LOW: - return unknownsLast - ? (LOW_MEDIUM - 1) * (LOW_MEDIUM - 1) * widthOverHeight - : 0; - case MEDIUM: - return unknownsLast - ? (MEDIUM_HIGH - 1) * (MEDIUM_HIGH - 1) * widthOverHeight - : LOW_MEDIUM * LOW_MEDIUM * widthOverHeight; - case HIGH: - return unknownsLast - ? 1e20 // less than 1e21 to prefer over fully unknown image sizes - : MEDIUM_HIGH * MEDIUM_HIGH * widthOverHeight; - default: - case UNKNOWN: - // images whose size is completely unknown will be avoided when possible - return unknownsLast ? 1e21 : -1; - } + static double estimatePixelCount(final Image image, final double widthOverHeight) { + if (image.getHeight() == HEIGHT_UNKNOWN) { + if (image.getWidth() == WIDTH_UNKNOWN) { + // images whose size is completely unknown will be in their own subgroups, so + // any one of them will do, hence returning the same value for all of them + return 0; } else { return image.getWidth() * image.getWidth() / widthOverHeight; } - } else if (image.getWidth() == Image.WIDTH_UNKNOWN) { + } else if (image.getWidth() == WIDTH_UNKNOWN) { return image.getHeight() * image.getHeight() * widthOverHeight; } else { @@ -70,36 +57,57 @@ public final class ImageStrategy { return null; // do not load images } + // this will be used to estimate the pixel count for images where only one of height or + // width are known final double widthOverHeight = images.stream() - .filter(image -> image.getHeight() != Image.HEIGHT_UNKNOWN - && image.getWidth() != Image.WIDTH_UNKNOWN) + .filter(image -> image.getHeight() != HEIGHT_UNKNOWN + && image.getWidth() != WIDTH_UNKNOWN) .mapToDouble(image -> ((double) image.getWidth()) / image.getHeight()) .findFirst() .orElse(1.0); - final Comparator comparator; - switch (preferredImageQuality) { - case LOW: - comparator = Comparator.comparingDouble( - image -> estimatePixelCount(image, widthOverHeight, true)); - break; - default: - case MEDIUM: - comparator = Comparator.comparingDouble(image -> { - final double pixelCount = estimatePixelCount(image, widthOverHeight, true); - final double mediumHeight = (LOW_MEDIUM + MEDIUM_HIGH) / 2.0; - return Math.abs(pixelCount - mediumHeight * mediumHeight * widthOverHeight); - }); - break; - case HIGH: - comparator = Comparator.comparingDouble( - image -> estimatePixelCount(image, widthOverHeight, false)) - .reversed(); - break; - } + final Image.ResolutionLevel preferredLevel = preferredImageQuality.toResolutionLevel(); + final Comparator initialComparator = Comparator + // the first step splits the images into groups of resolution levels + .comparingInt(i -> { + if (i.getEstimatedResolutionLevel() == Image.ResolutionLevel.UNKNOWN) { + return 3; // avoid unknowns as much as possible + } else if (i.getEstimatedResolutionLevel() == preferredLevel) { + return 0; // prefer a matching resolution level + } else if (i.getEstimatedResolutionLevel() == Image.ResolutionLevel.MEDIUM) { + return 1; // the preferredLevel is only 1 "step" away (either HIGH or LOW) + } else { + return 2; // the preferredLevel is the furthest away possible (2 "steps") + } + }) + // then each level's group is further split into two subgroups, one with known image + // size (which is also the preferred subgroup) and the other without + .thenComparing(image -> + image.getHeight() == HEIGHT_UNKNOWN && image.getWidth() == WIDTH_UNKNOWN); + + // The third step chooses, within each subgroup with known image size, the best image based + // on how close its size is to BEST_LOW_H or BEST_MEDIUM_H (with proper units). Subgroups + // without known image size will be left untouched since estimatePixelCount always returns + // the same number for those. + final Comparator finalComparator = switch (preferredImageQuality) { + case NONE -> initialComparator; // unreachable + case LOW -> initialComparator.thenComparingDouble(image -> { + final double pixelCount = estimatePixelCount(image, widthOverHeight); + return Math.abs(pixelCount - BEST_LOW_H * BEST_LOW_H * widthOverHeight); + }); + case MEDIUM -> initialComparator.thenComparingDouble(image -> { + final double pixelCount = estimatePixelCount(image, widthOverHeight); + return Math.abs(pixelCount - BEST_MEDIUM_H * BEST_MEDIUM_H * widthOverHeight); + }); + case HIGH -> initialComparator.thenComparingDouble( + // this is reversed with a - so that the highest resolution is chosen + i -> -estimatePixelCount(i, widthOverHeight)); + }; return images.stream() - .min(comparator) + // using "min" basically means "take the first group, then take the first subgroup, + // then choose the best image, while ignoring all other groups and subgroups" + .min(finalComparator) .map(Image::getUrl) .orElse(null); } diff --git a/app/src/main/java/org/schabi/newpipe/util/image/PreferredImageQuality.java b/app/src/main/java/org/schabi/newpipe/util/image/PreferredImageQuality.java index 9f17082ea..7106359b3 100644 --- a/app/src/main/java/org/schabi/newpipe/util/image/PreferredImageQuality.java +++ b/app/src/main/java/org/schabi/newpipe/util/image/PreferredImageQuality.java @@ -3,6 +3,7 @@ package org.schabi.newpipe.util.image; import android.content.Context; import org.schabi.newpipe.R; +import org.schabi.newpipe.extractor.Image; public enum PreferredImageQuality { NONE, @@ -21,4 +22,18 @@ public enum PreferredImageQuality { return MEDIUM; // default to medium } } + + public Image.ResolutionLevel toResolutionLevel() { + switch (this) { + case LOW: + return Image.ResolutionLevel.LOW; + case MEDIUM: + return Image.ResolutionLevel.MEDIUM; + case HIGH: + return Image.ResolutionLevel.HIGH; + default: + case NONE: + return Image.ResolutionLevel.UNKNOWN; + } + } } From bf908f0b7dc44338f24c7a2b3d745070023a8704 Mon Sep 17 00:00:00 2001 From: Stypox Date: Tue, 2 May 2023 21:06:12 +0200 Subject: [PATCH 094/172] Add documentation and fix SonarCloud issue --- .../playlist/model/PlaylistRemoteEntity.java | 6 +++- .../detail/BaseDescriptionFragment.java | 1 + .../external_communication/ShareUtils.java | 4 +-- .../newpipe/util/image/ImageStrategy.java | 22 +++++++++++-- .../newpipe/util/image/PicassoHelper.java | 31 ++++++++++--------- 5 files changed, 43 insertions(+), 21 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistRemoteEntity.java b/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistRemoteEntity.java index 5e8977821..a64f2952c 100644 --- a/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistRemoteEntity.java +++ b/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistRemoteEntity.java @@ -70,7 +70,9 @@ public class PlaylistRemoteEntity implements PlaylistLocalItem { @Ignore public PlaylistRemoteEntity(final PlaylistInfo info) { this(info.getServiceId(), info.getName(), info.getUrl(), - ImageStrategy.choosePreferredImage(info.getThumbnails()), + // use uploader avatar when no thumbnail is available + ImageStrategy.choosePreferredImage(info.getThumbnails().isEmpty() + ? info.getUploaderAvatars() : info.getThumbnails()), info.getUploaderName(), info.getStreamCount()); } @@ -84,6 +86,8 @@ public class PlaylistRemoteEntity implements PlaylistLocalItem { && getStreamCount() == info.getStreamCount() && TextUtils.equals(getName(), info.getName()) && TextUtils.equals(getUrl(), info.getUrl()) + // we want to update the local playlist data even when either the remote thumbnail + // URL changes, or the preferred image quality setting is changed by the user && TextUtils.equals(getThumbnailUrl(), ImageStrategy.choosePreferredImage(info.getThumbnails())) && TextUtils.equals(getUploader(), info.getUploaderName()); diff --git a/app/src/main/java/org/schabi/newpipe/fragments/detail/BaseDescriptionFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/detail/BaseDescriptionFragment.java index 2bd5906bc..ffd10d827 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/detail/BaseDescriptionFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/detail/BaseDescriptionFragment.java @@ -224,6 +224,7 @@ public abstract class BaseDescriptionFragment extends BaseFragment { case LOW: urls.append(getString(R.string.image_quality_low)); break; + default: // unreachable, Image.ResolutionLevel.UNKNOWN is already filtered out case MEDIUM: urls.append(getString(R.string.image_quality_medium)); break; diff --git a/app/src/main/java/org/schabi/newpipe/util/external_communication/ShareUtils.java b/app/src/main/java/org/schabi/newpipe/util/external_communication/ShareUtils.java index fc057de41..7524e5413 100644 --- a/app/src/main/java/org/schabi/newpipe/util/external_communication/ShareUtils.java +++ b/app/src/main/java/org/schabi/newpipe/util/external_communication/ShareUtils.java @@ -269,8 +269,8 @@ public final class ShareUtils { * *

* For Android 10+ users, a content preview is shown, which includes the title of the shared - * content and an image preview the content, if its URL is not null or empty and its - * corresponding image is in the image cache. + * content and an image preview the content, if the preferred image chosen by {@link + * ImageStrategy#choosePreferredImage(List)} is in the image cache. *

* * @param context the context to use diff --git a/app/src/main/java/org/schabi/newpipe/util/image/ImageStrategy.java b/app/src/main/java/org/schabi/newpipe/util/image/ImageStrategy.java index 89e63af3f..1583c0b09 100644 --- a/app/src/main/java/org/schabi/newpipe/util/image/ImageStrategy.java +++ b/app/src/main/java/org/schabi/newpipe/util/image/ImageStrategy.java @@ -38,19 +38,35 @@ public final class ImageStrategy { // images whose size is completely unknown will be in their own subgroups, so // any one of them will do, hence returning the same value for all of them return 0; - } else { return image.getWidth() * image.getWidth() / widthOverHeight; } - } else if (image.getWidth() == WIDTH_UNKNOWN) { return image.getHeight() * image.getHeight() * widthOverHeight; - } else { return image.getHeight() * image.getWidth(); } } + /** + * Chooses an image amongst the provided list based on the user preference previously set with + * {@link #setPreferredImageQuality(PreferredImageQuality)}. {@code null} will be returned in + * case the list is empty or the user preference is to not show images. + *
+ * These properties will be preferred, from most to least important: + *
    + *
  1. The image's {@link Image#getEstimatedResolutionLevel()} is not unknown and is close + * to {@link #preferredImageQuality}
  2. + *
  3. At least one of the image's width or height are known
  4. + *
  5. The highest resolution image is finally chosen if the user's preference is {@link + * PreferredImageQuality#HIGH}, otherwise the chosen image is the one that has the closest + * height to {@link #BEST_LOW_H} or {@link #BEST_MEDIUM_H}
  6. + *
+ * + * @param images the images from which to choose + * @return the chosen preferred image, or {@link null} if the list is empty or the user disabled + * images + */ @Nullable public static String choosePreferredImage(@NonNull final List images) { if (preferredImageQuality == PreferredImageQuality.NONE) { diff --git a/app/src/main/java/org/schabi/newpipe/util/image/PicassoHelper.java b/app/src/main/java/org/schabi/newpipe/util/image/PicassoHelper.java index ccf7c3737..fb0c97fe1 100644 --- a/app/src/main/java/org/schabi/newpipe/util/image/PicassoHelper.java +++ b/app/src/main/java/org/schabi/newpipe/util/image/PicassoHelper.java @@ -9,6 +9,7 @@ import android.content.Context; import android.graphics.Bitmap; import android.util.Log; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.graphics.BitmapCompat; @@ -49,7 +50,7 @@ public final class PicassoHelper { picassoCache = new LruCache(10 * 1024 * 1024); picassoDownloaderClient = new OkHttpClient.Builder() .cache(new okhttp3.Cache(new File(context.getExternalCacheDir(), "picasso"), - 50 * 1024 * 1024)) + 50L * 1024L * 1024L)) // this should already be the default timeout in OkHttp3, but just to be sure... .callTimeout(15, TimeUnit.SECONDS) .build(); @@ -90,50 +91,50 @@ public final class PicassoHelper { } - public static RequestCreator loadAvatar(final List images) { + public static RequestCreator loadAvatar(@NonNull final List images) { return loadImageDefault(images, R.drawable.placeholder_person); } - public static RequestCreator loadAvatar(final String url) { + public static RequestCreator loadAvatar(@Nullable final String url) { return loadImageDefault(url, R.drawable.placeholder_person); } - public static RequestCreator loadThumbnail(final List images) { + public static RequestCreator loadThumbnail(@NonNull final List images) { return loadImageDefault(images, R.drawable.placeholder_thumbnail_video); } - public static RequestCreator loadThumbnail(final String url) { + public static RequestCreator loadThumbnail(@Nullable final String url) { return loadImageDefault(url, R.drawable.placeholder_thumbnail_video); } - public static RequestCreator loadDetailsThumbnail(final List images) { + public static RequestCreator loadDetailsThumbnail(@NonNull final List images) { return loadImageDefault(choosePreferredImage(images), R.drawable.placeholder_thumbnail_video, false); } - public static RequestCreator loadBanner(final List images) { + public static RequestCreator loadBanner(@NonNull final List images) { return loadImageDefault(images, R.drawable.placeholder_channel_banner); } - public static RequestCreator loadPlaylistThumbnail(final List images) { + public static RequestCreator loadPlaylistThumbnail(@NonNull final List images) { return loadImageDefault(images, R.drawable.placeholder_thumbnail_playlist); } - public static RequestCreator loadPlaylistThumbnail(final String url) { + public static RequestCreator loadPlaylistThumbnail(@Nullable final String url) { return loadImageDefault(url, R.drawable.placeholder_thumbnail_playlist); } - public static RequestCreator loadSeekbarThumbnailPreview(final String url) { + public static RequestCreator loadSeekbarThumbnailPreview(@Nullable final String url) { return picassoInstance.load(url); } - public static RequestCreator loadNotificationIcon(final String url) { + public static RequestCreator loadNotificationIcon(@Nullable final String url) { return loadImageDefault(url, R.drawable.ic_newpipe_triangle_white); } public static RequestCreator loadScaledDownThumbnail(final Context context, - final List images) { + @NonNull final List images) { // scale down the notification thumbnail for performance return PicassoHelper.loadThumbnail(images) .transform(new Transformation() { @@ -182,18 +183,18 @@ public final class PicassoHelper { } @Nullable - public static Bitmap getImageFromCacheIfPresent(final String imageUrl) { + public static Bitmap getImageFromCacheIfPresent(@NonNull final String imageUrl) { // URLs in the internal cache finish with \n so we need to add \n to image URLs return picassoCache.get(imageUrl + "\n"); } - private static RequestCreator loadImageDefault(final List images, + private static RequestCreator loadImageDefault(@NonNull final List images, final int placeholderResId) { return loadImageDefault(choosePreferredImage(images), placeholderResId); } - private static RequestCreator loadImageDefault(final String url, + private static RequestCreator loadImageDefault(@Nullable final String url, final int placeholderResId) { return loadImageDefault(url, placeholderResId, true); } From 37af2c87e8a275f8168e76a1dc38cb6a631202b7 Mon Sep 17 00:00:00 2001 From: Stypox Date: Tue, 2 May 2023 21:12:32 +0200 Subject: [PATCH 095/172] Fix possible NPE in PlayQueueNavigator --- .../player/mediasession/PlayQueueNavigator.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/player/mediasession/PlayQueueNavigator.java b/app/src/main/java/org/schabi/newpipe/player/mediasession/PlayQueueNavigator.java index f925bff16..3339869c1 100644 --- a/app/src/main/java/org/schabi/newpipe/player/mediasession/PlayQueueNavigator.java +++ b/app/src/main/java/org/schabi/newpipe/player/mediasession/PlayQueueNavigator.java @@ -138,10 +138,12 @@ public class PlayQueueNavigator implements MediaSessionConnector.QueueNavigator .putLong(MediaMetadataCompat.METADATA_KEY_NUM_TRACKS, player.getPlayQueue().size()); descBuilder.setExtras(additionalMetadata); - final Uri thumbnailUri = Uri.parse( - ImageStrategy.choosePreferredImage(item.getThumbnails())); - if (thumbnailUri != null) { - descBuilder.setIconUri(thumbnailUri); + try { + descBuilder.setIconUri(Uri.parse( + ImageStrategy.choosePreferredImage(item.getThumbnails()))); + } catch (final Throwable e) { + // no thumbnail available at all, or the user disabled image loading, + // or the obtained url is not a valid `Uri` } return descBuilder.build(); From 87dca0f7ec6a22c8218489cb82454c4d6ed6beb6 Mon Sep 17 00:00:00 2001 From: Stypox Date: Tue, 2 May 2023 21:36:11 +0200 Subject: [PATCH 096/172] Separate imageListToDbUrl from choosePreferredImage imageListToDbUrl should be used if the URL is going to be saved to the database, to avoid saving nothing in case at the moment of saving the user preference is to not show images. --- .../database/playlist/PlaylistStreamEntry.kt | 2 +- .../playlist/model/PlaylistRemoteEntity.java | 4 +- .../database/stream/StreamStatisticsEntry.kt | 2 +- .../database/stream/model/StreamEntity.kt | 10 +- .../subscription/SubscriptionEntity.java | 4 +- .../list/channel/ChannelFragment.java | 2 +- .../subscription/SubscriptionFragment.kt | 4 +- .../local/subscription/SubscriptionManager.kt | 4 +- .../newpipe/util/image/ImageStrategy.java | 104 ++++++++++++++---- 9 files changed, 96 insertions(+), 40 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/database/playlist/PlaylistStreamEntry.kt b/app/src/main/java/org/schabi/newpipe/database/playlist/PlaylistStreamEntry.kt index 47dc1d06a..1d74c6d31 100644 --- a/app/src/main/java/org/schabi/newpipe/database/playlist/PlaylistStreamEntry.kt +++ b/app/src/main/java/org/schabi/newpipe/database/playlist/PlaylistStreamEntry.kt @@ -29,7 +29,7 @@ data class PlaylistStreamEntry( item.duration = streamEntity.duration item.uploaderName = streamEntity.uploader item.uploaderUrl = streamEntity.uploaderUrl - item.thumbnails = ImageStrategy.urlToImageList(streamEntity.thumbnailUrl) + item.thumbnails = ImageStrategy.dbUrlToImageList(streamEntity.thumbnailUrl) return item } diff --git a/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistRemoteEntity.java b/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistRemoteEntity.java index a64f2952c..7c6b4a8b0 100644 --- a/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistRemoteEntity.java +++ b/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistRemoteEntity.java @@ -71,7 +71,7 @@ public class PlaylistRemoteEntity implements PlaylistLocalItem { public PlaylistRemoteEntity(final PlaylistInfo info) { this(info.getServiceId(), info.getName(), info.getUrl(), // use uploader avatar when no thumbnail is available - ImageStrategy.choosePreferredImage(info.getThumbnails().isEmpty() + ImageStrategy.imageListToDbUrl(info.getThumbnails().isEmpty() ? info.getUploaderAvatars() : info.getThumbnails()), info.getUploaderName(), info.getStreamCount()); } @@ -89,7 +89,7 @@ public class PlaylistRemoteEntity implements PlaylistLocalItem { // we want to update the local playlist data even when either the remote thumbnail // URL changes, or the preferred image quality setting is changed by the user && TextUtils.equals(getThumbnailUrl(), - ImageStrategy.choosePreferredImage(info.getThumbnails())) + ImageStrategy.imageListToDbUrl(info.getThumbnails())) && TextUtils.equals(getUploader(), info.getUploaderName()); } diff --git a/app/src/main/java/org/schabi/newpipe/database/stream/StreamStatisticsEntry.kt b/app/src/main/java/org/schabi/newpipe/database/stream/StreamStatisticsEntry.kt index 81e17b720..1f3654e7a 100644 --- a/app/src/main/java/org/schabi/newpipe/database/stream/StreamStatisticsEntry.kt +++ b/app/src/main/java/org/schabi/newpipe/database/stream/StreamStatisticsEntry.kt @@ -31,7 +31,7 @@ class StreamStatisticsEntry( item.duration = streamEntity.duration item.uploaderName = streamEntity.uploader item.uploaderUrl = streamEntity.uploaderUrl - item.thumbnails = ImageStrategy.urlToImageList(streamEntity.thumbnailUrl) + item.thumbnails = ImageStrategy.dbUrlToImageList(streamEntity.thumbnailUrl) return item } diff --git a/app/src/main/java/org/schabi/newpipe/database/stream/model/StreamEntity.kt b/app/src/main/java/org/schabi/newpipe/database/stream/model/StreamEntity.kt index 4eecc9373..d9c160b89 100644 --- a/app/src/main/java/org/schabi/newpipe/database/stream/model/StreamEntity.kt +++ b/app/src/main/java/org/schabi/newpipe/database/stream/model/StreamEntity.kt @@ -68,7 +68,8 @@ data class StreamEntity( constructor(item: StreamInfoItem) : this( serviceId = item.serviceId, url = item.url, title = item.name, streamType = item.streamType, duration = item.duration, uploader = item.uploaderName, - uploaderUrl = item.uploaderUrl, thumbnailUrl = ImageStrategy.choosePreferredImage(item.thumbnails), viewCount = item.viewCount, + uploaderUrl = item.uploaderUrl, + thumbnailUrl = ImageStrategy.imageListToDbUrl(item.thumbnails), viewCount = item.viewCount, textualUploadDate = item.textualUploadDate, uploadDate = item.uploadDate?.offsetDateTime(), isUploadDateApproximation = item.uploadDate?.isApproximation ) @@ -77,7 +78,8 @@ data class StreamEntity( constructor(info: StreamInfo) : this( serviceId = info.serviceId, url = info.url, title = info.name, streamType = info.streamType, duration = info.duration, uploader = info.uploaderName, - uploaderUrl = info.uploaderUrl, thumbnailUrl = ImageStrategy.choosePreferredImage(info.thumbnails), viewCount = info.viewCount, + uploaderUrl = info.uploaderUrl, + thumbnailUrl = ImageStrategy.imageListToDbUrl(info.thumbnails), viewCount = info.viewCount, textualUploadDate = info.textualUploadDate, uploadDate = info.uploadDate?.offsetDateTime(), isUploadDateApproximation = info.uploadDate?.isApproximation ) @@ -87,7 +89,7 @@ data class StreamEntity( serviceId = item.serviceId, url = item.url, title = item.title, streamType = item.streamType, duration = item.duration, uploader = item.uploader, uploaderUrl = item.uploaderUrl, - thumbnailUrl = ImageStrategy.choosePreferredImage(item.thumbnails) + thumbnailUrl = ImageStrategy.imageListToDbUrl(item.thumbnails) ) fun toStreamInfoItem(): StreamInfoItem { @@ -95,7 +97,7 @@ data class StreamEntity( item.duration = duration item.uploaderName = uploader item.uploaderUrl = uploaderUrl - item.thumbnails = ImageStrategy.urlToImageList(thumbnailUrl) + item.thumbnails = ImageStrategy.dbUrlToImageList(thumbnailUrl) if (viewCount != null) item.viewCount = viewCount as Long item.textualUploadDate = textualUploadDate diff --git a/app/src/main/java/org/schabi/newpipe/database/subscription/SubscriptionEntity.java b/app/src/main/java/org/schabi/newpipe/database/subscription/SubscriptionEntity.java index 3fb474423..a61a22a84 100644 --- a/app/src/main/java/org/schabi/newpipe/database/subscription/SubscriptionEntity.java +++ b/app/src/main/java/org/schabi/newpipe/database/subscription/SubscriptionEntity.java @@ -58,7 +58,7 @@ public class SubscriptionEntity { final SubscriptionEntity result = new SubscriptionEntity(); result.setServiceId(info.getServiceId()); result.setUrl(info.getUrl()); - result.setData(info.getName(), ImageStrategy.choosePreferredImage(info.getAvatars()), + result.setData(info.getName(), ImageStrategy.imageListToDbUrl(info.getAvatars()), info.getDescription(), info.getSubscriberCount()); return result; } @@ -139,7 +139,7 @@ public class SubscriptionEntity { @Ignore public ChannelInfoItem toChannelInfoItem() { final ChannelInfoItem item = new ChannelInfoItem(getServiceId(), getUrl(), getName()); - item.setThumbnails(ImageStrategy.urlToImageList(getAvatarUrl())); + item.setThumbnails(ImageStrategy.dbUrlToImageList(getAvatarUrl())); item.setSubscriberCount(getSubscriberCount()); item.setDescription(getDescription()); return item; diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java index 3ece760ca..b16f40a4a 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java @@ -355,7 +355,7 @@ public class ChannelFragment extends BaseStateFragment channel.setServiceId(info.getServiceId()); channel.setUrl(info.getUrl()); channel.setData(info.getName(), - ImageStrategy.choosePreferredImage(info.getAvatars()), + ImageStrategy.imageListToDbUrl(info.getAvatars()), info.getDescription(), info.getSubscriberCount()); channelSubscription = null; diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionFragment.kt b/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionFragment.kt index ac82d5c91..fe2321059 100644 --- a/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionFragment.kt +++ b/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionFragment.kt @@ -61,7 +61,6 @@ import org.schabi.newpipe.util.OnClickGesture import org.schabi.newpipe.util.ServiceHelper import org.schabi.newpipe.util.ThemeHelper.getGridSpanCountChannels import org.schabi.newpipe.util.external_communication.ShareUtils -import org.schabi.newpipe.util.image.ImageStrategy import java.text.SimpleDateFormat import java.util.Date import java.util.Locale @@ -342,8 +341,7 @@ class SubscriptionFragment : BaseStateFragment() { val actions = DialogInterface.OnClickListener { _, i -> when (i) { 0 -> ShareUtils.shareText( - requireContext(), selectedItem.name, selectedItem.url, - ImageStrategy.choosePreferredImage(selectedItem.thumbnails) + requireContext(), selectedItem.name, selectedItem.url, selectedItem.thumbnails ) 1 -> ShareUtils.openUrlInBrowser(requireContext(), selectedItem.url) 2 -> deleteChannel(selectedItem) diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionManager.kt b/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionManager.kt index cfd5196be..bd42bbe41 100644 --- a/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionManager.kt +++ b/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionManager.kt @@ -74,7 +74,7 @@ class SubscriptionManager(context: Context) { Completable.fromRunnable { it.setData( info.name, - ImageStrategy.choosePreferredImage(info.avatars), + ImageStrategy.imageListToDbUrl(info.avatars), info.description, info.subscriberCount ) @@ -105,7 +105,7 @@ class SubscriptionManager(context: Context) { } else if (info is ChannelInfo) { subscriptionEntity.setData( info.name, - ImageStrategy.choosePreferredImage(info.avatars), + ImageStrategy.imageListToDbUrl(info.avatars), info.description, info.subscriberCount ) diff --git a/app/src/main/java/org/schabi/newpipe/util/image/ImageStrategy.java b/app/src/main/java/org/schabi/newpipe/util/image/ImageStrategy.java index 1583c0b09..da97179b6 100644 --- a/app/src/main/java/org/schabi/newpipe/util/image/ImageStrategy.java +++ b/app/src/main/java/org/schabi/newpipe/util/image/ImageStrategy.java @@ -49,30 +49,16 @@ public final class ImageStrategy { } /** - * Chooses an image amongst the provided list based on the user preference previously set with - * {@link #setPreferredImageQuality(PreferredImageQuality)}. {@code null} will be returned in - * case the list is empty or the user preference is to not show images. - *
- * These properties will be preferred, from most to least important: - *
    - *
  1. The image's {@link Image#getEstimatedResolutionLevel()} is not unknown and is close - * to {@link #preferredImageQuality}
  2. - *
  3. At least one of the image's width or height are known
  4. - *
  5. The highest resolution image is finally chosen if the user's preference is {@link - * PreferredImageQuality#HIGH}, otherwise the chosen image is the one that has the closest - * height to {@link #BEST_LOW_H} or {@link #BEST_MEDIUM_H}
  6. - *
+ * {@link #choosePreferredImage(List)} contains the description for this function's logic. * - * @param images the images from which to choose - * @return the chosen preferred image, or {@link null} if the list is empty or the user disabled - * images + * @param images the images from which to choose + * @param nonNoneQuality the preferred quality (must NOT be {@link PreferredImageQuality#NONE}) + * @return the chosen preferred image, or {@link null} if the list is empty + * @see #choosePreferredImage(List) */ @Nullable - public static String choosePreferredImage(@NonNull final List images) { - if (preferredImageQuality == PreferredImageQuality.NONE) { - return null; // do not load images - } - + static String choosePreferredImage(@NonNull final List images, + final PreferredImageQuality nonNoneQuality) { // this will be used to estimate the pixel count for images where only one of height or // width are known final double widthOverHeight = images.stream() @@ -82,7 +68,7 @@ public final class ImageStrategy { .findFirst() .orElse(1.0); - final Image.ResolutionLevel preferredLevel = preferredImageQuality.toResolutionLevel(); + final Image.ResolutionLevel preferredLevel = nonNoneQuality.toResolutionLevel(); final Comparator initialComparator = Comparator // the first step splits the images into groups of resolution levels .comparingInt(i -> { @@ -105,7 +91,7 @@ public final class ImageStrategy { // on how close its size is to BEST_LOW_H or BEST_MEDIUM_H (with proper units). Subgroups // without known image size will be left untouched since estimatePixelCount always returns // the same number for those. - final Comparator finalComparator = switch (preferredImageQuality) { + final Comparator finalComparator = switch (nonNoneQuality) { case NONE -> initialComparator; // unreachable case LOW -> initialComparator.thenComparingDouble(image -> { final double pixelCount = estimatePixelCount(image, widthOverHeight); @@ -128,8 +114,78 @@ public final class ImageStrategy { .orElse(null); } + /** + * Chooses an image amongst the provided list based on the user preference previously set with + * {@link #setPreferredImageQuality(PreferredImageQuality)}. {@code null} will be returned in + * case the list is empty or the user preference is to not show images. + *
+ * These properties will be preferred, from most to least important: + *
    + *
  1. The image's {@link Image#getEstimatedResolutionLevel()} is not unknown and is close + * to {@link #preferredImageQuality}
  2. + *
  3. At least one of the image's width or height are known
  4. + *
  5. The highest resolution image is finally chosen if the user's preference is {@link + * PreferredImageQuality#HIGH}, otherwise the chosen image is the one that has the height + * closest to {@link #BEST_LOW_H} or {@link #BEST_MEDIUM_H}
  6. + *
+ *
+ * Use {@link #imageListToDbUrl(List)} if the URL is going to be saved to the database, to avoid + * saving nothing in case at the moment of saving the user preference is to not show images. + * + * @param images the images from which to choose + * @return the chosen preferred image, or {@link null} if the list is empty or the user disabled + * images + * @see #imageListToDbUrl(List) + */ + @Nullable + public static String choosePreferredImage(@NonNull final List images) { + if (preferredImageQuality == PreferredImageQuality.NONE) { + return null; // do not load images + } + + return choosePreferredImage(images, preferredImageQuality); + } + + /** + * Like {@link #choosePreferredImage(List)}, except that if {@link #preferredImageQuality} is + * {@link PreferredImageQuality#NONE} an image will be chosen anyway (with preferred quality + * {@link PreferredImageQuality#MEDIUM}. + *
+ * To go back to a list of images (obviously with just the one chosen image) from a URL saved in + * the database use {@link #dbUrlToImageList(String)}. + * + * @param images the images from which to choose + * @return the chosen preferred image, or {@link null} if the list is empty + * @see #choosePreferredImage(List) + * @see #dbUrlToImageList(String) + */ + @Nullable + public static String imageListToDbUrl(@NonNull final List images) { + final PreferredImageQuality quality; + if (preferredImageQuality == PreferredImageQuality.NONE) { + quality = PreferredImageQuality.MEDIUM; + } else { + quality = preferredImageQuality; + } + + return choosePreferredImage(images, quality); + } + + /** + * Wraps the URL (coming from the database) in a {@code List} so that it is usable + * seamlessly in all of the places where the extractor would return a list of images, including + * allowing to build info objects based on database objects. + *
+ * To obtain a url to save to the database from a list of images use {@link + * #imageListToDbUrl(List)}. + * + * @param url the URL to wrap coming from the database, or {@code null} to get an empty list + * @return a list containing just one {@link Image} wrapping the provided URL, with unknown + * image size fields, or an empty list if the URL is {@code null} + * @see #imageListToDbUrl(List) + */ @NonNull - public static List urlToImageList(@Nullable final String url) { + public static List dbUrlToImageList(@Nullable final String url) { if (url == null) { return List.of(); } else { From 0085ca64162a37104fc031677a8b59bf7a84090c Mon Sep 17 00:00:00 2001 From: Stypox Date: Tue, 2 May 2023 21:45:07 +0200 Subject: [PATCH 097/172] Fix loading images from db even if disabled --- .../java/org/schabi/newpipe/util/image/PicassoHelper.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/schabi/newpipe/util/image/PicassoHelper.java b/app/src/main/java/org/schabi/newpipe/util/image/PicassoHelper.java index fb0c97fe1..904776580 100644 --- a/app/src/main/java/org/schabi/newpipe/util/image/PicassoHelper.java +++ b/app/src/main/java/org/schabi/newpipe/util/image/PicassoHelper.java @@ -202,7 +202,10 @@ public final class PicassoHelper { private static RequestCreator loadImageDefault(@Nullable final String url, final int placeholderResId, final boolean showPlaceholderWhileLoading) { - if (isNullOrEmpty(url)) { + // if the URL was chosen with `choosePreferredImage` it will be null, but check again + // `shouldLoadImages` in case the URL was chosen with `imageListToDbUrl` (which is the case + // for URLs stored in the database) + if (isNullOrEmpty(url) || !ImageStrategy.shouldLoadImages()) { return picassoInstance .load((String) null) .placeholder(placeholderResId) // show placeholder when no image should load From 1b485ddb5adf09a926d2c04857dd9f132f4ff006 Mon Sep 17 00:00:00 2001 From: Stypox Date: Sun, 13 Aug 2023 23:44:10 +0200 Subject: [PATCH 098/172] Allow using CHECKSTYLE:OFF comments --- checkstyle/checkstyle.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/checkstyle/checkstyle.xml b/checkstyle/checkstyle.xml index e8c9d94ca..3377e3b84 100644 --- a/checkstyle/checkstyle.xml +++ b/checkstyle/checkstyle.xml @@ -69,6 +69,8 @@ + + From 0a2d6d1d62040365cd6a54d45de2f26741a269f1 Mon Sep 17 00:00:00 2001 From: Stypox Date: Sun, 13 Aug 2023 23:44:51 +0200 Subject: [PATCH 099/172] Add test for ImageStrategy --- .../newpipe/util/image/ImageStrategyTest.java | 195 ++++++++++++++++++ 1 file changed, 195 insertions(+) create mode 100644 app/src/test/java/org/schabi/newpipe/util/image/ImageStrategyTest.java diff --git a/app/src/test/java/org/schabi/newpipe/util/image/ImageStrategyTest.java b/app/src/test/java/org/schabi/newpipe/util/image/ImageStrategyTest.java new file mode 100644 index 000000000..8c8bf6937 --- /dev/null +++ b/app/src/test/java/org/schabi/newpipe/util/image/ImageStrategyTest.java @@ -0,0 +1,195 @@ +package org.schabi.newpipe.util.image; + +import static org.junit.Assert.assertEquals; +import static org.schabi.newpipe.extractor.Image.HEIGHT_UNKNOWN; +import static org.schabi.newpipe.extractor.Image.WIDTH_UNKNOWN; +import static org.schabi.newpipe.util.image.ImageStrategy.choosePreferredImage; +import static org.schabi.newpipe.util.image.ImageStrategy.estimatePixelCount; + +import org.junit.Test; +import org.schabi.newpipe.extractor.Image; +import org.schabi.newpipe.extractor.Image.ResolutionLevel; + +import java.util.List; + +public class ImageStrategyTest { + + private static final List RESOLUTION_LEVELS = List.of( + ResolutionLevel.LOW, ResolutionLevel.MEDIUM, ResolutionLevel.HIGH); + + private Image img(final int height, final int width) { + return new Image("", height, width, ResolutionLevel.UNKNOWN); + } + + private Image img(final String url, final ResolutionLevel resolutionLevel) { + return new Image(url, HEIGHT_UNKNOWN, WIDTH_UNKNOWN, resolutionLevel); + } + + private Image img(final String url, + final int height, + final int width, + final ResolutionLevel resolutionLevel) { + return new Image(url, height, width, resolutionLevel); + } + + private void assertChoosePreferredImage(final String low, + final String medium, + final String high, + final List images) { + assertEquals(low, choosePreferredImage(images, PreferredImageQuality.LOW)); + assertEquals(medium, choosePreferredImage(images, PreferredImageQuality.MEDIUM)); + assertEquals(high, choosePreferredImage(images, PreferredImageQuality.HIGH)); + } + + + // CHECKSTYLE:OFF + @Test + public void testEstimatePixelCountAllKnown() { + assertEquals(20000.0, estimatePixelCount(img(100, 200), 1.0), 0.0); + assertEquals(20000.0, estimatePixelCount(img(100, 200), 12.0), 0.0); + assertEquals( 100.0, estimatePixelCount(img(100, 1), 12.0), 0.0); + assertEquals( 100.0, estimatePixelCount(img( 1, 100), 0.5), 0.0); + } + + @Test + public void testEstimatePixelCountHeightUnknown() { + assertEquals( 10000.0, estimatePixelCount(img(HEIGHT_UNKNOWN, 100), 1.0 ), 0.0); + assertEquals( 20000.0, estimatePixelCount(img(HEIGHT_UNKNOWN, 200), 2.0 ), 0.0); + assertEquals( 10.0, estimatePixelCount(img(HEIGHT_UNKNOWN, 1), 0.1 ), 0.0); + assertEquals(230400.0, estimatePixelCount(img(HEIGHT_UNKNOWN, 640), 16.0/9.0), 0.0); + } + + @Test + public void testEstimatePixelCountWidthUnknown() { + assertEquals( 10000.0, estimatePixelCount(img(100, WIDTH_UNKNOWN), 1.0 ), 0.0); + assertEquals( 20000.0, estimatePixelCount(img(200, WIDTH_UNKNOWN), 0.5 ), 0.0); + assertEquals( 12.0, estimatePixelCount(img( 1, WIDTH_UNKNOWN), 12.0 ), 0.0); + assertEquals(230400.0, estimatePixelCount(img(360, WIDTH_UNKNOWN), 16.0/9.0), 0.0); + } + + @Test + public void testEstimatePixelCountAllUnknown() { + assertEquals(0.0, estimatePixelCount(img(HEIGHT_UNKNOWN, WIDTH_UNKNOWN), 1.0 ), 0.0); + assertEquals(0.0, estimatePixelCount(img(HEIGHT_UNKNOWN, WIDTH_UNKNOWN), 12.0 ), 0.0); + assertEquals(0.0, estimatePixelCount(img(HEIGHT_UNKNOWN, WIDTH_UNKNOWN), 0.1 ), 0.0); + assertEquals(0.0, estimatePixelCount(img(HEIGHT_UNKNOWN, WIDTH_UNKNOWN), 16.0/9.0), 0.0); + } + // CHECKSTYLE:ON + + + @Test + public void testChoosePreferredImageAllKnown() { + // the resolution level of the images is more important than the actual resolution + assertChoosePreferredImage("a", "b", "c", List.of( + img("a", 1, 1, ResolutionLevel.LOW), + img("b", 200, 200, ResolutionLevel.MEDIUM), + img("c", 10000, 10000, ResolutionLevel.HIGH) + )); + assertChoosePreferredImage("a", "b", "c", List.of( + img("a", 10000, 10000, ResolutionLevel.LOW), + img("b", 200, 200, ResolutionLevel.MEDIUM), + img("c", 1, 1, ResolutionLevel.HIGH) + )); + + assertChoosePreferredImage("b", "c", "d", List.of( + img("a", 2, 1, ResolutionLevel.LOW), + img("b", 50, 25, ResolutionLevel.LOW), + img("c", 200, 100, ResolutionLevel.LOW), + img("d", 300, 150, ResolutionLevel.LOW) + )); + + assertChoosePreferredImage("c", "d", "d", List.of( + img("a", 2, 1, ResolutionLevel.MEDIUM), + img("b", 50, 25, ResolutionLevel.MEDIUM), + img("c", 60, 30, ResolutionLevel.MEDIUM), + img("d", 300, 150, ResolutionLevel.MEDIUM) + )); + } + + @Test + public void testChoosePreferredImageSomeKnown() { + // the resolution level of the images is more important than the actual resolution + assertChoosePreferredImage("a", "b", "c", List.of( + img("a", 1, WIDTH_UNKNOWN, ResolutionLevel.LOW), + img("b", HEIGHT_UNKNOWN, 200, ResolutionLevel.MEDIUM), + img("c", 10000, WIDTH_UNKNOWN, ResolutionLevel.HIGH) + )); + assertChoosePreferredImage("a", "b", "c", List.of( + img("a", HEIGHT_UNKNOWN, 10000, ResolutionLevel.LOW), + img("b", 200, WIDTH_UNKNOWN, ResolutionLevel.MEDIUM), + img("c", HEIGHT_UNKNOWN, 1, ResolutionLevel.HIGH) + )); + + assertChoosePreferredImage("b", "c", "d", List.of( + img("a", HEIGHT_UNKNOWN, 1, ResolutionLevel.HIGH), + img("b", 50, WIDTH_UNKNOWN, ResolutionLevel.HIGH), + img("c", HEIGHT_UNKNOWN, 120, ResolutionLevel.HIGH), + img("d", 340, WIDTH_UNKNOWN, ResolutionLevel.HIGH) + )); + + assertChoosePreferredImage("c", "d", "d", List.of( + img("a", 2, WIDTH_UNKNOWN, ResolutionLevel.MEDIUM), + img("b", HEIGHT_UNKNOWN, 50, ResolutionLevel.MEDIUM), + img("c", 60, WIDTH_UNKNOWN, ResolutionLevel.MEDIUM), + img("d", HEIGHT_UNKNOWN, 340, ResolutionLevel.MEDIUM) + )); + } + + @Test + public void testChoosePreferredImageMixed() { + for (final ResolutionLevel resolutionLevel : RESOLUTION_LEVELS) { + assertChoosePreferredImage("d", "b", "c", List.of( + img("a", ResolutionLevel.UNKNOWN), + img("b", 200, 100, resolutionLevel), + img("c", 400, WIDTH_UNKNOWN, resolutionLevel), + img("d", HEIGHT_UNKNOWN, 50, resolutionLevel), + img("e", resolutionLevel) + )); + } + for (final ResolutionLevel resolutionLevel : RESOLUTION_LEVELS) { + assertChoosePreferredImage("b", "b", "b", List.of( + img("a", ResolutionLevel.UNKNOWN), + img("b", 200, 100, resolutionLevel), + img("e", resolutionLevel) + )); + } + assertChoosePreferredImage("b", "b", "e", List.of( + img("a", ResolutionLevel.UNKNOWN), + img("b", 200, 100, ResolutionLevel.LOW), + img("e", ResolutionLevel.HIGH) + )); + } + + @Test + public void testChoosePreferredImageAllUnknown() { + assertChoosePreferredImage("b", "c", "d", List.of( + img("a", ResolutionLevel.UNKNOWN), + img("b", ResolutionLevel.LOW), + img("c", ResolutionLevel.MEDIUM), + img("d", ResolutionLevel.HIGH) + )); + assertChoosePreferredImage("c", "c", "d", List.of( + img("a", ResolutionLevel.UNKNOWN), + img("c", ResolutionLevel.MEDIUM), + img("d", ResolutionLevel.HIGH) + )); + assertChoosePreferredImage("b", "c", "c", List.of( + img("a", ResolutionLevel.UNKNOWN), + img("b", ResolutionLevel.LOW), + img("c", ResolutionLevel.MEDIUM) + )); + + // UNKNOWN is avoided as much as possible + assertChoosePreferredImage("d", "d", "d", List.of( + img("a", ResolutionLevel.UNKNOWN), + img("d", ResolutionLevel.HIGH) + )); + assertChoosePreferredImage("b", "b", "b", List.of( + img("a", ResolutionLevel.UNKNOWN), + img("b", ResolutionLevel.LOW) + )); + assertChoosePreferredImage("a", "a", "a", List.of( + img("a", ResolutionLevel.UNKNOWN) + )); + } +} From 027b829c384be26494b2d2867dd285a51388213b Mon Sep 17 00:00:00 2001 From: Stypox Date: Tue, 19 Sep 2023 18:35:29 +0200 Subject: [PATCH 100/172] Use @DrawableRes in PicassoHelper --- .../java/org/schabi/newpipe/util/image/PicassoHelper.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/util/image/PicassoHelper.java b/app/src/main/java/org/schabi/newpipe/util/image/PicassoHelper.java index 904776580..4b116bdf9 100644 --- a/app/src/main/java/org/schabi/newpipe/util/image/PicassoHelper.java +++ b/app/src/main/java/org/schabi/newpipe/util/image/PicassoHelper.java @@ -9,6 +9,7 @@ import android.content.Context; import android.graphics.Bitmap; import android.util.Log; +import androidx.annotation.DrawableRes; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.graphics.BitmapCompat; @@ -190,17 +191,17 @@ public final class PicassoHelper { private static RequestCreator loadImageDefault(@NonNull final List images, - final int placeholderResId) { + @DrawableRes final int placeholderResId) { return loadImageDefault(choosePreferredImage(images), placeholderResId); } private static RequestCreator loadImageDefault(@Nullable final String url, - final int placeholderResId) { + @DrawableRes final int placeholderResId) { return loadImageDefault(url, placeholderResId, true); } private static RequestCreator loadImageDefault(@Nullable final String url, - final int placeholderResId, + @DrawableRes final int placeholderResId, final boolean showPlaceholderWhileLoading) { // if the URL was chosen with `choosePreferredImage` it will be null, but check again // `shouldLoadImages` in case the URL was chosen with `imageListToDbUrl` (which is the case From f8b756c8bcaca8c45b41d7434db0b221ab3027d4 Mon Sep 17 00:00:00 2001 From: Stypox Date: Tue, 19 Sep 2023 18:40:14 +0200 Subject: [PATCH 101/172] Make question mark localizable --- .../newpipe/fragments/detail/BaseDescriptionFragment.java | 2 +- app/src/main/res/values/strings.xml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/schabi/newpipe/fragments/detail/BaseDescriptionFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/detail/BaseDescriptionFragment.java index ffd10d827..e3bdc6592 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/detail/BaseDescriptionFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/detail/BaseDescriptionFragment.java @@ -186,7 +186,7 @@ public abstract class BaseDescriptionFragment extends BaseFragment { private String imageSizeToText(final int heightOrWidth) { if (heightOrWidth < 0) { - return "?"; + return getString(R.string.question_mark); } else { return String.valueOf(heightOrWidth); } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 2ccc6a412..9a533f6b8 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -828,4 +828,5 @@ Low quality Medium quality High quality + \? \ No newline at end of file From bdc2aa2b394c0a4bf392dcf74ab2409f8129ccb1 Mon Sep 17 00:00:00 2001 From: Stypox Date: Fri, 22 Sep 2023 10:43:37 +0200 Subject: [PATCH 102/172] Update extractor and remove DeobfuscateException In ErrorInfo it was treated separately from other ParsingExceptions, including by showing a customized message, which has now been removed. --- app/build.gradle | 2 +- app/src/main/java/org/schabi/newpipe/error/ErrorInfo.kt | 2 -- app/src/main/res/values-ar/strings.xml | 1 - app/src/main/res/values-az/strings.xml | 1 - app/src/main/res/values-b+ast/strings.xml | 1 - app/src/main/res/values-b+uz+Latn/strings.xml | 1 - app/src/main/res/values-be/strings.xml | 1 - app/src/main/res/values-bg/strings.xml | 1 - app/src/main/res/values-bn-rBD/strings.xml | 1 - app/src/main/res/values-bn-rIN/strings.xml | 1 - app/src/main/res/values-bn/strings.xml | 1 - app/src/main/res/values-ca/strings.xml | 1 - app/src/main/res/values-ckb/strings.xml | 1 - app/src/main/res/values-cs/strings.xml | 1 - app/src/main/res/values-da/strings.xml | 1 - app/src/main/res/values-de/strings.xml | 1 - app/src/main/res/values-el/strings.xml | 1 - app/src/main/res/values-eo/strings.xml | 1 - app/src/main/res/values-es/strings.xml | 1 - app/src/main/res/values-et/strings.xml | 1 - app/src/main/res/values-eu/strings.xml | 1 - app/src/main/res/values-fa/strings.xml | 1 - app/src/main/res/values-fi/strings.xml | 1 - app/src/main/res/values-fr/strings.xml | 1 - app/src/main/res/values-gl/strings.xml | 1 - app/src/main/res/values-he/strings.xml | 1 - app/src/main/res/values-hi/strings.xml | 1 - app/src/main/res/values-hr/strings.xml | 1 - app/src/main/res/values-hu/strings.xml | 1 - app/src/main/res/values-in/strings.xml | 1 - app/src/main/res/values-is/strings.xml | 1 - app/src/main/res/values-it/strings.xml | 1 - app/src/main/res/values-ja/strings.xml | 1 - app/src/main/res/values-ka/strings.xml | 1 - app/src/main/res/values-kmr/strings.xml | 1 - app/src/main/res/values-ko/strings.xml | 1 - app/src/main/res/values-ku/strings.xml | 1 - app/src/main/res/values-lt/strings.xml | 1 - app/src/main/res/values-lv/strings.xml | 1 - app/src/main/res/values-mk/strings.xml | 1 - app/src/main/res/values-ml/strings.xml | 1 - app/src/main/res/values-ms/strings.xml | 1 - app/src/main/res/values-nb-rNO/strings.xml | 1 - app/src/main/res/values-ne/strings.xml | 1 - app/src/main/res/values-nl-rBE/strings.xml | 1 - app/src/main/res/values-nl/strings.xml | 1 - app/src/main/res/values-nqo/strings.xml | 1 - app/src/main/res/values-or/strings.xml | 1 - app/src/main/res/values-pa/strings.xml | 1 - app/src/main/res/values-pl/strings.xml | 1 - app/src/main/res/values-pt-rBR/strings.xml | 1 - app/src/main/res/values-pt-rPT/strings.xml | 1 - app/src/main/res/values-pt/strings.xml | 1 - app/src/main/res/values-ro/strings.xml | 1 - app/src/main/res/values-ru/strings.xml | 1 - app/src/main/res/values-ryu/strings.xml | 1 - app/src/main/res/values-sc/strings.xml | 1 - app/src/main/res/values-sk/strings.xml | 1 - app/src/main/res/values-sl/strings.xml | 1 - app/src/main/res/values-so/strings.xml | 1 - app/src/main/res/values-sq/strings.xml | 1 - app/src/main/res/values-sr/strings.xml | 1 - app/src/main/res/values-sv/strings.xml | 1 - app/src/main/res/values-ta/strings.xml | 1 - app/src/main/res/values-te/strings.xml | 1 - app/src/main/res/values-th/strings.xml | 1 - app/src/main/res/values-tr/strings.xml | 1 - app/src/main/res/values-uk/strings.xml | 1 - app/src/main/res/values-ur/strings.xml | 1 - app/src/main/res/values-vi/strings.xml | 1 - app/src/main/res/values-zh-rCN/strings.xml | 1 - app/src/main/res/values-zh-rHK/strings.xml | 1 - app/src/main/res/values-zh-rTW/strings.xml | 1 - app/src/main/res/values/strings.xml | 1 - 74 files changed, 1 insertion(+), 75 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index aa7ac8720..7b69b5b72 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -197,7 +197,7 @@ dependencies { // name and the commit hash with the commit hash of the (pushed) commit you want to test // This works thanks to JitPack: https://jitpack.io/ implementation 'com.github.TeamNewPipe:nanojson:1d9e1aea9049fc9f85e68b43ba39fe7be1c1f751' - implementation 'com.github.TeamNewPipe:NewPipeExtractor:3be76a6406d59f1fd8eedf5fab6552e6c2a3da76' + implementation 'com.github.TeamNewPipe:NewPipeExtractor:289db1178ab66694c23893e6a487d4708343c47b' implementation 'com.github.TeamNewPipe:NoNonsense-FilePicker:5.0.0' /** Checkstyle **/ diff --git a/app/src/main/java/org/schabi/newpipe/error/ErrorInfo.kt b/app/src/main/java/org/schabi/newpipe/error/ErrorInfo.kt index d87fa3330..6d8c1bd63 100644 --- a/app/src/main/java/org/schabi/newpipe/error/ErrorInfo.kt +++ b/app/src/main/java/org/schabi/newpipe/error/ErrorInfo.kt @@ -11,7 +11,6 @@ import org.schabi.newpipe.extractor.exceptions.AccountTerminatedException import org.schabi.newpipe.extractor.exceptions.ContentNotAvailableException import org.schabi.newpipe.extractor.exceptions.ContentNotSupportedException import org.schabi.newpipe.extractor.exceptions.ExtractionException -import org.schabi.newpipe.extractor.services.youtube.extractors.YoutubeStreamExtractor.DeobfuscateException import org.schabi.newpipe.ktx.isNetworkRelated import org.schabi.newpipe.util.ServiceHelper @@ -96,7 +95,6 @@ class ErrorInfo( throwable is ContentNotAvailableException -> R.string.content_not_available throwable != null && throwable.isNetworkRelated -> R.string.network_error throwable is ContentNotSupportedException -> R.string.content_not_supported - throwable is DeobfuscateException -> R.string.youtube_signature_deobfuscation_error throwable is ExtractionException -> R.string.parsing_error throwable is ExoPlaybackException -> { when (throwable.type) { diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index 78b59d4f9..cd666d69c 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -45,7 +45,6 @@ تعذر تحميل كافة الصور المصغرة خطأ تعذر تحليل الموقع - تعذر فك تشفير توقيع رابط الفيديو اضغط على عدسة المكبرة للبدء. اشتراك مشترك diff --git a/app/src/main/res/values-az/strings.xml b/app/src/main/res/values-az/strings.xml index 1b8109b41..4a3305e3b 100644 --- a/app/src/main/res/values-az/strings.xml +++ b/app/src/main/res/values-az/strings.xml @@ -641,7 +641,6 @@ Oynadıcı bildirişi Yeni yayımlar Xəta hesabatı bildirişi - Video URL\'i imzası şifrəsi qırılmadı Endirmək üçün yayım mövcud deyil Xəta baş verdi, bildirişi gör Şərhiniz (İngiliscə): diff --git a/app/src/main/res/values-b+ast/strings.xml b/app/src/main/res/values-b+ast/strings.xml index b9a57f1c2..40809d459 100644 --- a/app/src/main/res/values-b+ast/strings.xml +++ b/app/src/main/res/values-b+ast/strings.xml @@ -25,7 +25,6 @@ En direuto Fallu Nun pudieron cargase toles miniatures - Nun pudo sabese la robla de la URL del videu Nun pudo analizase\'l sitiu web Buff… Esto nun debió asoceder. Perdona mas asocedió daqué malo. diff --git a/app/src/main/res/values-b+uz+Latn/strings.xml b/app/src/main/res/values-b+uz+Latn/strings.xml index 76924b0d4..32a12d3dd 100644 --- a/app/src/main/res/values-b+uz+Latn/strings.xml +++ b/app/src/main/res/values-b+uz+Latn/strings.xml @@ -312,7 +312,6 @@ Yuklab olish menyusi sozlanmadi Tarkib mavjud emas Veb-saytni tahlil qilib bo\'lmadi - Videoning URL manzilini o\'chirib bo\'lmadi Barcha eskizlarni yuklab bo\'lmadi Tarmoqda xato Tashqi SD-kartaga yuklab olishning iloji yo\'q. Yuklash papkasining joylashuvi tiklansinmi\? diff --git a/app/src/main/res/values-be/strings.xml b/app/src/main/res/values-be/strings.xml index f79db16a8..9948872c7 100644 --- a/app/src/main/res/values-be/strings.xml +++ b/app/src/main/res/values-be/strings.xml @@ -124,7 +124,6 @@ Памылка Памылка сеткі Не атрымалася загрузіць усе мініяцюры - Не атрымалася расшыфраваць подпіс URL у відэа Не атрымалася разабраць вэб-сайт Кантэнт недаступны Не атрымалася стварыць меню загрузкі diff --git a/app/src/main/res/values-bg/strings.xml b/app/src/main/res/values-bg/strings.xml index 56dfb9a9a..1857ce1f8 100644 --- a/app/src/main/res/values-bg/strings.xml +++ b/app/src/main/res/values-bg/strings.xml @@ -176,7 +176,6 @@ Изтрива историята с въвежданите за търсене ключови думи Изтрий цялата история на търсенията\? Историята на търсенията е изтрита. - URL подписът на клипа не можа да бъде дешифрован Външните плейъри не поддържат този вид линкове Невалидна директория Невалиден файл или източник на съдържание diff --git a/app/src/main/res/values-bn-rBD/strings.xml b/app/src/main/res/values-bn-rBD/strings.xml index e660cb7bd..c4f1108f7 100644 --- a/app/src/main/res/values-bn-rBD/strings.xml +++ b/app/src/main/res/values-bn-rBD/strings.xml @@ -61,7 +61,6 @@ ত্রুটি নেটওয়ার্ক ত্রুটি সব থাম্বনেইল লোড করা যায়নি - ভিডিও URL স্বাক্ষর ডিক্রিপ্ট করা যায়নি ওয়েবসাইট বিশ্লেষন করা যায়নি কন্টেন্ট উপলব্ধ নয় ডাউনলোড মেনু সেটআপ করা যায়নি diff --git a/app/src/main/res/values-bn-rIN/strings.xml b/app/src/main/res/values-bn-rIN/strings.xml index 1f664ce26..ebbd5c7e5 100644 --- a/app/src/main/res/values-bn-rIN/strings.xml +++ b/app/src/main/res/values-bn-rIN/strings.xml @@ -44,7 +44,6 @@ ডাউনলোড মেনু সেটআপ করা যায়নি কন্টেন্ট উপলব্ধ নয় ওয়েবসাইট বিশ্লেষন করা যায়নি - ভিডিও URL স্বাক্ষর ডিক্রিপ্ট করা যায়নি সব থাম্বনেইল লোড করা যায়নি নেটওয়ার্ক ত্রুটি ত্রুটি diff --git a/app/src/main/res/values-bn/strings.xml b/app/src/main/res/values-bn/strings.xml index 24eed9eb0..46d9a171d 100644 --- a/app/src/main/res/values-bn/strings.xml +++ b/app/src/main/res/values-bn/strings.xml @@ -140,7 +140,6 @@ ডাউনলোড মেনু সেটআপ করা যায়নি কন্টেন্ট উপলব্ধ নয় ওয়েবসাইট বিশ্লেষন করা যায়নি - ভিডিও URL স্বাক্ষর ডিক্রিপ্ট করা যায়নি সব থাম্বনেইল লোড করা যায়নি নেটওয়ার্ক ত্রুটি বাহ্যিক স্টোরেজ নেই diff --git a/app/src/main/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml index 8ee3d6df4..82e08db32 100644 --- a/app/src/main/res/values-ca/strings.xml +++ b/app/src/main/res/values-ca/strings.xml @@ -137,7 +137,6 @@ Notificació de NewPipe Notificacions per al reproductor de NewPipe No s\'han pogut carregar totes les miniatures - No s\'ha pogut desxifrar la signatura de l\'URL del vídeo No s\'ha pogut processar el lloc web Contingut no disponible No s\'ha pogut configurar el menú de baixades diff --git a/app/src/main/res/values-ckb/strings.xml b/app/src/main/res/values-ckb/strings.xml index 841edef63..aca0979f6 100644 --- a/app/src/main/res/values-ckb/strings.xml +++ b/app/src/main/res/values-ckb/strings.xml @@ -383,7 +383,6 @@ هەمان فۆڵدەر بوونی نییە نیشانه‌كردنی خشته‌لێدان ناوی فایل ناکرێت بەتاڵ بێت - ناتوانرێت واژووی بەستەری ڤیدیۆ بخوێنرێتەوە پیشاندانی پەیامێک بۆ ئامادەبوونی به‌رنامه‌ لەکاتی بەردەست بوونی وەشانی نوێ مێژووی سەیرکردن سکاڵا لەسەر کێشەکان diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index 1864f3c65..95b84959c 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -39,7 +39,6 @@ Chyba Chyba sítě Nebylo možné nahrát všechny náhledy - Nebylo možné dekódovat URL videa Nebylo možné analyzovat stránku Obsah není k dispozici Přehrát video, délka: diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml index 59e112918..c4daa5a84 100644 --- a/app/src/main/res/values-da/strings.xml +++ b/app/src/main/res/values-da/strings.xml @@ -136,7 +136,6 @@ Det er endnu ikke muligt at downloade til et eksternt SD-kort. Nulstil download-mappens placering\? Netværksfejl Kunne ikke indlæse alle miniaturebilleder - Kunne ikke dekryptere URL-signatur for video Kunne ikke analysere websted Indhold ikke tilgængeligt Kunne ikke oprette downloadmenu diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 01aa2de34..1ef6fc656 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -43,7 +43,6 @@ Aussehen Fehler Konnte nicht alle Vorschaubilder laden - Konnte Video-URL-Signatur nicht entschlüsseln Konnte Webseite nicht analysieren Inhalt nicht verfügbar Inhalt diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index ddbc4c28b..b4d602ba4 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -145,7 +145,6 @@ Διαγραφή ολόκληρου του ιστορικού αναζητήσεων; Το ιστορικό αναζητήσεων διαγράφηκε Δεν ήταν δυνατή η φόρτωση όλων των εικονιδίων - Δεν ήταν δυνατή η αποκρυπτογράφηση της υπογραφής της URL του βίντεο Δεν ήταν δυνατή η ανάλυση του ιστοτόπου Το περιεχόμενο δεν είναι διαθέσιμο Δεν ήταν δυνατή η ρύθμιση του μενού λήψεων diff --git a/app/src/main/res/values-eo/strings.xml b/app/src/main/res/values-eo/strings.xml index 2d0951db4..a70c6d37e 100644 --- a/app/src/main/res/values-eo/strings.xml +++ b/app/src/main/res/values-eo/strings.xml @@ -36,7 +36,6 @@ Ĉu instali la mankan aplikaĵon Kore\? Montri \'Sekvajn\' kaj \'Similajn\' videojn Ĉiuj bildetoj ne ŝargeblas - La subskribo de la ligilo de la filmeto ne malĉifreblas La retejo ne analizeblas Ludi filmeton, daŭro: Bildeto de la alŝutinto diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 781325886..b5e9b1a6e 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -38,7 +38,6 @@ Error Error de conexión No se pudo cargar las miniaturas - No se pudo descifrar la URL del vídeo No se pudo analizar el sitio web Mostrar vídeos \'Siguientes\' y \'Similares\' Idioma predefinido del contenido diff --git a/app/src/main/res/values-et/strings.xml b/app/src/main/res/values-et/strings.xml index de29df8d3..b2ffbd0a8 100644 --- a/app/src/main/res/values-et/strings.xml +++ b/app/src/main/res/values-et/strings.xml @@ -119,7 +119,6 @@ Viga Võrgu viga Kõiki pisipilte ei õnnestunud laadida - Video URLi dekrüptimine nurjus Veebilehe töötlemine nurjus Sisu pole saadaval Allalaadimismenüü seadistamine nurjus diff --git a/app/src/main/res/values-eu/strings.xml b/app/src/main/res/values-eu/strings.xml index fa2c885ed..c0ca3cef5 100644 --- a/app/src/main/res/values-eu/strings.xml +++ b/app/src/main/res/values-eu/strings.xml @@ -68,7 +68,6 @@ Errorea Sare-errorea Ezin izan dira iruditxo guztiak deskargatu - Ezin izan da bideoaren URL sinadura deskodetu Ezin izan da webgunea analizatu Edukia ez dago eskuragarri Ezin izan da deskargen menua ezarri diff --git a/app/src/main/res/values-fa/strings.xml b/app/src/main/res/values-fa/strings.xml index 341b34102..2a1ccbbce 100644 --- a/app/src/main/res/values-fa/strings.xml +++ b/app/src/main/res/values-fa/strings.xml @@ -46,7 +46,6 @@ خطا خطای شبکه نمی‌توان تمام بندانگشتی‌ها را بار کرد - نمی‌توان امضای نشانی اینترنتی ویدیو را رمزگشایی کرد نمی‌توان پایگاه وب را تجزیه کرد محتوا در دسترس نیست نمی‌توان فهرست بارگیری را برپا ساخت diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml index 34a38ec33..9df4e304c 100644 --- a/app/src/main/res/values-fi/strings.xml +++ b/app/src/main/res/values-fi/strings.xml @@ -82,7 +82,6 @@ Virhe Verkkovirhe Kaikkia esikatselukuvia ei voitu ladata - Videon URL-allekirjoituksen salausta ei voitu purkaa Verkkosivua ei voitu jäsentää Sisältö ei ole saatavilla Latausvalikkoa ei voitu asettaa diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index bab3f6f47..fb5d4940c 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -51,7 +51,6 @@ Afficher le contenu avec limite d’âge En direct Impossible de charger toutes les miniatures - Impossible de déchiffrer la signature URL de la vidéo Désolé, cela n’aurait pas dû se produire. Signaler par courriel Information : diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml index 957415790..c4a702aa3 100644 --- a/app/src/main/res/values-gl/strings.xml +++ b/app/src/main/res/values-gl/strings.xml @@ -123,7 +123,6 @@ Erro Erro de rede Non foi posíbel carregar todas as miniaturas - Non foi posíbel descifrar a asinatura do vídeo Non foi posíbel procesar o sitio web Contido non dispoñíbel Non foi posíbel configurar o menú de descargas diff --git a/app/src/main/res/values-he/strings.xml b/app/src/main/res/values-he/strings.xml index 6d067e5e5..e7469bf5d 100644 --- a/app/src/main/res/values-he/strings.xml +++ b/app/src/main/res/values-he/strings.xml @@ -63,7 +63,6 @@ שגיאה שגיאת רשת אין אפשרות לטעון את כל התמונות הממוזערות - לא ניתן לפענח את חתימת כתובת הסרטון ניתוח האתר לא התאפשר תוכן אינו זמין לא הייתה אפשרות להכין את תפריט ההורדה diff --git a/app/src/main/res/values-hi/strings.xml b/app/src/main/res/values-hi/strings.xml index 5d2d3be10..1c0074229 100644 --- a/app/src/main/res/values-hi/strings.xml +++ b/app/src/main/res/values-hi/strings.xml @@ -101,7 +101,6 @@ त्रुटी नेटवर्क में त्रुटी सारे thumbnail(फोटो जो फ़ोन की मेमोरी में है ) भरे नहीं जा सकते - वीडियो के URL हस्ताक्षर को डीऑबफस्केट नहीं कर सकते इस website का निरंक्षण नहीं कर सकते विषय वस्तु उपलब्ध नहीं है डाउनलोड मेनू को स्थापित नहीं कर सकते diff --git a/app/src/main/res/values-hr/strings.xml b/app/src/main/res/values-hr/strings.xml index cea08931d..179470994 100644 --- a/app/src/main/res/values-hr/strings.xml +++ b/app/src/main/res/values-hr/strings.xml @@ -77,7 +77,6 @@ Greška Greška u mreži Nije bilo moguće učitati sve sličice - Nije bilo moguće dešifrirati URL potpis videozapisa Nije bilo moguće obraditi stranicu Sadržaj nije dostupan Nije bilo moguće postaviti izbornik za preuzimanje diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml index 264eb2c86..58411b01b 100644 --- a/app/src/main/res/values-hu/strings.xml +++ b/app/src/main/res/values-hu/strings.xml @@ -55,7 +55,6 @@ Elnézést, ennek nem kellett volna megtörténnie. Jelentés e-mailben Nem sikerült a letöltési menü beállítása - Nem sikerült a videó URL aláírásának feloldása Újra Videó Hang diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index 9961a71c6..2ddaa8bdd 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -75,7 +75,6 @@ Disalin ke papan klip Silakan pilih folder unduhan di pengaturan Pemutar stream tidak ditemukan. Pasang VLC\? - Tidak bisa dekripsi tanda tangan URL video App/UI rusak Apa:\\nPermintaan:\\nBahasa Konten:\\nNegara Konten:\\nBahasa Apl:\\nLayanan:\\nWaktu GMT:\\nPaket:\\nVersi:\\nVersi OS: Thread diff --git a/app/src/main/res/values-is/strings.xml b/app/src/main/res/values-is/strings.xml index 50d8b2220..bc1143063 100644 --- a/app/src/main/res/values-is/strings.xml +++ b/app/src/main/res/values-is/strings.xml @@ -645,7 +645,6 @@ Áhorfsferli eytt Eyða spilunarstöðum Eyðir öllum spilunarstöðum - Mistókst að afkóða vefslóð myndbandar Niðurhal á SD kort er ekki mögulegt. Endurstilla niðurhalsmöppu\? Strjúktu til að fjarlægja Engir spilunarlistar bókamerktir ennþá diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 5408fe7ec..16e2a9ff5 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -43,7 +43,6 @@ Errore Errore di connessione Impossibile caricare tutte le copertine - Impossibile decriptare la firma dell\'URL del video Contenuto non disponibile Impossibile analizzare il sito web Impossibile impostare il menu di download diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 65280130d..7da558e74 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -43,7 +43,6 @@ 音楽ファイルをダウンロードするフォルダーを選択して下さい エラー 全てのサムネイルを読み込めませんでした - 動画のURLを復号できませんでした ウェブサイトを解析できませんでした コンテンツが利用できません 保存メニューを設定できませんでした diff --git a/app/src/main/res/values-ka/strings.xml b/app/src/main/res/values-ka/strings.xml index 0c663ac49..bab397e4a 100644 --- a/app/src/main/res/values-ka/strings.xml +++ b/app/src/main/res/values-ka/strings.xml @@ -195,7 +195,6 @@ გარე მეხსიერება მიუწვდომელია Ქსელის შეცდომა ყველა ესკიზის ჩატვირთვა ვერ მოხერხდა - ვიდეოს URL-ის ხელმოწერის დებფუსირება ვერ მოხერხდა ვებსაიტის გარჩევა ვერ მოხერხდა კონტენტი მიუწვდომელია ჩამოტვირთვის მენიუს დაყენება ვერ მოხერხდა diff --git a/app/src/main/res/values-kmr/strings.xml b/app/src/main/res/values-kmr/strings.xml index b7478aa58..d6be1f170 100644 --- a/app/src/main/res/values-kmr/strings.xml +++ b/app/src/main/res/values-kmr/strings.xml @@ -98,7 +98,6 @@ Menuya dakêşanê nehat saz kirin Naverok tune Malperê nekare parsek bike - Nekarî îmzeya URL-ya vîdyoyê deobfuscate bike Nekarî hemî wêneyan barkir Çewtiya torê Dakêşandin ji karta SD ya derveyî re ne gengaz e. Cihê peldanka dakêşanê ji nû ve were çêkirin\? diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index 057118bef..3d613e554 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -47,7 +47,6 @@ 라이브 오류 모든 썸네일을 불러올 수 없습니다 - 비디오 URL 서명을 복호화할 수 없습니다 웹사이트를 가져올 수 없습니다 컨텐츠를 사용할 수 없습니다 다운로드 메뉴를 설정할 수 없습니다 diff --git a/app/src/main/res/values-ku/strings.xml b/app/src/main/res/values-ku/strings.xml index fc7e85616..34de8bb0a 100644 --- a/app/src/main/res/values-ku/strings.xml +++ b/app/src/main/res/values-ku/strings.xml @@ -327,7 +327,6 @@ پیشاندانی ڕێنمایی ”داگرتن تا پاشکۆ” پیشاندانی ڕێنمایی کاتێ لە پاشبنەما یاخوود پەنجەرەدا گرتە دەکرێ لەسەر وردەکاری ڤیدیۆیەک پەرەسەندوو - ناتوانرێ واژووی بەستەری ڤیدیۆ بخوێنرێتەوە نەگێڕانەوەی کارپێکەر بۆ پێش کێشە ڕوویدا گێڕانەوەی کارپێکەر بۆکاتی پێش کێشە هەمان فۆڵدەر بوونی نییە diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml index b6264fbf5..f82ad52b7 100644 --- a/app/src/main/res/values-lt/strings.xml +++ b/app/src/main/res/values-lt/strings.xml @@ -64,7 +64,6 @@ Klaida Tinklo klaida Negalima įkelti visų miniatiūrų - Negalima iššifruoti vaizdo įrašo skaitmeninio parašo Negalima apdoroti tinklapio Turinys neprieinamas Negalima sutvarkyti atsisiuntimų meniu diff --git a/app/src/main/res/values-lv/strings.xml b/app/src/main/res/values-lv/strings.xml index c312062b1..d35eb546a 100644 --- a/app/src/main/res/values-lv/strings.xml +++ b/app/src/main/res/values-lv/strings.xml @@ -192,7 +192,6 @@ Nevarēja iestatīt lejupielādes izvēlni Saturs nav pieejams Nevarēja apstrādāt mājaslapu - Nevarēja saprast video URL parakstu Nevarēja ielādēt visus video attēlus Tīkla kļūda Lejupielādēt uz SD karti nav iespējams. Atiestatīt lejupielāžu mapes lokāciju\? diff --git a/app/src/main/res/values-mk/strings.xml b/app/src/main/res/values-mk/strings.xml index e39172c72..03a285e37 100644 --- a/app/src/main/res/values-mk/strings.xml +++ b/app/src/main/res/values-mk/strings.xml @@ -112,7 +112,6 @@ Грешка Мрежна грешка Не можеа да се прочитаат сите сликички - Невозможно децифрирање на URL потписот Не може да се прочита страната Содржината е недостапна Неуспешно поставување на менито за превземања diff --git a/app/src/main/res/values-ml/strings.xml b/app/src/main/res/values-ml/strings.xml index 3687a325e..ae9f56592 100644 --- a/app/src/main/res/values-ml/strings.xml +++ b/app/src/main/res/values-ml/strings.xml @@ -226,7 +226,6 @@ ഡൗൺലോഡ് മെനു തുറക്കാനായില്ല കന്റെന്റ് ലഭ്യമല്ല വെബ്സൈറ്റ് വ്യാപരിക്കാനായില്ല - വീഡിയോ URL സിഗ്നേച്ചർ ഡീക്രിപ്റ്റ് ചെയ്യാൻ സാധിച്ചില്ല ലഘുചിത്രങ്ങൾ ലോഡ് ചെയ്യാനായില്ല നെറ്റ്‌വർക്ക് പിശക് എസ്ഡി കാർഡിലേക്ക്‌ ഡൗൺലോഡ് അസാധ്യം. ഡൗൺലോഡ് ഫോൾഡർ മാറ്റട്ടെ\? diff --git a/app/src/main/res/values-ms/strings.xml b/app/src/main/res/values-ms/strings.xml index d9e4f12ef..ee0431bbd 100644 --- a/app/src/main/res/values-ms/strings.xml +++ b/app/src/main/res/values-ms/strings.xml @@ -133,7 +133,6 @@ Tidak mampu Memuat turun ke kad SD luar. Tetapkan semula lokasi folder muat turun\? Ralat rangkaian Tidak dapat memuat semua thumbnail - Tidak dapat menyahsulit tanda tangan URL video Tidak dapat menghuraikan laman web Kandungan tidak tersedia Tidak dapat menyediakan menu muat turun diff --git a/app/src/main/res/values-nb-rNO/strings.xml b/app/src/main/res/values-nb-rNO/strings.xml index ae503b551..8f997b0be 100644 --- a/app/src/main/res/values-nb-rNO/strings.xml +++ b/app/src/main/res/values-nb-rNO/strings.xml @@ -46,7 +46,6 @@ Vis aldersbegrenset innhold Feil Kunne ikke laste inn alle miniatyrbilder - Kunne ikke dekryptere signaturen til videoens nettadresse Kunne ikke tolke nettside Innholdet er utilgjengelig Kunne ikke sette opp nedlastingsmeny diff --git a/app/src/main/res/values-ne/strings.xml b/app/src/main/res/values-ne/strings.xml index d1d0d15b0..d7c8f8494 100644 --- a/app/src/main/res/values-ne/strings.xml +++ b/app/src/main/res/values-ne/strings.xml @@ -138,7 +138,6 @@ बाह्य एस डी कार्ड (SD card) छैन। डाउनलोड फोल्डर स्थान रिसेट गर्ने\? नेटवर्क त्रुटि सबै थम्बनेल लोड गर्न सकेन - भिडियो URL हस्ताक्षर डिक्रिप्टगर्न सकेन वेबसाइट पार्स गर्न सकिँएन सामग्री अनउपलब्ध डाउनलोड मेनु स्थापित गर्न सकिएन diff --git a/app/src/main/res/values-nl-rBE/strings.xml b/app/src/main/res/values-nl-rBE/strings.xml index 0d582f6de..64f975547 100644 --- a/app/src/main/res/values-nl-rBE/strings.xml +++ b/app/src/main/res/values-nl-rBE/strings.xml @@ -112,7 +112,6 @@ Fout Netwerkfout Kon niet alle miniaturen laden - Kon video-URL-ondertekening niet ontsleutelen Kon website niet verwerken Inhoud niet beschikbaar Kon downloadmenu niet instellen diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 564ca873a..e56c39981 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -44,7 +44,6 @@ Fout Netwerkfout Kan niet alle miniatuurvoorbeelden laden - Kan video-URL-ondertekening niet ontsleutelen Kan website niet verwerken Inhoud niet beschikbaar Kan downloadmenu niet instellen diff --git a/app/src/main/res/values-nqo/strings.xml b/app/src/main/res/values-nqo/strings.xml index e177035b2..c9c4904ac 100644 --- a/app/src/main/res/values-nqo/strings.xml +++ b/app/src/main/res/values-nqo/strings.xml @@ -151,7 +151,6 @@ ߝߎ߬ߕߎ߲߬ߕߌ ߞߐߞߊ߲߫ ߦߟߌߕߏߟߊ߲߫ ߕߍ߫ ߦߋ߲߬ ߞߙߏ߬ߝߏ߫ ߝߎ߬ߕߎ߲߬ߕߌ - ߦߋߡߍ߲ߕߊ߫ ߛߘߌ߬ߜߋ߲߫ ߞߟߊ߬ߣߐ߮ ߡߊ߫ ߝߙߍߕߍߓߐ߫ ߟߊ߫ ߗߍߦߙߐ ߡߊ߫ ߛߋ߫ ߘߐߛߏ߯ߙߋ߫ ߟߊ߫ ߞߣߐߘߐ ߕߍ߫ ߡߊߛߐ߬ߘߐ߲߬ ߟߥߊ߬ߟߌ߬ߟߊ߲ ߓߘߊ߫ ߜߊߘߊ߲߫ diff --git a/app/src/main/res/values-or/strings.xml b/app/src/main/res/values-or/strings.xml index fdbe665a5..a9ef4277c 100644 --- a/app/src/main/res/values-or/strings.xml +++ b/app/src/main/res/values-or/strings.xml @@ -515,7 +515,6 @@ ସମସ୍ତ ପ୍ଲେକ୍ ପୋଜିସନ୍ ବିଲୋପ କରିବେ କି\? ସନ୍ଧାନ କୀ ଶବ୍ଦର ଇତିହାସ ବିଲୋପ କରେ ତ୍ରୁଟି - ଭିଡିଓ URL ଦସ୍ତଖତକୁ ଡିବଫସ୍କେଟ୍ କରିପାରିଲା ନାହିଁ ପୁନରୁଦ୍ଧାର ନ ହୋଇପାରିଲା ପରି ପ୍ଲେୟାର ତ୍ରୁଟି ଘଟିଲା ବହିଃ-ଚାଳକ ଏଭଳି ଲିଙ୍କ୍ ସମର୍ଥନ କରେନି ଫାଇଲ୍ ଘୁଞ୍ଚିଗଲା କିମ୍ବା ଡିଲିଟ୍ ହେଲା diff --git a/app/src/main/res/values-pa/strings.xml b/app/src/main/res/values-pa/strings.xml index 521931aae..2d67523fb 100644 --- a/app/src/main/res/values-pa/strings.xml +++ b/app/src/main/res/values-pa/strings.xml @@ -118,7 +118,6 @@ ਤਰੁੱਟੀ ਨੈੱਟਵਰਕ ਤਰੁੱਟੀ ਸਾਰੇ ਥੰਮਨੇਲ ਲੋਡ ਨਹੀਂ ਹੋ ਸਕੇ - ਵੀਡੀਓ URL ਦਸਤਖਤ ਦੀ ਅਸਪੱਸ਼ਟਤਾ ਦੂਰ ਨਹੀਂ ਹੋ ਸਕੀ ਵੈਬਸਾਈਟ parse ਨਹੀਂ ਹੋ ਸਕੀ ਸਮੱਗਰੀ ਉਪਲਬਧ ਨਹੀਂ ਹੈ ਡਾਊਨਲੋਡ ਮੀਨੂੰ ਸੈਟ-ਅਪ ਨਹੀਂ ਹੋ ਸਕਿਆ diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 9df249f39..b31883230 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -46,7 +46,6 @@ Błąd Błąd sieci Nie udało się załadować wszystkich miniatur - Nie udało się odszyfrować sygnatury URL wideo Nie udało się przetworzyć strony internetowej Treść niedostępna Nie udało się utworzyć menu pobierania diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 7fec3d54c..2949dfdcb 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -1,7 +1,6 @@ Áudio - Não foi possível decodificar assinatura da URL do vídeo Seu comentário (em inglês): O que aconteceu: Informação: diff --git a/app/src/main/res/values-pt-rPT/strings.xml b/app/src/main/res/values-pt-rPT/strings.xml index c7897a4a1..a63171ba4 100644 --- a/app/src/main/res/values-pt-rPT/strings.xml +++ b/app/src/main/res/values-pt-rPT/strings.xml @@ -217,7 +217,6 @@ Novos e tendências Remove o histórico de pesquisas Notificação de nova versão - Não foi possível decifrar a assinatura do URL Selecione uma lista de reprodução Última atualização: %s Importar base de dados diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index efa6060d8..f8f06b15a 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -43,7 +43,6 @@ Escolha a pasta para colocar os ficheiros de áudio Erro Não foi possível carregar todas as miniaturas - Não foi possível decifrar a assinatura do URL Não foi possível processar o site Conteúdo indisponível Conteúdo diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index 5d69144df..a31dde7aa 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -41,7 +41,6 @@ Eroare Eroare de rețea Nu s-au putut încărca toate miniaturile - Nu s-a putut deobfusca semnătura URL-ului video Nu s-a putut analiza site-ul web Conținut indisponibil Nu s-a putut configura meniul de descărcare diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index f54c0318e..fc226c37c 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -78,7 +78,6 @@ Аудио Повтор Не удалось загрузить все миниатюры - Не удалось расшифровать подпись URL у видео В фоне В окне Только некоторые устройства поддерживают видео в 2K/4K diff --git a/app/src/main/res/values-ryu/strings.xml b/app/src/main/res/values-ryu/strings.xml index 930a9585f..16b298dad 100644 --- a/app/src/main/res/values-ryu/strings.xml +++ b/app/src/main/res/values-ryu/strings.xml @@ -43,7 +43,6 @@ うんがくファイルダウンロードするフォルダーさんたくちくぃみそーれー エラー まじりぬサムネイルゆみくみやびらんたん - ちゃーしがぬURLふくごうなやびらんたん ウェブサイトこーいしちなやびらんたん コンテンツがいようなやびらん ふずんメニューしっていなやびらんたん diff --git a/app/src/main/res/values-sc/strings.xml b/app/src/main/res/values-sc/strings.xml index 1e915a3c0..f26907158 100644 --- a/app/src/main/res/values-sc/strings.xml +++ b/app/src/main/res/values-sc/strings.xml @@ -374,7 +374,6 @@ Impostatzione de su menù de iscarrigamentu fallida Cuntenutu no a disponimentu Anàlisi de su situ web fallida - Detziframentu de sa firma URL de su vìdeu fallida No est istadu possìbile carrigare totu sas miniaduras Errore de retza Impossìbile iscarrigare in s\'ischeda SD esterna. Cheres resetare sa positzione de sa cartella de iscarrigamentu\? diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml index 9d6117bb9..4677b1b01 100644 --- a/app/src/main/res/values-sk/strings.xml +++ b/app/src/main/res/values-sk/strings.xml @@ -39,7 +39,6 @@ Chyba Chyba siete Nemožno zobraziť všetky náhľady - Nepodarilo sa dekódovať URL videa Nemožno analyzovať webovú stránku Obsah nie je dostupný Prehrať video, dĺžka: diff --git a/app/src/main/res/values-sl/strings.xml b/app/src/main/res/values-sl/strings.xml index be6027620..cf96136a6 100644 --- a/app/src/main/res/values-sl/strings.xml +++ b/app/src/main/res/values-sl/strings.xml @@ -43,7 +43,6 @@ Izberite mapo za prenos avdio datotek Napaka Vseh sličic videov ni mogoče naložiti - Ni mogoče odšifrirati podpisa naslova URL videa Ni mogoče razčleniti spletišča Vsebina ni na voljo Ni mogoče nastaviti menija za prejem datotek diff --git a/app/src/main/res/values-so/strings.xml b/app/src/main/res/values-so/strings.xml index f36983526..4ba720595 100644 --- a/app/src/main/res/values-so/strings.xml +++ b/app/src/main/res/values-so/strings.xml @@ -289,7 +289,6 @@ Lama soo kicin karo tusmada dajinta shaygan lama heli karo Lama furi karo website-ka - Lama baddali karo sixiixa tixraaca muuqaalka Lama soo wada kicin karo galalkoo dhan khalad xaga khadka ah Ku dajinta kaydka dibadda (mimoriga) suurtogal ma aha. Dib u fadhiisi khaanada wax lagu dajiyo\? diff --git a/app/src/main/res/values-sq/strings.xml b/app/src/main/res/values-sq/strings.xml index ab5b914fe..334f516db 100644 --- a/app/src/main/res/values-sq/strings.xml +++ b/app/src/main/res/values-sq/strings.xml @@ -401,7 +401,6 @@ Nuk u arrit të vendosej menuja e shkarkimeve Përmbajtja e padisponueshme Nuk u arrit të analizohej faqja - Nuk u arrit të dekriptohej firma e URL së videos Nuk u mundën të ngarkoheshin të gjitha pamjet statike Problem rrjeti Shkarkimi në kartën SD të jashtme nuk ishte i mundur. Doni të rivendosni vendndodhjen e dosjes së shkarkimeve\? diff --git a/app/src/main/res/values-sr/strings.xml b/app/src/main/res/values-sr/strings.xml index ddb07544b..5926446f4 100644 --- a/app/src/main/res/values-sr/strings.xml +++ b/app/src/main/res/values-sr/strings.xml @@ -43,7 +43,6 @@ Преузети аудио записи се чувају овде Грешка Не могу да учитам све сличице - Не могу да дешифрујем потпис видео урл-а Не могу да рашчланим веб-сајт Садржај је недоступан Садржај diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index 939f5aa5c..66d6896f7 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -100,7 +100,6 @@ NewPipe avisering Aviseringar för NewPipes spelare [Okänd] - Kunde inte dekryptera video URL signatur Misslyckades med att spela denna ström Allvarligt spelarfel inträffade Återhämtar sig från spelarfel diff --git a/app/src/main/res/values-ta/strings.xml b/app/src/main/res/values-ta/strings.xml index 0383d7197..9b97445e1 100644 --- a/app/src/main/res/values-ta/strings.xml +++ b/app/src/main/res/values-ta/strings.xml @@ -362,7 +362,6 @@ அறிவிப்புகள் வீடியோ ஹாஷ் அறிவிப்பு புதிய நீரோடைகள் - வீடியோ URL கையொப்பத்தை நீக்க முடியவில்லை வீடியோ ஹேஷிங் முன்னேற்றத்திற்கான அறிவிப்புகள் சந்தாவுக்கான புதிய ஸ்ட்ரீம்கள் பற்றிய அறிவிப்புகள் இந்த வீடியோ வயது வரம்புக்குட்பட்டது. diff --git a/app/src/main/res/values-te/strings.xml b/app/src/main/res/values-te/strings.xml index 86f3e17c2..edfb85ade 100644 --- a/app/src/main/res/values-te/strings.xml +++ b/app/src/main/res/values-te/strings.xml @@ -263,7 +263,6 @@ ప్లేబ్యాక్ స్థానాలు తొలగించబడ్డాయి బాహ్య ప్లేయర్‌లు ఈ రకమైన లింక్‌లకు మద్దతు ఇవ్వవు చెక్సమ్ - వీడియో URL సంతకాన్ని డీఓబ్‌ఫస్కేట్ చేయడం సాధ్యపడలేదు GitHubపై నివేదించు ఇక్కడ క్రికెట్‌లు తప్ప మరేమీ లేదు ఎవరూ వినడం లేదు diff --git a/app/src/main/res/values-th/strings.xml b/app/src/main/res/values-th/strings.xml index 17f20c1e4..f68e2f635 100644 --- a/app/src/main/res/values-th/strings.xml +++ b/app/src/main/res/values-th/strings.xml @@ -131,7 +131,6 @@ การดาวน์โหลดไปยังการ์ดความจำภายนอกยังไม่สามารถทำได้ รีเซ็ตตำแหน่งโฟลเดอร์ดาวน์โหลดหรือไม่\? ข้อผิดพลาดของเครือข่าย ไม่สามารถโหลดรูปขนาดย่อทั้งหมด - ไม่สามารถถอดรหัสลายเซ็น URL ของวิดีโอ ไม่สามารถแยกวิเคราะห์เว็บไซต์ เนื้อหาไม่พร้อมใช้งาน ไม่สามารถตั้งค่าเมนูดาวน์โหลด diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index 52f4d7697..7aa143c47 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -46,7 +46,6 @@ Hata Ağ hatası Küçük resimlerin tamamı yüklenemedi - Video URL imzasının şifresi çözülemedi Web sitesi ayrıştırılamadı İçerik kullanılamıyor Uygulama/kullanıcı arayüzü çöktü diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index d65e1e435..193a1c74f 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -42,7 +42,6 @@ Помилка Помилка мережі Не вдалося завантажити всі ескізи - Не вдалося розшифрувати URL-підпис відео Не вдалося проаналізувати вебсайт Вміст недоступний Не вдалося налаштувати меню завантаження diff --git a/app/src/main/res/values-ur/strings.xml b/app/src/main/res/values-ur/strings.xml index 9632f5ff4..8f66fd836 100644 --- a/app/src/main/res/values-ur/strings.xml +++ b/app/src/main/res/values-ur/strings.xml @@ -111,7 +111,6 @@ خرابی نیٹ ورک کی خرابی تمام نظرِ انگشتی لوڈ نہیں کر سکے - ویڈیو یو آر ایل کے دستخط ڈکرپٹ نہیں ہو سکے ویب سائٹ کو تجزیہ نہیں کیا جاسکا مواد دستیاب نہیں ہے ڈاؤن لوڈ مینو ترتیب نہیں دے سکتے diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index 7f38d3c34..885487489 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -62,7 +62,6 @@ Lỗi Lỗi kết nối mạng Không thể tải tất cả hình thu nhỏ - Không thể giải mã chữ ký URL video Không thể phân tích cú pháp trang web Nội dung không khả dụng Không thể thiết lập menu tải về diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index b663b1953..2c6ce4f06 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -138,7 +138,6 @@ 反馈错误 错误 无法加载所有缩略图 - 无法解密视频的 URL 签名 无法解析网址 内容不可用 无法设置下载菜单 diff --git a/app/src/main/res/values-zh-rHK/strings.xml b/app/src/main/res/values-zh-rHK/strings.xml index 01eb91a8c..1292aeaf9 100644 --- a/app/src/main/res/values-zh-rHK/strings.xml +++ b/app/src/main/res/values-zh-rHK/strings.xml @@ -47,7 +47,6 @@ 實況 問題 載入唔晒全部縮圖 - 影片 URL 簽章解唔到碼 解析唔到網站 設定唔到下載功能表 啫係嗱,世事講唔埋嘅,真係唔好意思。 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 18d67f34f..00d257d1c 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -66,7 +66,6 @@ 最佳解析度 錯誤 無法載入所有縮圖 - 無法解析影片 URL 簽章 無法解析網站 內容無法使用 無法設定下載選單 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 9a533f6b8..d2d4a2314 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -229,7 +229,6 @@ Downloading to external SD card not possible. Reset download folder location? Network error Could not load all thumbnails - Could not deobfuscate video URL signature Could not parse website Content unavailable Could not set up download menu From 4c4f9b45d996b633f7b3f304bb8e65432e14be4c Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Thu, 21 Sep 2023 15:40:17 +0200 Subject: [PATCH 103/172] Translated using Weblate (Kazakh) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 0.5% (4 of 702 strings) Translated using Weblate (Kazakh) Currently translated at 6.6% (5 of 75 strings) Translated using Weblate (Punjabi) Currently translated at 100.0% (702 of 702 strings) Translated using Weblate (Hindi) Currently translated at 100.0% (702 of 702 strings) Merge branch 'origin/dev' into Weblate. Translated using Weblate (Spanish) Currently translated at 100.0% (702 of 702 strings) Translated using Weblate (ryu (generated) (ryu)) Currently translated at 100.0% (702 of 702 strings) Translated using Weblate (Hebrew) Currently translated at 100.0% (702 of 702 strings) Translated using Weblate (Japanese) Currently translated at 100.0% (702 of 702 strings) Translated using Weblate (Greek) Currently translated at 99.8% (701 of 702 strings) Translated using Weblate (Japanese) Currently translated at 98.2% (690 of 702 strings) Translated using Weblate (Serbian) Currently translated at 100.0% (702 of 702 strings) Translated using Weblate (Italian) Currently translated at 100.0% (702 of 702 strings) Translated using Weblate (German) Currently translated at 80.0% (60 of 75 strings) Translated using Weblate (German) Currently translated at 100.0% (702 of 702 strings) Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (702 of 702 strings) Translated using Weblate (Chinese (Simplified)) Currently translated at 100.0% (702 of 702 strings) Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (702 of 702 strings) Translated using Weblate (Polish) Currently translated at 100.0% (702 of 702 strings) Translated using Weblate (Ukrainian) Currently translated at 100.0% (702 of 702 strings) Translated using Weblate (Indonesian) Currently translated at 100.0% (702 of 702 strings) Translated using Weblate (Greek) Currently translated at 97.8% (687 of 702 strings) Translated using Weblate (Serbian) Currently translated at 98.5% (692 of 702 strings) Translated using Weblate (German) Currently translated at 99.5% (699 of 702 strings) Translated using Weblate (Odia) Currently translated at 100.0% (686 of 686 strings) Translated using Weblate (Portuguese (Portugal)) Currently translated at 100.0% (686 of 686 strings) Translated using Weblate (Serbian) Currently translated at 100.0% (686 of 686 strings) Translated using Weblate (Indonesian) Currently translated at 99.8% (685 of 686 strings) Translated using Weblate (Czech) Currently translated at 100.0% (686 of 686 strings) Translated using Weblate (Serbian) Currently translated at 100.0% (686 of 686 strings) Translated using Weblate (Punjabi) Currently translated at 100.0% (686 of 686 strings) Translated using Weblate (Hindi) Currently translated at 100.0% (686 of 686 strings) Translated using Weblate (Odia) Currently translated at 100.0% (686 of 686 strings) Translated using Weblate (Punjabi) Currently translated at 100.0% (686 of 686 strings) Translated using Weblate (Hindi) Currently translated at 100.0% (686 of 686 strings) Translated using Weblate (Hungarian) Currently translated at 99.7% (684 of 686 strings) Translated using Weblate (Punjabi) Currently translated at 100.0% (686 of 686 strings) Translated using Weblate (Serbian) Currently translated at 100.0% (686 of 686 strings) Translated using Weblate (Hindi) Currently translated at 100.0% (686 of 686 strings) Translated using Weblate (Serbian) Currently translated at 100.0% (686 of 686 strings) Translated using Weblate (Serbian) Currently translated at 16.0% (12 of 75 strings) Translated using Weblate (Galician) Currently translated at 99.5% (683 of 686 strings) Translated using Weblate (Serbian) Currently translated at 100.0% (686 of 686 strings) Translated using Weblate (Serbian) Currently translated at 100.0% (686 of 686 strings) Translated using Weblate (Serbian) Currently translated at 100.0% (686 of 686 strings) Translated using Weblate (Serbian) Currently translated at 16.0% (12 of 75 strings) Translated using Weblate (Bengali) Currently translated at 83.8% (575 of 686 strings) Translated using Weblate (Azerbaijani) Currently translated at 100.0% (686 of 686 strings) Translated using Weblate (Turkish) Currently translated at 100.0% (686 of 686 strings) Translated using Weblate (Serbian) Currently translated at 100.0% (686 of 686 strings) Translated using Weblate (Dutch) Currently translated at 100.0% (686 of 686 strings) Co-authored-by: Agnieszka C Co-authored-by: Aidos Co-authored-by: Daniel Rozario Co-authored-by: Emin Tufan Çetin Co-authored-by: Eric Co-authored-by: Fjuro Co-authored-by: GET100PERCENT Co-authored-by: GnuPGを使うべきだ Co-authored-by: Hosted Weblate Co-authored-by: Igor Rückert Co-authored-by: Ihor Hordiichuk Co-authored-by: Jeff Huang Co-authored-by: Linerly Co-authored-by: NEXI Co-authored-by: Nidi Co-authored-by: Philip Goto Co-authored-by: Random Co-authored-by: ShareASmile Co-authored-by: Subham Jena Co-authored-by: Tibor Botfai (gidano) Co-authored-by: TobiGr Co-authored-by: Vasilis K Co-authored-by: VfBFan Co-authored-by: WB Co-authored-by: Yaron Shahrabani Co-authored-by: gallegonovato Co-authored-by: kuragehime Co-authored-by: nexi Co-authored-by: ssantos Co-authored-by: zmni Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/de/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/kk/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/sr/ Translation: NewPipe/Metadata --- app/src/main/res/values-az/strings.xml | 10 +- app/src/main/res/values-bn/strings.xml | 15 +- app/src/main/res/values-de/strings.xml | 31 +- app/src/main/res/values-el/strings.xml | 16 + app/src/main/res/values-es/strings.xml | 18 +- app/src/main/res/values-gl/strings.xml | 7 +- app/src/main/res/values-he/strings.xml | 16 + app/src/main/res/values-hi/strings.xml | 544 ++++++------ app/src/main/res/values-hu/strings.xml | 5 + app/src/main/res/values-in/strings.xml | 18 + app/src/main/res/values-it/strings.xml | 16 + app/src/main/res/values-ja/strings.xml | 16 + app/src/main/res/values-kk/strings.xml | 7 +- app/src/main/res/values-nl/strings.xml | 4 +- app/src/main/res/values-or/strings.xml | 6 +- app/src/main/res/values-pa/strings.xml | 226 ++--- app/src/main/res/values-pl/strings.xml | 16 + app/src/main/res/values-pt-rBR/strings.xml | 16 + app/src/main/res/values-pt-rPT/strings.xml | 2 + app/src/main/res/values-ryu/strings.xml | 16 + app/src/main/res/values-sr/strings.xml | 800 +++++++++++------- app/src/main/res/values-tr/strings.xml | 19 +- app/src/main/res/values-uk/strings.xml | 16 + app/src/main/res/values-zh-rCN/strings.xml | 16 + app/src/main/res/values-zh-rTW/strings.xml | 16 + .../metadata/android/de/changelogs/977.txt | 6 +- .../metadata/android/kk/changelogs/63.txt | 8 + .../metadata/android/kk/changelogs/64.txt | 8 + .../metadata/android/kk/changelogs/65.txt | 24 + .../metadata/android/sr/changelogs/994.txt | 15 + .../metadata/android/sr/full_description.txt | 2 +- .../metadata/android/sr/short_description.txt | 2 +- 32 files changed, 1202 insertions(+), 735 deletions(-) create mode 100644 fastlane/metadata/android/kk/changelogs/63.txt create mode 100644 fastlane/metadata/android/kk/changelogs/64.txt create mode 100644 fastlane/metadata/android/kk/changelogs/65.txt create mode 100644 fastlane/metadata/android/sr/changelogs/994.txt diff --git a/app/src/main/res/values-az/strings.xml b/app/src/main/res/values-az/strings.xml index 4a3305e3b..40e802ce7 100644 --- a/app/src/main/res/values-az/strings.xml +++ b/app/src/main/res/values-az/strings.xml @@ -268,7 +268,7 @@ Əlaqəli elementlər Baxılmış kimi işarələ ilə aç - Gecə Teması + Gecə teması Ani pəncərə xüsusiyyətlərini xatırla Ani pəncərənin son ölçüsü və mövqeyini xatırla Video yayımı tapılmadı @@ -657,7 +657,7 @@ Hələ,əlfəcinlənmiş pleylistlər yoxdur Bu, cari quraşdırmanızı ləğv edəcək. Növbəyə qoy - Qara ekranla qarşılaşsanız və ya videonu oynatdıqda səs qırılarsa, media tunelini deaktiv edin + Qara ekranla qarşılaşsanız və ya videonu oynatdıqda səs pozularsa, media tunelin qeyri-aktiv edin Növbəti sıraya salındı Fonda oynatmağa başla Yayım təfərrüatları yüklənir… @@ -756,4 +756,10 @@ təsviri Həmişə ExoPlayer-in video çıxış səthi tənzimləməsin istifadə et Qabaqcıl məzmunda yükləmə aralığı həcmin dəyişdir (hazırda %s). Daha aşağı dəyər onların ilkin yüklənilməsin sürətləndirə bilər + Yayım yoxdur + Canlı yayım yoxdur + Media tunelləmə cihazınızda standart olaraq qeyri-aktiv edilib, çünki cihazınızın modelinin bunu dəstəkləmədiyi məlumdur. + %1$s %2$s + Əsas səhifə mövqeyi + Əsas səhifə seçicini aşağıya köçür \ No newline at end of file diff --git a/app/src/main/res/values-bn/strings.xml b/app/src/main/res/values-bn/strings.xml index 46d9a171d..47425bb56 100644 --- a/app/src/main/res/values-bn/strings.xml +++ b/app/src/main/res/values-bn/strings.xml @@ -278,7 +278,7 @@ সেটিংস খুঁজুন স্ট্রিম ফাইল ডাউনলোড করুন - ডাউনলোউড + ডাউনলোড শেয়ার ভাসমান অবস্থায় খুলো ব্রাউজারে খুলো @@ -342,7 +342,7 @@ রিক্যাপচা কুকিগুলো পরিষ্কার করা হয়েছে হ্যাঁ, এবং আংশিকভাবে দেখা ভিডিও ব্যবস্থা দ্বারা ক্রিয়া অস্বীকার করা হয়েছে - "স্বয়ংক্রিয়ভাবে প্লেব্যাক শুরু করো %s — তে" + স্বয়ংক্রিয়ভাবে প্লেব্যাক শুরু করো %s — তে একটি পপ-আপে প্লে শুরু করো পটভূমিতে প্লে শুরু করো অ্যান্ড্রয়েডে মুক্তভাবে ও সহজে প্রচার দেখার অ্যাপ। @@ -531,7 +531,8 @@ রিক্যাপচা পূরণ করলে নিউপাইপ যেসব কুকি রাখে তা মুছো ধারা ভুক্তিতে সেবাগুলোর মূল লেখা দৃশ্যমান হবে অনুসন্ধান ইতিহাস থেকে এই ভুক্তিটি মুছবে\? - প্রত্যেক ডাউনলোড কোথায় রাখা হবে তা জিজ্ঞেস করা হবে + প্রত্যেক ডাউনলোড কোথায় রাখা হবে তা জিজ্ঞেস করা হবে। +\nমেমোরি কার্ডে ডাউনলোড করতে সিস্টেম ফোল্ডার পিকার (SAF) এনেবল করুন এই নামের একটি ডাউনলোড চলমান অ্যাপ আবার শুরু হলে ভাষা পাল্টাবে মিডিয়া সুরঙ্গকরণ অক্ষম @@ -566,8 +567,8 @@ বন্ধ চালু - ডাউনলোড সমাপ্ত - %sটি ডাউনলোড সমাপ্ত + ডাউনলোড শেষ + %sটি ডাউনলোড শেষ দেখা হয়েছে চিহ্নিত করো চালক বিজ্ঞপ্তি @@ -623,8 +624,8 @@ ত্রুটি স্ন্যাকবার দেখাও নতুন সংস্করণের জন্য নিজে দেখো - %1$sটি ডাউনলোড মুছা হয়েছে - %1$sটি ডাউনলোড মুছা হয়েছে + %1$sটি ডাউনলোড মোছা হয়েছে + %1$sটি ডাউনলোড মোছা হয়েছে \"চালক বন্ধ করো\" দেখাও বিজ্ঞপ্তি নিষ্ক্রিয় diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 1ef6fc656..efa451fce 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -171,7 +171,7 @@ Audio-Einstellungen Konnte diesen Stream nicht abspielen Inhalt der Hauptseite - Kanal-Seite + Kanalseite Details Top 50 Nicht behebbarer Wiedergabefehler aufgetreten @@ -205,7 +205,7 @@ Video-Player Wiedergabe im Hintergrund Popup-Player - Informationen werden abgerufen … + Erhalte Informationen … Gewünschten Inhalt laden Datenbank importieren Datenbank exportieren @@ -494,15 +494,15 @@ Zeit nach der letzten Aktualisierung, bevor ein Abonnement als veraltet angesehen wird — %s Schnellmodus aktivieren Schnellmodus deaktivieren - Abos zuletzt aktualisiert: %s + Feed zuletzt aktualisiert: %s Grenzwert für Feed-Aktualisierung - Aus fest zugeordnetem Feed abholen wenn verfügbar + Aus fest zugeordnetem Feed abrufen wenn verfügbar Steht in manchen Diensten zur Verfügung, ist meist viel schneller, liefert aber eventuell eine eingeschränkte Anzahl an Elementen und oft unvollständige Informationen (z. B. keine Videolänge, keinen Elementtyp, keinen Live-Status) Glaubst du, dass das Laden von Feeds zu langsam ist\? Wenn ja, versuche den Schnelllademodus einzuschalten (du kannst ihn in den Einstellungen oder über die Schaltfläche unten ändern). \n \nNewPipe bietet zwei Feed-Ladestrategien: -\n• die Abholung des gesamten abonnierten Kanals, was langsam aber vollständig geschieht. -\n• die Verwendung eines fest zugeordneten Serviceendpunkts, was schnell aber für gewöhnlich inkomplett ist. +\n• das Abrufen des gesamten abonnierten Kanals, was langsam aber vollständig geschieht. +\n• das Verwenden eines fest zugeordneten Serviceendpunkts, was schnell aber für gewöhnlich inkomplett ist. \n \nDer Unterschied zwischen den beiden ist, dass der schnellen normalerweise einige Informationen fehlen, wie die Dauer oder der Typ des Elements (keine Unterscheidung zwischen Live-Videos und normalen) und sie eventuell weniger Elemente liefert. \n @@ -573,7 +573,7 @@ Vorschaubild anzeigen Hash wird berechnet Benachrichtigungen über den Hashing-Fortschritt von Videos - Video-Hash Benachrichtigung + Video-Hash-Benachrichtigung Letzte Metadaten anzeigen Ausschalten, um Metadaten-Felder mit zusätzlichen Informationen zu Stream-Ersteller, -Inhalten oder einer Suchanfrage auszublenden @@ -601,7 +601,7 @@ Wähle dein bevorzugtes Nachtdesign – %s Automatisch (Gerätedesign) Nachtdesign - Kanal-Details anzeigen + Kanaldetails anzeigen Deaktiviere das Media-Tunneling, wenn bei der Videowiedergabe ein schwarzer Bildschirm oder Stottern auftritt. Media-Tunneling deaktivieren Intern @@ -624,7 +624,7 @@ \nNewPipe wird diesen Feed in Zukunft nicht mehr laden können. \nMöchtest du dich von diesem Kanal abmelden\? Konto geschlossen - Der Schnelllademodus liefert hierzu keine weiteren Informationen. + Der Schnellmodus liefert hierzu keine weiteren Informationen. Noch kein Downloadordner festgelegt, wähle jetzt den Standard-Downloadordner Webseite öffnen Ab Android 10 wird nur noch „Storage Access Framework“ unterstützt @@ -662,7 +662,7 @@ \"Player abstürzen lassen\" anzeigen Player abstürzen lassen Zeigt eine Absturzoption an, wenn der Player verwendet wird - Benachrichtigung über Fehlerberichte + Fehlerbericht-Benachrichtigung Benachrichtigungen zur Meldung von Fehlern Bei NewPipe ist ein Fehler aufgetreten. Zum Melden antippen Ein Fehler ist aufgetreten, siehe die Benachrichtigung @@ -682,7 +682,7 @@ %s neuer Stream %s neue Streams - Stream-Details laden … + Lade Stream-Details … Über neue Streams aus Abonnements benachrichtigen , Jedes Netzwerk @@ -709,7 +709,7 @@ Häufig gestellte Fragen Wenn du Probleme bei der Verwendung der App hast, lies bitte die Antworten auf häufig gestellte Fragen! Sortieren - Schneller Modus + Schnellmodus Du verwendest die neueste Version von NewPipe Antippen um %s herunterzuladen Importieren oder Exportieren von Abonnements über das 3-Punkte-Menü @@ -771,4 +771,11 @@ Alben Tabs auf den Kanalseiten Welche Tabs auf den Kanalseiten angezeigt werden + Lade Metadaten … + Über + Banner-URL + Avatar-URL + Tabs der Kanalseiten abrufen + Tabs, die beim Aktualisieren des Feeds abgerufen werden. Diese Option hat keine Auswirkungen, wenn ein Kanal im Schnellmodus aktualisiert wird. + Titel \ No newline at end of file diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index b4d602ba4..e9a2a5615 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -762,4 +762,20 @@ Το media tunneling απενεργοποιήθηκε από προεπιλογή στη συσκευή σας, επειδή το μοντέλο της συσκευής σας είναι γνωστό ότι δεν το υποστηρίζει. Καμία ζωντανή ροή Καμία ροή + Φόρτωση μεταδεδομένων… + Βίντεο + Συνδρομητές + Ποιες καρτέλες εμφανίζονται στις σελίδες των καναλιών + Καρτέλες καναλιών + Shorts + Λήψη καρτελών καναλιών + Σχετικά + Banner URL + Άλμπουμ + Καρτέλες για ανάκτηση κατά την ενημέρωση της ροής. Αυτή η επιλογή δεν έχει καμία επίδραση εάν ένα κανάλι ενημερώνεται χρησιμοποιώντας τη γρήγορη λειτουργία. + URL άβαταρ + Λίστες + Κομμάτια + Κανάλια + Ζωντανά \ No newline at end of file diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index b5e9b1a6e..6499a6004 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -494,7 +494,7 @@ Nombre de grupo vacío ¿Borrar este grupo\? Nuevo - Contenido + Fuente Velocidad de actualización del contenido Tiempo para que una suscripción se considere desactualizada — %s Actualizar siempre @@ -778,4 +778,20 @@ Como se sabe que este dispositivo no es compatible con la tunelización de medios, esta función está desactivada de forma predeterminada. Sin retransmisiones Sin transmisiones en directo + Vídeos + Suscriptores + Qué pestañas se muestran en las páginas de los canales + Pestañas del canal + Cortos + Cargando los metadatos… + Recuperar las fichas del canal + Acerca de + Dirección url del anuncio + Álbumes + Pestañas para recuperar al actualizar el canal. Esta opción no tiene efecto si el canal se actualiza en modo rápido. + Dirección url del avatar + Listas de reproducción + Pistas + Canales + En directo \ No newline at end of file diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml index c4a702aa3..0778a8ee6 100644 --- a/app/src/main/res/values-gl/strings.xml +++ b/app/src/main/res/values-gl/strings.xml @@ -588,7 +588,7 @@ Desactíveo para ocultar a descrición do vídeo e a información adicional Ver descrición Pedir confirmación antes de baleirar unha cola - Tema Escuro + Tema escuro Nada Abrir con Non listado @@ -628,7 +628,7 @@ Miniatura na barra de busca Mostrar indicadores de imaxe - Desactive o túnel multimedia se experimentaren unha pantalla en negro ou interrupcións na reprodución + Desactive o túnel multimedia se experimentar unha pantalla en negro ou interrupcións na reprodución. Desactivar túnel multimedia Engadido á cola Cartafol de descarga aínda non definido, escolla o cartafol agora @@ -709,7 +709,7 @@ Se tes problemas para usala aplicación, asegúrate de consultar estas respostas ás preguntas comúns! Ordenar Modo rápido - Estás executandola última versión de NewPipe + Estás executando a última versión de NewPipe Toca para descargar %s Importa ou exporta subscricións dende o menú dos 3 puntos Esta opción só está dispoñible se %s está seleccionado para o tema @@ -757,4 +757,5 @@ Mova o selector da lapela principal para a parte inferior Posición prinicipal das lapelas A tunelización da multimedia foi deshabilitada por defecto, porque o seu modelo de dispositivo carece de soporte. + Sen emisións \ No newline at end of file diff --git a/app/src/main/res/values-he/strings.xml b/app/src/main/res/values-he/strings.xml index e7469bf5d..076844339 100644 --- a/app/src/main/res/values-he/strings.xml +++ b/app/src/main/res/values-he/strings.xml @@ -788,4 +788,20 @@ תיעול מדיה הושבת כברירת מחדל במכשיר שלך כיוון שדגם המכשיר ידוע בכך שאינו תומך בזה. אין תזרימים חיים אין תזרימים + סרטונים + מנויים + אין לשוניות מופיעות בעמודי הערוץ + לשוניות ערוץ + Shorts + נתוני העל נטענים… + משיכת לשוניות הערוץ + על אודות + כתובת כרזה + אלבומים + לשוניות למשיכה בעת עדכון ערוץ העדכונים. לאפשרות זו אין השפעה אם הערוץ מתעדכן במצב מהיר. + כתובת תמונה ייצוגית + רשימות נגינה + רצועות + ערוצים + שידור חי \ No newline at end of file diff --git a/app/src/main/res/values-hi/strings.xml b/app/src/main/res/values-hi/strings.xml index 1c0074229..7b16281eb 100644 --- a/app/src/main/res/values-hi/strings.xml +++ b/app/src/main/res/values-hi/strings.xml @@ -1,135 +1,135 @@ %1$s पे प्रकाशित हुआ - स्ट्रीमिंग के लिए चालक नहीं मिला। क्या आप वीएलसी इंस्टॉल करना चाहेंगे\? - स्थापित करें + स्ट्रीमिंग के लिए प्लेयर नहीं मिला। क्या आप वीएलसी इंस्टॉल करना चाहेंगे\? + इंस्टॉल करें ब्राउज़र में खोलें पॉपअप मोड में खोलें शेयर करें - डाउनलोड करे + डाउनलोड करें खोजें सेटिंग्स सब्सक्राइब करें - सब्सक्राइड है + सब्सक्राइब है चैनल अनसब्सक्राईब हुआ सब्सक्रिप्शनस बैकग्राउंड पॉपअप - ध्वनि + ऑडियो रौशनी काला देखे हुए वीडियोज़ का इतिहास - डाउनलोड करे + डाउनलोड करें वीडियो और ऑडियो इतिहास और कैश बैकग्राउंड में चल रहा है कोई विऊ नहीं - कोई वीडियो नहीं है - न्यूपाइप के बारे में जाने + कोई वीडियो नहीं + न्यूपाइप के बारे में जानें तृतीय-पक्ष लाइसेंस ऐप के बारे में और सामान्य प्रश्न लाइसेंस - गिटहब में देखें + गिटहब पर देखें न्यूपाइप का लाइसेंस लाइसेंस पढ़ें योगदान करें इतिहास इतिहास फ़िलहाल चर्चा में है - ऑडियो सेटिंग + ऑडियो सेटिंग्स आरंभ करने के लिए आवर्धक कांच को स्पर्श करें। रद्द करें क्या आप का मतलब \"%1$s\" था\? - के साथ शेयर करे - कोई दूसरा वीडियो चालक प्रयोग करें - कुछ वीडियो गुणवत्ता स्तर पर ध्वनि हट सकती है - कोई दूसरा ध्वनि चालक उपयोग करें + के साथ शेयर करें + बाहरी वीडियो प्लेयर का उपयोग करें + कुछ रिजॉल्युशनों पर ध्वनि हट सकती है + बाहरी ऑडियो प्लेयर का उपयोग करें सब्सक्रिप्शन बदली नहीं जा सकी सब्सक्रिप्शन अपडेट नहीं किया जा सका क्या नया है - वीडियो डाउनलोड का फ़ोल्डर - डाउनलोड की गई वीडियो फ़ाइलें यहां संग्रहीत हैं + वीडियो के लिए डाउनलोड फ़ोल्डर + डाउनलोड की गई वीडियो फ़ाइलें यहां संग्रहित होती हैं वीडियो फ़ाइलों के लिए डाउनलोड फ़ोल्डर चुनें - ध्वनि डाउनलोड फ़ोल्डर - डाउनलोड की गई ध्वनि फ़ाइलें यहां संग्रहीत हैं - ध्वनि फ़ाइलों के लिए डाउनलोड फ़ोल्डर चुनें - प्रथम स्थापित गुणवत्ता स्तर - पॉपअप का प्रथम स्थापित गुणवत्ता स्तर - उच्च गुणवत्ता स्तर दिखाएं - केवल कुछ ही डिवाईस 2के/4के मे वीडियो चला सकते हैं - कोडी मे चलाए - गैर- मौजूदा Kore ऐप स्थापित करें\? - \"कोडी मे चलाएं\" वाला विकल्प दिखाएँ - कोडी मीडिया सेंटर से वीडियो चलने के लिए विकल्प प्रदर्शित करें - प्रथम स्थापित ध्वनि फॉर्मेट - प्रथम स्थापित वीडियो फॉर्मेट - ऐप थीम + ऑडियो के लिए डाउनलोड फ़ोल्डर + डाउनलोड की गई ऑडियो फ़ाइलें यहां संग्रहित होती हैं + ऑडियो फ़ाइलों के लिए डाउनलोड फ़ोल्डर चुनें + डिफ़ॉल्ट रिजॉल्युशन + पॉपअप का डिफ़ॉल्ट रिजॉल्युशन + उच्च रिजॉल्युशन दिखाएं + केवल कुछ ही डिवाईस 2K/4K में वीडियो चला सकते हैं + Kodi में चलाएं + गैर- मौजूदा Kore ऐप इंस्टॉल करें\? + \"Kodi में चलाएं\" वाला विकल्प दिखाएँ + Kodi मीडिया सेंटर से वीडियो चलने के लिए विकल्प प्रदर्शित करें + डिफ़ॉल्ट ऑडियो फॉर्मेट + डिफ़ॉल्ट वीडियो फॉर्मेट + थीम गहरा - वीडियो पॉपअप का आकार और उसकी स्थिति को याद रखें + वीडियो पॉपअप के गुणस्वभाव को याद रखें वीडियो पॉपअप की अंतिम स्थिति और आकार को याद रखें खोज में सुझाव - खोज के दौरान दिखाये जाने वाले सुझाव चुने + खोज के दौरान दिखाये जाने वाले सुझाव चुनें खोज का इतिहास - खोज के डेटा को सिर्फ डिवाइस मेमोरी में रखे + खोज क्वेरीज़ को स्थानीय रूप से संग्रहित करें देखे गए वीडियोज़ की सूची रखें प्लेबैक फिर से शुरू करें - रुकावटें खत्म होने के बाद वीडियो प्ले करें (जैसे - फ़ोन कॉल) - \'अगला\' और \'समान\' वीडियो दिखाए + रुकावटें (जैसे कि फ़ोन कॉल) खत्म होने के बाद वीडियो प्ले जारी रखें + \'अगला\' और \'समान\' वीडियो दिखाएं \"कतार में जोड़ने के लिए स्पर्श बनाये रखें\" दिखाएं जब बैकग्राउंड और पॉपअप बटन वीडियो के विवरण पन्ने में दबाई जाए तो सलाह दिखाएं असमर्थित URL - डिफ़ॉल्ट विषय की भाषा + डिफ़ॉल्ट सामग्री की भाषा प्लेयर - चाल चलन + व्यवहार दिखावट - वीडियो पॉपअप के अंदाज में चल रहा + वीडियो पॉपअप के अंदाज में चल रहा है विषयवस्तु आयु प्रतिबंधित सामग्री दिखाएं लाइव - डाउनलोड - डाउनलोड + डाउनलोडस + डाउनलोडस त्रुटी की रिपोर्ट - सारे - बंद करे - साफ़ - बेहतर वीडियो की क्वालिटी - वापस जाएँ - सारे प्ले करे - NewPipe की सूचनापत्र - न्यूपाइप के बैकग्राउंड में चल रहे वीडियो और पॉपअप वीडियो के लिए सूचनापत्र - [नहीं जानते] + सभी + बंद किया + साफ करें + उत्तम रिजॉल्युशन + वापिस + सभी प्ले करें + न्यूपाइप की नोटीफिकेशन + न्यूपाइप के बैकग्राउंड और पॉपअप प्लेयर के लिए नोटीफिकेशन + [अज्ञात] त्रुटी नेटवर्क में त्रुटी - सारे thumbnail(फोटो जो फ़ोन की मेमोरी में है ) भरे नहीं जा सकते - इस website का निरंक्षण नहीं कर सकते + सभी थंमनेल लोड नहीं किए जा सके + वैबसाइट parse नहीं हो सकी विषय वस्तु उपलब्ध नहीं है - डाउनलोड मेनू को स्थापित नहीं कर सकते - APP/UI टूट गया + डाउनलोड मेनू स्थापित नहीं किया जा सका + APP/UI करैश हो गई इस वीडियो को चलाने में असफल हुए - कभी ठीक न होने वाले वीडियो प्लेयर की त्रुटी आ रही है + अनचाही वीडियो प्लेयर त्रुटी आयी है वीडियो प्लेयर त्रुटी से ठीक हो रहा है - खेद है की, ऐसा होना नहीं चाहिए था. - रिपोर्ट को ईमेल से भेजे - माफ़ करे, कुछ त्रुटि हो गई। + खेद है, कि ऐसा होना नहीं चाहिए था। + रिपोर्ट को ईमेल से भेजें + माफ़ करें, कुछ त्रुटि हो गई। रिपोर्ट करें जानकारी: क्या हुआ: क्या:\\nअनुरोध:\\nसामग्री भाषा:\\nसामग्री देश:\\nऐप भाषा:\\nसेवा:\\nजीएमटी समय:\\nपैकेज:\\nसंस्करण:\\nOS संस्करण: - आपकी टिप्पणी: + आपकी टिप्पणी(अंग्रेजी में): विवरण: - वीडियो चलाये, समय : - अपलोडर के thumbnail वाले फोटो + वीडियो चलाएं, अवधि : + अपलोडर का अवतार थंमनेल पसंद नापसंद - कोई परिणाम नहीं मिला - यहां के खालीपन को दूर करने के लिए कुछ सर्च करें या किसी चैनल को सब्सक्राइब करें और प्लेलिसट बनाकर उसमें वीडियो जोड़े + कोई परिणाम नहीं + यहां के खालीपन को दूर करने के लिए कुछ सर्च करें या किसी चैनल को सब्सक्राइब करें और प्लेलिसट बनाकर उसमें वीडियो जोड़ें वीडियो ऑडियो - फिर से कोशिश करे + फिर से कोशिश करें हज़ार - करोड़ + मिलियन अरब - कोई सब्सक्राइबर नहीं है + कोई सब्सक्राइबर नहीं %s सब्सक्राइबर %s सब्सक्राइबर्स @@ -140,7 +140,7 @@ %s वीडियो - %s वीडियोस् + %s वीडियोज़ शुरू रोकें @@ -148,57 +148,57 @@ चेकसम ठीक है फाइल का नाम - मेसेज के thread + थ्रेड्स त्रुटी - न्यूपाइप डाउनलोड हो रहा है - विवरण देखने के लिए दबाये + न्यूपाइप डाउनलोड कर रही है + विवरण के लिए टैप करें कृपया प्रतीक्षा करें… क्लिपबोर्ड पर कॉपी हो गया है - कृपया बाद में सेटिंग्स में डाउनलोड स्थान चुने - पॉपअप के तरीके में खोलने के लिए + कृपया बाद में सेटिंग्स में डाउनलोड स्थान चुनें + पॉपअप मोड में खोलने के लिए \nइस अनुमति की जरुरत है reCAPTCHA चुनौती reCAPTCHA चुनौती का अनुरोध किया डाउनलोड - फाइल के नाम के लिए आवश्यक कैरेक्टर (जैसे - १२३, abc) की अनुमति है - अमान्य कैरेक्टर्स इस संख्या से बदल जायेंगे + फ़ाइल नाम में अनुमत कैरेक्टर + अमान्य कैरेक्टर्स इस संख्या से बदल दिए जायेंगे रिप्लेसमेंट करैक्टर वर्ण और अंक - विशेष कैरेक्टर्स - %2$s के द्वारा © %1$s जो %3$s के अधीन आते है + सबसे विशेष कैरेक्टर्स + %2$s के द्वारा © %1$s जो %3$s के अधीन आते हैं एंड्राइड के लिए हल्का और मुफ्त स्ट्रीमिंग एप्लिकेशन। - अगर आपके पास कोई सुझाव हो जैसे -अनुवाद , डिजाईन में बदलाव ,code को साफ़ रखना , या फिर code में जायदा बदलाव लाना हो तो - साहयता के लिए आपका स्वागत है . जितना ज्यादा होगा उतना बेहतर होगा ! - क्या आप इसको खोज इतिहास के मिटाना चाहते है ? - मुख्य पेज की विषयवस्तु + अगर आपके पास कोई सुझाव हो जैसे कि - अनुवाद करना, डिजाईन में बदलाव करना, कोड को साफ़ रखना, या फिर कोड में जायदा बदलाव लाना हो तो - सहायता के लिए आपका स्वागत है। जितना ज्यादा होगा उतना बेहतर होगा ! + क्या आप इसको खोज इतिहास से मिटाना चाहते हैं \? + मुख्य पृष्ठ की विषयवस्तु खाली पन्ना - kiosk पन्ना - चैनल वाला पन्ना - चैनल को चुने - अभी तक किसी भी चैनल के सदस्य नहीं है - kiosk को चुने - टॉप 50 - नया और प्रचलित - निकाले + कियोस्क पन्ना + चैनल पेज + चैनल चुनें + अभी तक किसी चैनल की सब्सक्रिप्शन नहीं है + कियोस्क चुनें + शीर्ष 50 + नए और प्रचलित + निकालें विवरण - जोड़ने के लिए पकड़ें रहे - पृष्टभूमि में चलाना शुरू करे - पॉपअप में चलाना शुरू करे - स्ट्रीमिंग करने के लिए कोई चालक उपलब्ध नहीं है (आप इसे चलाने के लिए वीएलसी चालक स्थापित कर सकते हैं)। + कतार में जोड़ने के लिए दबाकर रखें + बैकग्राउंड में चलाना शुरू करें + पॉपअप में चलाना शुरू करें + स्ट्रीमिंग करने के लिए प्लेयर नहीं मिला (आप इसे चलाने के लिए वीएलसी प्लेयर इंस्टॉल कर सकते हैं)। स्ट्रीम फाइल डाउनलोड करें जानकारी दिखाएं बुकमार्क की गई प्लेलिस्टें में शामिल करें - डिफ़ॉल्ट देश का विषय + सामग्री का डिफ़ॉल्ट देश हमेशा - सिर्फ एक बार के लिए + सिर्फ एक बार बैकग्राउंड में स्विच करें पॉपअप मोड में जाएं मुख्य पर स्विच करें डेटाबेस आयात करें डेटाबेस निर्यात करें - आपके वर्तमान इतिहास, सब्सक्रिप्शनस, प्लेलिस्ट और (वैकल्पिक रूप से) सेटिंग्स को अधिभावी करेगा + आपके वर्तमान इतिहास, सब्सक्रिप्शनस, प्लेलिस्ट और (वैकल्पिक रूप से) सेटिंग्स को ओवरराइड करता है इतिहास, सब्सक्रिप्शन, प्लेलिस्ट और सेटिंग निर्यात करें - एक्सटर्नल प्लेयर इन प्रकार के लिंक सपोर्ट नहीं करता + बाहरी प्लेयर्स इन प्रकार के लिंक सपोर्ट नहीं करते कोई वीडियो स्ट्रीम नहीं मिला कोई ऑडियो स्ट्रीम नहीं मिली फिर से क्रम देने के लिए खींचें @@ -206,17 +206,17 @@ ख़ारिज करें नाम बदलें दान करें - न्यूपाइप स्वयंसेवकों द्वारा विकसित किया जाता है जो आपको अच्छा अनुभव देने के लिए अपना खाली समय व्यतीत करते हैं। स्वयंसेवको को मदद भेजे, ताकि वह न्यूपाइप को और अच्छा बना सके। + न्यूपाइप स्वयंसेवकों द्वारा विकसित किया जाता है जो आपको अच्छा अनुभव देने के लिए अपना खाली समय इस एप्लिकेशन को देते हैं। स्वयंसेवको को मदद भेजे, ताकि वह न्यूपाइप को और अच्छा बना सके। वापस दें वेबसाइट अधिक जानकारी और खबरों के लिए न्यूपाइप की वेबसाइट पर जाएं। पिछला चलाया गया अधिकतम चलाए गए - निर्यात किए गए - आयातित - कोई मांय ज़िप फ़ाइल नहीं + निर्यात संपन्न हुआ + आयात संपन्न हुआ + कोई वैध ज़िप फ़ाइल नहीं है चेतावनी: सभी फ़ाइलों को आयात नहीं किया जा सका। - यह आपके वर्तमान सेटअप को ओवरराइड करेगा । + यह आपके वर्तमान सेटअप को ओवरराइड कर देगा। ड्रावर खोलें ड्रावर बंद करें वीडियो प्लेयर @@ -229,21 +229,21 @@ नाम बदलें नाम प्लेलिस्ट में जोड़ें - प्लेलिस्ट थंमनेल के रूप में सेट करें + प्लेलिस्ट थंमनेल के रूप में सैंट करें प्लेलिस्ट बुकमार्क करें बुकमार्क हटायें - प्लेलिस्ट को हटाना चाहते हैं\? - सूची बना दी गई + प्लेलिस्ट को मिटाना चाहते हैं\? + प्लेलिस्ट बना दी गई प्लेलिस्ट में जोड़ा गया - प्लेलिस्ट का थंमनेल बदल दिया गया है। - कोई अनुशीर्षक नहीं है + प्लेलिस्ट का थंमनेल बदल दिया गया। + कोई अनुशीर्षक नहीं फिट भरें - ज़ूम करें + ज़ूम डीबग करें - ऑटो-जनरेटेड + अपने-आप बनी हीप डंप करने के दौरान मेमोरी लीक मॉनिटरिंग ऐप को अनुत्तरदायी बना सकता है - Out-of-Lifecycle त्रुटियों की रिपोर्ट करें + चक्र से बाहर त्रुटियों की रिपोर्ट करें तेज और अनिश्चित तलाश का प्रयोग करें अनिश्चित खोज से प्लेयर में कम सटीकता से लेकिन तेजी से वीडियो पोजीशन्स की तलाश कर सकता हैं। 5, 15 या 25 सेकंड की तलाश में यह काम नहीं करता चित्र कैश मिटाया गया @@ -251,45 +251,45 @@ कैश किए गए सभी वेबपेज का डेटा हटाएं मेटाडाटा कैश मिटाया गया अगली स्ट्रीम को अपने आप जोड़े - गैर-दोहराने वाली कतार में अंतिम स्ट्रीम चलाते समय संबंधित स्ट्रीम को स्वतः संलग्न करें + खत्म होने वाली पर ना-दोहराने वाली प्लेबैक कतार को संबंधित स्ट्रीम जोड़ते हुए जारी रखें फाइल चेनल्स - सूची - क्स + प्लेलिस्ट + ट्रैकस उपभोगता देखे हुए वीडियो की सूची साफ करें चलाये गए स्ट्रीम के इतिहास और प्लेबैक स्थानों को साफ करता है - देखे गए सभी का इतिहास साफ करें\? - देखा हुआ इतिहास साफ कर दिया गया - ढूंढने के इतिहास को साफ करें - ढूंढे गए शब्दो का इतिहास साफ करता है - पूरे खोज इतिहास को मिटा दे \? - खोज के इतिहास को साफ कर दिया - एसी कोई भी फ़ोल्डर मौजूद नहीं है + क्या देखा गया सब इतिहास मिटा दिया जाए\? + देखा हुआ इतिहास मिटा दिया गया + खोज इतिहास को साफ करें + खोजे गए शब्दों का इतिहास साफ करता है + पूरे खोज इतिहास को मिटा दें\? + खोज इतिहास मिटाया गया + ऐसा कोई फ़ोल्डर मौजूद नहीं अमान्य फाइल/विषय - वस्तु का स्रोत - फ़ाइल मौजूद नहीं है या उसे पढ़ने या लिखने की पर्याप्त अनुमति नही़ं है + फ़ाइल मौजूद नहीं है या उसे पढ़ने या लिखने की पर्याप्त अनुमति नहीं है फ़ाइल का नाम खाली नहीं हो सकता - एक भूल हुई: %1$s - डाउनलोड करने के लिए कोई स्ट्रीम उपलब्ध नही है - एक चीज़ साफ कर दी गई। + एक त्रुटी उत्पन्न हुई: %1$s + डाउनलोड करने के लिए कोई स्ट्रीम उपलब्ध नहीं है + एक आइटम मिटा दी गई। न्यूपाइप की गोपनीयता नीति - न्यूपाइप परियोजना आपकी गोपनीयता को बहोत गंभीर रूप से लेता है। इसलिए, ऐप आपकी अनुमति के बिना कोई डेटा जमा नही करता। -\nन्यूपाइप की गोपनीयता नीति विस्तार से समज़ाती है कि कोनसा डेटा भेजा या संग्रह किया जाता है जब आप क्रेश विवरण भेजते है। - गोपनीयता नीति पढ़े - क्या आप सेटिंग्स भी आयात करना चाहते है? + न्यूपाइप परियोजना आपकी गोपनीयता को बहुत गंभीर रूप से लेता है। इसलिए, ऐप आपकी अनुमति के बिना कोई डेटा जमा नहीं करता। +\nन्यूपाइप की गोपनीयता नीति विस्तार से समझाती है कि कौनसा डेटा भेजा और संग्रह किया जाता है जब आप क्रेश विवरण भेजते हैं। + गोपनीयता नीति पढें + क्या आप सेटिंग्स भी आयात करना चाहते हैं\? तरजीही \'open\' एक्शन सामग्री खोलते समय डिफ़ॉल्ट कारवाही — %s अनुशीर्षक - प्लेयर अनुशीर्षक के शब्दों का परिमाण और पृष्ठभूमि शैलियों को बदले। लागू करने के लिए ऐप को पुनः प्रारम्भ करना जरूरी है + प्लेयर कैप्शन टेक्स्ट स्केल और पृष्ठभूमि शैलियों को संशोधित करें। प्रभावी होने के लिए ऐप को पुनरारंभ करना आवश्यक है आयात - से आयात करे + से आयात करें पर निर्यात करे आयात किया जा रहा है… निर्यात किया जा रहा है… - फाइल आयात करे + फाइल आयात करें पहले वाला निर्यात - सब्सक्रिप्शन आयात नही कर सके - सब्सक्रिप्शन निर्यात नही कर सके + सब्सक्रिप्शन आयात नहीं कर सके + सब्सक्रिप्शन निर्यात नहीं कर सके गूगल टेकआउट से यूट्यूब सदस्यता आयात करें: \n \n1. इस यूआरएल पर जाएं: %1$s @@ -300,77 +300,77 @@ \n6. नीचे आयात फ़ाइल पर क्लिक करें और डाउनलोड की गई .zip फ़ाइल चुनें \n7. [यदि .zip आयात विफल हो जाता है] .csv फ़ाइल निकालें (आमतौर पर \"यूट्यूब और यूट्यूब म्युज़िक/सब्सक्रिपशन/subscriptions.csv\" के अंतर्गत), नीचे आयात फ़ाइल पर क्लिक करें और निकाली गई सीएसवी फ़ाइल चुनें आपका आईडी, soundcloud.com/(आपका आईडी) - ध्यान रखे, यह तरीका नेटवर्क साधनो के लिए मंहगा हो सकता है। + ध्यान रखें, यह तरीका नेटवर्क खर्चीला हो सकता है। \n -\nक्या आप आगे बढ़ना चाहते है? - चलाने की गति के नियंत्रण - गति - ऊंचाई - अनहुक (बिगाड़ सकता है) - खामोशी के समय तेज़ी से आगे बढ़े +\nक्या आप आगे बढ़ना चाहते हैं\? + प्लेबैक स्पीड कंट्रोल + ताल + पिच + अनहुक (आवाज़ में बिगाड़ पड़ सकता है) + खामोशी के समय तेज़ी से आगे बढ़ें कदम - रीसेट - स्वीकारे - अस्वीकार करे + रीसेट करें + स्वीकार करें + अस्वीकार करें असीमित - मोबाइल डेटा उपयोग करते समय रिजॉल्युशन को सिमित करे - ऐप बदलते समय उसे मिनिमाइज करे - मुख्य वीडियो चालक से दूसरी ऐप पर जाने पर — %s - कोई नही - बैकग्राउंड प्लेयर में बदले - पॉपअप प्लेयर में बदले + मोबाइल डेटा उपयोग करते समय रिजॉल्युशन को सीमित करें + ऐप बदलते समय उसे मिनिमाइज करें + मुख्य वीडियो प्लेयर से दूसरी ऐप पर जाने पर कार्रवाई — %s + कोई नहीं + बैकग्राउंड प्लेयर में बदलें + पॉपअप प्लेयर में बदलें न्यूपाइप एक काॅपीलेफ़्ट फ़्री साॅफ़्टवेर है: इसे आप अपनी इच्छा के अनुसार इस्तेमाल, जाँच, बाँट तथा और बेहतर बना सकते है। खास तौर पर आप इसे फ़्री साॅफ़्टवेर फ़ाउंडेशन के द्वारा जारी जीएनयू जनरल पब्लिक लाइसेंस के तीसरे या उसके बाद आने वाले कोई भी वर्णन के शर्तों के मुताबिक फिर से बाँट या बदल सकते हैं। अनसब्सक्राईब करें टैब चुने कतारबद्ध करें - अपडेट + अपडेटस फाइल मिटा दी गयी - ऐप अपडेट अधिसूचना - नए NewPipe अपडेट की सूचनापत्र + ऐप अपडेट नोटीफिकेशन + नए नयूपाईप अपडेट का नोटीफिकेशन एक्सटर्नल स्टोरेज अनुपलब्ध - SD कार्ड पर डाउनलोड करना संभव नहीं।डाउनलोड स्थान पुनः चुने\? - सामान्य चुनाव पर लौटें - क्या आप सामान्य चुनाव पर लौटना चाहते है\? - सब्सक्राइबर स॔ख्या अनुपलब्ध + SD कार्ड पर डाउनलोड करना संभव नहीं। डाउनलोड स्थान पुनः चुनें\? + डिफ़ॉल्टस पुन: स्थापित करें + क्या आप डिफ़ॉल्टस पर लौटना चाहते है\? + सब्सक्राइबर संख्या अनुपलब्ध मुख्य पृष्ठ पर कौन से टैब दिखाए जाते हैं - अपडेट + अपडेटस सूची न्यूपाइप अपडेट उपलब्ध! समाप्त अपूर्ण रोका हुआ कतार में - प्रक्रिया के बाद + पोस्ट-प्रोसेसिंग कार्य सिस्टम द्वारा अस्वीकार डाउनलोड विफल रहा - अनोखा नाम बनाये - ऊपर लिखना + अनोखा नाम बनायें + ओवरराइट करें इस नाम का एक डाउनलोड चालू है - गंतव्य फ़ोल्डर नहीं बनाया जा सकता + डेस्टीनेशन फ़ोल्डर नहीं बनाया जा सकता फ़ाइल नहीं बनाई जा सकती सुूरक्षित कनेक्शन विफल सर्वर नहीं ढूँढ सका सर्वर से जुड़ नहीं सकता सर्वर डेटा नहीं भेजता है नहीं मिला - प्रक्रिया के बाद का कार्य विफल रहा - रोके + पोसट प्रोसेसिंग विफल रही + रोकें अधिकतम पुनर्प्रयास डाउनलोड रद्द करने से पहले प्रयासों की अधिकतम संख्या - मीटर्ड नेटवर्क पर रोके + मीटर्ड नेटवर्क पर रोकें मोबाइल डाटा का इस्तेमाल करते समय उपयोगी है, परंतु कुछ डाउन्लोड रोके नहीं जा सकते है घटनायें - सम्मेलनों + कॉन्फ्रेंस टिप्पणियां दिखाएं टिप्पणियां छिपाने के लिए इसे बंद करे - ऑटोप्ले करे + ऑटोप्ले कोई टिपण्णी नहीं - टिप्पणियाँ लोड नहीं कर सका - बंद करे + टिप्पणियाँ लोड नहीं हो पाई + बंद करें प्लेबैक वापस चालू करें आखिरी प्लेबैक पोजिशन पर वापस लौटे सूचियों में स्थान - प्लेबैक पोजिशन के निशान सूचियों में दिखाए + प्लेबैक पोजिशन के निशान सूचियों में दिखाएं डाटा मिटायें प्लेबैक स्थान मिटा दिए गए फाइल की जगह बदली गयी या फिर फाइल मिटा दी गयी @@ -389,39 +389,39 @@ डाउनलोड रोकें डाउनलोड कहाँ करने के लिए पूछे आपको हर डाउनलोड का स्थान पूछा जाएगा -\nयदि आप बाहरी एसडी कार्ड में डाउनलोड करना चाहते हैं तो सिस्टम फोल्डर पिकर (एसएएफ) को सक्षम करें - सिस्टम फोल्डर पिकर (एसएएफ) का प्रयोग करें - प्लेबैक स्थानों को मिटाये - सारे प्लेबैक स्थानों को मिटाये - सारे प्लेबैक स्थानों को मिटाये\? - फ्रेगमेंट या एक्टिविटी लाइफसाइकिल के बाद Rx सन्देश ना पहुँचाया जा सके तोह ज़रूर कोशिश करे +\nयदि आप बाहरी एसडी कार्ड में डाउनलोड करना चाहते हैं तो सिस्टम फोल्डर पिकर (SAF) को सक्षम करें + सिस्टम फोल्डर पिकर (SAF) का प्रयोग करें + प्लेबैक स्थानों को मिटाएं + सारे प्लेबैक स्थानों को मिटाता है + सारे प्लेबैक स्थानों को मिटाएं\? + निपटान के बाद खंड या गतिविधि जीवन चक्र के बाहर अविभाज्य आरएक्स अपवादों की रिपोर्टिंग को बलपूर्वक लागू करें साउंडक्लाउड प्रोफाइल निर्यात करने के लिए आईडी या युआरएल दीजिये: \n -\n1. अपने वेब ब्राउज़र में \"डेस्कटॉप मोड\" चालू करे (वेबसाइट मोबाइल उपकरणों के लिए उपलब्ध नहीं है) -\n2. इस युआरएल को खोले: %1$s -\n3. लॉग इन करे -\n4. आप जिस प्रोफाइल युआरएल पे भेजे जाते है उसे कॉपी करे। - यूरोप के जेनेरल डाटा प्रोटेक्शन रेगुलेशन (जीडीपीआर) का पालन करने के लिए, हम आपका ध्यान न्यूपाइप की नयी प्राइवेसी पालिसी पे डालना चाहते है। इसे बारीकी से पढ़िए। -\nआपको अगर हमें कोई त्रुटि रिपोर्ट भेजना हो तो इसे स्वीकार करे। - सामान्य टैब्स का इस्तेमाल, सहेजे टैब्स को पढ़ने में रूकावट - जब इस ऐप के लिए अपडेट उपलब्ध हो, तब अधिसूचना दिखाई जाये +\n1. अपने वेब ब्राउज़र में \"डेस्कटॉप मोड\" चालू करें (वेबसाइट मोबाइल उपकरणों के लिए उपलब्ध नहीं है) +\n2. इस युआरएल को खोलें: %1$s +\n3. लॉग इन करें +\n4. आप जिस प्रोफाइल युआरएल पे भेजे जाते हैं उसे कॉपी करें।
+ यूरोपीय जनरल डेटा प्रोटेक्शन रेगुलेशन (जीडीपीआर) का अनुपालन करने के लिए, हम आपका ध्यान न्यूपाइप की गोपनीयता नीति पे डालना चाहते हैं। इसे बारीकी से पढ़िए। +\nआपको अगर हमें कोई त्रुटि रिपोर्ट भेजना हो तो इसे स्वीकार करना होगा। + सहेजे टैब्स को पढ़ने में रूकावट, इसलिए सामान्य टैब्स का इस्तेमाल हो रहा है + जब नई अपडेट उपलब्ध हो, तब एप अपडेट करने के लिए अधिसूचना दिखाई जाये सूचि देखने वाला ढंग ग्रिड ऑटो - त्रुटि दिखाए + त्रुटि दिखाएं सर्वर मल्टी थ्रेडेड डाउनलोड स्वीकार नहीं करता, पुनः कोशिश करे @string/msg_threads = 1 के साथ \'स्टोरेज एक्सेस फ्रेमवर्क\' आपको बाहरी एसडी कार्ड पर डाउनलोड करने देता है - सेवा चुने, वर्तमान चुनाव : - सामान्य कीओस्क - कोई दर्शक नहीं + सेवा चुनें, वर्तमान चुनाव : + डिफ़ॉल्ट कियोस्क + कोई दर्शक नहीं देख रहा %s दर्शक है %s दर्शक हैं - कोई नहीं सुन रहा है + कोई श्रोता नहीं सुन रहा %s श्रोता - %s श्रोताए + %s श्रोता ऐप के पुनः आरंभ होने के बाद भाषा बदल जाएगी तेज मोड सक्षम करें @@ -439,17 +439,17 @@ \nतो आखिर में चुनाव आपकी पसंद पर है: गति या फिर सटीक जानकारी।
यह सामग्री फिलहाल न्यूपाइप सपोर्ट नहीं करता है। \n -\nइसे आशा से भविष्य के संस्करणों में सपोर्ट किया जायेगा। +\nआशा है कि भविष्य के संस्करणों में सपोर्ट किया जायेगा। चैनल का अवतार थंमनेल %s के द्वारा %s के द्वारा बनाया गया - प्लेलिस्ट पृष्ठ - %s : के लिए परिणाम दिखया जा रहा है - हो गया + प्लेलिस्ट पन्ना + %s : के लिए परिणाम दिखाया जा रहा है + संपन्न कलाकार - गाने + गीत कभी नहीं - reCAPTCHA कुकीज़ को साफ़ कर दिए गए हैं + reCAPTCHA कुकीज़ साफ़ कर दिए गए ReCAPTCHA कुकीज़ साफ़ करें एल्बम वीडियो @@ -458,27 +458,27 @@ \nयदि आप इसे देखना चाहते हैं तो सेटिंग में \"%1$s\" चालू करें। यूट्यूब एक \"प्रतिबंधित मोड\" प्रदान करता है जो संभावित रूप से परिपक्व सामग्री को छुपाता है यूट्यूब का \"प्रतिबंधित मोड\" चालू करें - बच्चों के लिए अनुपयुक्त सामग्री दिखाएं क्योंकि इसकी आयु सीमा है (जैसे 18) + वह सामग्री भी दिखाएं जो आयु सीमा की वजह से शायद बच्चों के लिए अनुपयुक्त हो (जैसे 18+) केवल HTTPS यूआरएल ही समर्थित हैं URL की पहचान नहीं हो सकी। दूसरे ऐप से खोलें\? अपने आप कतार में जोड़े कतार को मिटाने से पहले सत्यापन के लिए पूछें - तलाश अवधि फास्ट-फ़ॉरवर्ड /- रिवाइंड करे - एंड्रॉइड को थम्बनेल में मुख्य रंग के अनुसार अधिसूचना रंग को अनुकूलित करने की अनुमति दे (ध्यान दें कि यह सभी उपकरणों पर उपलब्ध नहीं है) - अभिसूचना को रंगीन करें + फास्ट-फ़ॉरवर्ड /- रिवाइंड करने की अवधि + एंड्रॉइड को थंमनेल में मुख्य रंग के अनुसार नोटीफिकेशन रंग को अनुकूलित करने की अनुमति दें (ध्यान दें कि यह सभी उपकरणों पर उपलब्ध नहीं है) + नोटीफिकेशन को रंगीन करें कुछ नहीं बफरिंग - शफल करे + शफल करें दोहराएं - आप संछिप्त अभिसूचना में दिखाए जाने वाले विकल्प में से अधिकतम 3 को चुन सकते है ! - नीचे दी गई प्रत्येक अधिसूचना क्रिया को उस पर टैप करके संपादित करें। दाईं ओर चेकबॉक्स का उपयोग करके उनमें से अधिकतम तीन का चयन करें जिन्हें कॉम्पैक्ट अधिसूचना में दिखाया जाना है + आप कंपैकट नोटीफिकेशन में दिखाए जाने वाले विकल्प में से अधिकतम 3 को चुन सकते है ! + नीचे दी गई प्रत्येक नोटीफिकेशन क्रिया को उस पर टैप करके संपादित करें। दाईं ओर चेकबॉक्स का उपयोग करके उनमें से अधिकतम तीन का चयन करें जिन्हें कंपैकट नोटीफिकेशन में दिखाया जाना है पांचवा एक्शन बटन चतुर्थी एक्शन बटन तृतीय एक्शन बटन द्वितीय एक्शन बटन प्रथम एक्शन बटन - नोटिफिकेशन में दिखाए गए वीडियो थम्बनेल को 16:9 के बजाय 1:1 के अनुपात में दिखाए - थम्बनेल को 1:1 के अनुपात में दिखाएं + नोटीफिकेशन में दिखाए गए वीडियो थंमनेल को 16:9 के बजाय 1:1 के अनुपात में दिखाएँ + थंमनेल को 1:1 के अनुपात में करें %d घंटा %d घंटे @@ -496,14 +496,14 @@ केवल वाईफाई पर स्वचालित रूप से प्लेबैक शुरू करें —%s मेमरी लीक दर्शाएँ - मौन हटायें - मौन + अवाज चालू करें + अवाज बंद करें सबसे पसंद किए गए हाल ही में जोड़ा स्थानीय - अभी कोई प्लेलिस्ट का बुक्मार्क नहीं है - प्लेलिस्ट का चयन करें - ∞ विडीओज़ + अभी कोई प्लेलिस्ट बुक्मार्क नहीं की हुई + प्लेलिस्ट चुनें + अनगिनत विडीओज़ 100+ विडीओज़ विवरण संबंधित स्ट्रीमस @@ -511,18 +511,18 @@ कृपया जांचें लें कि क्या आपके क्रैश पर चर्चा करने वाला मुद्दा पहले से मौजूद है। डुप्लिकेट टिकट बनाते समय, आप हमसे समय लेते हैं जो हम वास्तविक बग को ठीक करने के लिए खर्च कर सकते हैं। गिटहब पर रिपोर्ट करें अन्य ऐप्स पर प्रदर्शित करने की अनुमति दें - विडीओ हैशिंग की प्रगति की सूचना - वीडियो हैश अधिसूचना + विडीओ हैशिंग की प्रगति का नोटीफिकेशन + वीडियो हैश नोटीफिकेशन स्ट्रीम निर्माता, स्ट्रीम सामग्री या खोज अनुरोध के बारे में अतिरिक्त जानकारी के साथ मेटा जानकारी बक्से को छिपाने के लिए बंद करें - मेटा जानकारी दिखाएँ + मेटा जानकारी दिखाएं वीडियो का विवरण और अतिरिक्त जानकारी छिपाने के लिए इसे बंद करें विवरण दिखाएं - सक्रिय चालक की क़तार बदल दी जाएगी - एक चालक से दूसरे चालक में जाने से आपकी कतार बदल सकती है + सक्रिय प्लेयर की क़तार बदल दी जाएगी + एक प्लेयर से दूसरे प्लेयर में जाने से आपकी कतार बदल सकती है इसमें खोलें थंमनेल दिखाएं - लॉक स्क्रीन और नोटिफिकेशन दोनों के लिए थंमनेल का इस्तेमाल करे - पाठ + लॉक स्क्रीन और नोटिफिकेशन दोनों के लिए थंमनेल का इस्तेमाल करें + चैप्टर आपके डिवाइस का कोई भी ऐप इसे नहीं खोल सकता है यह सामग्री आपके देश में उपलब्ध नहीं है। यह एक साउंडक्लाउड गो+ ट्रैक है, कम से कम आपके देश में, इस कारण इसे न्यूपाइप द्वारा स्ट्रीम या डाउनलोड नहीं किया जा सकता है। @@ -532,36 +532,36 @@ रेडियो ऑटोमैटिक (डिवाइस थीम) अपनी पसंदीदा नाइट थीम चुने — %s - आप अपनी पसंदीदा नाइट थीम नीचे चुन सकते है - डाउलोड शुरू हो गया है + आप अपनी पसंदीदा नाइट थीम नीचे चुन सकते हैं + डाउनलोड शुरू हो गया है यह वीडियो आयु-प्रतिबंधित है। \nयूट्यूब की नई नीतियों के कारण न्यूपाइप किसी भी आयु प्रतिबंधित वीडियो स्ट्रीम का इस्तेमाल नहीं कर सकता है और इस कारण इसे वीडियो को प्ले करने में असमर्थ है। - पियरट्यूब उदाहरण - विशेष रुप से प्रदर्शित + पियरट्यूब इंसटैंस + फीचर्ड रात्रि थीम - हैश की गणना - स्वरूपित रिपोर्ट कॉपी करें - कुकी साफ़ करें जिसे न्यूपाइप आपके द्वारा रीकैप्चा हल करने पर संग्रहीत करता है - उदाहरण पहले से मौजूद है + हैश की गणना कर रहा है + फार्मेट की हूई रिपोर्ट कॉपी करें + कुकी साफ़ करें जिसे न्यूपाइप आपके द्वारा रीकैप्चा हल करने पर संग्रहित करता है + इंसटैंस पहले से मौजूद है इंसटैंस मान्य नहीं किया जा सका इंसटैंस यूआरएल दर्ज करें - उदाहरण जोड़ें + इंसटैंस जोड़ें %s पर अपनी पसंद के इंसटैंस ढूँढ़ें अपने पसंदीदा पीयर ट्यूब इंसटैंस चुनें मुख्य प्लेयर को पूर्ण स्क्रीन में शुरू करें मिनी प्लेयर में वीडियो शुरू न करें, लेकिन ऑटो रोटेशन लॉक होने पर सीधे फुल स्क्रीन मोड पर जाएं। आप अब भी फ़ुलस्क्रीन से बाहर निकलकर मिनी प्लेयर तक पहुंच सकते हैं टिप्पणियाँ करना बंद है देखा हुआ चिह्नित करें - चालक सूचनापत्र - सूचनापत्र - चालक असफल हुआ + प्लेयर नोटीफिकेशन + नोटीफिकेशन + प्लेयर क्रैश करें स्थानीय खोज सुझाव सार्वजनिक - अभी चल रही स्ट्रीम अधिसूचना को कॉन्फ़िगर करें + चल रही स्ट्रीम नोटीफिकेशन को कॉन्फ़िगर करें नई स्ट्रीमें - सब्सक्रिप्शनस के नई स्ट्रीमों के बारे में अधिसूचनाएं - त्रुटि रिपोर्ट अधिसूचना - त्रुटियों की रिपोर्ट करने के लिए अधिसूचनाएं + सब्सक्रिप्शनस की नई स्ट्रीमों के नोटीफिकेशन + त्रुटि रिपोर्ट नोटीफिकेशन + त्रुटियों की रिपोर्ट करने के लिए नोटीफिकेशन न्यूपाइप को एक त्रुटि का सामना करना पड़ा, रिपोर्ट करने के लिए टैप करें हल करें कतारबद्ध करें @@ -583,16 +583,16 @@ निम्न गुणवत्ता (छोटा) सीकबार थंमनेल पूर्वावलोकन उच्च गुणवत्ता (बड़ा) - अपडेट्स के लिए जांच हो रही है… - ठीक हो रहा है + अपडेटस के लिए जांच हो रही है… + पुन: प्राप्ति हो रही डिस्क से सभी डाउनलोड की गई फ़ाइलें मिटाएं\? एंड्रॉइड 10 से शुरू होकर केवल \'स्टोरेज एक्सेस फ्रेमवर्क\' समर्थित है एक इंस्टेंस चुनें हां, और आंशिक रूप से देखे गए वीडियो भी - फीड लोड हो रही है… + फ़ीड लोड हो रही है… फ़ीड अपडेट चरणसीमा - फ़ीड लोड करने में गड़बड़ी - \'%s\' के लिए फ़ीड लोड नहीं कर सका। + फ़ीड लोड करने में त्रुटि हूई + \'%s\' के लिए फ़ीड लोड नहीं हो सकी। हाल ही के विवरण में पाठ का चयन सक्षम करें गोपनीयता @@ -600,17 +600,17 @@ आयु सीमा सहायता होसट - अधिसूचनाएं अक्षम हैं + नोटीफिकेशन अक्षम हैं गैर-सूचीबद्ध सबको टॉगल करें अधिसूचना पायें , - नए संस्करणों के लिए मैन्युअल रूप से जांचें - एग्ज़ोप्लेयर के कमी के कारण खोज की अवधि %d सेकंड पर सेट की गई - खाता समाप्त किया गया + नई अपडेट के लिए मैन्युअल रूप से जांचें + एक्सोप्लेयर की बंदिश के कारण सीक करने की अवधि %d सेकंड पर सेट की गई + खाता बंद किया गया जो स्ट्रीम अभी तक डाउनलोडर द्वारा समर्थित नहीं हैं, वो नहीं दिखाई जाती बाहरी प्लेयरस के लिए क्वालिटी का चयन करें - अज्ञात प्रारूप + अज्ञात फार्मेट अज्ञात क्वालिटी ऐप को क्रैश करें श्रेणी @@ -619,7 +619,7 @@ हमेशा अपडेट करें विवरण में पाठ का चयन अक्षम करें मत दिखाओ - दूरस्थ खोज सुझाव + रिमोट खोज सुझाव %s नई स्ट्रीम %s नई स्ट्रीमें @@ -627,33 +627,33 @@ प्रतिशत सैमीटोन - डाउनलोड समाप्त - %s डाउनलोडस समाप्त + डाउनलोड संपूर्ण + %s डाउनलोडस संपूर्ण %d दिन - %d दिनो + %d दिन %d चयनित %d चयनित हुए - एग्ज़ोप्लेयर डिफ़ॉल्ट + एक्सोप्लेयर डिफ़ॉल्ट प्लेबैक लोड अंतराल आकार समूह का नाम नहीं सब्सक्रिप्शनस चुनें क्या आप इस समूह को हटाना चाहते हैं\? नया फ़ीड - नई फ़ीड आइटम - फ़ीड संसाधित हो रही है … + नये फ़ीड आइटम + फ़ीड प्रोसेस हो रही है … वेबसाइट खोलें उपलब्ध होने पर समर्पित फ़ीड से प्राप्त करें भाषा ऑन स्वतः बने (कोई अपलोडर नहीं मिला) चैनल समूह - कई बार पूछे प्रश्न + अक्सर पूछे जाते प्रश्न वेबसाइट पर देखें आइटम हटाने के लिए स्वाइप करें मीडिया टनलिंग अक्षम करें @@ -665,25 +665,25 @@ यदि आपको ऐप का उपयोग करने में परेशानी हो रही है, तो सामान्य प्रश्नों के इन उत्तरों को देखना सुनिश्चित करें! कतार में आगे जोड़ें प्रगतिशील सामग्री पर लोड अंतराल आकार बदलें (वर्तमान में %s)। एक कम मान उनकी आरंभिक लोडिंग को गति दे सकता है - लीककैनरी उपलब्ध नहीं है - एक त्रुटी हुई है, अधिसूचना देखें + लीक-कैनरी उपलब्ध नहीं है + एक त्रुटी हुई है, नोटीफिकेशन देखें यदि वीडियो प्लेबैक पर आप काली स्क्रीन या रुक-रुक कर वीडियो चलने का अनुभव करते हैं तो मीडिया टनलिंग को अक्षम करें। छवियों के शीर्ष पर पिकासो रंगीन रिबन दिखाएँ जो उनके स्रोत को दर्शाता है: नेटवर्क के लिए लाल, डिस्क के लिए नीला और मेमोरी के लिए हरा - गड़बड़ी की सूचना बनाएं + त्रुटी की नोटीफिकेशन बनाएं इस डाउनलोड को पुनर्प्राप्त नहीं किया जा सकता अभी तक कोई डाउनलोड फ़ोल्डर सेट नहीं किया गया है, अब डिफ़ॉल्ट डाउनलोड फ़ोल्डर चुनें हल होने पर \"संपन्न\" दबाएं चैनल विवरण दिखाएं आइटम्स का असल अपलोड समय दिखाएं सेवाओं से मूल पाठ स्ट्रीम आइटम में दिखाई देंगे - प्लेलिस्ट में जोड़े गए पहले और बाद में देखे गए वीडियो हटा दिए जाएंगे। + प्लेलिस्ट में शामिल, पहले और बाद में देखे जा चुके वीडियो हटा दिए जाएंगे। \nक्या यक़ीनन आप ऐसा चाह्ते हैं\? इसे असंपादित नहीं किया जा सकेगा! %d मिनट %d मिनट्स - फीड अंतिम अपडेट: %s - कोई सदस्यता चयनित नहीं है + फ़ीड आख़िरी दफा %s को अपडेट हुई + कोई सब्सक्रिप्शन नहीं चुनी हूई केवल असमूहीकृत सब्सक्रिप्शनस दिखाएं फ़ास्ट फ़ीड मोड इस पर अधिक जानकारी प्रदान नहीं करता है। अपडेट अंतराल जब सब्सक्रिप्शन फ़ीड दोबारा अपडेट किये जा सकें — %s @@ -692,7 +692,7 @@ \nक्या आप इस चैनल की सदस्यता समाप्त करना चाहते हैं\? चयनित स्ट्रीम बाहरी प्लेयरस द्वारा समर्थित नहीं है इस क्रिया के लिए कोई उपयुक्त फ़ाइल प्रबंधक नहीं मिला। -\nकृपया स्टोरेज एक्सेस फ्रेमवर्क संगत फ़ाइल प्रबंधक स्थापित करें +\nकृपया स्टोरेज एक्सेस फ्रेमवर्क संगत फ़ाइल प्रबंधक इंस्टॉल करें निजी आंतरिक पिन की हुई टिप्पणी @@ -701,9 +701,9 @@ आपने इस चैनल को अभी सब्सक्राइब किया है बाहरी प्लेयरस के लिए कोई वीडियो स्ट्रीम उपलब्ध नहीं है बाहरी प्लेयरस के लिए कोई ऑडियो स्ट्रीम उपलब्ध नहीं है - कुछ सेवाओं में उपलब्ध, यह आमतौर पर बहुत तेज होता है लेकिन सीमित मात्रा में आइटम और अक्सर अधूरी जानकारी (जैसे कोई अवधि नहीं, आइटम प्रकार, कोई लाइव स्थिति नहीं) लौटा सकता है + कुछ सेवाओं में उपलब्ध, यह आमतौर पर बहुत तेज होता है लेकिन सीमित मात्रा में जानकारी प्रदान कर पाता है और वह भी अक्सर अधूरी जानकारी (जैसे कि अवधि, आइटम की किसम, स्ट्रीम लाइव है, नहीं बता पाता) इस क्रिया के लिए कोई उपयुक्त फ़ाइल प्रबंधक नहीं मिला। -\nकृपया फ़ाइल प्रबंधक स्थापित करें या डाउनलोड सेटिंग में \'%s\' को अक्षम करने का प्रयास करें +\nकृपया फ़ाइल प्रबंधक इंस्टॉल करें या डाउनलोड सेटिंग में \'%s\' को अक्षम करने का प्रयास करें %1$s डाउनलोड हटाए गए %1$s डाउनलोड्स हटाए गए @@ -714,14 +714,14 @@ आप न्यूपाइप का नवीनतम संस्करण चला रहे हैं %s डाउनलोड करने के लिए टैप करें यह विकल्प केवल तभी उपलब्ध होता है जब थीम के लिए %s का चयन किया जाता है - स्थायी थंमनेल अनसेट करें + स्थायी थंमनेल अनसैंट करें कार्ड क्लिपबोर्ड पर कॉपी करने में विफल धुंधली की गई प्‍लेलिस्‍ट में पहले से ही यह आइटम है। डुप्लीकेट जोड़ा गया %d बार डुप्लीकेट हटाएं - डुप्लीकेट हटाएं\? - क्या आप इस प्लेलिस्ट की सभी डुप्लीकेट स्ट्रीम हटाना चाहते हैं\? + डुप्लीकेट हटाए जाएं\? + क्या आप इस प्लेलिस्ट में मौजूद सभी डुप्लीकेट स्ट्रीम हटाना चाहते हैं\? निम्नलिखित स्ट्रीम दिखाएँ आगामी हार्डवेयर मीडिया बटन घटनाओं की अनदेखी करें @@ -731,7 +731,7 @@ आंशिक रूप से देखा गया बाएँ इशारा क्रिया चमक - आवाज + आवाज़ कोई नहीं प्लेयर स्क्रीन के बाएँ आधे हिस्से के लिए जेस्चर चुनें प्लेयर स्क्रीन के दाहिने आधे हिस्से के लिए जेस्चर चुनें @@ -744,15 +744,15 @@ ऑडियो ट्रैक बाहरी प्लेयर्स के लिए ऑडियो ट्रैक का चयन करें अज्ञात - ExoPlayer सेटिंग्स + एक्सोप्लेयर सेटिंग्स एक्सोप्लेयर के डिकोडर फॉलबैक फीचर का उपयोग करें - हमेशा ExoPlayer के वीडियो आउटपुट सतह सेटिंग वर्कअराउंड का उपयोग करें + हमेशा एक्सोप्लेयर के वीडियो आउटपुट सतह सेटिंग वर्कअराउंड का उपयोग करें मूल - डब + डब की हूई वर्णनात्मक एक ऑडियो ट्रैक पहले से ही इस स्ट्रीम में मौजूद होना चाहिए इस विकल्प को सक्षम करें यदि आपके पास डिकोडर आरंभीकरण समस्याएं हैं, जो प्राथमिक डिकोडर आरंभ करने में विफल होने पर कम प्राथमिकता वाले डिकोडर पर वापस आ जाती हैं। प्राथमिक डिकोडर का उपयोग करते समय इसके परिणामस्वरूप खराब प्लेबैक प्रदर्शन हो सकता है - कुछ ExoPlayer सेटिंग्स प्रबंधित करें। इन परिवर्तनों को प्रभावी बनाने के लिए किसी प्लेयर को पुनरारंभ करने की आवश्यकता होती है + कुछ एक्सोप्लेयर सेटिंग्स प्रबंधित करें। इन परिवर्तनों को प्रभावी बनाने के लिए किसी प्लेयर को पुनरारंभ करने की आवश्यकता होती है सतह को सीधे कोडेक पर सेट करने के बजाय, सतह परिवर्तन होने पर यह वर्कअराउंड वीडियो कोडेक्स को जारी और पुन: चालू करता है। इस समस्या के साथ कुछ उपकरणों पर ExoPlayer द्वारा पहले से ही उपयोग किया जाता है, इस सेटिंग का केवल Android 6 और उच्चतर पर प्रभाव पड़ता है \n \nइस विकल्प को सक्षम करने से वर्तमान वीडियो प्लेयर स्विच करते समय या फुलस्क्रीन पर स्विच करते समय प्लेबैक त्रुटियों को रोका जा सकता है @@ -762,4 +762,20 @@ आपके डिवाइस पर मीडिया टनलिंग डिफ़ॉल्ट रूप से अक्षम कर दी गई थी क्योंकि यह ज्ञात है कि आपका डिवाइस मॉडल इसका समर्थन नहीं करता। कोई स्ट्रीम नहीं कोई लाइव स्ट्रीम नहीं + वीडियोज़ + सब्सक्राइबर्स + चैनल पेजों पर कौन से टैब दिखाए जाते हैं + चैनल टैब्स + शॉर्ट्स + मेटाडेटा लोड हो रहा है… + चैनल टैब प्राप्त करें + बारे में + बैनर URL + एल्बम्स + फ़ीड अपडेट करते समय प्राप्त करने वाले टैब। यदि किसी चैनल को तेज़ मोड का उपयोग करके अपडेट किया जाता है तो इस विकल्प का कोई प्रभाव नहीं पड़ता है। + अवतार URL + प्लेलिस्ट्स + ट्रैक्स + चैनल्स + लाइव \ No newline at end of file diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml index 58411b01b..0814cbfe5 100644 --- a/app/src/main/res/values-hu/strings.xml +++ b/app/src/main/res/values-hu/strings.xml @@ -757,4 +757,9 @@ Eltávolítja az ismétlődéseket\? Eltávolítja az összes ismétlődő közvetítést ebből a lejátszólistáról\? eredeti + Kezdőlap pozíció + A médiacsatornázás alapértelmezés szerint le van tiltva az Ön készülékén, mivel az Ön készülékmodellje nem támogatja azt. + Kezdőlap választó alulra helyezése + Nincs élő adatfolyam + Nincs adatfolyam \ No newline at end of file diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index 2ddaa8bdd..308bc9a76 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -747,4 +747,22 @@ Posisi tab utama %1$s %2$s Terowongan media dinonaktifkan secara bawaan di perangkat Anda karena model perangkat Anda tidak mendukungnya. + Tidak ada siaran langsung + Video + Pelanggan + Tab apa saja yang ditampilkan di halaman saluran + Tab saluran + Shorts + Memuat Metadata… + Dapatjan tab saluran + Tentang + URL banner + Album + Tab untuk didapatkan ketika memperarui umpan. Opsi ini tidak memiliki efek jika saluran diperbarui menggunakan mode cepat. + URL avatar + Daftar putar + Trek + Tidak ada saluran + Saluran + Langsung \ No newline at end of file diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 16e2a9ff5..4f4068d9a 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -775,4 +775,20 @@ Il tunneling multimediale è stato disabilitato per impostazione predefinita sul dispositivo in uso, poiché è noto che il modello del dispositivo non lo supporta. Nessuna trasmissione Nessuna trasmissione in diretta + Video + Iscritti + Quali schede mostrare nelle pagine del canale + Schede canale + Short + Caricamento metadati… + Recupera schede del canale + Informazioni + URL banner + Album + Schede da recuperare quando si aggiorna il feed. Questa opzione non ha effetto se un canale viene aggiornato usando la modalità veloce. + URL avatar + Playlist + Tracce + Canali + Dirette \ No newline at end of file diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 7da558e74..038c1ba2f 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -749,4 +749,20 @@ お使いのデバイスのモデルではメディアトンネリングがサポートされていないため、このデバイスではメディアトンネリングがデフォルトで無効になっています。 ストリームはありません ライブ配信はありません + 登録者 + メタ情報を読み込んでいます… + バナーのURL + アバターのURL + 動画 + チャンネルページに表示されるタブ + チャンネルタブ + ショート + チャンネルタブを取得する + 詳細 + アルバム + フィードを更新するときに取得するタブ。 高速モードを使用してチャンネルを更新する場合は、効果がありません。 + プレイリスト + トラック + チャンネル + ライブ \ No newline at end of file diff --git a/app/src/main/res/values-kk/strings.xml b/app/src/main/res/values-kk/strings.xml index a6b3daec9..c248c35f4 100644 --- a/app/src/main/res/values-kk/strings.xml +++ b/app/src/main/res/values-kk/strings.xml @@ -1,2 +1,7 @@ - \ No newline at end of file + + Бастау үшін үлкейткіш әйнекті басыңыз. + %1$s жарияланды + Ағындық ойнатқыш табылмады (оны ойнату үшін VLC орнатуға болады). + Ағындық ойнатқыш табылмады. VLC орнату керек пе\? + \ No newline at end of file diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index e56c39981..d91b4793c 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -710,7 +710,7 @@ Sorteer Snelle modus Importeer of exporteer abonnementen vanuit het 3-punten menu - U heeft de laatste versie van NewPipe + U heeft de nieuwste versie van NewPipe Druk om %s te downloaden Kon niet naar klembord kopiëren Deze instelling is alleen beschikbaar als %s als thema ingesteld is @@ -757,7 +757,7 @@ origineel nagesynchroniseerd beschrijvend - Secties onderaan weergeven + Verplaats de tabselector naar beneden Positie van sectie-tabbladen Geen streams Geen live-streams diff --git a/app/src/main/res/values-or/strings.xml b/app/src/main/res/values-or/strings.xml index a9ef4277c..9adf27691 100644 --- a/app/src/main/res/values-or/strings.xml +++ b/app/src/main/res/values-or/strings.xml @@ -44,7 +44,7 @@ ଏଥିରେ ଖୋଲନ୍ତୁ ବାତିଲ୍ କରନ୍ତୁ ଦେଖାଯାଇଥିବା ପରି ଚିହ୍ନିତ କର - ସଞ୍ଚୟ କରନ୍ତୁ + ଡାଉନଲୋଡ୍ କରିବା ସେଟିଂ ତୁମେ ଏହା ଚାଂହ କି \"%1$s\"\? ଫାଇଲ୍ ଡାଉନଲୋଡ କରନ୍ତୁ @@ -202,7 +202,7 @@ ସଦସ୍ୟତା ରଦ୍ଦ କରନ୍ତୁ ଚ୍ୟାନେଲ ସଦସ୍ୟତା ରଦ୍ଦ ହେଲା ସଦସ୍ୟତା ପରିବର୍ତ୍ତନ କରିପାରିଲା ନାହିଁ - ସୂଚନା ଦେଖାନ୍ତୁ + ସୂଚନା ଦେଖାଅ ଏଥିରେ ଯୋଡ଼ିବା ଡିଫଲ୍ଟ ପପ୍ଅପ୍ ରେଜୋଲୁସନ କେବଳ କିଛି ଡିଭାଇସ୍ 2K / 4K ଭିଡିଓ ଚଲାଇ ପାରିବେ @@ -214,7 +214,7 @@ ପଞ୍ଚମ କୃତ୍ୟ ବଟନ୍ ଶଫଲ୍ ବଫରିଂ - କିଛି ନୁହେଁ + କିଛି ନାହିଁ ଡିଫଲ୍ଟ ଭିଡିଓ ଫର୍ମାଟ୍ ପପ୍ଅପ୍ ଗୁଣଗୁଡିକ ମନେରଖ ପ୍ରକ୍ରିୟାକରଣ… କିଛି ସମୟ ନେଇପାରେ diff --git a/app/src/main/res/values-pa/strings.xml b/app/src/main/res/values-pa/strings.xml index 2d67523fb..d6016759f 100644 --- a/app/src/main/res/values-pa/strings.xml +++ b/app/src/main/res/values-pa/strings.xml @@ -23,7 +23,7 @@ ਚੈਨਲ ਅਨ-ਸਬਸਕ੍ਰਾਈਬ ਹੋ ਗਿਆ ਸਬਸਕ੍ਰਿਪਸ਼ਨ ਬਦਲਣ ਵਿੱਚ ਨਾਕਾਮੀ ਜਾਣਕਾਰੀ ਵਿਖਾਓ - ਸਬਸਕ੍ਰਿਪਸ਼ਨ ਅਪਡੇਟ ਕਰਨ ਵਿੱਚ ਨਾਕਾਮੀ + ਸਬਸਕ੍ਰਿਪਸ਼ਨ ਅੱਪਡੇਟ ਕਰਨ ਵਿੱਚ ਨਾਕਾਮੀ ਸਬਸਕ੍ਰਿਪਸ਼ਨਾਂ ਬੁੱਕਮਾਰਕ ਕੀਤੀਆਂ ਪਲੇ-ਸੂਚੀਆਂ ਨਵਾਂ ਕੀ ਹੈ @@ -63,7 +63,7 @@ ਇੱਕ ਮੁੱਕਣ ਵਾਲੀ ਪਰ ਨਾ-ਦੁਹਰਾਉਣ ਵਾਲੀ ਕਤਾਰ ਨੂੰ, ਸੰਬੰਧਤ ਸਟ੍ਰੀਮ ਜੋੜਦਿਆਂ, ਚਲਾਉਂਦੇ ਜਾਓ ਖੋਜ ਸੁਝਾਅ ਖੋਜ ਕਰਨ ਵੇਲੇ ਵਿਖਾਏ ਜਾਂਦੇ ਸੁਝਾਵਾਂ ਦੀ ਚੋਣ ਕਰੋ - ਖੋਜ ਇਤਿਹਾਸ ਨੂੰ ਵੇਖੋ + ਖੋਜ ਇਤਿਹਾਸ ਖੋਜ ਇਤਲਾਹਾਂ ਨੂੰ ਸਥਾਨਕ ਤੌਰ ਤੇ ਸਟੋਰ ਕਰੋ ਵੇਖੇ ਗਏ ਵੀਡੀਓਜ਼ ਦੀ ਸੂਚੀ ਵੇਖੇ ਗਏ ਵੀਡੀਓਜ਼ ਦੀ ਸੂਚੀ ਰੱਖੋ @@ -74,7 +74,7 @@ \"ਜੋੜਨ ਲਈ ਬਟਨ ਦਬਾ ਕੇ ਰੱਖੋ\" ਵਿਖਾਓ ਵੀਡੀਓ ਦੇ ਵੇਰਵੇ ਪੰਨੇ \'ਤੇ ਬੈਕਗ੍ਰਾਉਂਡ ਜਾਂ ਪੌਪ-ਅਪ ਬਟਨ ਨੱਪਣ \'ਤੇ ਸੁਝਾਅ ਵਿਖਾਓ ਅਣ-ਸਹਾਇਕ URL - ਮੂਲ ਦੇਸ਼ + ਸਮੱਗਰੀ ਦਾ ਮੂਲ ਦੇਸ਼ ਪਲੇਅਰ ਵਿਵਹਾਰ ਵੀਡੀਓ ਅਤੇ ਆਡੀਓ @@ -155,13 +155,13 @@ ਦੋਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ ਹਜ਼ਾਰ ਮਿਲੀਅਨ - ਬਿਲੀਅਨ + ਅਰਬ ਕੋਈ ਸਬਸਕ੍ਰਾਈਬਰ ਨਹੀਂ %s ਸਬਸਕ੍ਰਾਈਬਰ %s ਸਬਸਕ੍ਰਾਈਬਰ - ਕੋਈ ਵਿਊਜ਼ ਨਹੀਂ + ਕੋਈ ਵਿਊ ਨਹੀਂ %s ਵਿਊ %s ਵਿਊਜ਼ @@ -176,14 +176,14 @@ ਬਣਾਓ ਮਿਟਾਓ ਚੈੱਕ-ਸਮ - ਬਰਖਾਸਤ ਕਰੋ + ਖਾਰਿਜ ਕਰੋ ਨਾਮ ਬਦਲੋ ਠੀਕ ਹੈ ਫਾਈਲ ਦਾ ਨਾਮ ਥਰੈੱਡ ਤਰੁੱਟੀ ਨਿਊਪਾਈਪ ਡਾਊਨਲੋਡ ਕਰ ਰਹੀ ਹੈ - ਵੇਰਵਿਆਂ ਲਈ ਖੋਲੋ + ਵੇਰਵਿਆਂ ਲਈ ਟੈਪ ਕਰੋ ਕ੍ਰਿਪਾ ਕਰਕੇ ਉਡੀਕ ਕਰੋ… ਕਲਿਪ-ਬੋਰਡ ਵਿੱਚ ਕਾਪੀ ਹੋ ਗਿਆ ਹੈ ਬਾਅਦ ਵਿੱਚ ਸੈਟਿੰਗਾਂ ਵਿਚੋਂ ਇੱਕ ਡਾਊਨਲੋਡ ਫੋਲਡਰ ਨੂੰ ਚੁਣੋ @@ -198,12 +198,12 @@ ਵਟਾਂਦਰਾ ਚਿੰਨ ਅੱਖਰ ਅਤੇ ਅੰਕ ਬਹੁਤੇ ਖ਼ਾਸ ਅੱਖਰ - ਨਿਊਪਾਈਪ ਬਾਰੇ + ਨਿਊਪਾਈਪ ਬਾਰੇ ਵਿੱਚ ਜਾਣੋ ਤੀਜੀ ਧਿਰ ਦੇ ਲਾਈਸੈਂਸ - © %1$s ਵਲੋਂ %2$s, %3$s ਅਧੀਨ + %2$s ਵੱਲੋਂ © %1$s , %3$s ਅਧੀਨ ਐਪ ਬਾਰੇ ਤੇ ਆਮ ਸਵਾਲ ਲਾਈਸੈਂਸ - ਐਂਡਰਾਇਡ ਤੇ ਮੁਫ਼ਤ ਹਲਕੀ-ਫੁਲਕੀ ਸਟ੍ਰੀਮਿੰਗ। + ਐਂਡਰਾਇਡ ਦੇ ਲਈ ਹਲਕੀ ਅਤੇ ਮੁਫ਼ਤ ਸਟ੍ਰੀਮਿੰਗ ਐਪਲੀਕੇਸ਼ਨ। ਯੋਗਦਾਨ ਪਾਓ ਭਾਵੇਂ ਤੁਹਾਡੇ ਕੋਲ ਵਿਚਾਰ ਹਨ; ਅਨੁਵਾਦ, ਡਿਜ਼ਾਈਨ ਬਦਲਾਵ, ਕੋਡ ਦੀ ਸਫਾਈ, ਜਾਂ ਅਸਲ ਭਾਰੀ ਕੋਡ ਬਦਲਾਵ — ਹਰ ਮਦਦ ਦਾ ਸਦਾ ਸਵਾਗਤ ਹੈ। ਜਿੰਨਾ ਇਸ ਨੂੰ ਜ਼ਿਆਦਾ ਕੀਤਾ ਜਾਂਦਾ ਹੈ ਉੱਨਾ ਹੀ ਇਹ ਬਿਹਤਰ ਹੁੰਦਾ ਹੈ! ਗਿਟਹੱਬ ਤੇ ਵੇਖੋ @@ -217,7 +217,7 @@ ਲਾਈਸੈਂਸ ਪੜ੍ਹੋ ਇਤਿਹਾਸ ਇਤਿਹਾਸ - ਕੀ ਤੁਸੀਂ ਇਸ ਚੀਜ਼ ਨੂੰ ਖੋਜ-ਸੂਚੀ ਦੇ ਇਤਿਹਾਸ ਵਿੱਚੋਂ ਮਿਟਾਉਣਾ ਚਾਹੁੰਦੇ ਹੋ\? + ਕੀ ਤੁਸੀਂ ਇਸਨੂੰ ਖੋਜ ਇਤਿਹਾਸ ਵਿੱਚੋਂ ਮਿਟਾਉਣਾ ਚਾਹੁੰਦੇ ਹੋ\? ਆਖਰੀ ਚਲਾਈ ਗਈ ਸਭ ਤੋਂ ਜਿਆਦਾ ਚਲਾਈ ਗਈ ਮੁੱਖ ਪੰਨੇ ਦੀ ਸਮੱਗਰੀ @@ -232,7 +232,7 @@ ਕੋਈ ਵੈਧ ZIP ਫਾਈਲ ਨਹੀਂ ਹੈ ਚੇਤਾਵਨੀ: ਸਾਰੀਆਂ ਫਾਈਲਾਂ ਇੰਪੋਰਟ ਨਹੀਂ ਕੀਤੀਆਂ ਜਾ ਸਕੀਆਂ। ਇਹ ਤੁਹਾਡੇ ਮੌਜੂਦਾ ਸੈਟ-ਅਪ ਨੂੰ ਓਵਰ-ਰਾਈਡ ਕਰ ਦੇਵੇਗਾ। - ਰੁਝਾਨ ਵਿੱਚ + ਫਿਲਹਾਲ ਰੁਝਾਨ ਵਿੱਚ ਹੈ ਸਿਖਰਲੇ 50 ਨਵੇਂ ਅਤੇ ਤਾਜ਼ਾ-ਤਰੀਨ ਹਟਾਓ @@ -254,9 +254,9 @@ ਨਵੀਂ ਪਲੇ-ਲਿਸਟ ਨਾਮ ਬਦਲੋ ਨਾਮ - ਪਲੇ-ਸੂਚੀ ਵਿੱਚ ਸ਼ਾਮਲ ਕਰੋ + ਪਲੇ-ਸੂਚੀ ਵਿੱਚ ਜੋੜ੍ਹੋ ਬਤੌਰ ਪਲੇ-ਸੂਚੀ ਥੰਮਨੇਲ ਸੈੱਟ ਕਰੋ - ਬੁੱਕਮਾਰਕ ਪਲੇ-ਲਿਸਟ + ਪਲੇ-ਲਿਸਟ ਬੁੱਕਮਾਰਕ ਕਰੋ ਬੁੱਕਮਾਰਕ ਹਟਾਓ ਇਸ ਪਲੇ-ਲਿਸਟ ਨੂੰ ਮਿਟਾਉਣਾ ਹੈ\? ਪਲੇ-ਲਿਸਟ ਬਣਾਈ ਗਈ @@ -271,10 +271,10 @@ ਪਲੇਅਰ ਕੈਪਸ਼ਨ, ਟੈਕਸਟ ਸਕੇਲ ਅਤੇ ਬੈਕਗ੍ਰਾਊਂਡ ਸਟਾਈਲ ਨੂੰ ਬਦਲੋ। ਪ੍ਰਭਾਵੀ ਕਰਨ ਲਈ ਐਪ ਨੂੰ ਮੁੜ ਚਾਲੂ ਕਰਨ ਦੀ ਜ਼ਰੂਰਤ ਹੈ ਮੈਮੋਰੀ ਲੀਕ ਨਿਗਰਾਨੀ, ਐਪ ਨੂੰ ਆਕ੍ਰਿਆਸ਼ੀਲ ਬਣਾ ਸਕਦੀ ਹੈ ਜਦੋਂ ਹੀਪ ਡੰਪਿੰਗ ਹੁੰਦੀ ਹੈ ਚੱਕਰ ਤੋਂ ਬਾਹਰ ਤਰੁੱਟੀਆਂ ਰਿਪੋਰਟ ਕਰੋ - ਨਿਪਟਾਰੇ ਦੇ ਬਾਅਦ ਫਰੈਗਮੈਂਟ ਜਾਂ ਐਕਟੀਵਿਟੀ ਦੇ ਚੱਕਰ ਤੋਂ ਬਾਹਰ ਨਾ ਪਹੁੰਚਾਉਣ ਯੋਗ ਆਰ-ਐਕਸ ਅਪਵਾਦਾਂ ਬਾਰੇ ਜ਼ਬਰੀ ਰਿਪੋਰਟ ਕਰਨਾ + ਨਿਪਟਾਰੇ ਦੇ ਬਾਅਦ ਫਰੈਗਮੈਂਟ ਜਾਂ ਐਕਟੀਵਿਟੀ ਦੇ ਚੱਕਰ ਤੋਂ ਬਾਹਰ ਨਾ ਪਹੁੰਚਾਉਣ ਯੋਗ ਆਰ-ਐਕਸ ਅਪਵਾਦਾਂ ਬਾਰੇ ਜ਼ਬਰੀ ਰਿਪੋਰਟ ਕਰੋ ਇੰਪੋਰਟ - ਇੰਪੋਰਟ ਕਰੋ - ਐਕਸਪੋਰਟ ਕਰੋ + ਤੋਂ ਇੰਪੋਰਟ ਕਰੋ + ਤੇ ਐਕਸਪੋਰਟ ਕਰੋ ਇੰਪੋਰਟ ਹੋ ਰਿਹਾ ਹੈ… ਐਕਸਪੋਰਟ ਹੋ ਰਿਹਾ ਹੈ… ਇੰਪੋਰਟ ਫਾਈਲ @@ -318,8 +318,8 @@ ਐਪ ਸਵਿੱਚ ਕਰਨ ਤੇ ਮਿਨੀਮਾਈਜ਼ ਕਰੋ ਮੁੱਖ ਵੀਡੀਓ ਪਲੇਅਰ ਤੋਂ ਦੂਜੇ ਐਪ \'ਤੇ ਜਾਣ ਵੇਲ਼ੇ ਕਾਰਵਾਈ — %s ਕੋਈ ਨਹੀਂ - ਬੈਕਗ੍ਰਾਉਂਡ ਪਲੇਅਰ ਵਿੱਚ ਮਿਨੀਮਾਈਜ਼ ਕਰੋ - ਪੌਪ-ਅਪ ਪਲੇਅਰ ਵਿੱਚ ਮਿਨੀਮਾਈਜ਼ ਕਰੋ + ਬੈਕਗ੍ਰਾਉਂਡ ਪਲੇਅਰ ਵਿੱਚ ਬਦਲੋ + ਪੌਪ-ਅਪ ਪਲੇਅਰ ਵਿੱਚ ਬਦਲੋ ਚੁੱਪ ਦੌਰਾਨ ਤੇਜ਼ੀ ਨਾਲ ਅੱਗੇ ਕਰੋ ਕਦਮ ਰੀਸੈੱਟ @@ -329,35 +329,35 @@ ਯੂਜ਼ਰਸ ਅਨ-ਸਬਸਕ੍ਰਾਈਬ ਕਰੋ ਟੈਬ ਚੁਣੋ - ਮੂਲ ਭਾਸ਼ਾ ਸਮੱਗਰੀ - ਅਪਡੇਟਾਂ + ਸਮੱਗਰੀ ਦੀ ਮੂਲ ਭਾਸ਼ਾ + ਅੱਪਡੇਟਾਂ ਫਾਈਲ ਮਿਟਾ ਦਿੱਤੀ ਗਈ ਹੈ ਐਪ ਅੱਪਡੇਟ ਨੋਟੀਫਿਕੇਸ਼ਨ ਨਵੇਂ ਨਿਊਪਾਈਪ ਸੰਸਕਰਣਾਂ ਲਈ ਪ੍ਰਾਪਤ ਸੂਚਨਾਵਾਂ ਬਾਹਰੀ ਸਟੋਰੇਜ ਉਪਲਬਧ ਨਹੀਂ ਹੈ - ਬਾਹਰੀ SD ਕਾਰਡ ਤੇ ਡਾਊਨਲੋਡ ਕਰਨਾ ਸੰਭਵ ਨਹੀਂ ਹੈ। ਕੀ ਡਾਊਨਲੋਡ ਫੋਲਡਰ ਦੀ ਸਥਿਤੀ ਨੂੰ ਰੀਸੈਟ ਕੀਤਾ ਜਾਵੇ \? + ਬਾਹਰੀ SD ਕਾਰਡ ਤੇ ਡਾਊਨਲੋਡ ਕਰਨਾ ਸੰਭਵ ਨਹੀਂ ਹੈ। ਕੀ ਡਾਊਨਲੋਡ ਫ਼ੋਲਡਰ ਦੀ ਸਥਿਤੀ ਨੂੰ ਰੀਸੈਟ ਕੀਤਾ ਜਾਵੇ \? ਸਾਂਭੀਆਂ ਟੈਬਾਂ ਨਹੀਂ ਪੜ੍ਹ ਹੋਈਆਂ, ਇਸ ਲਈ ਡਿਫਾਲਟ ਟੈਬਾਂ ਦੀ ਵਰਤੋਂ ਹੋ ਰਹੀ ਹੈ ਡੀਫ਼ਾਲਟ ਮੁੜ-ਸਥਾਪਿਤ ਕਰੋ ਕੀ ਤੁਸੀਂ ਡਿਫਾਲਟ ਮੁੜ-ਸਥਾਪਿਤ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ\? ਸਬਸਕ੍ਰਾਈਬਰਾਂ ਦੀ ਗਿਣਤੀ ਅਣ-ਉਪਲਬਧ ਮੁੱਖ ਪੰਨੇ ਤੇ ਕਿਹੜੇ ਟੈਬ ਵਿਖਾਏ ਜਾਣਗੇ - ਅਪਡੇਟਾਂ - ਜਦੋਂ ਨਵਾਂ ਸੰਸਕਰਣ ਉਪਲਬਧ ਹੁੰਦਾ ਹੈ ਤਾਂ ਐਪ ਅੱਪਡੇਟ ਕਰਨ ਨੂੰ ਪੁੱਛਣ ਲਈ ਇੱਕ ਨੋਟੀਫਿਕੇਸ਼ਨ ਵਿਖਾਓ - ਲਿਸਟ ਵਿਊ ਮੋਡ - ਲਿਸਟ + ਅੱਪਡੇਟਾਂ + ਜਦੋਂ ਐਪ ਦੀ ਨਵੀਂ ਅੱਪਡੇਟ ਉਪਲੱਬਧ ਹੋਵੇ ਤਾਂ ਅੱਪਡੇਟ ਕਰਨ ਵਾਸਤੇ ਨੋਟੀਫਿਕੇਸ਼ਨ ਵਿਖਾਓ + ਸੂਚੀ ਵੇਖਣ ਦਾ ਢੰਗ + ਸੂਚੀ ਗਰਿੱਡ ਆਟੋ - ਨਿਊ-ਪਾਈਪ ਦੀ ਅਪਡੇਟ ਉਪਲਬੱਧ ਹੈ! + ਨਿਊ-ਪਾਈਪ ਦੀ ਅੱਪਡੇਟ ਉਪਲਬੱਧ ਹੈ! ਮੁਕੰਮਲ ਹੋਇਆ ਬਕਾਇਆ - ਰੁਕਿਆ - ਕਤਾਰਬੱਧ - Post-processing - ਕਤਾਰ ਕਰੋ + ਰੋਕਿਆ ਹੋਇਆ + ਕਤਾਰ ਵਿੱਚ + ਪੋਸਟ-ਪ੍ਰੋਸੈਸਿੰਗ + ਕਤਾਰਬੱਧ ਕਰੋ ਸਿਸਟਮ ਦੁਆਰਾ ਕਾਰਵਾਈ ਤੋਂ ਇਨਕਾਰ ਕੀਤਾ ਗਿਆ ਡਾਊਨਲੋਡ ਫੇਲ੍ਹ ਵਿਲੱਖਣ ਨਾਮ ਬਣਾਓ - overwrite + ਓਵਰਰਾਈਟ ਕਰੋ ਇਸ ਨਾਮ ਦੇ ਨਾਲ ਇੱਕ ਡਾਊਨਲੋਡ ਪਹਿਲਾਂ ਤੋਂ ਜਾਰੀ ਹੈ ਤਰੁੱਟੀ ਵਿਖਾਓ ਮੰਜ਼ਿਲ ਫੋਲਡਰ ਬਣਾਇਆ ਨਹੀਂ ਜਾ ਸਕਿਆ @@ -366,20 +366,20 @@ ਸਰਵਰ ਨਹੀਂ ਲੱਭ ਸਕਿਆ ਸਰਵਰ ਨਾਲ ਜੁੜ ਨਹੀਂ ਸਕਿਆ ਸਰਵਰ ਨੇ ਡਾਟਾ ਨਹੀਂ ਭੇਜਿਆ - ਸਰਵਰ ਮਲਟੀ-Threaded ਡਾਊਨਲੋਡਸ ਨੂੰ ਸਵੀਕਾਰ ਨਹੀਂ ਕਰਦਾ, ਇਸ ਨਾਲ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ @string/msg_threads = 1 + ਸਰਵਰ ਮਲਟੀ-ਥਰਿੱਡ ਡਾਊਨਲੋਡਾਂ ਨੂੰ ਸਵੀਕਾਰ ਨਹੀਂ ਕਰਦਾ ਹੈ, @string/msg_threads = 1 ਨਾਲ ਮੁੜ ਕੋਸ਼ਿਸ਼ ਕਰੋ ਨਹੀਂ ਲਭਿਆ - Post-processing ਫੇਲ੍ਹ - ਰੁਕੋ + ਪੋਸਟ ਪ੍ਰੋਸੈਸਿੰਗ ਫੇਲ੍ਹ ਹੋਈ + ਰੋਕੋ ਵੱਧ ਤੋਂ ਵੱਧ ਕੋਸ਼ਿਸ਼ਾਂ ਡਾਉਨਲੋਡ ਰੱਦ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ ਵੱਧ ਤੋਂ ਵੱਧ ਕੋਸ਼ਿਸ਼ਾਂ - ਮੀਟਰ ਕੀਤੇ ਨੈਟਵਰਕਸ ਤੇ ਰੁਕਾਵਟ - ਮੋਬਾਈਲ ਡਾਟਾ ਤੇ ਸਵਿੱਚ ਕਰਨ ਵੇਲੇ ਲਾਭਦਾਇਕ ਹੈ, ਹਾਲਾਂਕਿ ਕੁਝ ਡਾਉਨਲੋਡਾਂ ਨੂੰ ਮੁਅੱਤਲ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ + ਮੀਟਰ ਕੀਤੇ ਨੈੱਟਵਰਕ ਤੇ ਰੋਕੋ + ਮੋਬਾਈਲ ਡਾਟਾ ਦੇ ਇਸਤੇਮਾਲ ਵੇਲੇ ਫਾਇਦੇਮੰਦ ਹੈ, ਹਾਲਾਂਕਿ ਕੁਝ ਡਾਉਨਲੋਡਾਂ ਨੂੰ ਮੁਅੱਤਲ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ ਇਵੇੰਟਸ ਕਾਨਫਰੰਸਾਂ ਟਿੱਪਣੀਆਂ ਵਿਖਾਓ ਟਿੱਪਣੀਆਂ ਲੁਕਾਉਣ ਲਈ ਇਸਨੂੰ ਬੰਦ ਕਰੋ ਆਟੋ-ਪਲੇਅ - ਕੋਈ ਟਿੱਪਣੀ ਨਹੀਂ ਕੀਤੀ ਗਈ + ਕੋਈ ਟਿੱਪਣੀ ਨਹੀਂ ਟਿੱਪਣੀਆਂ ਲੋਡ ਨਹੀਂ ਹੋ ਸਕੀਆਂ ਬੰਦ ਕਰੋ ਪਲੇਅਬੈਕ ਫਿਰ ਚਾਲੂ ਕਰੋ @@ -388,31 +388,31 @@ ਸੂਚੀਆਂ ਵਿੱਚ ਪਲੇਅਬੈਕ ਸਥਿਤੀ ਸੂਚਕ ਵਿਖਾਓ ਡਾਟਾ ਮਿਟਾਓ ਵੇਖੀਆਂ ਸਟ੍ਰੀਮਾਂ ਦੀ ਇਤਿਹਾਸ ਸੂਚੀ ਨੂੰ ਮਿਟਾ ਦਿੱਤਾ ਗਿਆ - ਪਲੇਬੈਕ ਸਥਿਤੀਆਂ ਨੂੰ ਮਿਟਾ ਦਿੱਤਾ ਗਿਆ ਹੈ + ਪਲੇਬੈਕ ਸਥਿਤੀਆਂ ਨੂੰ ਮਿਟਾ ਦਿੱਤਾ ਗਿਆ ਫਾਈਲ ਤਬਦੀਲ ਕੀਤੀ ਜਾਂ ਮਿਟਾਈ ਗਈ ਇਸ ਨਾਮ ਵਾਲੀ ਇੱਕ ਫਾਈਲ ਪਹਿਲਾਂ ਹੀ ਮੌਜੂਦ ਹੈ ਇਸ ਨਾਮ ਨਾਲ ਡਾਉਨਲੋਡ ਕੀਤੀ ਫਾਈਲ ਪਹਿਲਾਂ ਹੀ ਮੌਜੂਦ ਹੈ - ਫਾਈਲ Overwrite ਨਹੀਂ ਹੋ ਸਕਦੀ - ਇਸ ਨਾਮ ਦੇ ਨਾਲ ਇੱਥੇ ਇੱਕ ਬਕਾਇਆ ਡਾਊਨਲੋਡ ਹੈ - ਫਾਈਲ ਤੇ ਕੰਮ ਕਰਦੇ ਸਮੇਂ NewPipe ਬੰਦ ਕੀਤੀ ਗਈ ਸੀ + ਫਾਈਲ ਓਵਰਰਾਈਟ ਨਹੀਂ ਹੋ ਸਕਦੀ + ਇਸ ਨਾਮ ਦਾ ਇੱਕ ਡਾਊਨਲੋਡ ਬਕਾਇਆ ਹੈ + ਫਾਈਲ ਤੇ ਕੰਮ ਕਰਦੇ ਸਮੇਂ ਨਿਊਪਾਈਪ ਬੰਦ ਕੀਤੀ ਗਈ ਡਿਵਾਈਸ ਤੇ ਕੋਈ ਜਗ੍ਹਾ ਨਹੀਂ ਬਚੀ ਹੈ - Progress lost, ਕਿਉਂਕਿ ਫਾਈਲ ਮਿਟ ਗਈ ਸੀ - ਕੁਨੈਕਸ਼ਨ timeout - ਕੀ ਤੁਸੀਂ ਆਪਣਾ ਡਾਊਨਲੋਡ ਇਤਿਹਾਸ ਸਾਫ਼ ਕਰਨਾ ਜਾਂ ਡਾਊਨਲੋਡ ਕੀਤੀਆਂ ਸਾਰੀਆਂ ਫ਼ਾਈਲਾਂ ਮਿਟਾਉਣਾ ਚਾਹੁੰਦੇ ਹੋ\? - ਡਾਊਨਲੋਡ ਸੀਮਾ ਕਤਾਰ ਵਿੱਚ - ਇੱਕ ਸਮੇਂ ਤੇ ਇੱਕੋ ਡਾਊਨਲੋਡ ਚੱਲੇਗਾ + ਪ੍ਰਗਤੀ ਖਤਮ ਹੋ ਗਈ, ਕਿਉਂਕਿ ਫਾਈਲ ਮਿਟਾਈ ਗਈ + ਕੁਨੈਕਸ਼ਨ ਦਾ ਸਮਾਂ ਸਮਾਪਤ + ਕੀ ਤੁਸੀਂ ਆਪਣਾ ਡਾਊਨਲੋਡ ਇਤਿਹਾਸ ਹਟਾਉਣਾ ਚਾਹੁੰਦੇ ਹੋ ਜਾਂ ਡਾਊਨਲੋਡ ਕੀਤੀਆਂ ਸਾਰੀਆਂ ਫ਼ਾਈਲਾਂ ਮਿਟਾਉਣਾ ਚਾਹੁੰਦੇ ਹੋ\? + ਡਾਊਨਲੋਡ ਕਤਾਰ ਸੀਮਤ ਕਰੋ + ਇੱਕ ਹੀ ਸਮੇਂ ਤੇ ਇੱਕੋ ਡਾਊਨਲੋਡ ਚੱਲੇਗਾ ਡਾਊਨਲੋਡ ਸ਼ੁਰੂ ਕਰੋ - ਡਾਊਨਲੋਡਸ ਰੋਕੋ - ਪੁੱਛੋ ਕਿੱਥੇ ਡਾਊਨਲੋਡ ਕਰਨਾ ਹੈ + ਡਾਊਨਲੋਡ ਰੋਕੋ + ਡਾਊਨਲੋਡ ਕਿੱਥੇ ਕਰਨਾ ਹੈ, ਦੇ ਲਈ ਪੁੱਛੋ ਤੁਹਾਨੂੰ ਹਰ ਵਾਰ ਪੁੱਛਿਆ ਜਾਵੇਗਾ ਕਿ ਡਾਊਨਲੋਡ ਨੂੰ ਕਿੱਥੇ ਸਾਂਭਣਾ ਹੈ। \nਜੇ ਤੁਸੀਂ ਡਾਊਨਲੋਡ ਨੂੰ ਕਿਸੇ ਬਾਹਰੀ SD ਕਾਰਡ ਤੇ ਸਾਂਭਣਾ ਚਾਹੁੰਦੇ ਹੋ ਤਾਂ ਸਿਸਟਮ ਡਾਊਨਲੋਡ ਫ਼ੋਲਡਰ ਚੋਣਕਾਰ (SAF) ਚਾਲੂ ਕਰੋ ਸਿਸਟਮ ਡਾਊਨਲੋਡ ਫ਼ੋਲਡਰ ਚੋਣਕਾਰ (SAF) ਦੀ ਵਰਤੋਂ ਕਰੋ - \'ਸਟੋਰੇਜ ਐਕਸੈਸ ਫ਼ਰੇਮਵਰਕ\' ਬਾਹਰੀ SD ਕਾਰਡ ਵਿੱਚ ਡਾਊਨਲੋਡ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ + \'ਸਟੋਰੇਜ ਐਕਸੈਸ ਫ਼ਰੇਮਵਰਕ\' ਬਾਹਰੀ SD ਕਾਰਡ ਵਿੱਚ ਡਾਊਨਲੋਡ ਕਰਨ ਦਿੰਦਾ ਹੈ ਥੰਮਨੇਲ ਨੂੰ 1:1 ਮਾਪ ਦਾ ਕਰੋ %s ਲਈ ਨਤੀਜੇ ਵਿਖਾਏ ਜਾ ਰਹੇ ਹਨ ਜਦੋਂ ਉਪਲਬਧ ਹੋਵੇ ਤਾਂ ਖ਼ਾਸ ਫ਼ੀਡ ਤੋਂ ਮੰਗਵਾਓ ਤੇਜ਼ ਫ਼ੀਡ ਮੋਡ ਇਸ ਬਾਰੇ ਕੋਈ ਹੋਰ ਜਾਣਕਾਰੀ ਮੁੱਹਈਆ ਨਹੀਂ ਕਰਾਉਂਦਾ। - ਐਕਸੋਪਲੇਅਰ ਦੀਆਂ ਬੰਦਿਸ਼ਾਂ ਕਰਕੇ ਲੱਭਣ ਮਿਆਦ %d ਸਕਿੰਟ ਸੈੱਟ ਕੀਤੀ ਗਈ ਸੀ + ਐਕਸੋਪਲੇਅਰ ਦੀ ਬੰਦਿਸ਼ ਕਰਕੇ ਸੀਕ ਕਰਨ ਦੀ ਮਿਆਦ %d ਸਕਿੰਟ ਸੈੱਟ ਕੀਤੀ ਗਈ ਇਹ ਡਾਊਨਲੋਡ ਮੁੜ-ਪ੍ਰਾਪਤ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ ਮੁੜ-ਪ੍ਰਾਪਤੀ ਜੇ ਤੁਹਾਨੂੰ ਕਾਲ਼ੀ ਸਕਰੀਨ ਮਿਲੇ ਜਾਂ ਵੀਡਿਓ ਰੁਕ-ਰੁਕ ਕੇ ਚੱਲੇ ਤਾਂ ਮੀਡੀਆ ਟਨਲਿੰਗ ਬੰਦ ਕਰ ਦਿਓ। @@ -424,7 +424,7 @@ ਹਾਲੇ ਕੋਈ ਵੀ ਪਲੇ-ਸੂਚੀ ਬੁੱਕਮਾਰਕ ਨਹੀਂ ਕੀਤੀ ਹੋਈ ਡਿਫ਼ਾਲਟ ਕਿਓਸਕ ਹੈਸ਼ ਦਾ ਲੇਖਾ-ਜੋਖਾ ਹੋ ਰਿਹਾ ਹੈ - ਸੇਵਾ ਟੌਗਲ ਕਰੋ, ਮੌਜੂਦਾ ਚੋਣ: + ਸੇਵਾ ਚੁਣੋ, ਮੌਜੂਦਾ ਚੋਣ: ਮਿਹਰਬਾਨੀ ਕਰਕੇ ਜਾਂਚ ਲਓ ਕਿ ਤੁਹਾਡੇ ਵਾਲ੍ਹੇ ਕ੍ਰੈਸ਼ ਦੀ ਗੱਲ ਕਰਦਾ ਕੋਈ ਮਸਲਾ ਪਹਿਲਾਂ ਹੀ ਮੌਜੂਦ ਤਾਂ ਨਹੀਂ। ਇੱਕੋ ਮਸਲੇ ਦੀਆਂ ਦੋ ਜਾਂ ਵੱਧ ਨਕਲਾਂ ਬਣਾ ਕੇ ਤੁਸੀਂ ਸਾਡੇ ਤੋਂ ਉਹ ਵਕਤ ਖੋਹ ਲੈਂਦੇ ਹੋ ਜੋ ਅਸੀਂ ਅਸਲੀ ਮਸਲੇ ਦੇ ਹੱਲ ਲਈ ਲਾਉਣਾ ਸੀ। ਫ਼ਾਰਮੈਟਡ ਰਿਪੋਰਟ ਨਕਲ ਕਰੋ reCAPTCHA ਹੱਲ ਕਰਦੇ ਵੇਲ਼ੇ ਨਿਊਪਾਈਪ ਵਿੱਚ ਜਮ੍ਹਾਂ ਹੋਣ ਵਾਲ਼ੀਆਂ ਕੁਕੀਜ਼ ਸਾਫ਼ ਕਰੋ @@ -442,12 +442,12 @@ ਜਨਤਕ ਮੇਜ਼ਬਾਨ ਸਹਾਇਤਾ - ਭਾਸ਼ਾ/ਬੋਲੀ + ਭਾਸ਼ਾ ਉਮਰ ਹੱਦ ਪਰਦੇਦਾਰੀ ਲਾਈਸੈਂਸ ਟੈਗ - ਵਰਗ + ਸ਼੍ਰੇਣੀ ਵੇਰਵੇ \'ਚੋਂ ਲਿਖਤ ਚੁਣਨਾ ਬੰਦ ਕਰੋ ਵੇਰਵੇ \'ਚੋਂ ਲਿਖਤ ਚੁਣਨਾ ਚਾਲੂ ਕਰੋ ਤੁਸੀਂ ਹੁਣ ਵੇਰਵੇ \'ਚੋਂ ਲਿਖਤ ਨੂੰ ਚੁਣ ਸਕਦੇ ਹੋ। ਨੋਟ ਕਰੋ ਕਿ ਪੰਨਾ ਜਗ-ਬੁੱਝ ਸਕਦਾ ਹੈ ਅਤੇ ਚੋਣ ਮੋਡ ਵਿੱਚ ਹੋਣ ਵੇਲੇ ਲਿੰਕ ਕਲਿੱਕ ਕਰਨ ਯੋਗ ਨਹੀਂ ਹੋ ਸਕਦੇ ਹਨ। @@ -456,13 +456,13 @@ ਆਪਣੀ ਪਸੰਦੀਦਾ ਰਾਤ ਦੀ ਥੀਮ ਚੁਣੋ — %s ਆਟੋਮੈਟਿਕ (ਡਿਵਾਈਸ ਥੀਮ) ਰੇਡੀਓ - ਉਚੇਚੀ ਪੇਸ਼ਕਸ਼ + ਫੀਚਰਡ ਇਹ ਸਮੱਗਰੀ ਸਿਰਫ਼ ਉਹਨਾਂ ਵਰਤੋਂਕਾਰਾਂ ਲਈ ਉਪਲਬਧ ਹੈ ਜਿੰਨ੍ਹਾਂ ਨੇ ਇਸਦੇ ਲਈ ਕੀਮਤ ਦਿੱਤੀ ਹੈ, ਇਸ ਕਰਕੇ ਨਿਊ-ਪਾਈਪ ਦੁਆਰਾ ਚਲਾਈ ਜਾਂ ਡਾਊਨਲੋਡ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ। - %s ਨੇ ਇਹ ਕਰਨ ਦੱਸਿਆ ਹੈ: + %s ਇਸਦਾ ਕਾਰਨ ਪ੍ਰਦਾਨ ਕਰਦਾ ਹੈ: ਖਾਤਾ ਬੰਦ ਕੀਤਾ ਗਿਆ ਇਹ ਵੀਡੀਓ ਸਿਰਫ਼ ਯੂਟਿਊਬ ਮਿਊਜ਼ਿਕ ਦੇ ਪ੍ਰੀਮੀਅਮ ਮੈਂਬਰਾਂ ਲਈ ਉਪਲਬਧ ਹੈ, ਇਸ ਕਰਕੇ ਨਿਊ-ਪਾਈਪ ਦੁਆਰਾ ਚਲਾਈ ਜਾਂ ਡਾਊਨਲੋਡ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ। ਇਹ ਸਮੱਗਰੀ ਨਿੱਜੀ (ਪ੍ਰਾਈਵੇਟ) ਹੈ, ਇਸ ਕਰਕੇ ਨਿਊ-ਪਾਈਪ ਦੁਆਰਾ ਚਲਾਈ ਜਾਂ ਡਾਊਨਲੋਡ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ। - ਇਹ ਸਮੱਗਰੀ ਤੁਹਾਡੇ ਮੁਲਕ ਵਿੱਚ ਉਪਲਬਧ ਨਹੀਂ। + ਇਹ ਸਮੱਗਰੀ ਤੁਹਾਡੇ ਮੁਲਕ ਵਿੱਚ ਉਪਲਬਧ ਨਹੀਂ ਹੈ। ਤੁਹਾਡੇ ਡਿਵਾਈਸ ਦੀ ਕੋਈ ਵੀ ਐਪ ਇਸ ਨੂੰ ਖੋਲ੍ਹ ਨਹੀਂ ਸਕਦੀ ਚੈਪਟਰ ਹਾਲੀਆ @@ -481,13 +481,13 @@ \nਕੀ ਤੁਸੀਂ ਇਸ ਚੈਨਲ ਨੂੰ ਅਨ-ਸਬਸਕ੍ਰਾਈਬ ਕਰਨਾ ਚਾਹੋਗੇ\? \'%s\' ਵਾਸਤੇ ਫ਼ੀਡ ਲੋਡ ਨਹੀਂ ਹੋ ਸਕੀ। ਫ਼ੀਡ ਲੋਡ ਕਰਨ ਵਿੱਚ ਤਰੁੱਟੀ ਰਹੀ - ਹਮੇਸ਼ਾ ਅਪਡੇਟ ਕਰੋ - ਫ਼ੀਡ ਅਪਡੇਟ ਦੀ ਹੱਦ + ਹਮੇਸ਼ਾਂ ਅੱਪਡੇਟ ਕਰੋ + ਫ਼ੀਡ ਅੱਪਡੇਟ ਦੀ ਹੱਦ ਫ਼ੀਡ ਸਿਰਫ਼ ਉਹ ਸਬਸਕ੍ਰਿਪਸ਼ਨਾਂ ਵਿਖਾਓ ਜੋ ਕਿਸੇ ਗਰੁੱਪ ਵਿੱਚ ਨਹੀਂ ਪਾਈਆਂ ਹੋਈਆਂ ਨਵਾਂ ਕੀ ਤੁਸੀਂ ਇਸ ਗਰੁੱਪ ਨੂੰ ਮਿਟਾਉਣਾ ਚਾਹੁੰਦੇ ਹੋ\? - ਖ਼ਾਲੀ ਗਰੁੱਪ ਨਾਮ + ਗਰੁੱਪ ਦਾ ਨਾਮ ਨਹੀਂ %d ਚੁਣੀ %d ਚੁਣੀਆਂ @@ -496,8 +496,8 @@ ਸੁਬਸਕ੍ਰਿਪਸ਼ਨਾਂ ਚੁਣੋ ਫ਼ੀਡ \'ਤੇ ਅਮਲ ਹੋ ਰਿਹੈ… ਫ਼ੀਡ ਲੋਡ ਹੋ ਰਹੀ ਹੈ… - ਲੋਡ ਨਹੀਂ ਹੋਇਆ: %d - ਫ਼ੀਡ ਆਖ਼ਰੀ ਵਾਰ %s ਨੂੰ ਅਪਡੇਟ ਹੋਈ ਸੀ + ਲੋਡ ਨਹੀਂ ਹੋਏ: %d + ਫ਼ੀਡ ਆਖ਼ਰੀ ਵਾਰ %s ਨੂੰ ਅੱਪਡੇਟ ਹੋਈ ਚੈਨਲ ਗਰੁੱਪ %d ਦਿਨ @@ -516,18 +516,18 @@ %d ਸਕਿੰਟ ਹਾਂ, ਅਤੇ ਅੱਧ-ਪਚੱਧੀਆਂ ਵੇਖੀਆਂ ਹੋਈਆਂ ਵੀ - ਵੀਡੀਓਜ਼ ਜੋ ਪਲੇ-ਸੂਚੀ ਵਿੱਚ ਜੋੜੇ ਜਾਣ ਤੋਂ ਪਹਿਲਾਂ ਅਤੇ ਬਾਅਦ ਵਿੱਚ ਵੇਖੀਆਂ ਜਾ ਚੁੱਕੀਆਂ ਹਨ, ਉਹ ਹਟਾ ਦਿੱਤੀਆਂ ਜਾਣਗੀਆਂ. + ਪਲੇ-ਸੂਚੀ ਵਿੱਚ ਸ਼ਾਮਿਲ, ਪਹਿਲਾਂ ਚਾਹੇ ਬਾਅਦ ਵਿੱਚ ਵੇਖੇ ਜਾ ਚੁੱਕੇ ਵੀਡੀਓ ਹਟਾ ਦਿੱਤੇ ਜਾਣਗੇ। \nਕੀ ਵਾਕਿਆ ਹੀ ਤੁਸੀਂ ਇਹਨਾਂ ਨੂੰ ਹਟਾਉਣਾ ਚਾਹੁੰਦੇ ਹੋ\? ਇਸ ਕਾਰਵਾਈ ਨੂੰ ਵਾਪਸ ਨਹੀਂ ਮੋੜਿਆ ਜਾ ਸਕਣਾ! - ਵੇਖੀਆਂ ਹੋਈਆਂ ਵੀਡੀਓਜ਼ ਹਟਾਉਣੀਆਂ ਹਨ\? - ਵੇਖੀਆਂ ਹੋਈਆਂ ਹਟਾਓ + ਵੇਖੇ ਹੋਏ ਵੀਡੀਓ ਹਟਾ ਦੇਈਏ\? + ਵੇਖੇ ਹੋਏ ਨੂੰ ਹਟਾਓ ਸਿਸਟਮ ਡਿਫ਼ਾਲਟ - ਐਪ ਭਾਸ਼ਾ - ਕੋਈ ਸਥਿਤੀ ਚੁਣੋ - \'ਸਟੋਰੇਜ ਐਕਸੈੱਸ ਫ਼ਰੇਮਵਰਕ\' ਐਂਡਰਾਇਡ 10 ਤੋਂ ਕੰਮ ਕਰਨਾ ਸ਼ੁਰੂ ਕਰਦਾ ਹੈ - ਤੁਹਾਨੂੰ ਹਰ ਵਾਰ ਪੁੱਛਿਆ ਜਾਵੇਗਾ ਕਿ ਡਾਊਨਲੋਡ ਨੂੰ ਕਿੱਥੇ ਸਾਂਭਣਾ ਹੈ + ਐਪ ਦੀ ਭਾਸ਼ਾ + ਕੋਈ ਇੰਸਟੈਂਸ ਚੁਣੋ + ਐਂਡਰਾਇਡ 10 ਤੋਂ ਸ਼ੁਰੂ ਹੋ ਕੇ ਕੇਵਲ \'ਸਟੋਰੇਜ ਐਕਸੈੱਸ ਫ਼ਰੇਮਵਰਕ\' ਸਮਰਥਿਤ ਹੈ + ਤੁਹਾਨੂੰ ਪੁੱਛਿਆ ਜਾਵੇਗਾ ਕਿ ਹਰ ਡਾਊਨਲੋਡ ਨੂੰ ਕਿੱਥੇ ਸਾਂਭਣਾ ਹੈ ਡਾਊਨਲੋਡ ਕੀਤੀਆਂ ਫ਼ਾਈਲਾਂ ਮਿਟਾਓ - ਡਾਊਨਲੋਡ ਇਤਿਹਾਸ ਸਾਫ਼ ਕਰੋ - ਕਦੇ ਵੀ ਨਹੀਂ + ਡਾਊਨਲੋਡ ਇਤਿਹਾਸ ਹਟਾਓ + ਕਦੇ ਨਹੀਂ ਸਿਰਫ਼ ਵਾਈ-ਫ਼ਾਈ \'ਤੇ ਪਲੇਬੈਕ ਆਪਣੇ-ਆਪ ਸ਼ੁਰੂ ਕਰੋ — %s ਐਪ ਕ੍ਰੈਸ਼ ਕਰੋ @@ -536,8 +536,8 @@ ਕਤਾਰਬੱਧ ਹੋ ਗਿਆ ਕਤਾਰਬੱਧ ਕਰੋ ਚੈਨਲ ਵੇਰਵੇ ਵਿਖਾਓ - ਕਤਾਰ ਚਲਾਓ - ਸਭ ਤੋਂ ਵੱਧ ਪਸੰਦ + ਪਲੇਅ ਕਤਾਰ + ਵਧੇਰੇ ਪਸੰਦ ਕੀਤੇ ਗਏ ਹਾਲ ਹੀ ਵਿੱਚ ਸ਼ਾਮਿਲ ਸਥਾਨਕ ਭਾਸ਼ਾ ਐਪ ਨੂੰ ਦੋਬਾਰਾ ਚਲਾਉਣ \'ਤੇ ਬਦਲੇਗੀ @@ -563,7 +563,7 @@ ਟਿੱਪਣੀਆਂ ਗਿਟਹੱਬ \'ਤੇ ਜਾ ਕੇ ਇਤਲਾਹ ਦਿਓ ਦੂਜੀਆਂ ਐਪਾਂ ਦੇ ਉੱਤੇ ਵਿਖਾਉਣ ਦੀ ਇਜਾਜ਼ਤ ਦਿਓ - ਸਾਰੀਆਂ ਪਲੇ-ਸਥਿਤੀਆਂ ਮਿਟਾਉਣੀਆਂ ਹਨ\? + ਕੀ ਸਾਰੀਆਂ ਪਲੇ-ਸਥਿਤੀਆਂ ਮਿਟਾਉਣੀਆਂ ਹਨ\? ਸਾਰੀਆਂ ਪਲੇ-ਸਥਿਤੀਆਂ ਮਿਟਾਉਂਦਾ ਹੈ ਪਲੇ-ਸਥਿਤੀਆਂ ਮਿਟਾਓ ਵੀਡੀਓ ਹੈਸ਼ ਇਤਲਾਹ @@ -577,14 +577,14 @@ ਯੂਟਿਊਬ \"ਪਾਬੰਦੀਸ਼ੁਦਾ ਮੋਡ\" ਉਪਲਬਧ ਕਰਾਉਂਦਾ ਹੈ ਜੋ ਬਾਲਗਾਂ ਵਾਲ਼ੀ ਸਮੱਗਰੀ ਲੁਕਾਉਂਦਾ ਹੈ ਯੂਟਿਊਬ ਦਾ ਪਾਬੰਦੀਸ਼ੁਦਾ ਮੋਡ ਚਾਲੂ ਕਰੋ ਉਹ ਸਮੱਗਰੀ ਵੀ ਵਿਖਾਓ ਜੋ ਉਮਰ-ਸੀਮਾ ਕਰਕੇ ਬੱਚਿਆਂ ਲਈ ਸ਼ਾਇਦ ਸਹੀ ਨਾ ਹੋਵੇ (ਜਿਵੇਂ 18+) - ਸਥਿਤੀ ਪਹਿਲਾਂ ਨੂੰ ਮੌਜੂਦ ਹੈ + ਇੰਸਟੈਂਸ ਪਹਿਲਾਂ ਤੋਂ ਮੌਜੂਦ ਹੈ ਸਿਰਫ਼ HTTP URLs ਹੀ ਮੰਨਣਯੋਗ ਹਨ - ਸਥਿਤੀ ਦੀ ਜਾਇਜ਼ਗੀ ਤਸਦੀਕ ਨਹੀਂ ਹੋ ਸਕੀ - ਸਥਿਤੀ URL ਦਾਖ਼ਲ ਕਰੋ - ਸਥਿਤੀਆਂ ਜੋੜੋ - ਤੁਹਾਡੀਆਂ ਪਸੰਦੀਦਾ ਸਥਿਤੀਆਂ %s \'ਤੇ ਲੱਭੋ - ਆਪਣੀ ਪਸੰਦੀਦਾ ਪੀਅਰਟਿਊਬ ਸਥਿਤੀਆਂ ਚੁਣੋ - ਪੀਅਰਟਿਊਬ ਸਥਿਤੀਆਂ + ਇੰਸਟੈਂਸ ਦੀ ਜਾਇਜ਼ਗੀ ਤਸਦੀਕ ਨਹੀਂ ਹੋ ਸਕੀ + ਇੰਸਟੈਂਸ URL ਦਾਖ਼ਲ ਕਰੋ + ਇੰਸਟੈਂਸ ਜੋੜੋ + ਤੁਹਾਡੇ ਪਸੰਦੀਦਾ ਇੰਸਟੈਂਸ %s \'ਤੇ ਲੱਭੋ + ਆਪਣੇ ਪਸੰਦੀਦਾ ਪੀਅਰਟਿਊਬ ਇੰਸਟੈਂਸ ਚੁਣੋ + ਪੀਅਰਟਿਊਬ ਇੰਸਟੈਂਸ URL ਪਛਾਣ ਨਹੀਂ ਹੋਇਆ। ਕਿਸੇ ਹੋਰ ਐਪ ਨਾਲ਼ ਖੋਲ੍ਹਣਾ ਹੈ\? ਆਟੋ ਕਤਾਰਬੱਧ ਕਰੋ ਸਟ੍ਰੀਮ ਦੇ ਕਰਤਾ, ਸਮੱਗਰੀ ਜਾਂ ਖੋਜ ਬੇਨਤੀ ਵਾਲੇ ਵਾਧੂ ਜਾਣਕਾਰੀ ਬਕਸਿਆਂ ਵਾਲ਼ੀ ਮੈਟਾ ਜਾਣਕਾਰੀ ਲੁਕਾਉਣ ਲਈ ਇਸਨੂੰ ਬੰਦ ਕਰ ਦਿਓ @@ -610,7 +610,7 @@ ਦੂਜਾ ਕਾਰਵਾਈ ਬਟਨ ਪਹਿਲਾ ਕਾਰਵਾਈ ਬਟਨ ਨਾਂ ਵਿਖਾਓ - ਚਾਲੂ ਕਰੋ + ਆਨ , ਡਾਉਨਲੋਡ ਮੁਕੰਮਲ @@ -622,7 +622,7 @@ ਮੋਜੂਦਾ ਚੱਲ ਰਹੀ ਸਟ੍ਰੀਮ ਦੀ ਨੋਟੀਫਿਕੇਸ਼ਨ ਸੰਰਚਨਾ ਕਰੋ ਨੋਟੀਫਿਕੇਸ਼ਨ ਨਵੀਂਆਂ ਸਟ੍ਰੀਮਾਂ - ਸਬਸਕ੍ਰਿਪਸ਼ਨ ਦੁਆਰਾ ਨਵੀਂ ਸਟ੍ਰੀਮ ਦੇ ਨੋਟੀਫਿਕੇਸ਼ਨ + ਸਬਸਕ੍ਰਿਪਸ਼ਨਜ਼ ਦੇ ਨਵੀਂ ਸਟ੍ਰੀਮ ਦੇ ਨੋਟੀਫਿਕੇਸ਼ਨ ਨਿਊਪਾਈਪ ਖਾਮੀ ਤੋਂ ਪ੍ਰਭਾਵਤ ਹੋਈ ਹੈ, ਇੱਥੇ ਨੱਪ ਕੇ ਰਿਪੋਰਟ ਕਰੋ ਇੱਕ ਖਾਮੀ ਪ੍ਰਭਾਵੀ ਹੋਈ ਹੈ, ਨੋਟੀਫੀਕੇਸ਼ਨ ਵੇਖੋ ਆਈਟਮਾਂ ਨੂੰ ਇੱਕ ਪਾਸੇ ਖਿੱਚ ਕੇ ਹਟਾਓ @@ -644,8 +644,8 @@ %s ਨਵੀਂ ਸਟ੍ਰੀਮ %s ਨਵੀਆਂ ਸਟ੍ਰੀਮਾਂ - ਨਵੀਂਆ ਫੀਡ ਇਕਾਈਆਂ - ਸੂਚਨਾ ਪ੍ਰਾਪਤ ਕਰੋ + ਨਵੀਆਂ ਫੀਡ ਆਈਟਮਾਂ + ਸੂਚਨਾ ਪਾਓ ਬਾਹਰੀ ਪਲੇਅਰਾਂ ਲਈ ਕੁਆਲਿਟੀ ਚੁਣੋ ਤਰੁੱਟੀ ਰਿਪੋਰਟ ਨੋਟੀਫਿਕੇਸ਼ਨ ਖ਼ਾਮੀਆਂ ਰਿਪੋਰਟ ਕਰਨ ਲਈ ਨੋਟੀਫਿਕੇਸ਼ਨ @@ -653,12 +653,12 @@ ਲੀਕ-ਕੈਨਰੀ ਉਪਲੱਬਧ ਨਹੀਂ ਹੈ ਤਰੁੱਟੀ ਤੇ ਸਨੈਕਬਾਰ ਵਿਖਾਓ ਕੁਝ ਸੇਵਾਵਾਂ ਵਿੱਚ ਹੀ ਉਪਲੱਬਧ ਇਹ ਤਰੀਕਾ ਸਬਸਕ੍ਰਿਪਸ਼ਨ ਫੀਡ ਵਿੱਚ ਤੇਜ ਜਾਣਕਾਰੀ ਮੁਹੱਈਆ ਕਰਵਾਉਂਦਾ ਹੈ, ਪਰ ਕੁਝ ਗਿਣਤੀ ਦੀਆਂ ਹੀ ਆਈਟਮ ਪ੍ਰਦਾਨ ਕਰ ਸਕਦਾ ਹੈ ਉਹ ਵੀ ਅਕਸਰ ਬਿਨਾਂ ਪੂਰੀ ਜਾਣਕਾਰੀ( ਜਿਵੇਂ ਅਵਧੀ, ਸਟ੍ਰੀਮ ਦੀ ਕਿਸਮ, ਕੋਈ ਸਟ੍ਰੀਮ ਲਾਈਵ ਹੈ, ਨਹੀਂ ਦੱਸਦਾ) - ਇਹ ਸਾਊਂਡਕਲਾਊਡ ਗੋ-ਪਲੱਸ ਟਰੈਕ ਹੈ, ਤੁਹਾਡੇ ਦੇਸ਼ ਵਿੱਚ ਇਹ ਸਟ੍ਰੀਮ ਜਾਂ ਡਾਊਨਲੋਡ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ। + ਇਹ ਸਾਊਂਡਕਲਾਊਡ ਗੋ-ਪਲੱਸ ਟਰੈਕ ਹੈ, ਘੱਟੋ-ਘੱਟ ਤੁਹਾਡੇ ਦੇਸ਼ ਵਿੱਚ, ਇਸ ਲਈ ਇਹ ਸਟ੍ਰੀਮ ਜਾਂ ਡਾਊਨਲੋਡ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ। ਅਗਿਆਤ ਫਾਰਮੈਟ ਅਗਿਆਤ ਕੁਆਲਿਟੀ - ਆਮ ਸਵਾਲ + ਅਕਸਰ ਪੁੱਛੇ ਜਾਂਦੇ ਸਵਾਲ ਵੈੱਬਸਾਈਟ \'ਤੇ ਵੇਖੋ - ਸਟ੍ਰੀਮ ਲੋਡ ਹੋ ਰਹੀ ਹੈ… + ਸਟ੍ਰੀਮ ਦੇ ਵਿਵਰਣ ਲੋਡ ਹੋ ਰਹੇ ਹਨ… ਕਾਰਵਾਈ ਵਿੱਚ... ਕੁਝ ਸਮਾਂ ਲੱਗ ਰਿਹਾ ਹੈ \"ਪਲੇਅਰ ਕਰੈਸ਼ ਕਰੋ\" ਵਿਖਾਉ ਵਰਤਦੇ ਸਮੇਂ ਪਲੇਅਰ ਕਰੈਸ਼ ਦਾ ਵਿਕਲਪ ਵਿਖਾਉਂਦਾ ਹੈ @@ -673,8 +673,8 @@ ਘੱਟ ਗੁਣਵੱਤਾ (ਛੋਟਾ ਆਕਾਰ) ਡਿਸਕ ਤੋਂ ਸਾਰੀਆਂ ਡਾਊਨਲੋਡ ਕੀਤੀਆਂ ਫਾਈਲਾਂ ਹਟਾਓ\? - %1$s ਡਾਊਨਲੋਡ ਡਿਲੀਟ ਕੀਤਾ - %1$s ਡਾਊਨਲੋਡ ਡਿਲੀਟ ਕੀਤੇ + %1$s ਡਾਊਨਲੋਡ ਹਟਾਇਆ + %1$s ਡਾਊਨਲੋਡ ਹਟਾਏ ਚੈਨਲ ਦਾ ਅਵਤਾਰ ਥੰਮਨੇਲ ਇਸ ਕਾਰਜ ਲਈ ਕੋਈ ਢੁਕਵਾਂ ਫਾਈਲ ਮੈਨੇਜਰ ਨਹੀਂ ਮਿਲਿਆ। @@ -689,7 +689,7 @@ ਪਲੇਅਰ ਕਰੈਸ਼ ਕਰੋ ਵੀਡੀਓ ਮਿੰਨੀ ਪਲੇਅਰ ਚਲਾਉਣ ਦੀ ਵਜਾਏ ਪੂਰੇ ਸਕਰੀਨ ਵਿੱਚ ਚਲਾਉਂਦਾ ਹੈ। ਜੇ ਆਟੋ-ਰੋਟੇਸ਼ਨ ਲਾਕ ਹੈ ਮੇਨ-ਪਲੇਅਰ ਤੋਂ ਬਾਹਰ ਆਕੇ ਤੇ ਮਿੰਨੀ-ਪਲੇਅਰ ਤੱਕ ਰਸਾਈ ਹਾਸਿਲ ਕੀਤੀ ਜਾ ਸਕਦੀ ਹੈ ਅਗਰ ਤੁਸੀਂ ਐਪ ਦੀ ਵਰਤੋਂ ਸਬੰਧੀ ਮੁਸ਼ਕਿਲਾਂ ਦਾ ਸਾਹਮਣਾ ਕਰ ਰਹੇ ਹੋ, ਤਾਂ ਇਹਨਾਂ ਆਮ ਸਵਾਲਾਂ ਦੇ ਜਵਾਬ ਜਾਣਨਾ ਨਾ ਭੁੱਲੋ! - ਕਤਾਰ ਵਿੱਚ ਅੱਗੇ ਲਗਾਓ + ਕਤਾਰ ਵਿੱਚ ਅੱਗੇ ਲਗਾਇਆ ਗਿਆ ਨੈੱਟਵਰਕ ਦੀ ਕਿਸਮ ਨਵੇਂ ਸੰਸਕਰਣਾਂ ਲਈ ਹੱਥੀਂ ਜਾਂਚ ਕਰੋ ਵਧੀਆ ਗੁਣਵੱਤਾ (ਵੱਡਾ ਆਕਾਰ) @@ -698,33 +698,33 @@ ਤੁਸੀਂ ਇਸ ਚੈਨਲ ਨੂੰ ਸਬਸਕ੍ਰਾਈਬ ਕਰ ਲਿਆ ਹੈ ਕੋਈ ਵੀਡੀਓ ਸਟ੍ਰੀਮ ਬਾਹਰੀ ਪਲੇਅਰਾਂ ਲਈ ਉਪਲੱਬਧ ਨਹੀਂ ਹੈ ਐਕਸੋਪਲੇਅਰ ਡਿਫਾਲਟ - ਕੀ ਤੁਹਾਨੂੰ ਲੱਗਦਾ ਹੈ ਫੀਡ ਹੌਲੀ ਲੋਡ ਹੋ ਰਹੀ ਹੈ\? ਅਜਿਹਾ ਹੈ ਤਾਂ ਤੇਜ਼ ਫੀਡ ਕ੍ਰਿਆਸ਼ੀਲ ਕਰਕੇ ਵੇਖੋ (ਤੁਸੀਂ ਇਸਨੂੰ ਸੈਟਿੰਗਾਂ ਵਿੱਚ ਜਾ ਕੇ ਜਾਂ ਹੇਠਲਾ ਬਟਨ ਦੱਬ ਕੇ ਕਰ ਸਕਦੇ ਹੋ ) -\n -\nਨਿਊਪਾਈਪ ਫੀਡ ਲੋਡ ਕਰਨ ਲਈ ਦੋ ਤਰਾਂ ਦੀਆਂ ਵਿਧੀਆਂ ਦੀ ਪੇਸ਼ਕਸ਼ ਕਰਦੀ ਹੈ: -\n• ਸਬਸਕ੍ਰਿਪਸ਼ਨ ਚੈਨਲ ਤੋਂ ਪੂਰੀ ਜਾਣਕਾਰੀ ਲੈਂਦੀ ਹੈ ਜੋ ਹੌਲ੍ਹੀ ਮਿਲਦੀ ਹੈ। -\n• ਸਮਰਪਿਤ ਸੇਵਾ ਅੰਤਮ ਬਿੰਦੂ ਤੋਂ, ਜੋ ਕਿ ਤੇਜ਼ ਮਿਲਦੀ ਹੈ ਪਰ ਆਮਤੌਰ ਤੇ ਅਧੂਰੀ/ਅਣਸਟੀਕ ਹੁੰਦੀ ਹੈ। -\n -\nਇਨਾਂ ਦੋਹਾਂ ਵਿੱਚ ਫਰਕ ਇਹ ਹੁੰਦਾ ਹੈ ਕਿ ਤੇਜ਼ ਤਰੀਕਾ ਆਮਤੌਰ ਤੇ ਕੁਝ ਜਾਣਕਾਰੀ ਨਹੀਂ ਦੇ ਪਾਉਂਦਾ ਜਿਵੇਂ ਕਿ ਨਗਾਂ ਦੀ ਅਵਧੀ ਜਾਂ ਕਿਸਮ(ਕਿ ਵੀਡੀਓ ਲਾਈਵ ਹਨ ਜਾਂ ਆਮ) ਤੇ ਘੱਟ ਨਗ ਦਿਖ ਸਕਦੇ ਹਨ। -\n + ਕੀ ਤੁਹਾਨੂੰ ਲੱਗਦਾ ਹੈ ਫੀਡ ਹੌਲੀ ਲੋਡ ਹੋ ਰਹੀ ਹੈ\? ਅਜਿਹਾ ਹੈ ਤਾਂ ਤੇਜ਼ ਫੀਡ ਕ੍ਰਿਆਸ਼ੀਲ ਕਰਕੇ ਵੇਖੋ (ਤੁਸੀਂ ਇਸਨੂੰ ਸੈਟਿੰਗਾਂ ਵਿੱਚ ਜਾ ਕੇ ਜਾਂ ਹੇਠਲਾ ਬਟਨ ਦੱਬ ਕੇ ਕਰ ਸਕਦੇ ਹੋ ) +\n +\nਨਿਊਪਾਈਪ ਫੀਡ ਲੋਡ ਕਰਨ ਲਈ ਦੋ ਤਰਾਂ ਦੀਆਂ ਵਿਧੀਆਂ ਦੀ ਪੇਸ਼ਕਸ਼ ਕਰਦੀ ਹੈ: +\n• ਸਬਸਕ੍ਰਿਪਸ਼ਨ ਚੈਨਲ ਤੋਂ ਪੂਰੀ ਜਾਣਕਾਰੀ ਲੈਂਦੀ ਹੈ ਜੋ ਹੌਲ੍ਹੀ ਮਿਲਦੀ ਹੈ। +\n• ਸਮਰਪਿਤ ਸੇਵਾ ਅੰਤਮ ਬਿੰਦੂ ਤੋਂ, ਜੋ ਕਿ ਤੇਜ਼ ਮਿਲਦੀ ਹੈ ਪਰ ਆਮਤੌਰ ਤੇ ਅਧੂਰੀ/ਅਣਸਟੀਕ ਹੁੰਦੀ ਹੈ। +\n +\nਇਨਾਂ ਦੋਹਾਂ ਵਿੱਚ ਫਰਕ ਇਹ ਹੁੰਦਾ ਹੈ ਕਿ ਤੇਜ਼ ਤਰੀਕਾ ਆਮ ਤੌਰ ਤੇ ਕੁਝ ਜਾਣਕਾਰੀ ਨਹੀਂ ਦੇ ਪਾਉਂਦਾ ਜਿਵੇਂ ਕਿ ਨਗਾਂ ਦੀ ਅਵਧੀ ਜਾਂ ਕਿਸਮ(ਕਿ ਵੀਡੀਓ ਲਾਈਵ ਹਨ ਜਾਂ ਆਮ) ਤੇ ਘੱਟ ਨਗ ਦਿਖ ਸਕਦੇ ਹਨ। +\n \nਯੂਟਿਊਬ ਇੱਕ ਅਜਿਹੀ ਸੇਵਾ ਹੈ ਜਿਹੜੀ RSS ਫੀਡ ਜ਼ਰੀਏ ਇਹ ਤੇਜ਼ ਤਰੀਕਾ ਪ੍ਰਦਾਨ ਕਰਦੀ ਹੈ। -\n +\n \nਤੁਹਾਡੀ ਚੋਣ ਇਸ ਗੱਲ ਤੇ ਮੁਨੱਸਰ ਕਰਦੀ ਹੈ ਕਿ ਤੁਸੀਂ ਗਤੀ ਤੇ ਸਟੀਕਤਾ ਵਿੱਚੋਂ ਕਿਸ ਨੂੰ ਪ੍ਰਾਥਮਿਕਤਾ ਦਿੰਦੇ ਹੋ। ਤੇਜ ਮੋਡ 3-ਡੌਟ ਮੀਨੂ ਤੋਂ ਸਬਸਕ੍ਰਿਪਸ਼ਨਾਂ ਨੂੰ ਆਯਾਤ ਜਾਂ ਨਿਰਯਾਤ ਕਰੋ ਤੁਸੀਂ ਨਿਊਪਾਈਪ ਦਾ ਨਵੀਨਤਮ ਸੰਸਕਰਣ ਚਲਾ ਰਹੇ ਹੋ %s ਨੂੰ ਡਾਊਨਲੋਡ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ - ਇਹ ਵਿਕਲਪ ਤਾਂ ਹੀ ਉਪਲਬਧ ਹੈ ਜੇਕਰ %s ਨੂੰ ਥੀਮ ਲਈ ਚੁਣਿਆ ਗਿਆ ਹੈ + ਇਹ ਵਿਕਲਪ ਤਾਂ ਹੀ ਉਪਲਬਧ ਹੁੰਦਾ ਹੈ ਜੇਕਰ %s ਨੂੰ ਥੀਮ ਲਈ ਚੁਣਿਆ ਜਾਂਦਾ ਹੈ ਸਥਾਈ ਥੰਮਨੇਲ ਨੂੰ ਅਨਸੈੱਟ ਕਰੋ ਕਲਿੱਪਬੋਰਡ \'ਤੇ ਕਾਪੀ ਕਰਨ ਵਿੱਚ ਅਸਫਲ ਕਾਰਡ - ਪਲੇਲਿਸਟਾਂ ਜੋ ਧੁੰਦਲੀਆਂ ਹੋ ਗਈਆਂ ਹਨ ਉਹਨਾਂ ਵਿੱਚ ਪਹਿਲਾਂ ਹੀ ਇਹ ਆਈਟਮ ਹੈ। + ਧੁੰਦਲੀਆਂ ਕੀਤੀਆਂ ਪਲੇਲਿਸਟਾਂ ਵਿੱਚ ਪਹਿਲਾਂ ਹੀ ਇਹ ਆਈਟਮ ਹੈ। ਡੁਪਲੀਕੇਟ ਜੋੜਿਆ ਗਿਆ %d ਵਾਰ ਉਪਯੋਗੀ ਹੈ, ਉਦਾਹਰਨ ਲਈ, ਜੇਕਰ ਤੁਸੀਂ ਟੁੱਟੇ ਭੌਤਿਕ ਬਟਨਾਂ ਵਾਲਾ ਹੈੱਡਸੈੱਟ ਵਰਤ ਰਹੇ ਹੋ ਡੁਪਲੀਕੇਟ ਹਟਾਓ - ਕੀ ਡੁਪਲੀਕੇਟ ਹਟਾਉਣੇ ਹਨ\? + ਡੁਪਲੀਕੇਟ ਹਟਾਉਣੇ ਹਨ\? ਕੀ ਤੁਸੀਂ ਇਸ ਪਲੇਲਿਸਟ ਵਿੱਚ ਸਾਰੀਆਂ ਡੁਪਲੀਕੇਟ ਸਟ੍ਰੀਮਾਂ ਨੂੰ ਹਟਾਉਣਾ ਚਾਹੁੰਦੇ ਹੋ\? - ਅੱਗੇ ਦਿੱਤੀਆਂ ਸਟ੍ਰੀਮਾਂ ਵਿਖਾਓ - ਪੂਰੀ ਤਰ੍ਹਾਂ ਵੇਖਿਆ ਗਿਆ + ਨਿਮਨਲਿਖਤ ਸਟ੍ਰੀਮਾਂ ਵਿਖਾਓ + ਪੂਰੀ ਵੇਖਿਆ ਅੰਸ਼ਕ ਤੌਰ \'ਤੇ ਵੇਖਿਆ ਗਿਆ ਆਗਾਮੀ ਹਾਰਡਵੇਅਰ ਮੀਡੀਆ ਬਟਨ ਇਵੈਂਟਾਂ ਨੂੰ ਅਣਡਿੱਠ ਕਰੋ @@ -762,4 +762,20 @@ ਮੀਡੀਆ ਟਨਲਿੰਗ ਤੁਹਾਡੀ ਡਿਵਾਈਸ \'ਤੇ ਡਿਫ਼ਾਲਟ ਤੌਰ \'ਤੇ ਅਸਮਰੱਥ ਕੀਤੀ ਗਈ ਸੀ ਕਿਉਂਕਿ ਤੁਹਾਡੀ ਡਿਵਾਈਸ ਮਾਡਲ ਇਸਦਾ ਸਮਰਥਨ ਨਹੀਂ ਕਰਨ ਲਈ ਜਾਣਿਆ ਜਾਂਦਾ ਹੈ। ਕੋਈ ਸਟ੍ਰੀਮ ਨਹੀਂ ਕੋਈ ਲਾਈਵ ਸਟ੍ਰੀਮ ਨਹੀਂ + ਵੀਡੀਓਜ਼ + ਸਬਸਕ੍ਰਾਈਬਰਜ਼ + ਚੈਨਲ ਪੰਨਿਆਂ \'ਤੇ ਕਿਹੜੀਆਂ ਟੈਬਾਂ ਵਿਖਾਈਆਂ ਜਾਂਦੀਆਂ ਹਨ + ਚੈਨਲ ਟੈਬਾਂ + ਸ਼ੌਰਟਸ + ਮੈਟਾਡੇਟਾ ਲੋਡ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ… + ਚੈਨਲ ਟੈਬਾਂ ਪ੍ਰਾਪਤ ਕਰੋ + ਦੇ ਬਾਰੇ + ਬੈਨਰ URL + ਐਲਬਮਜ਼ + ਫ਼ੀਡ ਅੱਪਡੇਟ ਕਰਨ ਵੇਲੇ ਪ੍ਰਾਪਤ ਕਰਨ ਲਈ ਟੈਬਾਂ। ਇਸ ਵਿਕਲਪ ਦਾ ਕੋਈ ਅਸਰ ਨਹੀਂ ਹੁੰਦਾ ਜੇਕਰ ਚੈਨਲ ਨੂੰ ਫਾਸਟ ਮੋਡ ਦੀ ਵਰਤੋਂ ਕਰਕੇ ਅੱਪਡੇਟ ਕੀਤਾ ਜਾਂਦਾ ਹੈ। + ਅਵਤਾਰ URL + ਪਲੇਲਿਸਟਾਂ + ਟ੍ਰੈਕਸ + ਚੈਨਲਜ਼ + ਲਾਈਵ \ No newline at end of file diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index b31883230..4f6f68234 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -783,4 +783,20 @@ Tunelowanie multimediów zostało domyślnie wyłączone na Twoim urządzeniu, ponieważ wiadomo, że model Twojego urządzenia go nie obsługuje Brak strumieni Brak transmisji na żywo + Wideo + Subskrybujący + Karty wyświetlane na stronach kanałów + Karty kanałów + Shorts + Ładowanie metadanych… + Pobieranie kart kanału + Informacje + Adres URL banera + Albumy + Karty do pobrania podczas aktualizacji kanału. Ta opcja nie działa, jeśli kanał jest aktualizowany w trybie szybkim + Adres URL awatara + Playlisty + Utwory + Kanały + Na żywo \ No newline at end of file diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 2949dfdcb..eb2c26d5f 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -775,4 +775,20 @@ Nenhuma transmissão Nenhuma transmissão ao vivo O tunelamento de mídia foi desabilitado por padrão em seu dispositivo porque seu modelo é conhecido por não suportá-lo. + Vídeos + Inscritos + Quais guias são mostradas nas páginas do canal + Guias de canal + Shorts + Carregando metadados… + Buscar guias de canal + Sobre + URL do banner + Álbuns + Guias a serem buscadas ao atualizar o feed. Esta opção não tem efeito se um canal for atualizado usando o modo rápido. + URL do avatar + Playlists + Faixas + Canais + Ao vivo \ No newline at end of file diff --git a/app/src/main/res/values-pt-rPT/strings.xml b/app/src/main/res/values-pt-rPT/strings.xml index a63171ba4..abf504406 100644 --- a/app/src/main/res/values-pt-rPT/strings.xml +++ b/app/src/main/res/values-pt-rPT/strings.xml @@ -773,4 +773,6 @@ Mova o seletor da guia principal para a parte inferior Posição das guias principais O túnel multimédia foi desativado por predefinição no seu dispositivo porque se sabe que o modelo do dispositivo não o suporta. + Nenhum vídeo em direto + Nenhum vídeo \ No newline at end of file diff --git a/app/src/main/res/values-ryu/strings.xml b/app/src/main/res/values-ryu/strings.xml index 16b298dad..40b988c8a 100644 --- a/app/src/main/res/values-ryu/strings.xml +++ b/app/src/main/res/values-ryu/strings.xml @@ -765,4 +765,20 @@ オリジナル ストリームーあいびらん ライブーいしのーあいびらん + ちゃーしが + とうるくさゃ + チャンネルページんかいひょうじさりーんタブ + チャンネルタブ + ショート + メタじょうほうゆみくどーいびーん… + チャンネルタブしーゅとぅくしーん + しょうさい + バナーぬURL + アルバム + フィードこうしんすんとぅちなしゅとぅくしーんタブ。 こうすくモードさしてぃチャンネルこうしんすーあえー、かんがぬあいびらん。 + アバターぬURL + プレイリスト + トラック + チャンネル + ライブ \ No newline at end of file diff --git a/app/src/main/res/values-sr/strings.xml b/app/src/main/res/values-sr/strings.xml index 5926446f4..3b506c760 100644 --- a/app/src/main/res/values-sr/strings.xml +++ b/app/src/main/res/values-sr/strings.xml @@ -1,147 +1,147 @@ Објављено %1$s - Нема плејера токова. Инсталирати ВЛЦ\? + Нема плејера стримова. Инсталирати VLC\? Инсталирај Откажи - Отвори у претраживачу + Отвори у прегледачу Подели Преузми - Тражи + Претрага Подешавања Да ли сте мислили: „%1$s“\? Подели помоћу - Фасцикла за видео - Преузети видео записи се чувају овде - Избор фасцикле за преузимање видеа + Фолдер за преузимање видео снимака + Преузети видео снимци се чувају овде + Изаберите фолдер за преузимање видео снимака Подразумевана резолуција - Пусти помоћу Кодија - Инсталирати даљински за Коди\? - Прикажи „Пусти помоћу Кодија“ - Приказ опције за пуштање видеа у Коди медија центру - Аудио - Подразумевани формат звука + Пусти помоћу Kodi-ја + Инсталирати апликацију Kore која недостаје\? + Прикажи опцију „Пусти помоћу Kodi-ја“ + Прикажите опцију за пуштање видео снимака преко Kodi медија центра + Аудио снимак + Подразумевани формат аудио снимка Преузимање - УРЛ није подржан - Прикажи „следећи“ и „слични“ видео + URL није подржан + Прикажи „следеће“ и „сличне“ видео снимке Подразумевани језик садржаја - Видео и аудио - Пусти видео, трајање: + Видео и аудио снимци + Пусти видео снимак, трајање: Аватар пошиљаоца Несвиђања Свиђања - Користи спољашњи видео плејер - Користи спољашњи аудио плејер - Пуштам у позадини + Користи спољни плејер видео снимака + Користи спољни плејер аудио снимака + Пуштање у позадини Тема - тамна - светла + Тамна + Светла Изглед - Грешка мреже - Фасцикла за аудио - Избор фасцикле за аудио фајлове - Преузети аудио записи се чувају овде + Мрежна грешка + Фолдер за преузимање аудио снимака + Изаберите фолдер за преузимање аудио снимака + Преузети аудио снимци се чувају овде Грешка - Не могу да учитам све сличице - Не могу да рашчланим веб-сајт + Није могуће учитати све сличице + Није могуће рашчланити веб-сајт Садржај је недоступан Садржај - Прикажи старосно-ограничени садржај - Не могу да поставим мени преузимања - Нажалост, ово не би требало да се деси. - Пријавите ову грешку е-поштом + Прикажи старосно ограничени садржај + Није могуће подесити мени преузимања + Извините, ово није требало да се деси. + Пријави путем имејла Извините, нешто није у реду. Пријави - Подаци: + Информације: Шта се десило: Ваш коментар (на енглеском): Детаљи: - Видео - Аудио + Видео снимак + Аудио снимак Покушај поново Уживо - Кликните на лупу да започнете. + Додирните лупу да бисте започели. Почни Паузирај - Обриши + Избриши Контролна сума У реду Назив фајла Нити Грешка - Њупајп преузима - Тапните за детаље + NewPipe преузима + Додирните за детаље Сачекајте… Копирано у привремену меморију - Одредите фасциклу за преузимање касније у поставкама + Одредите фолдер за преузимање касније у подешавањима Преузимања Преузимања Извештај о грешци - Програм се срушио - Шта:\\nЗахтев:\\nЈезик садржаја:\\nЗемља садржаја:\\nЈезик апликације:\\nУслуга:\\nГМТ време:\\nПакет:\\nИздање:\\nИздање ОС-а: + Програм је отказао + Шта:\\nЗахтев:\\nЈезик садржаја:\\nЗемља садржаја:\\nЈезик апликације:\\nУслуга:\\nGMT време:\\nПакет:\\nВерзија:\\nВерзија ОС-а: „reCAPTCHA“ задатак Решите „reCAPTCHA“ задатак - црна + Црна Све - хиљ - мил - млрд + хиљ. + мил. + млрд. Отвори у искачућем режиму Ова дозвола је потребна за \nотварање у искачућем режиму - Пуштање у режиму прозорчета - Искључено - Подразумевани формат видеа - Резолуција искачућег прозора + Пуштање у режиму искачућег прозора + Онемогућено + Подразумевани формат видео снимка + Подразумевана резолуција искачућих прозора Прикажи веће резолуције - Само неки уређаји могу да пуштају 2K/4K видео + Само неки уређаји могу да пуштају 2K/4K видео снимке Очисти Позадина - Прозорче + Искачући прозор Уклања звук на неким резолуцијама Упамти својства искачућег прозора - памти последњу величину и позицију искачућег прозора - Предлози у претрази - Приказује предлоге током претраге + Памти последњу величину и позицију искачућег прозора + Предлози за претрагу + Изаберите предлоге који ће се приказати приликом претраге Пратите Прати Праћења Шта је ново - Историјат претраге - Појмове претраге складишти локално + Историја претраге + Локално чувајте упите за претрагу Историја гледања - Чувај историјат гледања - Настави са репродукцијом + Чувајте листу одгледаних видео снимака + Настави са пуштањем Најбоља резолуција Преузимање - О програму - О програму + О NewPipe + О нама и ЧПП Лиценце - Слободно и лагано стримовање на Андроиду. - Погледај на Гитхабу + Слободно и лагано стримовање на Android-у. + Погледај на GitHub-у Прочитај лиценцу Допринос - Историјат - Историјат - Настави пуштање након прекида (нпр. позива) - Дозвољени знакови у називима - слова и бројке + Историја + Историја + Наставите са пуштањем након прекида (нпр. телефонски позиви) + Дозвољени знакови у називима фајлова + Слова и бројеви © %1$s од %2$s под %3$s - Одјављен са канала - Не могу да променим претплату - Не могу да ажурирам претплату + Отказано праћење канала + Није могуће променити праћење + Није могуће ажурирати праћење Плејер Понашање Историја и кеш - Врати - Њупајп обавештење - Обавештења за Њупајп плејере у позадини и искачућем прозору + Поништи + NewPipe обавештење + Обавештења за NewPipe плејер Нема резултата - Нема ничега овде осим цврчака + Овде нема ничега осим цврчака Нема пратилаца %s пратилац - %s пратилаца + %s пратиоца %s пратилаца Нема прегледа @@ -150,25 +150,25 @@ %s прегледа %s прегледа - Нема видеа + Нема видео снимака - %s видео - %s видеа - %s видеа + %s видео снимак + %s видео снимка + %s видео снимака - Неисправни знакови биће замењени овим - Знак за замену - и посебни знакови + Неисправни знакови биће замењени овим вредностима + Заменски знак + Већина посебних знакова Лиценце треће стране - Лиценца Њупајпа - Помоћ је увек добро дошла, било да имате идеју за превод, дизајн, козметичке или озбиљне измене кôда. Што се више уради, боље је! - Покажите савет када притиснете позадину или искачуће дугме у видеу „Детаљи:“ + Лиценца NewPipe-а + Без обзира имате ли идеје; превод, промене дизајна, чишћење кода или праве, озбиљне, промене кода—помоћ је увек добродошла. Што се више уради, то је боље! + Прикажите савет када притиснете позадину или искачуће дугме у видео снимку „Детаљи:“ Пусти све - Не могу да пустим овај ток - Десила се непоправљива грешка плејера - Опорављам се од грешке плејера - Желите да обришете ову ставку из историјата претраге\? - Садржај главне стране + Није могуће пустити овај стрим + Дошло је до непоправљиве грешке плејера + Опорављање од грешке плејера + Желите ли да избришете ову ставку из историје претраге\? + Садржај главне странице Празна страница Киоск страница Страница канала @@ -180,50 +180,50 @@ Ново и популарно Уклони Детаљи - Поставке звука - Нема плејера тока (можете инсталирати ВЛЦ). - Преузимање фајла тока - Прикажи податке - Обележене листе + Подешавања аудио снимка + Није пронађен ниједан плејер стримова (можете инсталирати VLC да бисте га покренули). + Преузимање фајла стрима + Прикажи информације + Обележене плејлисте Додај на Подразумевана држава за садржај Исправљање грешака Увек Само једном - [непознато] - Прикажи поруку „задржи ради заказивања” + [Непознато] + Прикажи савет „Задржи за стављање у ред чекања” Донација - ЊуПајп развијају волонтери у своје слободно време како би вам пружили најбоље искуство. Узвратите им како би наставили са побољшавањем ЊуПајпа док уживају уз шољицу кафе. + NewPipe је развијен од стране волонтера који проводе своје слободно време доносећи вам најбоље корисничко искуство. Узвратите програмерима како би учинили NewPipe још бољим, док уживају у шољици кафе. Узврати - Веб страна - За више информација и новости посетите ЊуПајпов вебсајт. - Задржи за стављање у ред + Веб-сајт + За више информација и новости посетите NewPipe веб-сајт. + Задржи за стављање у ред чекања Користи брзо, непрецизно премотавање Непрецизно премотавање омогућава плејеру да брже долази до позиције уз смањену прецизност. Премотавање за 5, 15 или 25 секунди са овом опцијом не ради Очишћен кеш са сликама Уклони кеширане метаподатке - Уклања све податке кешираних веб-страна + Уклања све податке кешираних веб-страница Откажи праћење - Изаберите језичак + Изаберите картицу Приказ коментара - искључите за сакривање коментара - Због ограничења плејера, премотавање је постављено на %d секунди - Да, и делимично одгледани снимци - Видео записи који су гледани пре и након додавања на листу биће уклоњени. -\nДа ли сте сигурни\? Ово се не може повратити! + Искључите да бисте сакрили коментаре + Због ограничења ExoPlayer-а, премотавање је постављено на %d секунди + Да, и делимично одгледани видео снимци + Видео снимци који су одгледани пре и после додавања на плејлисту биће уклоњени. +\nЈесте ли сигурни\? Ово се не може поништити! Уклонити одгледане видео снимке\? - Уклони гледано - Системски + Уклони одгледано + Системски подразумевано Језик апликације Изаберите инстанцу - „Storage Access Framework“ омогућава преузимање на спољну СД картицу - Користи системски бирач фасцикли (SAF) - Питаће вас где да сачувате свако преузимање. -\nУкључите системски бирач фасцикли „SAF“ ако желите да користите спољну СД картицу + „Storage Access Framework“ омогућава преузимање на спољну, SD (меморијску), картицу + Користи системски бирач фолдера (SAF) + Бићете упитани где желите да сачувате свако преузимање. +\nОмогућите системски бирач фолдера (SAF), ако желите да преузмете на спољну, SD (меморијску), картицу Питај где да се преузме Паузирај преузимања Започни преузимања - По једно преузимање ће бити активно + Једно преузимање ће бити покренуто у исто време Ограничи ред за преузимање Затвори Корисно при преласку на мобилне податке, иако нека преузимања не могу бити обустављена @@ -232,59 +232,59 @@ Највише покушаја Заустави Избриши преузете фајлове - Желите да очистите историју преузимања или обришете све преузете фајлове\? - Обриши историју преузимања - Не могу да опоравим ово преузимање + Желите ли да очистите историју преузимања или избришете све преузете фајлове\? + Очисти историју преузимања + Није могуће опоравити ово преузимање Веза је истекла - Напредак је изгубљен јер је фајл обрисан - Нема простора на уређају - ЊуПајп је затворен док је радио на фајлу + Напредак је изгубљен, јер је фајл избрисан + Недовољно меморије на уређају + NewPipe је затворен док је радио на фајлу Накнадна обрада није успела Није пронађено Сервер не прихвата преузимања са више нити. Покушајте са @string/msg_threads = 1 Сервер не шаље податке - Не могу да се повежем са сервером - Не могу да пронађем сервер - Не могу да успоставим безбедну везу - Не могу да направим одредишну фасциклу + Није могуће повезати се са сервером + Није могуће пронаћи сервер + Није могуће успоставити безбедну везу + Одредишни фолдер се не може направити Фајл се не може направити Прикажи грешку Преузимање са овим називом чека на ред У току је преузимање са овим називом - не могу да пребришем фајл + није могуће преписати фајл Преузет фајл са овим називом већ постоји Фајл са овим називом већ постоји - Пребриши + Препиши Генериши јединствен назив - Преузимање неуспешно - Систем одбија радњу + Преузимање није успело + Систем је одбио радњу Ред чекања - опоравља се + опорављање накнадна обрада - у реду + у реду чекања паузирано На чекању Завршено - Доступно је ажурирање за ЊуПајп! - аутоматски - мрежа - листа + Доступно је ажурирање за NewPipe! + Аутоматски + Мрежа + Листа Режим приказа листе - никад - само на бежичној - Покрени аутоматски — %s - умањи на искачући плејер - умањи на позадински плејер - ништа - Радња при преласку на другу апликацију са главног видео плејера — %s + Никад + Само на Wi-Fi-у + Покрени репродукцију аутоматски — %s + Умањи на искачући плејер + Умањи на позадински плејер + Ниједно + Радња при преласку на другу апликацију са главног плејера видео снимака — %s Умањи при мењању апликације Прикажи обавештење када постоји нова верзија апликације Ажурирања - Ограничити резолуцију на мобилној мрежи + Ограничи резолуцију када користиш мобилне податке Одбиј - без ограничења + Без ограничења Прихвати - Да бисмо били у складу са Европском општом уредбом о заштити података („GDPR“), скрећемо вам пажњу на политику приватности апликације ЊуПајпа. Пажљиво је прочитајте. + Да бисмо били у складу са Европском општом уредбом о заштити података (GDPR), скрећемо вам пажњу на политику приватности NewPipe-а. Пажљиво је прочитајте. \nМорате је прихватити да бисте нам послали извештај о грешци. Ресетуј Корак @@ -296,107 +296,108 @@ Имајте на уму да ова операција може потрошити доста података. \n \nЖелите ли да наставите\? - вашИД, soundcloud.com/yourid - Увезите СаундКлауд профил тако што ћете откуцати УРЛ или свој ИД: + ВашID, soundcloud.com/yourid + Увезите SoundCloud профил тако што ћете откуцати URL или свој ID: \n -\n1. Омогућите „режим радне површине“ у веб прегледачу (веб локација није доступна за мобилне уређаје) -\n2. Идите на ову УРЛ адресу: %1$s -\n3. Пријавите се када вас питају -\n4. Копирајте УРЛ профила на који сте преусмерени. - Увезите Јутјуб претплате са Гугл тејкаута: +\n1. Омогућите „десктоп режим“ у веб-прегледачу (веб-локација није доступна за мобилне уређаје) +\n2. Идите на ову URL адресу: %1$s +\n3. Пријавите се када се то од вас затражи +\n4. Копирајте URL профила на који сте преусмерени. + Увезите YouTube праћења из Google Takeout-а: \n -\n1. Идите на ову УРЛ адресу: %1$s -\n2. Пријавите се када вас питају -\n3. Кликните на „Сви подаци су укључени“, затим на „Поништи избор свих“, а затим изаберите само „претплате“ и кликните на „У реду“ +\n1. Идите на ову URL адресу: %1$s +\n2. Пријавите се када се то од вас затражи +\n3. Кликните на „Сви подаци укључени“, затим на „Опозови све“, затим изаберите само „праћења“ и кликните на „ У реду“ \n4. Кликните на „Следећи корак“, а затим на „Направи извоз“ -\n5. Кликните на дугме „Преузми“ након што се појави и -\n6. Из преузете зип датотеке за преузимање извадите .json датотеку (обично под „YouTube и YouTube Music/subscriptions/subscriptions.json“) и увезите је овде. - Не могу да извезем претплате - Не могу да увезем претплате +\n5. Кликните на дугме „Преузми“ након што се појави +\n6. Кликните на УВЕЗИ ФАЈЛ испод и изаберите преузети .zip фајл +\n7. [Ако увоз .zip не успе] Извуците .csv фајл (обично под „YouTube and YouTube Music/subscriptions/subscriptions.csv“), кликните на УВЕЗИ ФАЈЛ испод и изаберите извучени csv фајл + Није могуће извести праћења + Није могуће увести праћења Претходни извоз Увези фајл - Увозим… - Извозим… + Увоз… + Извоз… Извоз у Увоз из Увоз Срушите апликацију - Изворни текстови са услуга биће видљиви у ставкама тока + Изворни текстови са услуга биће видљиви у ставкама стрима Прикажи изворно време ставки - Присили пријављивање неиспоручивих „Rx“ изузетака изван делова или активности након одлагања + Присилно извештавање о „Rx“ изузецима који се не могу испоручити ван фрагмента или животног циклуса активности након одлагања Пријави грешке ван животног циклуса Прикажи цурење меморије - Надгледање цурења меморије може изазвати заглављивање апликација при стварању записника - Мења величину и позадину титлова плејера. Захтева поновно покретање да би ступило на снагу + Праћење цурења меморије може довести до тога да апликација престане да реагује када се прикупљају извештаји + Измените размеру натписа титлова плејера и стилове позадине. Захтева рестартовање апликације да би се применило Титлови - Аутоматски направљено - Увеличај + Аутоматски генерисано + Увеличано Попуњено Уклопљено Без титлова - Аутоматски направљено (нема отпремача) - Сличица листе је промењена. - Листа пуштања - Листа је направљена - Да обришем ову листу\? - Обележи листу + Аутоматски генерисано (нема отпремача) + Сличица плејлисте је промењена. + Додато на плејлисту + Плејлиста је направљена + Избрисати ову плејлисту\? + Обележи плејлисту Уклони обележивач - Постави као сличицу листе - Упали звук - Утишај - Додај на листу + Постави као сличицу плејлисте + Укључи звук + Искључи звук + Додај на плејлисту Назив Преименуј - Нова листа - Учитавам тражени садржај - Добављам податке… + Нова плејлиста + Учитавање траженог садржаја + Прикупљање информација… Увек питај - Плејер у искачућем прозору - Плејер у позадини - Видео плејер + Искачући плејер + Позадински плејер + Плејер видео снимака Подразумевана радња при отварању садржаја — %s - Пожељна радња при отварању + Преферирана радња при отварању Затвори фиоку Отвори фиоку Почни пуштање у искачућем прозору Почни пуштање у позадини - Стави у ред - На листи + Стави у ред чекања + Стављено у ред чекања Ред пуштања Конференције Највише свиђања Недавно додато Локално - Језик ће бити промењен након поновног покретања - Не могу да учитам коментаре - Желите да увезете и поставке\? - Ово ће прегазити тренутна подешавања. - Упозорење: не могу да увезем све фајлове. - Није исправан ЗИП фајл + Језик ће бити промењен након рестартовања апликације + Није могуће учитати коментаре + Желите ли да увезете и подешавања\? + Ово ће заменити ваше тренутно подешавање. + Упозорење: Није могуће увести све фајлове. + Нема важећег ZIP фајла Увезено Извезено Још нема обележивача на листи Изаберите листу пуштања Подразумевани киоск - Које картице се налазе на главној страници + Које картице се приказују на главној страници Највише пуштано Последње пуштано - ЊуПајп је бесплатни слободни софтвер. Можете га користити, проучавати и делити по жељи. Конкретно, можете га дистрибуирати и/или мењати под условима ГНУ Опште јавне лиценце коју је објавила Фондација за слободни софтвер, било верзије 3 лиценце, или (по вашој жељи) било које касније верзије. - Прочитајте политику приватности - Пројекат ЊуПајп врло озбиљно схвата вашу приватност. Стога апликација не прикупља никакве податке без вашег пристанка. -\nПолитика приватности ЊуПајпа детаљно објашњава који се подаци шаљу и чувају када пошаљете извештај о паду апликације. - Политика приватности ЊуПајпа + NewPipe је слободан софтвер за копирање: Можете га користити, проучавати, делити и побољшавати по жељи. Конкретно, можете га поново дистрибуирати и/или модификовати под условима GNU Опште јавне лиценце коју је објавила Фондација за слободни софтвер, било верзију 3 лиценце или (по вашем избору) било коју каснију верзију. + Прочитај политику приватности + Пројекат NewPipe веома озбиљно схвата вашу приватност. Стога, апликација не прикупља никакве податке без вашег пристанка. +\nПолитика приватности NewPipe-а детаљно објашњава који се подаци шаљу и чувају када пошаљете извештај о отказивању апликације. + Политика приватности NewPipe-а Готово Реши - Притисните „Готово“ кад решите - Обрисана је 1 ставка. + Притисните „Готово“ када решите + Избрисана је 1 ставка. Израчунавање хеша Преименуј Одбаци Направи Нема коментара - ∞ видеа - 100+ видеа + ∞ видео снимака + 100+ видео снимака %s слушалац %s слушаоца @@ -410,44 +411,44 @@ Нико не гледа Број пратилаца није доступан - Мењај услугу, тренутно изабрана: + Изабери услугу, тренутно изабрана: Превуците за преуређивање Опис Коментари - Проверите да ли већ постоји проблем који говори о вашем паду апликације. Када правите дупликате карата, одузимате нам време које бисмо могли потрошити на исправљање стварне грешке. - Пријави на Гитхабу + Проверите да ли већ постоји проблем који говори о вашем отказивању апликације. Када правите дупликате карата, одузимате нам време које бисмо могли потрошити на исправљање стварне грешке. + Пријави на GitHub-у Копирајте форматирани извештај - Дајте дозволу за приказ преко других апликација - Врати подразумеване - Желите да вратите подразумеване вредности\? - Не могу да очитам сачуване картице. Користим подразумеване - Нема тока доступног за преузимање + Дајте дозволу за приказивање преко других апликација + Врати подразумеване вредности + Желите ли да вратите подразумеване вредности\? + Није могуће прочитати сачуване картице, тако да се користе подразумеване + Нема стримова доступних за преузимање Дошло је до грешке: %1$s Фајл не постоји или нема дозволе за читање или писање Назив фајла не може бити празан Нема таквог фајла/извора садржаја - Нема такве фасцикле + Нема таквог фолдера Фајл је премештен или избрисан - Нема видео тока - Нема аудио тока - Спољни плејери не подржавају ове врсте веза - Преузимање на спољну СД картицу није могуће. Ресетовати локацију фасцикле за преузимање\? - Спољно складиште није доступно - Историја претраге је обрисана - Да обришем целу историју претраге\? + Нису пронађени видео стримови + Нису пронађени аудио стримови + Спољни плејери не подржавају ове врсте линкова + Преузимање на спољну, SD (меморијску), картицу није могуће. Ресетовати локацију фолдера за преузимање\? + Спољна меморија није доступна + Историја претраге је избрисана + Избрисати целу историју претраге\? Брише историју кључних речи за претрагу - Обриши историју претраге - Позиције репродукције су обрисане - Обрисати све позиције репродукције\? + Очисти историју претраге + Позиције репродукције су избрисане + Избрисати све позиције репродукције\? Брише све позиције репродукције - Обриши позиције репродукције + Избриши позиције репродукције Историја гледања је избрисана - Обрисати целу историју гледања\? - Брише историју пуштаних токова и позиције репродукције + Избрисати целу историју гледања\? + Брише историју пуштаних стримова и позиције репродукције Очисти историју гледања - Чисти колачиће које ЊуПајп чува када решите „reCAPTCHA“ - Извоз историје, претплата, листи и поставки - Замениће вашу тренутну историју, претплате, листе и (опционо) поставке + Чисти колачиће које NewPipe чува када решите „reCAPTCHA“ + Извоз историје, праћења, плејлисти и подешавања + Замениће вашу тренутну историју, праћења, плејлисте и (опционо) подешавања „reCAPTCHA“ колачићи су очишћени Очисти „reCAPTCHA“ колачиће Извоз базе података @@ -455,9 +456,9 @@ Пребаци на главно Пребаци на искачући прозор Пребаци у позадину - Обавештења о напретку хеширања видео записа - Обавештење о видео хешу - Обавештења о новој верзији ЊуПајпа + Обавештења о напретку хеширања видео снимка + Обавештење о хешу видео снимка + Обавештења о новим верзијама NewPipe-а Обавештење о ажурирању апликације Фајл Фајл избрисан @@ -466,121 +467,121 @@ Песме Догађаји Корисници - Нумере - Видео - Листе пуштања + Снимци + Видео снимци + Плејлисте Канали - Овај видео је старосно ограничен. -\nЗбог нових Јутјуб смерница за такве видео записе, Њупајп не може да им приступи, па није у могућности да их репродукује. - Овај видео је старосно ограничен. + Овај видео снимак је старосно ограничен. +\nЗбог нових YouTube смерница за старосно ограничене видео снимке, NewPipe не може да им приступи, па није у могућности да их пушта. + Овај видео снимак је старосно ограничен. \n -\nУкључите „%1$s“ у поставкама ако желите да га видите. - Јутјуб омогућава „Ограничени режим“ који скрива потенцијални садржај за одрасле - Укључити Јутјубов „Ограничени режим“ - Приказ садржаја који можда није прикладан за децу јер има старосну границу (попут 18+) +\nУкључите „%1$s“ у подешавањима, ако желите да га видите. + YouTube омогућава „Ограничени режим“ који скрива потенцијални садржај за одрасле + Укључи YouTube-ов „Ограничени режим“ + Приказивање садржаја који можда није прикладан за децу, јер има старосну границу (попут 18+) Ажурирања Инстанца већ постоји - Подржане су само HTTPS УРЛ адресе - Не могу да потврдим инстанцу - Унесите УРЛ инстанце + Подржане су само HTTPS URL адресе + Није могуће потврдити инстанцу + Унесите URL инстанце Додајте инстанцу - Пронађите инстанце које вам се свиђају на %s - PeerTube инстанца - Изаберите своје омиљене инстанце PeerTube - УРЛ није препознат. Отворити другом апликацијом\? + Пронађите инстанце које Вам се свиђају на %s + PeerTube инстанце + Изаберите своје омиљене PeerTube инстанце + URL није препознат. Отворити помоћу друге апликације\? Аутоматско пуштање Очисти податке Прикажите индикаторе положаја репродукције на листама Позиције на листама Вратите последњу позицију репродукције - Наставак репродукције - Самостално заказивање - Наставите да завршавате (не понављајући) ред репродукције додавањем повезаног стрима - Самостално закажи следећи ток + Настави репродукцију + Аутоматско стављање у ред чекања + Наставите да завршавате (непонављајући) ред репродукције додавањем повезаног стрима + Аутоматски стави у ред чекања следећи стрим Кеш метаподатака обрисан - Искључите за сакривање поља мета-података са додатним информацијама о творцу тока, садржају или захтеву за претрагу - Прикажи мета-податке - Искључите за сакривање описа видеа и додатних информација + Искључите да бисте сакрили поља за метаподатке са додатним информацијама о креатору стрима, садржају стрима или захтеву за претрагу + Прикажи метаподатке + Искључите да бисте сакрили опис видео снимка и додатне информације Прикажи опис - Редослед активног плејера биће замењен - Пребацивање на други плејер може променити ваш редослед - Питај за потврду пре пражњења редоследа + Ред активног плејера биће замењен + Пребацивање на други плејер може променити ваш ред чекања + Питај за потврду пре чишћења реда Период премотавања напред/назад - ноћна тема - Андроид ће прилагодити боју обавештења према главној боји на сличици (није доступно на свим уређајима) - Обоји обавештења + Ноћна тема + Android ће прилагодити боју обавештења према главној боји на сличици (није доступно на свим уређајима) + Обоји обавештење Ништа Учитавање Мешање Понављање Можете да изаберете највише три радње за приказ у компактном обавештењу! - Уредите сваку радњу обавештења додиром на њу. Означите до три радње које ће се приказивати у компактном обавештењу помоћу кућица са десне стране + Измените сваку радњу обавештења додиром на њу. Означите до три радње које ће се приказивати у компактном обавештењу помоћу поља за потврду са десне стране Дугме пете радње Дугме четврте радње Дугме треће радње Дугме друге радње Дугме прве радње - мења размеру сличице видеа у обавештењима са 16:9 на 1:1 (може довести до изобличења) - Умањени приказ размере 1:1 - Приказ резултата за: %s + Исеците сличицу видеа приказану у обавештењу с размере 16:9 на размеру 1:1 + Исеци сличицу на размеру 1:1 + Приказивање резултата за: %s Отвори помоћу Преузимање је започело - Испод можете одабрати своју омиљену ноћну тему + Испод можете изабрати своју омиљену ноћну тему Изаберите своју омиљену ноћну тему — %s - аутоматски (тема уређаја) + Аутоматски (тема уређаја) Радио Истакнуто - Овај садржај је доступан само корисницима који су платили, тако да га ЊуПајп не може стримовати или преузимати. - Овај видео је доступан само премијум члановима Јутјуб музике, тако да га ЊуПајп не може стримовати или преузимати. - Овај садржај је приватан, тако да га ЊуПајп не може стримовати или преузимати. - Ово је СаундКлауд Го+ нумера, барем у вашој земљи, тако да је ЊуПајп не може стримовати или преузимати. + Овај садржај је доступан само корисницима који су платили, тако да га NewPipe не може стримовати или преузимати. + Овај видео снимак је доступан само премијум YouTube Music члановима, тако да га NewPipe не може стримовати или преузимати. + Овај садржај је приватан, тако да га NewPipe не може стримовати или преузимати. + Ово је SoundCloud Go+ нумера, барем у вашој земљи, тако да је NewPipe не може стримовати или преузимати. Овај садржај није доступан у вашој земљи. - Нема апликације која отвара ово + Ниједна апликација на вашем уређају не може да отвори ово Поглавља Недавни - користи сличицу и за позадину закључаног екрана и за обавештења - Приказ сличице - Страница листе - од %s - Направи %s + Користите сличицу и за позадину закључаног екрана и за обавештења + Прикажи сличицу + Страница плејлисте + Од %s + Направио %s Сличица аватара канала - ЊуПајп још увек не подржава овај садржај. + NewPipe још увек не подржава овај садржај. \n \nНадамо се да ће бити подржан у будућој верзији. - Да ли је учитавање довода преспоро\? Ако је тако, укључите брзо учитавање (промените у поставкама или притиском на дугме испод). + Мислите ли да је учитавање фида превише споро\? Ако јесте, покушајте да омогућите брзо учитавање (можете га променити у подешавањима или притиском на дугме испод). \n -\nЊуПајп нуди два начина учитавања довода: -\n• Преузимање целог претплаћеног канала, што је споро али потпуно. -\n• Коришћење наменске крајње тачке услуге, што је брже али обично није потпуно. +\nNewPipe нуди две стратегије учитавања фида: +\n• Прикупљање целог претплатничког канала, што је споро, али потпуно. +\n• Коришћење наменске крајње тачке услуге, која је брза, али обично није потпуна. \n -\nРазлика је у томе што брзом обично недостају неке информације, попут трајања или врсте (не могу се разликовати живи видео од уобичајених), а можда ће вратити и мање ставки. +\nРазлика између њих је у томе што брзом начину обично недостају неке информације, као што је трајање или врста ставке (не могу да се разликују видео снимци уживо и нормални) и може да врати мање ставки. \n -\nЈутјуб је пример услуге која нуди овај брзи метод својим РСС доводом. +\nYouTube је пример услуге која нуди ову брзу методу са својим RSS фидом. \n -\nДакле, избор се своди на оно шта желите: брзину или прецизне информације. - Искључи брзи режим - Укључи брзи режим - Доступно у неким услугама. Обично је много брже али може вратити мање ставки и често непотпуне информације (нпр. нема трајања, врсте предмета, нема статуса уживо) - Преузми из наменског довода када је доступан - Увек ажурна - Време након којег се претплата сматра застарелом — %s - Праг освежавања довода - Довод - Прикажи само негруписане претплате +\nДакле, избор се своди на оно што ви преферирате: брзину или прецизне информације. + Онемогући брзи режим + Омогући брзи режим + Доступан у неким услугама, обично је много бржи, али може да врати ограничену количину ставки и често непотпуне информације (нпр. нема трајања, врсте ставке, нема статуса уживо) + Прикупи из наменског фида, када је доступан + Увек ажурирај + Време након последњег ажурирања пре него што се праћење сматра застарелом — %s + Праг освежавања фида + Фид + Прикажи само негруписана праћења Нова - Желите да избришете ову групу\? + Желите ли да избришете ову групу\? Празан назив групе %d одабран %d одабрана %d одабраних - Нема изабраних претплата - Изабери претплате - Обрађујем довод… - Учитавам довод… + Нема изабраних праћења + Изабрана праћења + Обрађивање фида… + Учитавање фида… Није учитано: %d - Довод освежен: %s + Фид последњи пут ажуриран: %s Групе канала %d дан @@ -603,48 +604,191 @@ %d секунди Прикажи детаље о каналу - Повезани записи - Искључите тунеловање ако имате црн екран или прекиде у репродукцији - Искључи тунеловање медија - Отвори веб страну - интерно - лично - ненаведено - јавно + Повезани видео снимци + Онемогућите тунеловање медија ако искусите црни екран или застајкивање при репродукцији видео снимка. + Онемогући тунеловање медија + Отвори веб-сајт + Унутрашње + Приватно + Неизлистано + Јавно Домаћин Подршка Језик Старосно ограничење - Доступност + Приватност Лиценца Ознаке Категорија Омогући бирање текста унутар описа Онемогући бирање текста унутар описа - Сада можете изабрати текст унутар описа. Знајте да страна може треперети а везе неће радити док сте у режиму избора. + Сада можете изабрати текст унутар описа. Имајте на уму да страница може треперети и да се на линкове можда неће моћи кликнути док сте у режиму избора. %s даје овај разлог: Налог укинут - Режим брзог довода не даје више информација о овоме. + Режим брзог фида не пружа више информација о овоме. Налог аутора је укинут. -\nЊуПајп убудуће неће моћи да учита овај довод. -\nЖелите ли да прекинете праћење канала\? - Не могу да учитам довод за „%s“. - Грешка учитавања довода - Од Андроида 10 само „Storage Access Framework“ је подржан - Питаће вас где да сачувате свако преузимање - Фасцикла за преузимање није одређена. Изаберите подразумевану фасциклу - искљ - укљ +\nNewPipe убудуће неће моћи да учита овај фид. +\nЖелите ли да откажете праћење овог канала\? + Није могуће учитати фид за „%s“. + Грешка при учитавању фида + Од Android-а 10 само „Storage Access Framework“ је подржан + Бићете упитани где желите да сачувате свако преузимање + Фолдер за преузимање није одређен, изаберите подразумевани фолдер + Искључи + Укључи Режим таблета - Закажи следеће - Заказано је следеће - Местни предлози претраге + Стави у ред чекања следећи + Стављен у ред чекања следећи + Локални предлози претраге Удаљени предлози претраге Означи као одгледано - Разговори су онемогућени - Обрађујем… Може потрајати пар тренутака - Приказуј указиваче слике - Не покрећи видео у малом прозору, већ пређи одмах у пун приказ заслона, уколико је обртање приказа закључано. И даље можете приступити малом приказу извођача изласком из пуног приказа - Покрени пуни главни приказ извођача - Прекините плејер + Коментари су онемогућени + Обрађивање… Може потрајати пар тренутака + Прикажи индикаторе слике + Не покрећите видео снимке у мини-плејеру, већ директно пређите на режим целог екрана, ако је аутоматска ротација закључана. И даље можете приступити мини-плејеру тако што ћете изаћи из целог екрана + Покрени главни плејер преко целог екрана + Срушите плејер + + %s преузимање је завршено + %s преузимања су завршена + %s преузимања је завршено + + %1$s %2$s + Обавештења о новим стримовима + Обавештења + Погледај на веб-сајту + Ако имате проблема са коришћењем апликације, обавезно погледајте ове одговоре на честа питања! + Дупликат је додат %d пут(а) + Потребна мрежна веза + Потпуно одгледано + Делимично одгледано + Превуците ставке да бисте их уклонили + Низак квалитет (мањи) + Поништи трајну сличицу + Било која мрежа + Ручно проверите постоје ли нове верзије + Спољни плејери не подржавају изабрани стрим + Померите главни бирач картице на дно + Положај главних картица + Дошло је до грешке, погледајте обавештење + NewPipe је наишао на грешку, додирните да бисте пријавили + Прикажи траку са грешком + Учесталост провере + Картица + Уклонити дупликате\? + Желите ли да уклоните све дупликате стримова на овој плејлисти\? + Предстојеће + Подешавања ExoPlayer-а + Увек користи заобилазно решење ExoPlayer-а за подешавање површине излаза видео снимка + Изабери квалитет за спољне плејере + Нема стримова + Нема стримова уживо + + %s нови стрим + %s нова стрима + %s нових стримова + + Учитавање детаља стрима… + Прикажи „Сруши плејер“ + Покрени проверу нових стримова + Тунеловање медија је подразумевано онемогућено на вашем уређају, јер је познато да ваш уређај то не подржава. + Полутон + Обавештавање о новим стримовима из праћења + Провера ажурирања… + Избрисати све преузете фајлове са диска\? + Уклони дупликате + Прикачен коментар + ExoPlayer подразумевано + Изабери све + Не приказују се стримови које програм за преузимање још увек не подржава + Аудио снимак би већ требало да буде присутан у овом стриму + Нема доступних аудио стримова за спољне плејере + Нема доступних видео стримова за спољне плејере + Непознати формат + Непознати квалитет + Непознато + Висок квалитет (већи) + Величина интервала учитавања репродукције + Обавештење о извештају о грешци + Нове ставке фида + Игнориши догађаје хардверског дугмета за медије + Плејлисте које су затамњене већ садрже ову ставку. + LeakCanary није доступан + Додирните да бисте преузели %s + Провери ажурирања + Преглед сличице траке за претрагу + Прикажи следеће стримове + Прикажи/сакриј стримове + Користите резервну функцију декодера ExoPlayer-а + оригинални + Промените величину интервала учитавања на прогресивним садржајима (тренутно %s). Нижа вредност може убрзати њихово почетно учитавање + Корисно, на пример, ако користите слушалице са поквареним физичким дугмадима + Изаберите покрет за леву половину екрана плејера + Радња покретом улево + Изаберите покрет за десну половину екрана плејера + Обавештење плејера + Обавештења о новим стримовима за праћења + Конфигуришите обавештење о тренутно репродукованом стриму + Изаберите оригинални аудио снимак, без обзира на језик + Изаберите аудио снимак са описима за особе са оштећеним видом, ако је доступан + Дај предност описном аудио снимку + Радња покретом удесно + Осветљеност + Јачина звука + Ниједно + Нови стримови + Обавештења за пријаву грешака + Увезите или извезите праћења из менија са 3 тачке + Аудио снимак + Прикажите Picasso обојене траке на врху слика које указују на њихов извор: црвена за мрежу, плава за диск и зелена за меморију + Направите обавештење о грешци + Проценат + Користите најновију верзију NewPipe-а + Не приказуј + Није пронађен одговарајући менаџер фајлова за ову радњу. +\nИнсталирајте менаџер фајлова или покушајте да онемогућите „%s“ у подешавањима преузимања + Често постављана питања + Приказује опцију рушења, када користите плејер + + Избрисано је %1$s преузимање + Избрисано је %1$s преузимања + Избрисано је %1$s преузимања + + Није пронађен одговарајући менаџер фајлова за ову радњу. +\nИнсталирајте менаџер фајлова компатибилан са Storage Access Framework-ом + Срце од стране креатора + Обавештења су онемогућена + Добијајте обавештења + Омогућите ову опцију ако имате проблема са иницијализацијом декодера, која се враћа на декодере нижег приоритета, ако иницијализација примарних декодера не успе. Ово може резултирати лошијим перформансама репродукције него када користите примарне декодере + Ова опција је доступна само ако је %s изабрано за тему + описни + синхронизовани + Управљајте неким подешавањима ExoPlayer-а. Ове промене захтевају рестартовање плејера да би се примениле + Дај предност оригиналном аудио снимку + Ово заобилазно решење ослобађа и поново инстанцира кодеке видео снимка када дође до промене површине, уместо да се површина директно поставља на кодек. ExoPlayer већ користи ово на неким уређајима са овим проблемом, ово подешавање утиче само на Android 6 и новије верзије. +\n +\nОмогућавање ове опције може спречити грешке при репродукцији приликом пребацивања тренутног плејера видео снимака или преласка на цео екран + Аудио снимак: %s + Брзи режим + , + Копирање у привремену меморију није успело + Сортирање + Сада пратите овај канал + Изабери аудио снимак за спољне плејере + Пратиоци + Учитавање метаподатака… + Прикупи картице канала + URL банера + Картице за прикупљање приликом ажурирања фида. Ова опција нема ефекта ако се канал ажурира у брзом режиму. + URL аватара + Видео снимци + Које картице се приказују на страницама канала + Картице канала + Shorts + Информације + Албуми + Плејлисте + Снимци + Канали + Уживо \ No newline at end of file diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index 7aa143c47..3df4c90b0 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -592,9 +592,9 @@ Gözde gece temanızı aşağıdan seçebilirsiniz Gözde gece temanızı seçin — %s Otomatik (cihaz teması) - Gece Teması + Gece teması Kanal ayrıntılarını göster - Ortam yürütümünde siyah ekran veya tutukluk yaşıyorsanız ortam tünellemeyi devre dışı bırakın + Ortam yürütümünde siyah ekran veya tutukluk yaşıyorsanız ortam tünellemeyi devre dışı bırakın. Ortam tünellemeyi devre dışı bırak İç Gizli @@ -747,4 +747,19 @@ Betimlemeli sesi yeğle Ses parçası Bu akışta halihazırda bir ses parçası bulunmalıdır + Akış yok + Canlı akış yok + Sağ kaydırma eylemi + Ana sekme seçiciyi alta taşı + Ana sekme konumu + Ortam tünelleme öntanımlı olarak devre dışı bırakılmıştır çünkü aygıt modelinizin desteği bilinmemektedir. + Çözücü ilklendirme sorunlarınız varsa bu seçeneği etkinleştirin, eğer birincil çözücülerin ilklendirmesi başarısızsa düşük öncelikli çözücülere dönülür. Bu, birincil çözücüler kullanılırkenki başarımdan daha kötü sonuçlanabilir + Her zaman ExoPlayer\'ın video çıktısı yüzey ayar çözümünü kullan + Bu çözüm, bir yüzey değişimi yaşandığında yüzeyi doğrudan kodlayıcıya ayarlamaktansa video kodlayıcısını serbest bırakır ve yeniden örneklendirir. Bu sorunu olan bazı aygıtlarda ExoPlayer tarafından halihazırda kullanılır, bu ayar yalnızca Android 6 ve üstünde etkilidir +\n +\nBu ayarı etkinleştirmek, geçerli video oynatıcısını değiştirirken veya tam ekrana geçerkenki oynatma hatalarını önleyebilir + Progresif içeriklerdeki yükleme aralığı boyutunu değiştir (şu anda %s). Daha düşük değer ilk yüklemeyi hızlandırabilir + Sol kaydırma eylemi + Parmağınızı ekranın sağ yarısında kaydırırken ne yapılacağını seçin + ExoPlayer\'ın çözücü yedek özelliğini kullan \ No newline at end of file diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 193a1c74f..42cf760cb 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -779,4 +779,20 @@ Тунелювання медіа типово було вимкнено на вашому пристрої, оскільки ваша модель його не підтримує. Немає трансляцій Немає трансляцій наживо + Відео + Підписники + Які вкладки показуються на сторінках каналів + Вкладки каналу + Shorts + Завантаження метаданих… + Отримання вкладок каналу + Про канал + URL банера + Альбоми + Отримувані вкладки під час оновлення стрічки. Ця опція не застосовується, якщо канал оновлюється за допомогою швидкого режиму. + URL аватара + Добірки + Доріжки + Канали + Наживо \ No newline at end of file diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 2c6ce4f06..2eec8b548 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -749,4 +749,20 @@ 媒体隧道功能在你的设备上默认停用,因为已知你的设备型号不支持它。 无直播 无音视频流 + 视频 + 订阅者 + 展示在频道页面上的标签页 + 频道标签页 + 短视频 + 正在加载元数据… + 获取频道标签页 + 关于 + 横幅 URL + 专辑 + 更新数据源时要获取的标签页。如果使用快速模式更新频道,则该选项无效果。 + 头像 URL + 播放列表 + 歌曲 + 频道 + 直播 \ No newline at end of file diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 00d257d1c..02cc9e9e9 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -749,4 +749,20 @@ 因為您的裝置型號已知不支援媒體隧道,因此已預設停用。 無串流 無直播串流 + 影片 + 訂閱者 + 頻道頁面上顯示哪些分頁 + 頻道分頁 + 短片 + 正在載入詮釋資料…… + 擷取頻道分頁 + 關於 + 橫幅 URL + 專輯 + 更新 feed 時要擷取的分頁。若使用快速模式更新頻道,則此選項無效。 + 大頭照 URL + 播放清單 + 軌道 + 頻道 + 直播 \ No newline at end of file diff --git a/fastlane/metadata/android/de/changelogs/977.txt b/fastlane/metadata/android/de/changelogs/977.txt index fffd6c9ad..20ab730a4 100644 --- a/fastlane/metadata/android/de/changelogs/977.txt +++ b/fastlane/metadata/android/de/changelogs/977.txt @@ -1,7 +1,7 @@ -• Die Schaltfläche „Weiter abspielen“ wurde dem Langdruckmenü hinzugefügt -• YouTube Shorts Pfadpräfix zum Absichtsfilter hinzugefügt +• Die Schaltfläche „Weiter abspielen“ dem Langdruckmenü hinzugefügt +• YouTube-Shorts-Pfadpräfix zum Absichtsfilter hinzugefügt • Import von Einstellungen behoben -• Position der Suchleiste mit Player-Schaltflächen im Warteschlangen-Bildschirm vertauscht +• Position der Suchleiste mit Player-Schaltflächen im Warteschlangen-Bildschirm getauscht • Verschiedene Korrekturen im Zusammenhang mit MediasessionManager • Die Suchleiste wurde nach dem Ende des Videos nicht abgeschlossen … diff --git a/fastlane/metadata/android/kk/changelogs/63.txt b/fastlane/metadata/android/kk/changelogs/63.txt new file mode 100644 index 000000000..9442b136f --- /dev/null +++ b/fastlane/metadata/android/kk/changelogs/63.txt @@ -0,0 +1,8 @@ +### Жақсартулар +- Импорттау/экспорттау параметрлері #1333 +- Артық шығындарды азайту (өнімділікті арттыру) #1371 +- №1375 кодты сәл жақсарту +- GDPR #1420 туралы бәрін қосыңыз + +### Түзетілді +- Жүктеуші: файлдардан аяқталмаған жүктеулерді жүктеу кезінде ақаулық жойылды .giga #1407 diff --git a/fastlane/metadata/android/kk/changelogs/64.txt b/fastlane/metadata/android/kk/changelogs/64.txt new file mode 100644 index 000000000..7dda13e3a --- /dev/null +++ b/fastlane/metadata/android/kk/changelogs/64.txt @@ -0,0 +1,8 @@ +### Жақсартулар +- Мобильді деректерді пайдалану кезінде бейне сапасын шектеу мүмкіндігі қосылды. #1339 +- #1442 сессиясының жарықтығын есте сақтаңыз +- Әлсіз #1431 процессорлары үшін жүктеу өнімділігі жақсарды +- #1433 медиа сессиясына (жұмыс) қолдау қосылды + +### Түзету +- Жүктеулерді ашқан кезде ақаулық жойылды (түзету енді шығарылым құрылымдары үшін қол жетімді) #1441 diff --git a/fastlane/metadata/android/kk/changelogs/65.txt b/fastlane/metadata/android/kk/changelogs/65.txt new file mode 100644 index 000000000..ae8d58657 --- /dev/null +++ b/fastlane/metadata/android/kk/changelogs/65.txt @@ -0,0 +1,24 @@ +### Жақсартулар +- Burgermenu белгішесінің анимациясын өшіріңіз #1486 +- #1472 жүктеулерді жоюды болдырмау +- Бөлісу мәзіріндегі жүктеу опциясы #1498 +- #1454 ұзақ басу мәзіріне" бөлісу " опциясы қосылды +- #1354 шыққан кезде негізгі ойыншыны айналдырыңыз +- Кітапхана нұсқасын жаңарту және № 1510 дерекқордың сақтық көшірмесін түзету +- Exoplayer 2.8.2 # 1392 Жаңартуы + - Жылдамдықты тезірек өзгерту үшін әр түрлі қадам өлшемдерін сақтау үшін ойнату жылдамдығын басқару диалогы қайта жасалды. + - Ойнату жылдамдығын басқаруда кідірту кезінде жылдам алға жылжу үшін қосқыш қосылды. Бұл аудиокітаптар мен белгілі бір музыкалық жанрлар үшін пайдалы болуы керек және шынымен тегіс ойнатуды қамтамасыз етуі мүмкін (және әнді көптеген қателіктермен бұзуы мүмкін =\\). + - Мультимедиа көзінің ажыратымдылығы метадеректерді қолмен емес, ойнатқыштың ішіндегі медиамен бірге жіберуге мүмкіндік беру үшін өзгертілді. Енді бізде метадеректердің жалғыз көзі бар, ол ойнатуды бастаған кезде тікелей қол жетімді. + - Ойнату тізімінің үзіндісін ашқан кезде жаңа метадеректер қол жетімді болған кезде қашықтағы ойнату тізімінің метадеректері жаңартылмағаны түзетілді. + - Пайдаланушы интерфейсінің әртүрлі түзетулері: # 1383, ойнатқыштың фондық хабарландыру басқару элементтері қазір әрқашан ақ түсті, қалқымалы ойнатқышты өшіру оңай +- Мультисервистік жұмыс үшін қайта өңделген архитектурасы бар жаңа экстракторды қолданыңыз + +### Түзетулер +- Түзетілді # 1440 жұмыс істемейтін бейне ақпарат макеті #1491 +- #1497 тарихты қарауды түзету + - #1495, пайдаланушы ойнату тізіміне кіргеннен кейін метадеректерді (нобай, Бейне атауы және Саны) жаңарту. + - #1475, пайдаланушы егжей-тегжейлі фрагментте сыртқы ойнатқышта бейнені іске қосқан кезде дерекқорда көріністі тіркеу арқылы. +- Қалқымалы режимде іске қосылған кезде Күту уақыты түзетілді. #1463 (түзетілген #640) +- Негізгі бейне ойнатқышты түзету #1509 + - [#1412] ойыншының белсенділігі фонда болған кезде жаңа ниет алған кезде ойыншының NPE шақыратын қайталау режимі түзетілді. + - Егер қалқымалы терезеге рұқсат берілмесе, ойнатқышты қалқымалы терезеге кішірейту ойнатқыштың жойылуына әкелмейтіні түзетілді. diff --git a/fastlane/metadata/android/sr/changelogs/994.txt b/fastlane/metadata/android/sr/changelogs/994.txt new file mode 100644 index 000000000..3ed14410d --- /dev/null +++ b/fastlane/metadata/android/sr/changelogs/994.txt @@ -0,0 +1,15 @@ +Ново +• Подржава више аудио снимака/језика +• Дозвољава подешавање јачине звука и покрета за осветљење на било којој страни екрана +• Подршка за приказивање главних картица на дну екрана + +Побољшано +• [Bandcamp] Управљање нумерама иза платног зида + +Поправљено +• [YouTube] 403 HTTP грешке за стримове +• Црни плејер при преласку на главни плејер са приказа плејлисте +• Цурење сервисне меморије плејера +• [PeerTube] Аватари отпремаоца и подканала су замењени + +и још много тога diff --git a/fastlane/metadata/android/sr/full_description.txt b/fastlane/metadata/android/sr/full_description.txt index df0c3c3f9..e488a0ea4 100644 --- a/fastlane/metadata/android/sr/full_description.txt +++ b/fastlane/metadata/android/sr/full_description.txt @@ -1 +1 @@ -ЊуПајп не користи ниједну библиотеку Гугл оквира нити Јутјуб АПИ. Само скида са Јутјуба оно што му је потребно. Стога се ова апликација може користити на уређајима без инсталираних Гугл услуга. Такође, није вам потребан Јутјуб налог да бисте користили ЊуПајп, и још је слободан, бесплатан и отвореног кода. +NewPipe не користи никакве библиотеке Google оквира, нити YouTube API. Само анализира веб-сајт како би добио потребне информације. Из тог разлога, ова апликација се може користити на уређајима без инсталираних Google услуга. Такође, није Вам потребан YouTube налог да бисте користили NewPipe, a чак је и слободног, отвореног кода. diff --git a/fastlane/metadata/android/sr/short_description.txt b/fastlane/metadata/android/sr/short_description.txt index 34168631b..82608e9db 100644 --- a/fastlane/metadata/android/sr/short_description.txt +++ b/fastlane/metadata/android/sr/short_description.txt @@ -1 +1 @@ -Бесплатна и лагана Јутјуб замена за Андроид. +Бесплатна и лагана замена за YouTube за Android. From 0c9df501e84f43b7c790ea2dc9e83b4eb497b016 Mon Sep 17 00:00:00 2001 From: VfBFan Date: Fri, 22 Sep 2023 05:53:35 +0000 Subject: [PATCH 104/172] Translated using Weblate (German) Currently translated at 100.0% (713 of 713 strings) --- app/src/main/res/values-de/strings.xml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index efa451fce..a3b006d3e 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -778,4 +778,11 @@ Tabs der Kanalseiten abrufen Tabs, die beim Aktualisieren des Feeds abgerufen werden. Diese Option hat keine Auswirkungen, wenn ein Kanal im Schnellmodus aktualisiert wird. Titel + Bildschirmausrichtung umschalten + Vollbildmodus umschalten + Wiedergabewarteschlange öffnen + Vorspulen + Zurückspulen + Wiederholen + Abspielen \ No newline at end of file From ac6811867f0f62728006c6b748fe37a78b88ee80 Mon Sep 17 00:00:00 2001 From: TobiGr Date: Thu, 21 Sep 2023 14:23:35 +0000 Subject: [PATCH 105/172] Translated using Weblate (German) Currently translated at 100.0% (713 of 713 strings) --- app/src/main/res/values-de/strings.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index a3b006d3e..e6cb4f838 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -785,4 +785,8 @@ Zurückspulen Wiederholen Abspielen + Nächster Stream + Mehr Optionen + Dauer + Vorheriger Stream \ No newline at end of file From 0a292cf893ece128f8561c5fa9120118e6d2a0d2 Mon Sep 17 00:00:00 2001 From: gallegonovato Date: Thu, 21 Sep 2023 14:18:28 +0000 Subject: [PATCH 106/172] Translated using Weblate (Spanish) Currently translated at 100.0% (713 of 713 strings) --- app/src/main/res/values-es/strings.xml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 6499a6004..bc0ad2230 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -794,4 +794,15 @@ Pistas Canales En directo + Alternar la orientación de la pantalla + Alternar a pantalla completa + Siguiente retransmisión + Abrir la cola de reproducción + Avanzar + Rebobinar + Volver a reproducir + Reproducir + Más opciones + Duración + Retransmisión anterior \ No newline at end of file From 11c74bd26b096df85b2c9360382b548d9ab5b8a8 Mon Sep 17 00:00:00 2001 From: kuragehime Date: Thu, 21 Sep 2023 21:23:25 +0000 Subject: [PATCH 107/172] Translated using Weblate (Japanese) Currently translated at 100.0% (713 of 713 strings) --- app/src/main/res/values-ja/strings.xml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 038c1ba2f..e97168961 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -765,4 +765,15 @@ トラック チャンネル ライブ + 画面の向きを切り替える + フルスクリーンに切り替える + 次のストリーム + 再生キューを開く + フォワード + 巻き戻し + リプレイ + 再生 + その他のオプション + 期間 + 前のストリーム \ No newline at end of file From 03c339dd4b03192972fa9bd247ce184129927c4e Mon Sep 17 00:00:00 2001 From: Vasilis K Date: Thu, 21 Sep 2023 19:53:30 +0000 Subject: [PATCH 108/172] Translated using Weblate (Greek) Currently translated at 100.0% (713 of 713 strings) --- app/src/main/res/values-el/strings.xml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index e9a2a5615..e59a2fbe9 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -778,4 +778,15 @@ Κομμάτια Κανάλια Ζωντανά + Εναλλαγή προσανατολισμού οθόνης + Λειτουργία πλήρους οθόνης + Επόμενη ροή + Άνοιγμα ουράς αναπαραγωγής + Εμπρός + Πίσω + Επανάληψη + Αναπαραγωγή + Περισσότερες επιλογές + Διάρκεια + Προηγούμενη ροή \ No newline at end of file From 7da35bf71dc9de7798b03d0f9f3596e6dc8a403a Mon Sep 17 00:00:00 2001 From: Marian Hanzel Date: Fri, 22 Sep 2023 10:36:56 +0000 Subject: [PATCH 109/172] Translated using Weblate (Slovak) Currently translated at 99.7% (711 of 713 strings) --- app/src/main/res/values-sk/strings.xml | 34 +++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml index 4677b1b01..bc769e5d3 100644 --- a/app/src/main/res/values-sk/strings.xml +++ b/app/src/main/res/values-sk/strings.xml @@ -604,7 +604,7 @@ Najlepšie Zobraziť podrobnosti kanála Vyrieš - Nočná Téma + Nočná téma Ak vám video pri prehrávaní seká alebo sa zobrazuje čierna obrazovka zakážte tunelovanie médií Zakázať tunelovanie médií Interné @@ -770,4 +770,36 @@ \n \nPovolenie tejto možnosti môže zabrániť chybám pri prehrávaní pri prepínaní aktuálneho prehrávača videa alebo prepínaní na celú obrazovku popisná + Videá + Odberatelia + Karty zobrazované na stránkach kanála + Karty kanálov + Krátke + Načítavanie metadát… + Prepnúť orientáciu obrazovky + Pozícia hlavných kariet + Prepnúť na celú obrazovku + Načítať karty kanála + Ďalší prúd + Vaše zariadenie nepodporuje tunelovanie medií a preto bolo tunelovanie medií zakázané. + Otvoriť zoznam prehrávania + O kanále + URL Bannera + Dopredu + Albumy + Dozadu + Opakovať + Karty na načítanie pri aktualizácii informačného kanála. Táto možnosť nemá žiadny účinok, ak je kanál aktualizovaný pomocou rýchleho režimu. + URL Avatara + Zoznamy skladieb + Presunúť lištu kariet dolu + Žiadne živé prenosy + Prehrať + Ďalšie možnosti + Stopy + Dĺžka + Žiadne videá + Kanály + Predchádzajúci prúd + Naživo \ No newline at end of file From f0bcb3ba28ba29f765055bf03ec1ebe752b686d3 Mon Sep 17 00:00:00 2001 From: Rex_sa Date: Fri, 22 Sep 2023 13:02:42 +0000 Subject: [PATCH 110/172] Translated using Weblate (Arabic) Currently translated at 100.0% (713 of 713 strings) --- app/src/main/res/values-ar/strings.xml | 27 ++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index cd666d69c..9035b8c5e 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -814,4 +814,31 @@ تم تعطيل نفق وسائل الإعلام عن طريق التقصير على جهازك لأن نموذج جهازك معروف بأنه لا يدعمه. لاتوجد بثوث لاتوجد بثوث مباشرة + الفيديوات + المشتركون + ما هي التبويبات المعروضة على صفحات القناة + تبويبات القنوات + الفديوهات القصيرة + جلب البيانات الوصفية… + تبديل تدوير الشاشة + الانتقال إلى وضع ملئ الشاشة + اجلب تبويبات القنوات + البث التالي + فتح قائمة انتظار التسغيل + حول + عنوان الافتة + تقديم المحتوى + الألبومات + إعادة المحتوى + إعادة التشغيل + علامات التبويب لجلبها عند تحديث الخلاصة. ليس لهذا الخيار أي تأثير إذا تم تحديث القناة باستخدام الوضع السريع. + عنوان الصورة الرمزية + قوائم التشغيل + شغِّل + المزيد من الخيارات + المسارات + المدة + القنوات + البث السابق + مباشر \ No newline at end of file From d41b5d80addaa9ca8f30d0712e741e7599c86f6f Mon Sep 17 00:00:00 2001 From: Linerly Date: Fri, 22 Sep 2023 00:15:26 +0000 Subject: [PATCH 111/172] Translated using Weblate (Indonesian) Currently translated at 100.0% (713 of 713 strings) --- app/src/main/res/values-in/strings.xml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index 308bc9a76..321925595 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -765,4 +765,15 @@ Tidak ada saluran Saluran Langsung + Saklar orientasi layar + Saklar layar penuh + Saluran berikutnya + Buka antrean pemain + Maju + Mundur + Putar ulang + Putar + Opsi tambahan + Durasi + Saluran sebelumnya \ No newline at end of file From 1a5dfae7a08b5231c4d6274d99f1f86d573045cd Mon Sep 17 00:00:00 2001 From: Ihor Hordiichuk Date: Thu, 21 Sep 2023 21:09:50 +0000 Subject: [PATCH 112/172] Translated using Weblate (Ukrainian) Currently translated at 100.0% (713 of 713 strings) --- app/src/main/res/values-uk/strings.xml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 42cf760cb..4d3f3ce76 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -795,4 +795,15 @@ Доріжки Канали Наживо + Змінити орієнтацію екрана + Перемкнути повноекранний режим + Наступний стрим + Відкрити чергу відтворення + Перемотати вперед + Відмотати назад + Повторити + Відтворити + Інші опції + Тривалість + Попередній стрим \ No newline at end of file From a69af42f7faf03a6c0022344f6ec1f2ac8bdfd6e Mon Sep 17 00:00:00 2001 From: Agnieszka C Date: Thu, 21 Sep 2023 15:00:02 +0000 Subject: [PATCH 113/172] Translated using Weblate (Polish) Currently translated at 100.0% (713 of 713 strings) --- app/src/main/res/values-pl/strings.xml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 4f6f68234..8d8029e77 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -799,4 +799,15 @@ Utwory Kanały Na żywo + Przełącz orientację ekranu + Włącz/Wyłącz pełny ekran + Następny strumień + Otwórz kolejkę odtwarzania + Przewiń do przodu + Przewiń do tyłu + Odtwórz ponownie + Odtwórz + Więcej opcji + Czas trwania + Poprzedni strumień \ No newline at end of file From dc45adf7f2ef53682df7a03f03523c21f6415f24 Mon Sep 17 00:00:00 2001 From: Eric Date: Fri, 22 Sep 2023 00:41:27 +0000 Subject: [PATCH 114/172] Translated using Weblate (Chinese (Simplified)) Currently translated at 100.0% (713 of 713 strings) --- app/src/main/res/values-zh-rCN/strings.xml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 2eec8b548..39375fc3e 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -765,4 +765,15 @@ 歌曲 频道 直播 + 切换全屏方向 + 切换全屏 + 下一条串流 + 打开播放队列 + 前进 + 后退 + 重放 + 播放 + 更多选项 + 持续时间 + 上一条串流 \ No newline at end of file From b9c7f8769be38c17a18df3aa055e549cd790f1d0 Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Fri, 22 Sep 2023 02:10:11 +0000 Subject: [PATCH 115/172] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (713 of 713 strings) --- app/src/main/res/values-zh-rTW/strings.xml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 02cc9e9e9..e6e0fef9f 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -765,4 +765,15 @@ 軌道 頻道 直播 + 切換螢幕方向 + 切換全螢幕 + 下一個串流 + 開啟播放佇列 + 快轉 + 倒帶 + 重播 + 播放 + 更多選項 + 持續時間 + 上一個串流 \ No newline at end of file From 39c06c54612c2e10a97b1d5d233b1ce3e8ae1c2d Mon Sep 17 00:00:00 2001 From: Yaron Shahrabani Date: Thu, 21 Sep 2023 16:35:49 +0000 Subject: [PATCH 116/172] Translated using Weblate (Hebrew) Currently translated at 100.0% (713 of 713 strings) --- app/src/main/res/values-he/strings.xml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/app/src/main/res/values-he/strings.xml b/app/src/main/res/values-he/strings.xml index 076844339..62fa87510 100644 --- a/app/src/main/res/values-he/strings.xml +++ b/app/src/main/res/values-he/strings.xml @@ -804,4 +804,15 @@ רצועות ערוצים שידור חי + החלפת כיוון מסך + מילוי המסך/רגיל + התזרים הבא + פתיחת תור נגינה + דילוג קדימה + החזרה אחורה + נגינה חוזרת + נגינה + אפשרויות נוספות + משך + התזרים הקודם \ No newline at end of file From 1084b7c3ade1780de70fdf1dfa5669bc99113c37 Mon Sep 17 00:00:00 2001 From: ShareASmile Date: Thu, 21 Sep 2023 18:17:30 +0000 Subject: [PATCH 117/172] Translated using Weblate (Hindi) Currently translated at 100.0% (713 of 713 strings) --- app/src/main/res/values-hi/strings.xml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/app/src/main/res/values-hi/strings.xml b/app/src/main/res/values-hi/strings.xml index 7b16281eb..b3f9314b2 100644 --- a/app/src/main/res/values-hi/strings.xml +++ b/app/src/main/res/values-hi/strings.xml @@ -778,4 +778,15 @@ ट्रैक्स चैनल्स लाइव + स्क्रीन ओरिएंटेशन टॉगल करें + फ़ुलस्क्रीन टॉगल करें + अगली स्ट्रीम + प्ले कतार खोलें + फॉरवर्ड करें + रिवाइंड करें + पुनः चलाएं + चलाएं + अधिक विकल्प + अवधि + पिछली स्ट्रीम \ No newline at end of file From b9e5ee6759506ea8e5d2ed293f989baefe9637b6 Mon Sep 17 00:00:00 2001 From: ShareASmile Date: Thu, 21 Sep 2023 18:13:16 +0000 Subject: [PATCH 118/172] Translated using Weblate (Punjabi) Currently translated at 100.0% (713 of 713 strings) --- app/src/main/res/values-pa/strings.xml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/app/src/main/res/values-pa/strings.xml b/app/src/main/res/values-pa/strings.xml index d6016759f..fb0c69563 100644 --- a/app/src/main/res/values-pa/strings.xml +++ b/app/src/main/res/values-pa/strings.xml @@ -778,4 +778,15 @@ ਟ੍ਰੈਕਸ ਚੈਨਲਜ਼ ਲਾਈਵ + ਸਕ੍ਰੀਨ ਸਥਿਤੀ ਨੂੰ ਟੌਗਲ ਕਰੋ + ਫੁੱਲ ਸਕ੍ਰੀਨ ਨੂੰ ਟੌਗਲ ਕਰੋ + ਅਗਲੀ ਸਟ੍ਰੀਮ + ਪਲੇ ਕਤਾਰ ਖੋਲ੍ਹੋ + ਅੱਗੇ ਕਰੋ + ਰੀਵਾਈਂਡ ਕਰੋ + ਰੀਪਲੇਅ + ਚਲਾਓ + ਹੋਰ ਵਿਕਲਪ + ਮਿਆਦ + ਪਿਛਲੀ ਸਟ੍ਰੀਮ \ No newline at end of file From cb4f6566733dd8e185bd7c9098d49dfc09b7d54e Mon Sep 17 00:00:00 2001 From: Marian Hanzel Date: Fri, 22 Sep 2023 10:45:44 +0000 Subject: [PATCH 119/172] Translated using Weblate (Slovak) Currently translated at 18.6% (14 of 75 strings) Translation: NewPipe/Metadata Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/sk/ --- fastlane/metadata/android/sk/changelogs/994.txt | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 fastlane/metadata/android/sk/changelogs/994.txt diff --git a/fastlane/metadata/android/sk/changelogs/994.txt b/fastlane/metadata/android/sk/changelogs/994.txt new file mode 100644 index 000000000..4095fafb2 --- /dev/null +++ b/fastlane/metadata/android/sk/changelogs/994.txt @@ -0,0 +1,15 @@ +Nové +• Podpora viacerých zvukových skladieb / jazykov +• Umožňuje nastaviť objem a jasové gestá na každej strane obrazovky +• Podpora pre zobrazenie hlavných bodov v dolnej časti obrazovky + +Zlepšené +• [Bandcamp] podpora skladieb dostupná pre predplatiteľov + +Opravené +• [YouTube] 403 HTTP chýb pre streamy +• Čierná obrazovka pri prepínaní do hlavného prehrávača zo zobraznia z playlistu +• Pretečenie pamäte prehrávača +• [PeerTube] Avatary uploadera a subkanála boli vymenené + +a viac From a5fcb41ab07f7d3ea69737b3ee07be11c1c5978d Mon Sep 17 00:00:00 2001 From: kuragehime Date: Thu, 21 Sep 2023 21:33:42 +0000 Subject: [PATCH 120/172] Translated using Weblate (ryu (generated) (ryu)) Currently translated at 100.0% (713 of 713 strings) --- app/src/main/res/values-ryu/strings.xml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/app/src/main/res/values-ryu/strings.xml b/app/src/main/res/values-ryu/strings.xml index 40b988c8a..6272fea4b 100644 --- a/app/src/main/res/values-ryu/strings.xml +++ b/app/src/main/res/values-ryu/strings.xml @@ -781,4 +781,15 @@ トラック チャンネル ライブ + やしがみんぬむききりかいーん + フルスクリーンんかいきりかいーん + ちぎぬストリーム + さいせいキューふぃらちゅん + フォワード + まきんどぅし + リプレイ + さいせい + うぬふかぬオプション + ちかん + めーぬストリーム \ No newline at end of file From 279fd2399dcc479b26792d45c088090d1c189732 Mon Sep 17 00:00:00 2001 From: TobiGr Date: Fri, 22 Sep 2023 21:44:58 +0200 Subject: [PATCH 121/172] Remove translations without default value --- app/src/main/res/values-ar/strings.xml | 2 -- app/src/main/res/values-de/strings.xml | 2 -- app/src/main/res/values-el/strings.xml | 2 -- app/src/main/res/values-es/strings.xml | 2 -- app/src/main/res/values-he/strings.xml | 2 -- app/src/main/res/values-hi/strings.xml | 2 -- app/src/main/res/values-in/strings.xml | 2 -- app/src/main/res/values-it/strings.xml | 2 -- app/src/main/res/values-ja/strings.xml | 2 -- app/src/main/res/values-nn/strings.xml | 1 - app/src/main/res/values-nqo/strings.xml | 3 --- app/src/main/res/values-pa/strings.xml | 2 -- app/src/main/res/values-pl/strings.xml | 2 -- app/src/main/res/values-pt-rBR/strings.xml | 2 -- app/src/main/res/values-ryu/strings.xml | 5 ----- app/src/main/res/values-sk/strings.xml | 2 -- app/src/main/res/values-sr/strings.xml | 2 -- app/src/main/res/values-uk/strings.xml | 2 -- app/src/main/res/values-zh-rCN/strings.xml | 2 -- app/src/main/res/values-zh-rTW/strings.xml | 2 -- 20 files changed, 43 deletions(-) diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index 9035b8c5e..957854e00 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -826,13 +826,11 @@ البث التالي فتح قائمة انتظار التسغيل حول - عنوان الافتة تقديم المحتوى الألبومات إعادة المحتوى إعادة التشغيل علامات التبويب لجلبها عند تحديث الخلاصة. ليس لهذا الخيار أي تأثير إذا تم تحديث القناة باستخدام الوضع السريع. - عنوان الصورة الرمزية قوائم التشغيل شغِّل المزيد من الخيارات diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index e6cb4f838..5923aaaaa 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -773,8 +773,6 @@ Welche Tabs auf den Kanalseiten angezeigt werden Lade Metadaten … Über - Banner-URL - Avatar-URL Tabs der Kanalseiten abrufen Tabs, die beim Aktualisieren des Feeds abgerufen werden. Diese Option hat keine Auswirkungen, wenn ein Kanal im Schnellmodus aktualisiert wird. Titel diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index e59a2fbe9..2a5fbb445 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -770,10 +770,8 @@ Shorts Λήψη καρτελών καναλιών Σχετικά - Banner URL Άλμπουμ Καρτέλες για ανάκτηση κατά την ενημέρωση της ροής. Αυτή η επιλογή δεν έχει καμία επίδραση εάν ένα κανάλι ενημερώνεται χρησιμοποιώντας τη γρήγορη λειτουργία. - URL άβαταρ Λίστες Κομμάτια Κανάλια diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index bc0ad2230..0f623d8ba 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -786,10 +786,8 @@ Cargando los metadatos… Recuperar las fichas del canal Acerca de - Dirección url del anuncio Álbumes Pestañas para recuperar al actualizar el canal. Esta opción no tiene efecto si el canal se actualiza en modo rápido. - Dirección url del avatar Listas de reproducción Pistas Canales diff --git a/app/src/main/res/values-he/strings.xml b/app/src/main/res/values-he/strings.xml index 62fa87510..9fd93dff3 100644 --- a/app/src/main/res/values-he/strings.xml +++ b/app/src/main/res/values-he/strings.xml @@ -796,10 +796,8 @@ נתוני העל נטענים… משיכת לשוניות הערוץ על אודות - כתובת כרזה אלבומים לשוניות למשיכה בעת עדכון ערוץ העדכונים. לאפשרות זו אין השפעה אם הערוץ מתעדכן במצב מהיר. - כתובת תמונה ייצוגית רשימות נגינה רצועות ערוצים diff --git a/app/src/main/res/values-hi/strings.xml b/app/src/main/res/values-hi/strings.xml index b3f9314b2..df34f3a07 100644 --- a/app/src/main/res/values-hi/strings.xml +++ b/app/src/main/res/values-hi/strings.xml @@ -770,10 +770,8 @@ मेटाडेटा लोड हो रहा है… चैनल टैब प्राप्त करें बारे में - बैनर URL एल्बम्स फ़ीड अपडेट करते समय प्राप्त करने वाले टैब। यदि किसी चैनल को तेज़ मोड का उपयोग करके अपडेट किया जाता है तो इस विकल्प का कोई प्रभाव नहीं पड़ता है। - अवतार URL प्लेलिस्ट्स ट्रैक्स चैनल्स diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index 321925595..296b2d41b 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -756,10 +756,8 @@ Memuat Metadata… Dapatjan tab saluran Tentang - URL banner Album Tab untuk didapatkan ketika memperarui umpan. Opsi ini tidak memiliki efek jika saluran diperbarui menggunakan mode cepat. - URL avatar Daftar putar Trek Tidak ada saluran diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 4f4068d9a..00a6d4894 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -783,10 +783,8 @@ Caricamento metadati… Recupera schede del canale Informazioni - URL banner Album Schede da recuperare quando si aggiorna il feed. Questa opzione non ha effetto se un canale viene aggiornato usando la modalità veloce. - URL avatar Playlist Tracce Canali diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index e97168961..c1dd66046 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -751,8 +751,6 @@ ライブ配信はありません 登録者 メタ情報を読み込んでいます… - バナーのURL - アバターのURL 動画 チャンネルページに表示されるタブ チャンネルタブ diff --git a/app/src/main/res/values-nn/strings.xml b/app/src/main/res/values-nn/strings.xml index 55c3cdc62..a6d12fe2a 100644 --- a/app/src/main/res/values-nn/strings.xml +++ b/app/src/main/res/values-nn/strings.xml @@ -90,7 +90,6 @@ Stadfest radtømming Byte ifrå ein avspelar til ein annan kan skifta ut rada di Den noverande avspelingsrada vil verta skift ut - Hent fram småbilete Sjå bort ifrå mediaknappetrykk Nyttig om du til dømes nyttar høyretelefonar med skadde knappar Ingen diff --git a/app/src/main/res/values-nqo/strings.xml b/app/src/main/res/values-nqo/strings.xml index c9c4904ac..b04c8d5f0 100644 --- a/app/src/main/res/values-nqo/strings.xml +++ b/app/src/main/res/values-nqo/strings.xml @@ -85,7 +85,6 @@ ߛߋ߲߬ߠߊ߬ ߕߏߟߏ߲ߟߊ߲ ߠߊ߫ ߕߎ߲߰ߠߌ߲ ߘߌߣߊ߬ ߣߐ߬ߘߐߓߌ߬ߟߊ߬ ߞߊ߬ ߕߙߏߞߏ ߞߟߋߞߟߋ߫ ߞߘߎ ߟߊ߫ ߖߊ߲߬ߖߊ߲߬ ߠߎ߬ ߡߊߓߌ߬ߟߊ߬ ߏ߬ ߢߊߕߣߐ ߞߊߓߏ߬߸ ߣߴߌ ߦߋ߫ ߕߟߏߡߊߘߏ߲ ߠߊߓߊ߯ߙߊ ߟߊ߫ ߡߍ߲ ߞߘߎ߬ ߜߎ ߟߎ߬ ߕߍ߫ ߛߐ߲߬ - ߞߊ߬ ߞߏ߬ߋߞߏ߬ߋ ߟߎ߬ ߖߛߐ߫ ߣߎߡߊ߲߫ ߖߍ߰ߙߍ ߞߍߟߌ ߕߏߟߏ߲ߟߊ߲߫ ߥߊ߲߬ߥߊ߲ ߞߌߣߌ߲߫ ߕߟߊ ߖߍ߰ߙߍ ߛߎߥߊ߲ߘߌ߫ ߞߌߣߌ߲߫ ߖߍ߰ߙߍ ߞߍߟߌ @@ -206,7 +205,6 @@ ߘߐ߬ߞߊ߬ߙߊ߲߬ߠߌ߲߫ ߘߊ߲߬ߘߌߦߊ ߟߎ߬ ߓߍ߯ ߖߐ߬ߛߌ߫ ߞߐߞߊ߲߫ ߦߟߌߕߏߟߊ߲߫ ߞߊ߲߬ ߟߊ߬ߖߌ߰ߟߌ ߕߍ߫ ߓߍ߲߬. ߦߴߊ߬ ߝߍ߬ ߞߊ߬ ߟߊ߬ߖߌ߰ߟߌ߬ ߞߎ߲ߓߍ߲ ߘߌ߲߬ߞߌߙߊ ߢߡߊߛߊ߬ߦߌ߬ ؟ ߟߊ߬ߖߌ߰ߟߌ ߢߣߊߥߟߊ߫ ߕߍ߫ ߛߋ߫ ߘߐߛߌ߰ ߟߊ߫ - ߊ߬ ߟߊߛߊ߬ ߞߏߛߊ߫ ߞߏ߬ߋߞߏ߬ߋ ߟߎ߬ ߞߊߣߊ߬ ߖߛߐ߫߸ ߞߊ߬ ߟߐ߲ߕߊ ߣߌ߫ ߦߟߌߕߏߟߊ߲ ߡߊߞߐߙߐ߲ߞߐߙߐ߲߫. ߡߝߊ߬ߟߋ߲߬ߠߌ߲ ߘߌ߫ ߖߌ߬ߦߊ߬ߓߍ ߟߎ߬ ߦߟߌߡߊߛߌ ߓߍ߯ ߖߏ߬ߛߌ߫ ߦߟߌߕߏߟߊ߲ ߣߌ߫ ߝߘߍ߬ߜߍߟߍ߲ ߞߊ߲߬ ߞߊ߬ ߞߊ߲߬ߞߎߡߊ ߟߎ߫ ߦߌ߬ߘߊ߬ ߊ߬ ߟߊߛߊ߬ ߞߊ߬ ߞߊ߲߬ߞߎߡߊ ߟߎ߬ ߢߡߊߘߏ߲߰ ߞߊ߬ ߦߋߡߍ߲ߕߊ߫ ߣߊ߬ߕߊ ߟߎ߬ ߣߌ߫ ߢߐ߲߰ߘߐ ߟߎ߫ ߦߌ߬ߘߊ߬ @@ -645,7 +643,6 @@ ߞߊ߲ ߞߐߞߘߐߓߌ߲ߓߌ߲ ߖߊ߬ߕߌ߮ - ߞߏ߬ߋߞߏ߬ߋ߫ ߛߘߌ߬ߜߋ߲ ߝߘߏ߬ߓߊ ߊ߬ ߛߙߍߘߍߦߊߣߍ߲߫ ߕߍ߫ ߘߎ߲߬ߘߎ߬ߡߊ diff --git a/app/src/main/res/values-pa/strings.xml b/app/src/main/res/values-pa/strings.xml index fb0c69563..6a5f40e1a 100644 --- a/app/src/main/res/values-pa/strings.xml +++ b/app/src/main/res/values-pa/strings.xml @@ -770,10 +770,8 @@ ਮੈਟਾਡੇਟਾ ਲੋਡ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ… ਚੈਨਲ ਟੈਬਾਂ ਪ੍ਰਾਪਤ ਕਰੋ ਦੇ ਬਾਰੇ - ਬੈਨਰ URL ਐਲਬਮਜ਼ ਫ਼ੀਡ ਅੱਪਡੇਟ ਕਰਨ ਵੇਲੇ ਪ੍ਰਾਪਤ ਕਰਨ ਲਈ ਟੈਬਾਂ। ਇਸ ਵਿਕਲਪ ਦਾ ਕੋਈ ਅਸਰ ਨਹੀਂ ਹੁੰਦਾ ਜੇਕਰ ਚੈਨਲ ਨੂੰ ਫਾਸਟ ਮੋਡ ਦੀ ਵਰਤੋਂ ਕਰਕੇ ਅੱਪਡੇਟ ਕੀਤਾ ਜਾਂਦਾ ਹੈ। - ਅਵਤਾਰ URL ਪਲੇਲਿਸਟਾਂ ਟ੍ਰੈਕਸ ਚੈਨਲਜ਼ diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 8d8029e77..8b6701564 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -791,10 +791,8 @@ Ładowanie metadanych… Pobieranie kart kanału Informacje - Adres URL banera Albumy Karty do pobrania podczas aktualizacji kanału. Ta opcja nie działa, jeśli kanał jest aktualizowany w trybie szybkim - Adres URL awatara Playlisty Utwory Kanały diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index eb2c26d5f..53bd19e28 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -783,10 +783,8 @@ Carregando metadados… Buscar guias de canal Sobre - URL do banner Álbuns Guias a serem buscadas ao atualizar o feed. Esta opção não tem efeito se um canal for atualizado usando o modo rápido. - URL do avatar Playlists Faixas Canais diff --git a/app/src/main/res/values-ryu/strings.xml b/app/src/main/res/values-ryu/strings.xml index 6272fea4b..53df30d2f 100644 --- a/app/src/main/res/values-ryu/strings.xml +++ b/app/src/main/res/values-ryu/strings.xml @@ -195,7 +195,6 @@ ちゃーしがダウンロード じょうほうひょうじ ブックマークさるプレイリスト - サムネイルゆみくむん やしがぞうキャッシュしーょうきょさびたん キャッシュしーょうきょ アプリねーんぬキャッシュデータまじりさくじょさます @@ -253,7 +252,6 @@ プライバシーポリシーかくにん おおまかやるシーク おおまかやるシークしようするくとぅっしさいどぅがさがいるかわりんかいこうすくんかいシークぬなやびーん。5びょう、15びょうあらんでぃ25びょうかんかくぬシークーなやびらん - サムネイルぬゆみくみとぅふずんんーかなやーさびーん。(くぬオプションきりけーいねーメモリとぅディスクじょうぬがぞうキャッシュぬしーょうきょさりやびーん) キューんかいかんりんちゃーがちいからちさいせいちづきーん(くいけーしさんーあい) まじりぬさいせいりりきさちゅるじょさびーが? まじりどぅきらんさくりりきさちゅるじょさびーが? @@ -611,7 +609,6 @@ ぎんぐ サポート ホスト - サムネイルぬURL ウェブサイトふぃらちゅん ダウンロードぬかーじにふずんすーしょたんにやびーん ダウンロードフォルダーぬなーらしっていさりやびらん。なまちゃーきデフォルトぬフォルダーさんたくちくぃみそーれー @@ -773,10 +770,8 @@ メタじょうほうゆみくどーいびーん… チャンネルタブしーゅとぅくしーん しょうさい - バナーぬURL アルバム フィードこうしんすんとぅちなしゅとぅくしーんタブ。 こうすくモードさしてぃチャンネルこうしんすーあえー、かんがぬあいびらん。 - アバターぬURL プレイリスト トラック チャンネル diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml index bc769e5d3..b6c823e68 100644 --- a/app/src/main/res/values-sk/strings.xml +++ b/app/src/main/res/values-sk/strings.xml @@ -784,13 +784,11 @@ Vaše zariadenie nepodporuje tunelovanie medií a preto bolo tunelovanie medií zakázané. Otvoriť zoznam prehrávania O kanále - URL Bannera Dopredu Albumy Dozadu Opakovať Karty na načítanie pri aktualizácii informačného kanála. Táto možnosť nemá žiadny účinok, ak je kanál aktualizovaný pomocou rýchleho režimu. - URL Avatara Zoznamy skladieb Presunúť lištu kariet dolu Žiadne živé prenosy diff --git a/app/src/main/res/values-sr/strings.xml b/app/src/main/res/values-sr/strings.xml index 3b506c760..380fa05f8 100644 --- a/app/src/main/res/values-sr/strings.xml +++ b/app/src/main/res/values-sr/strings.xml @@ -778,9 +778,7 @@ Пратиоци Учитавање метаподатака… Прикупи картице канала - URL банера Картице за прикупљање приликом ажурирања фида. Ова опција нема ефекта ако се канал ажурира у брзом режиму. - URL аватара Видео снимци Које картице се приказују на страницама канала Картице канала diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 4d3f3ce76..dd3632f66 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -787,10 +787,8 @@ Завантаження метаданих… Отримання вкладок каналу Про канал - URL банера Альбоми Отримувані вкладки під час оновлення стрічки. Ця опція не застосовується, якщо канал оновлюється за допомогою швидкого режиму. - URL аватара Добірки Доріжки Канали diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 39375fc3e..7bf14e520 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -757,10 +757,8 @@ 正在加载元数据… 获取频道标签页 关于 - 横幅 URL 专辑 更新数据源时要获取的标签页。如果使用快速模式更新频道,则该选项无效果。 - 头像 URL 播放列表 歌曲 频道 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index e6e0fef9f..458332272 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -757,10 +757,8 @@ 正在載入詮釋資料…… 擷取頻道分頁 關於 - 橫幅 URL 專輯 更新 feed 時要擷取的分頁。若使用快速模式更新頻道,則此選項無效。 - 大頭照 URL 播放清單 軌道 頻道 From 242e20316b2973649a49c8737ec967ef7d662174 Mon Sep 17 00:00:00 2001 From: TobiGr Date: Wed, 20 Sep 2023 18:45:52 +0200 Subject: [PATCH 122/172] [AboutFragment / LicenseFragment] Fix license restore after rotation Do not restore last opened license after a rotation change when the license was closed earlier. This commit adds onCancelListener and onDismissListener to the AlertDialogs which are used to display the licenses. --- .../schabi/newpipe/about/LicenseFragment.kt | 60 ++++++++++++++++++- .../newpipe/about/LicenseFragmentHelper.kt | 57 +----------------- 2 files changed, 60 insertions(+), 57 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/about/LicenseFragment.kt b/app/src/main/java/org/schabi/newpipe/about/LicenseFragment.kt index f19ecd74a..a560f407a 100644 --- a/app/src/main/java/org/schabi/newpipe/about/LicenseFragment.kt +++ b/app/src/main/java/org/schabi/newpipe/about/LicenseFragment.kt @@ -1,15 +1,24 @@ package org.schabi.newpipe.about import android.os.Bundle +import android.util.Base64 import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import android.webkit.WebView +import androidx.appcompat.app.AlertDialog import androidx.core.os.bundleOf import androidx.fragment.app.Fragment +import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers +import io.reactivex.rxjava3.core.Observable import io.reactivex.rxjava3.disposables.CompositeDisposable +import io.reactivex.rxjava3.disposables.Disposable +import io.reactivex.rxjava3.schedulers.Schedulers import org.schabi.newpipe.R import org.schabi.newpipe.databinding.FragmentLicensesBinding import org.schabi.newpipe.databinding.ItemSoftwareComponentBinding +import org.schabi.newpipe.util.Localization +import org.schabi.newpipe.util.external_communication.ShareUtils /** * Fragment containing the software licenses. @@ -41,7 +50,7 @@ class LicenseFragment : Fragment() { binding.licensesAppReadLicense.setOnClickListener { activeLicense = StandardLicenses.GPL3 compositeDisposable.add( - showLicense(activity, StandardLicenses.GPL3) + showLicense(StandardLicenses.GPL3) ) } for (component in softwareComponents) { @@ -59,13 +68,13 @@ class LicenseFragment : Fragment() { root.setOnClickListener { activeLicense = component.license compositeDisposable.add( - showLicense(activity, component) + showLicense(component) ) } binding.licensesSoftwareComponents.addView(root) registerForContextMenu(root) } - activeLicense?.let { compositeDisposable.add(showLicense(activity, it)) } + activeLicense?.let { compositeDisposable.add(showLicense(it)) } return binding.root } @@ -74,6 +83,51 @@ class LicenseFragment : Fragment() { activeLicense?.let { savedInstanceState.putSerializable(LICENSE_KEY, it) } } + private fun showLicense(component: SoftwareComponent): Disposable { + return showLicense(component.license) { + setPositiveButton(R.string.dismiss) { dialog, _ -> + dialog.dismiss() + } + setNeutralButton(R.string.open_website_license) { _, _ -> + ShareUtils.openUrlInApp(requireContext(), component.link) + } + } + } + + private fun showLicense(license: License) = showLicense(license) { + setPositiveButton(R.string.ok) { dialog, _ -> dialog.dismiss() } + } + + private fun showLicense( + license: License, + block: AlertDialog.Builder.() -> AlertDialog.Builder + ): Disposable { + return if (context == null) { + Disposable.empty() + } else { + val context = requireContext() + Observable.fromCallable { getFormattedLicense(context, license) } + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe { formattedLicense -> + val webViewData = Base64.encodeToString( + formattedLicense.toByteArray(), Base64.NO_PADDING + ) + val webView = WebView(context) + webView.loadData(webViewData, "text/html; charset=UTF-8", "base64") + + Localization.assureCorrectAppLanguage(context) + AlertDialog.Builder(requireContext()) + .setTitle(license.name) + .setView(webView) + .setOnCancelListener { activeLicense = null } + .setOnDismissListener { activeLicense = null } + .block() + .show() + } + } + } + companion object { private const val ARG_COMPONENTS = "components" private const val LICENSE_KEY = "ACTIVE_LICENSE" diff --git a/app/src/main/java/org/schabi/newpipe/about/LicenseFragmentHelper.kt b/app/src/main/java/org/schabi/newpipe/about/LicenseFragmentHelper.kt index 5af7eefec..56e21c88a 100644 --- a/app/src/main/java/org/schabi/newpipe/about/LicenseFragmentHelper.kt +++ b/app/src/main/java/org/schabi/newpipe/about/LicenseFragmentHelper.kt @@ -1,17 +1,8 @@ package org.schabi.newpipe.about import android.content.Context -import android.util.Base64 -import android.webkit.WebView -import androidx.appcompat.app.AlertDialog -import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers -import io.reactivex.rxjava3.core.Observable -import io.reactivex.rxjava3.disposables.Disposable -import io.reactivex.rxjava3.schedulers.Schedulers import org.schabi.newpipe.R -import org.schabi.newpipe.util.Localization import org.schabi.newpipe.util.ThemeHelper -import org.schabi.newpipe.util.external_communication.ShareUtils import java.io.IOException /** @@ -20,7 +11,7 @@ import java.io.IOException * @return String which contains a HTML formatted license page * styled according to the context's theme */ -private fun getFormattedLicense(context: Context, license: License): String { +fun getFormattedLicense(context: Context, license: License): String { try { return context.assets.open(license.filename).bufferedReader().use { it.readText() } // split the HTML file and insert the stylesheet into the HEAD of the file @@ -34,7 +25,7 @@ private fun getFormattedLicense(context: Context, license: License): String { * @param context the Android context * @return String which is a CSS stylesheet according to the context's theme */ -private fun getLicenseStylesheet(context: Context): String { +fun getLicenseStylesheet(context: Context): String { val isLightTheme = ThemeHelper.isLightThemeSelected(context) val licenseBackgroundColor = getHexRGBColor( context, if (isLightTheme) R.color.light_license_background_color else R.color.dark_license_background_color @@ -56,48 +47,6 @@ private fun getLicenseStylesheet(context: Context): String { * @param color the color number from R.color * @return a six characters long String with hexadecimal RGB values */ -private fun getHexRGBColor(context: Context, color: Int): String { +fun getHexRGBColor(context: Context, color: Int): String { return context.getString(color).substring(3) } - -fun showLicense(context: Context?, component: SoftwareComponent): Disposable { - return showLicense(context, component.license) { - setPositiveButton(R.string.dismiss) { dialog, _ -> - dialog.dismiss() - } - setNeutralButton(R.string.open_website_license) { _, _ -> - ShareUtils.openUrlInApp(context!!, component.link) - } - } -} - -fun showLicense(context: Context?, license: License) = showLicense(context, license) { - setPositiveButton(R.string.ok) { dialog, _ -> dialog.dismiss() } -} - -private fun showLicense( - context: Context?, - license: License, - block: AlertDialog.Builder.() -> AlertDialog.Builder -): Disposable { - return if (context == null) { - Disposable.empty() - } else { - Observable.fromCallable { getFormattedLicense(context, license) } - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe { formattedLicense -> - val webViewData = - Base64.encodeToString(formattedLicense.toByteArray(), Base64.NO_PADDING) - val webView = WebView(context) - webView.loadData(webViewData, "text/html; charset=UTF-8", "base64") - - Localization.assureCorrectAppLanguage(context) - AlertDialog.Builder(context) - .setTitle(license.name) - .setView(webView) - .block() - .show() - } - } -} From e206a26a85caeef92d201dbc7b8f9e8524e8565d Mon Sep 17 00:00:00 2001 From: TobiGr Date: Thu, 21 Sep 2023 10:31:04 +0200 Subject: [PATCH 123/172] Restore license dialog buttons to open the SoftwareComponent's website Do not keep the active License but the active SoftwareComponent. --- .../schabi/newpipe/about/LicenseFragment.kt | 66 ++++++++++--------- .../schabi/newpipe/about/SoftwareComponent.kt | 3 +- 2 files changed, 36 insertions(+), 33 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/about/LicenseFragment.kt b/app/src/main/java/org/schabi/newpipe/about/LicenseFragment.kt index a560f407a..10e825efd 100644 --- a/app/src/main/java/org/schabi/newpipe/about/LicenseFragment.kt +++ b/app/src/main/java/org/schabi/newpipe/about/LicenseFragment.kt @@ -14,6 +14,7 @@ import io.reactivex.rxjava3.core.Observable import io.reactivex.rxjava3.disposables.CompositeDisposable import io.reactivex.rxjava3.disposables.Disposable import io.reactivex.rxjava3.schedulers.Schedulers +import org.schabi.newpipe.BuildConfig import org.schabi.newpipe.R import org.schabi.newpipe.databinding.FragmentLicensesBinding import org.schabi.newpipe.databinding.ItemSoftwareComponentBinding @@ -25,13 +26,13 @@ import org.schabi.newpipe.util.external_communication.ShareUtils */ class LicenseFragment : Fragment() { private lateinit var softwareComponents: Array - private var activeLicense: License? = null + private var activeSoftwareComponent: SoftwareComponent? = null private val compositeDisposable = CompositeDisposable() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) softwareComponents = arguments?.getParcelableArray(ARG_COMPONENTS) as Array - activeLicense = savedInstanceState?.getSerializable(LICENSE_KEY) as? License + activeSoftwareComponent = savedInstanceState?.getSerializable(SOFTWARE_COMPONENT_KEY) as? SoftwareComponent // Sort components by name softwareComponents.sortBy { it.name } } @@ -48,9 +49,8 @@ class LicenseFragment : Fragment() { ): View { val binding = FragmentLicensesBinding.inflate(inflater, container, false) binding.licensesAppReadLicense.setOnClickListener { - activeLicense = StandardLicenses.GPL3 compositeDisposable.add( - showLicense(StandardLicenses.GPL3) + showLicense(NEWPIPE_SOFTWARE_COMPONENT) ) } for (component in softwareComponents) { @@ -66,7 +66,6 @@ class LicenseFragment : Fragment() { val root: View = componentBinding.root root.tag = component root.setOnClickListener { - activeLicense = component.license compositeDisposable.add( showLicense(component) ) @@ -74,39 +73,24 @@ class LicenseFragment : Fragment() { binding.licensesSoftwareComponents.addView(root) registerForContextMenu(root) } - activeLicense?.let { compositeDisposable.add(showLicense(it)) } + activeSoftwareComponent?.let { compositeDisposable.add(showLicense(it)) } return binding.root } override fun onSaveInstanceState(savedInstanceState: Bundle) { super.onSaveInstanceState(savedInstanceState) - activeLicense?.let { savedInstanceState.putSerializable(LICENSE_KEY, it) } - } - - private fun showLicense(component: SoftwareComponent): Disposable { - return showLicense(component.license) { - setPositiveButton(R.string.dismiss) { dialog, _ -> - dialog.dismiss() - } - setNeutralButton(R.string.open_website_license) { _, _ -> - ShareUtils.openUrlInApp(requireContext(), component.link) - } - } - } - - private fun showLicense(license: License) = showLicense(license) { - setPositiveButton(R.string.ok) { dialog, _ -> dialog.dismiss() } + activeSoftwareComponent?.let { savedInstanceState.putSerializable(SOFTWARE_COMPONENT_KEY, it) } } private fun showLicense( - license: License, - block: AlertDialog.Builder.() -> AlertDialog.Builder + softwareComponent: SoftwareComponent ): Disposable { return if (context == null) { Disposable.empty() } else { val context = requireContext() - Observable.fromCallable { getFormattedLicense(context, license) } + activeSoftwareComponent = softwareComponent + Observable.fromCallable { getFormattedLicense(context, softwareComponent.license) } .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe { formattedLicense -> @@ -117,20 +101,38 @@ class LicenseFragment : Fragment() { webView.loadData(webViewData, "text/html; charset=UTF-8", "base64") Localization.assureCorrectAppLanguage(context) - AlertDialog.Builder(requireContext()) - .setTitle(license.name) + val builder = AlertDialog.Builder(requireContext()) + .setTitle(softwareComponent.name) .setView(webView) - .setOnCancelListener { activeLicense = null } - .setOnDismissListener { activeLicense = null } - .block() - .show() + .setOnCancelListener { activeSoftwareComponent = null } + .setOnDismissListener { activeSoftwareComponent = null } + if (softwareComponent == NEWPIPE_SOFTWARE_COMPONENT) { + builder.setPositiveButton(R.string.ok) { dialog, _ -> dialog.dismiss() } + } else { + builder.setPositiveButton(R.string.dismiss) { dialog, _ -> + dialog.dismiss() + } + .setNeutralButton(R.string.open_website_license) { _, _ -> + ShareUtils.openUrlInApp(requireContext(), softwareComponent.link) + } + } + + builder.show() } } } companion object { private const val ARG_COMPONENTS = "components" - private const val LICENSE_KEY = "ACTIVE_LICENSE" + private const val SOFTWARE_COMPONENT_KEY = "ACTIVE_SOFTWARE_COMPONENT" + private val NEWPIPE_SOFTWARE_COMPONENT = SoftwareComponent( + "NewPipe", + "2014-2023", + "Team NewPipe", + "https://newpipe.net/", + StandardLicenses.GPL3, + BuildConfig.VERSION_NAME + ) fun newInstance(softwareComponents: Array): LicenseFragment { val fragment = LicenseFragment() fragment.arguments = bundleOf(ARG_COMPONENTS to softwareComponents) diff --git a/app/src/main/java/org/schabi/newpipe/about/SoftwareComponent.kt b/app/src/main/java/org/schabi/newpipe/about/SoftwareComponent.kt index 354e8fef7..262641caa 100644 --- a/app/src/main/java/org/schabi/newpipe/about/SoftwareComponent.kt +++ b/app/src/main/java/org/schabi/newpipe/about/SoftwareComponent.kt @@ -2,6 +2,7 @@ package org.schabi.newpipe.about import android.os.Parcelable import kotlinx.parcelize.Parcelize +import java.io.Serializable @Parcelize class SoftwareComponent @@ -13,4 +14,4 @@ constructor( val link: String, val license: License, val version: String? = null -) : Parcelable +) : Parcelable, Serializable From 94c1438913860e9550c7157911796db3260b9a2c Mon Sep 17 00:00:00 2001 From: TobiGr Date: Sat, 23 Sep 2023 13:56:49 +0200 Subject: [PATCH 124/172] Use "done" button to close license dialogs. Rename string res "recaptcha_done_button" to "done". --- .../org/schabi/newpipe/about/LicenseFragment.kt | 13 +++++-------- app/src/main/res/menu/menu_recaptcha.xml | 2 +- app/src/main/res/values-ar/strings.xml | 2 +- app/src/main/res/values-az/strings.xml | 2 +- app/src/main/res/values-b+ast/strings.xml | 2 +- app/src/main/res/values-b+uz+Latn/strings.xml | 2 +- app/src/main/res/values-be/strings.xml | 2 +- app/src/main/res/values-bg/strings.xml | 2 +- app/src/main/res/values-bn-rBD/strings.xml | 2 +- app/src/main/res/values-bn-rIN/strings.xml | 2 +- app/src/main/res/values-bn/strings.xml | 2 +- app/src/main/res/values-ca/strings.xml | 2 +- app/src/main/res/values-ckb/strings.xml | 2 +- app/src/main/res/values-cs/strings.xml | 2 +- app/src/main/res/values-da/strings.xml | 2 +- app/src/main/res/values-de/strings.xml | 2 +- app/src/main/res/values-el/strings.xml | 2 +- app/src/main/res/values-eo/strings.xml | 2 +- app/src/main/res/values-es/strings.xml | 2 +- app/src/main/res/values-et/strings.xml | 2 +- app/src/main/res/values-eu/strings.xml | 2 +- app/src/main/res/values-fa/strings.xml | 2 +- app/src/main/res/values-fi/strings.xml | 2 +- app/src/main/res/values-fr/strings.xml | 2 +- app/src/main/res/values-gl/strings.xml | 2 +- app/src/main/res/values-he/strings.xml | 2 +- app/src/main/res/values-hi/strings.xml | 2 +- app/src/main/res/values-hr/strings.xml | 2 +- app/src/main/res/values-hu/strings.xml | 2 +- app/src/main/res/values-hy/strings.xml | 2 +- app/src/main/res/values-ia/strings.xml | 2 +- app/src/main/res/values-in/strings.xml | 2 +- app/src/main/res/values-is/strings.xml | 2 +- app/src/main/res/values-it/strings.xml | 2 +- app/src/main/res/values-ja/strings.xml | 2 +- app/src/main/res/values-ka/strings.xml | 2 +- app/src/main/res/values-kab/strings.xml | 2 +- app/src/main/res/values-kmr/strings.xml | 2 +- app/src/main/res/values-ko/strings.xml | 2 +- app/src/main/res/values-ku/strings.xml | 2 +- app/src/main/res/values-la/strings.xml | 2 +- app/src/main/res/values-lt/strings.xml | 2 +- app/src/main/res/values-lv/strings.xml | 2 +- app/src/main/res/values-ml/strings.xml | 2 +- app/src/main/res/values-ms/strings.xml | 2 +- app/src/main/res/values-nb-rNO/strings.xml | 2 +- app/src/main/res/values-ne/strings.xml | 2 +- app/src/main/res/values-nl-rBE/strings.xml | 2 +- app/src/main/res/values-nl/strings.xml | 2 +- app/src/main/res/values-nqo/strings.xml | 2 +- app/src/main/res/values-or/strings.xml | 2 +- app/src/main/res/values-pa/strings.xml | 2 +- app/src/main/res/values-pl/strings.xml | 2 +- app/src/main/res/values-pt-rBR/strings.xml | 2 +- app/src/main/res/values-pt-rPT/strings.xml | 2 +- app/src/main/res/values-pt/strings.xml | 2 +- app/src/main/res/values-ro/strings.xml | 2 +- app/src/main/res/values-ru/strings.xml | 2 +- app/src/main/res/values-ryu/strings.xml | 2 +- app/src/main/res/values-sc/strings.xml | 2 +- app/src/main/res/values-sk/strings.xml | 2 +- app/src/main/res/values-sl/strings.xml | 2 +- app/src/main/res/values-so/strings.xml | 2 +- app/src/main/res/values-sq/strings.xml | 2 +- app/src/main/res/values-sr/strings.xml | 2 +- app/src/main/res/values-sv/strings.xml | 2 +- app/src/main/res/values-te/strings.xml | 2 +- app/src/main/res/values-tr/strings.xml | 2 +- app/src/main/res/values-uk/strings.xml | 2 +- app/src/main/res/values-ur/strings.xml | 2 +- app/src/main/res/values-vi/strings.xml | 2 +- app/src/main/res/values-zh-rCN/strings.xml | 2 +- app/src/main/res/values-zh-rHK/strings.xml | 2 +- app/src/main/res/values-zh-rTW/strings.xml | 2 +- app/src/main/res/values/strings.xml | 2 +- 75 files changed, 79 insertions(+), 82 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/about/LicenseFragment.kt b/app/src/main/java/org/schabi/newpipe/about/LicenseFragment.kt index 10e825efd..a5cf2924a 100644 --- a/app/src/main/java/org/schabi/newpipe/about/LicenseFragment.kt +++ b/app/src/main/java/org/schabi/newpipe/about/LicenseFragment.kt @@ -106,15 +106,12 @@ class LicenseFragment : Fragment() { .setView(webView) .setOnCancelListener { activeSoftwareComponent = null } .setOnDismissListener { activeSoftwareComponent = null } - if (softwareComponent == NEWPIPE_SOFTWARE_COMPONENT) { - builder.setPositiveButton(R.string.ok) { dialog, _ -> dialog.dismiss() } - } else { - builder.setPositiveButton(R.string.dismiss) { dialog, _ -> - dialog.dismiss() + .setPositiveButton(R.string.done) { dialog, _ -> dialog.dismiss() } + + if (softwareComponent != NEWPIPE_SOFTWARE_COMPONENT) { + builder.setNeutralButton(R.string.open_website_license) { _, _ -> + ShareUtils.openUrlInApp(requireContext(), softwareComponent.link) } - .setNeutralButton(R.string.open_website_license) { _, _ -> - ShareUtils.openUrlInApp(requireContext(), softwareComponent.link) - } } builder.show() diff --git a/app/src/main/res/menu/menu_recaptcha.xml b/app/src/main/res/menu/menu_recaptcha.xml index 89fa024d0..fd614df32 100644 --- a/app/src/main/res/menu/menu_recaptcha.xml +++ b/app/src/main/res/menu/menu_recaptcha.xml @@ -5,6 +5,6 @@ diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index 957854e00..980859710 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -466,7 +466,7 @@ لغة التطبيق النظام الافتراضي اضغط على \"تم\" عند حلها - منجز + منجز الفيديوهات %d ثانية diff --git a/app/src/main/res/values-az/strings.xml b/app/src/main/res/values-az/strings.xml index 40e802ce7..d4b1076a1 100644 --- a/app/src/main/res/values-az/strings.xml +++ b/app/src/main/res/values-az/strings.xml @@ -327,7 +327,7 @@ Hələ endirmə qovluğu təyin edilməyib, indi standart endirmə qovluğu seç reCAPTCHA çağırışı reCAPTCHA sorğusu göndərildi - Bitdi + Bitdi Etibarsız simvollar bu dəyərlə əvəz olunur Əvəzedici xarakter Ən xüsusi simvollar diff --git a/app/src/main/res/values-b+ast/strings.xml b/app/src/main/res/values-b+ast/strings.xml index 40809d459..626e3f284 100644 --- a/app/src/main/res/values-b+ast/strings.xml +++ b/app/src/main/res/values-b+ast/strings.xml @@ -420,7 +420,7 @@ Un aplicación llibre pa ver/sentir plataformes de tresmisión n\'Android. Caráuteres de troquéu Los caráuteres que nun son válidos van trocase por esti valor - Fecho + Fecho Primi «Fecho» al resolvelu Desanicióse 1 elementu. Defini una capeta de descargues dempués, nos axustes de l\'aplicación diff --git a/app/src/main/res/values-b+uz+Latn/strings.xml b/app/src/main/res/values-b+uz+Latn/strings.xml index 32a12d3dd..0ba69ae41 100644 --- a/app/src/main/res/values-b+uz+Latn/strings.xml +++ b/app/src/main/res/values-b+uz+Latn/strings.xml @@ -214,7 +214,7 @@ Noto\'g\'ri belgilar ushbu qiymat bilan almashtiriladi Fayl nomidagi ruxsat berilgan belgilar Yuklab olish - Bajarildi + Bajarildi reCAPTCHA muammosi so\'raldi Hal etilganda \"Bajarildi\" tugmasini bosing reCAPTCHA muammosi diff --git a/app/src/main/res/values-be/strings.xml b/app/src/main/res/values-be/strings.xml index 9948872c7..f13a7093f 100644 --- a/app/src/main/res/values-be/strings.xml +++ b/app/src/main/res/values-be/strings.xml @@ -453,7 +453,7 @@ Няма закладак у плейлісце Выберыце плэйліст Кіёск па змаўчанні - Так + Так Націсніце \"Так\" калі вырашана ∞ відэа 100+ відэа diff --git a/app/src/main/res/values-bg/strings.xml b/app/src/main/res/values-bg/strings.xml index 1857ce1f8..08a6bd93b 100644 --- a/app/src/main/res/values-bg/strings.xml +++ b/app/src/main/res/values-bg/strings.xml @@ -445,7 +445,7 @@ Отбелязан със сърце от автора Конференции Най-харесвани - Готово + Готово Коментари Езикът ще се смени след рестартиране на приложението Скрит diff --git a/app/src/main/res/values-bn-rBD/strings.xml b/app/src/main/res/values-bn-rBD/strings.xml index c4f1108f7..11fe2c2c8 100644 --- a/app/src/main/res/values-bn-rBD/strings.xml +++ b/app/src/main/res/values-bn-rBD/strings.xml @@ -257,7 +257,7 @@ পিয়ার টিউব এর ইন্সটান্স সমূহ ছক স্থানীয় - হয়েছে + হয়েছে ইভেন্টগুলো আপডেট কোনোটি না diff --git a/app/src/main/res/values-bn-rIN/strings.xml b/app/src/main/res/values-bn-rIN/strings.xml index ebbd5c7e5..b2eacd22a 100644 --- a/app/src/main/res/values-bn-rIN/strings.xml +++ b/app/src/main/res/values-bn-rIN/strings.xml @@ -239,7 +239,7 @@ যোগদান নিউ পাইপ এর সম্বন্ধে শব্দ ও নম্বর - হয়েছে + হয়েছে কোন মন্তব্য নেই কোন সাবস্ক্রাইবার নেই ডাউন লোড এর জন্য কোন স্ট্রিম নেই diff --git a/app/src/main/res/values-bn/strings.xml b/app/src/main/res/values-bn/strings.xml index 47425bb56..fd80afacf 100644 --- a/app/src/main/res/values-bn/strings.xml +++ b/app/src/main/res/values-bn/strings.xml @@ -78,7 +78,7 @@ নিউপাইপ এর সম্বন্ধে শব্দ ও নম্বর ডাউনলোড - হয়েছে + হয়েছে reCAPTCHA চ্যালেঞ্জ অনুরোধ করা হয়েছে reCAPTCHA চ্যালেঞ্জ একটি আইটেম ডিলিট হয়েছে। diff --git a/app/src/main/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml index 82e08db32..a0dbc0b36 100644 --- a/app/src/main/res/values-ca/strings.xml +++ b/app/src/main/res/values-ca/strings.xml @@ -535,7 +535,7 @@ Local Encara no hi ha llistes de reproducció favorites Sel·leccioneu una llista de reproducció - Fet + Fet Calculant-ne la funció de verificació Si us plau, comproveu abans si el problema que ha causat aquesta fallada ja ha estat informat. Els tiquets per duplicat fan que perdem temps que podríem aprofitar resolent-los. Avisa del problema a GitHub diff --git a/app/src/main/res/values-ckb/strings.xml b/app/src/main/res/values-ckb/strings.xml index aca0979f6..df26383a4 100644 --- a/app/src/main/res/values-ckb/strings.xml +++ b/app/src/main/res/values-ckb/strings.xml @@ -293,7 +293,7 @@ دابه‌زاندنێكی دیكه‌ له‌ نۆره‌دایه‌ بەهەمان ناو هیچ بەژدارییەک دیار نەکراوە ناوی کۆمەڵە بەتاڵە - كرا + كرا بەدڵه‌كان بیرهاتنه‌وه‌ی كۆتا قه‌باره‌ و شوێنی په‌نجه‌ره‌ سازکردن diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index 95b84959c..d8ff56daf 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -451,7 +451,7 @@ Jazyk aplikace Jazyk systému Po vyřešení klepněte na „Hotovo“ - Hotovo + Hotovo Videa %d vteřina diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml index c4daa5a84..601a0c603 100644 --- a/app/src/main/res/values-da/strings.xml +++ b/app/src/main/res/values-da/strings.xml @@ -620,7 +620,7 @@ Mest likede Kunne ikke indlæse kommentarer Standard Kiosk - Færdig + Færdig Tryk på \"Færdig\" når den er løst Ingen kommentarer ∞ videoer diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 5923aaaaa..918fbe3af 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -455,7 +455,7 @@ Sprache der App Systemstandard „Fertig“ drücken, wenn es gelöst wurde - Fertig + Fertig Videos %d Sekunde diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index 2a5fbb445..ed74240f5 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -459,7 +459,7 @@ Αναπαραγωγή ουράς Δεν υπάρχουν σελιδοδείκτες λίστας αναπαραγωγής ακόμα Επιλέξτε μια λίστα αναπαραγωγής - Τέλος + Τέλος Πατήστε «Τέλος» όταν επιλυθεί ∞ βίντεο 100+ βίντεο diff --git a/app/src/main/res/values-eo/strings.xml b/app/src/main/res/values-eo/strings.xml index a70c6d37e..99e8f7589 100644 --- a/app/src/main/res/values-eo/strings.xml +++ b/app/src/main/res/values-eo/strings.xml @@ -445,7 +445,7 @@ Preferata aplingvo Sistemnormo Premu “Finita” kiam solvita - Finita + Finita %d sekundo %d sekundoj diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 0f623d8ba..83260fcd5 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -454,7 +454,7 @@ Idioma de aplicación Predefinido del sistema Pulsa en «Hecho» al resolverlo - Hecho + Hecho Vídeos %d segundo diff --git a/app/src/main/res/values-et/strings.xml b/app/src/main/res/values-et/strings.xml index b2ffbd0a8..cb34d1226 100644 --- a/app/src/main/res/values-et/strings.xml +++ b/app/src/main/res/values-et/strings.xml @@ -494,7 +494,7 @@ Esitusloendi järjehoidjaid veel pole Vali esitusloend Vaikimisi seadistatud kiosk - Valmis + Valmis Kui oled lõpetanud, siis vajuta „Valmis“ nuppu Kommentaare pole ∞ videot diff --git a/app/src/main/res/values-eu/strings.xml b/app/src/main/res/values-eu/strings.xml index c0ca3cef5..ba0793db8 100644 --- a/app/src/main/res/values-eu/strings.xml +++ b/app/src/main/res/values-eu/strings.xml @@ -446,7 +446,7 @@ Aplikazioaren hizkuntza Sistemaren lehenetsia Sakatu \"Egina\" konponduta dagoenean - Egina + Egina Bideoak segundu %d diff --git a/app/src/main/res/values-fa/strings.xml b/app/src/main/res/values-fa/strings.xml index 2a1ccbbce..0dc26070a 100644 --- a/app/src/main/res/values-fa/strings.xml +++ b/app/src/main/res/values-fa/strings.xml @@ -471,7 +471,7 @@ محلی با آغاز دوبارهٔ کاره، زبان تغییر خواهد کرد کیوسک پیش‌فرض - انجام شد + انجام شد وقتی انجام شد، «Done» یا «انجام شد» را بفشارید ∞ ویدیو بیش از ۱۰۰ ویدیو diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml index 9df4e304c..0ac6813ba 100644 --- a/app/src/main/res/values-fi/strings.xml +++ b/app/src/main/res/values-fi/strings.xml @@ -340,7 +340,7 @@ Kieli vaihtuu, kun sovellus uudelleenkäynnistetään Kommentteja ei voitu ladata Mitkä välilehdet näytetään pääsivulla - Valmis + Valmis Paina ”Valmis”, kun ratkaistu ∞ videota 100+ videota diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index fb5d4940c..9fac96903 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -451,7 +451,7 @@ Langue de l’application Prédéfini par le système Appuyez sur « Terminé » une fois résolu - Terminé + Terminé Vidéos En raison des contraintes d’ExoPlayer, le pas de déplacement a été réglée à %d secondes Couper le son diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml index 0778a8ee6..bfc8aa6e1 100644 --- a/app/src/main/res/values-gl/strings.xml +++ b/app/src/main/res/values-gl/strings.xml @@ -469,7 +469,7 @@ Seleccionar unha lista de reprodución Quiosco predeterminado Que lapelas se amosan na páxina principal - Feito + Feito Prema \"Feito\" cando o resolva Ningún comentario ∞ vídeos diff --git a/app/src/main/res/values-he/strings.xml b/app/src/main/res/values-he/strings.xml index 9fd93dff3..ed9f50f52 100644 --- a/app/src/main/res/values-he/strings.xml +++ b/app/src/main/res/values-he/strings.xml @@ -456,7 +456,7 @@ שפת היישומון ברירת המחדל של המערכת יש ללחוץ על „סיום” לאחר הפתירה - סיום + סיום סרטונים שנייה אחת diff --git a/app/src/main/res/values-hi/strings.xml b/app/src/main/res/values-hi/strings.xml index df34f3a07..c8954c394 100644 --- a/app/src/main/res/values-hi/strings.xml +++ b/app/src/main/res/values-hi/strings.xml @@ -445,7 +445,7 @@ %s के द्वारा बनाया गया प्लेलिस्ट पन्ना %s : के लिए परिणाम दिखाया जा रहा है - संपन्न + संपन्न कलाकार गीत कभी नहीं diff --git a/app/src/main/res/values-hr/strings.xml b/app/src/main/res/values-hr/strings.xml index 179470994..13535994a 100644 --- a/app/src/main/res/values-hr/strings.xml +++ b/app/src/main/res/values-hr/strings.xml @@ -429,7 +429,7 @@ Memorija uređaja je popunjena Najomiljeniji Pritisni „Gotovo” kad je riješeno - Gotovo + Gotovo ∞ videa Više od 100 videa Prijavi grešku na GitHub-u diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml index 0814cbfe5..0b3b10235 100644 --- a/app/src/main/res/values-hu/strings.xml +++ b/app/src/main/res/values-hu/strings.xml @@ -457,7 +457,7 @@ Feliratkozások kiválasztása © %1$s %2$s, %3$s licenc alatt Harmadik féltől származó licencek - Kész + Kész Nincs megjegyzés ∞ videó 100+ videó diff --git a/app/src/main/res/values-hy/strings.xml b/app/src/main/res/values-hy/strings.xml index 033e93c0e..5becf32fb 100644 --- a/app/src/main/res/values-hy/strings.xml +++ b/app/src/main/res/values-hy/strings.xml @@ -192,7 +192,7 @@ Նշել նվագացանկ Տառեր և թվեր Բեռնումներ - Եղավ + Եղավ Նվագել ամենը Ուղիղ Շարունակել նվագարկումը diff --git a/app/src/main/res/values-ia/strings.xml b/app/src/main/res/values-ia/strings.xml index 512598eaa..2b85a1353 100644 --- a/app/src/main/res/values-ia/strings.xml +++ b/app/src/main/res/values-ia/strings.xml @@ -140,7 +140,7 @@ Le plus reproducite Contento del pagina principal Selige un canal - Preste + Preste Rememorar ultime grandor e position del reproductor emergente Rememorar grandor e position del fenestra emergente diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index 296b2d41b..7082a2b22 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -439,7 +439,7 @@ Izinkan untuk ditampilkan di atas aplikasi lain Bahasa apl Default sistem - Selesai + Selesai Durasi maju/mundur cepat Tekan \"Selesai\" saat selesai Video diff --git a/app/src/main/res/values-is/strings.xml b/app/src/main/res/values-is/strings.xml index bc1143063..ee90a9333 100644 --- a/app/src/main/res/values-is/strings.xml +++ b/app/src/main/res/values-is/strings.xml @@ -250,7 +250,7 @@ Afritað á klemmuspjald 1 atriði eytt. Leysa - Lokið + Lokið Beðið eftir þraut reCAPTCHA Leyfi þriðja aðila Hugbúnaðarleyfi diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 00a6d4894..820fa6eb5 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -451,7 +451,7 @@ Lingua dell\'applicazione Predefinita di sistema Premere \"Fatto\" quando risolto - Fatto + Fatto Video %d secondo diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index c1dd66046..2a082955f 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -441,7 +441,7 @@ アプリの言語 システムの既定 解けたら「完了」を押してください - 完了 + 完了 動画 %d 秒 diff --git a/app/src/main/res/values-ka/strings.xml b/app/src/main/res/values-ka/strings.xml index bab397e4a..8825b8f58 100644 --- a/app/src/main/res/values-ka/strings.xml +++ b/app/src/main/res/values-ka/strings.xml @@ -292,7 +292,7 @@ როდესაც მოგვარდება, დააჭირეთ შესრულებულია მოთხოვნილია reCAPTCHA გამოწვევა ამოხსნა - შესრულებულია + შესრულებულია შემცვლელი პერსონაჟი ასოები და ციფრები NewPipe-ის შესახებ diff --git a/app/src/main/res/values-kab/strings.xml b/app/src/main/res/values-kab/strings.xml index ed4ef0f3b..4c40518a9 100644 --- a/app/src/main/res/values-kab/strings.xml +++ b/app/src/main/res/values-kab/strings.xml @@ -69,7 +69,7 @@ Iẓiki Immed Adigan - Immed + Immed Wennez Snulfu-d Qbel diff --git a/app/src/main/res/values-kmr/strings.xml b/app/src/main/res/values-kmr/strings.xml index d6be1f170..aa4696c78 100644 --- a/app/src/main/res/values-kmr/strings.xml +++ b/app/src/main/res/values-kmr/strings.xml @@ -537,7 +537,7 @@ Karakteyên nederbasdar bi vê nirxê têne veguheztin Di navên pelan de tîpan destûr dan Dakêşînin - Kirî + Kirî reCAPTCHA dijwarî xwestin Dema ku çareser bibe \"Kirî\" çap bikin Tevlêbûnên YouTube-ê ji barkirina Google-ê bikişînin: diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index 3d613e554..2ded4d484 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -459,7 +459,7 @@ 이 비디오는 연령제한이 있습니다. \n \n만약, 시청을 원한다면 설정에 \"%1$s\"를 활성화 하세요. - 완료 + 완료 아티스트 앨범 비디오 diff --git a/app/src/main/res/values-ku/strings.xml b/app/src/main/res/values-ku/strings.xml index 34de8bb0a..50ba6c205 100644 --- a/app/src/main/res/values-ku/strings.xml +++ b/app/src/main/res/values-ku/strings.xml @@ -444,7 +444,7 @@ زمانی ئەپ بنەڕەتی سیستەم گرتە بکە لەسەر ”تەواو” کاتێ کە چارەسەرکرا - تەواو + تەواو ڤیدیۆکان %d چرکە diff --git a/app/src/main/res/values-la/strings.xml b/app/src/main/res/values-la/strings.xml index 42b619efc..16961c30b 100644 --- a/app/src/main/res/values-la/strings.xml +++ b/app/src/main/res/values-la/strings.xml @@ -93,7 +93,7 @@ %d secundus %d secundi - Factum + Factum Quaere semper Index Nullus limus diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml index f82ad52b7..fefc04323 100644 --- a/app/src/main/res/values-lt/strings.xml +++ b/app/src/main/res/values-lt/strings.xml @@ -505,7 +505,7 @@ NewPipe į jūsų privatumą žiūri labai rimtai. Programa be jūsų sutikimo nerenka jokių duomenų. \nNewPipe privatumo politika išsamiai parodo kokie duomenys siunčiami ir saugomi pranešant apie problemą. NewPipe privatumo politika - Atlikta + Atlikta Išspręsta Paspauskite \"atlikta\" kai išspręsta Patikrinkite ar apie problemą su kuria susidūrėte dar nėra pranešta. Sukurdami kelis pranešimus apie tą pačią problemą atimate iš mūsų laiką kurį galėtume skirti klaidų taisymui. diff --git a/app/src/main/res/values-lv/strings.xml b/app/src/main/res/values-lv/strings.xml index d35eb546a..9bf252ccb 100644 --- a/app/src/main/res/values-lv/strings.xml +++ b/app/src/main/res/values-lv/strings.xml @@ -77,7 +77,7 @@ Nederīgas rakstzīmes tiks aizvietotas ar šo Atļautās rakstzīmes failu nosaukumos Lejupielādēt - Pabeigts + Pabeigts reCAPTCHA izaicinājums dots Nospiediet \"Pabeigts\", kad to atrisinat reCAPTCHA izaicinājums diff --git a/app/src/main/res/values-ml/strings.xml b/app/src/main/res/values-ml/strings.xml index ae9f56592..38606fea8 100644 --- a/app/src/main/res/values-ml/strings.xml +++ b/app/src/main/res/values-ml/strings.xml @@ -131,7 +131,7 @@ സ്വീകാര്യമല്ലാത്ത അടയാളങ്ങൾ ഈ അടയാളം കൊണ്ട് മാറ്റുന്നതാണ് ഫയൽനാമങ്ങളിൽ അനുവദിച്ചിട്ടുള്ള അടയാളങ്ങൾ ഡൗൺലോഡ് - ഓകെ + ഓകെ reCAPTCHA ചാലഞ്ചിനായി അഭ്യർത്ഥിച്ചു തീർന്നാൽ \"Done\" അമർത്തുക reCAPTCHA ചാലഞ്ച് diff --git a/app/src/main/res/values-ms/strings.xml b/app/src/main/res/values-ms/strings.xml index ee0431bbd..33fd41f59 100644 --- a/app/src/main/res/values-ms/strings.xml +++ b/app/src/main/res/values-ms/strings.xml @@ -377,7 +377,7 @@ %s pendengar Tekan \"Selesai\" saat selesai - Selesai + Selesai Selesaikan Tidak ada ulasan diff --git a/app/src/main/res/values-nb-rNO/strings.xml b/app/src/main/res/values-nb-rNO/strings.xml index 8f997b0be..f9287aeb1 100644 --- a/app/src/main/res/values-nb-rNO/strings.xml +++ b/app/src/main/res/values-nb-rNO/strings.xml @@ -446,7 +446,7 @@ Programspråk Systemforvalg Trykk \"Ferdig\" når den er løst - Ferdig + Ferdig Videoer %d sekund diff --git a/app/src/main/res/values-ne/strings.xml b/app/src/main/res/values-ne/strings.xml index d7c8f8494..b573bb79d 100644 --- a/app/src/main/res/values-ne/strings.xml +++ b/app/src/main/res/values-ne/strings.xml @@ -441,7 +441,7 @@ सिस्टम पूर्वनिर्धारित reCAPTCHA चुनौती प्रेस हल गर्दा \"डन\" - सकियो + सकियो भिडियोहरु %d सेकेन्ड diff --git a/app/src/main/res/values-nl-rBE/strings.xml b/app/src/main/res/values-nl-rBE/strings.xml index 64f975547..b8370a1cb 100644 --- a/app/src/main/res/values-nl-rBE/strings.xml +++ b/app/src/main/res/values-nl-rBE/strings.xml @@ -490,7 +490,7 @@ Geen afspeellijst bladwijzers Selecteer een afspeellijst Standaard kiosk - Klaar + Klaar Tik op ‘Klaar’ zodra opgelost ∞ video\'s 100+ video\'s diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index d91b4793c..0c2497f0d 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -443,7 +443,7 @@ App-taal Systeemtaal gebruiken Druk op ‘Klaar’ als u dit heeft opgelost - Klaar + Klaar Video\'s Door beperkingen van ExoPlayer is de zoekduur ingesteld op %d seconden Geluid dempen diff --git a/app/src/main/res/values-nqo/strings.xml b/app/src/main/res/values-nqo/strings.xml index b04c8d5f0..060021846 100644 --- a/app/src/main/res/values-nqo/strings.xml +++ b/app/src/main/res/values-nqo/strings.xml @@ -382,7 +382,7 @@ ߞߟߏߘߋ߲߫ ߠߊߘߌ߬ߢߍ߬ߣߍ߲ ߠߎ߬ ߞߐߕߐ߯ ߕߐ߮ ߘߐ߫ ߞߟߏߘߋ߲߫ ߠߊߘߌ߬ߢߍ߬ߓߊߟߌ ߟߎ߫ ߣߐ߬ߘߐߓߌ߬ߟߊ߬ߕߐ߫ ߡߐ߬ߟߐ߲ ߣߌ߬ ߠߋ߬ ߟߊ߫ ߣߘߐ߬ߓߌ߬ߟߊ߬ߟߌ߬ ߞߟߏߘߋ߲ - ߊ߬ ߓߘߊ߫ ߓߊ߲߫ + ߊ߬ ߓߘߊ߫ ߓߊ߲߫ ߟߊ߬ߖߌ߰ߟߌ ߟߊ߬ߘߌߢߍ ߟߎ߬ ߊ߬ ߡߊߝߍߣߍ߲߫ GitHub ߞߊ߲߬ diff --git a/app/src/main/res/values-or/strings.xml b/app/src/main/res/values-or/strings.xml index 9adf27691..bfbd901d1 100644 --- a/app/src/main/res/values-or/strings.xml +++ b/app/src/main/res/values-or/strings.xml @@ -304,7 +304,7 @@ କ୍ଲିପବୋର୍ଡରେ କପି କରାଯାଇଛି 1 ଆଇଟମ୍ ଡିଲିଟ୍ ହୋଇଛି । reCAPTCHA ଆହ୍ୱାନ - ସମାପ୍ତ + ସମାପ୍ତ ଡାଉନଲୋଡ୍ କରନ୍ତୁ ଅବୈଧ ବର୍ଣ୍ଣଗୁଡିକ ଏହି ମୂଲ୍ୟ ସହିତ ବଦଳାଯାଏ ପ୍ରତିସ୍ଥାପନ ବର୍ଣ୍ଣ diff --git a/app/src/main/res/values-pa/strings.xml b/app/src/main/res/values-pa/strings.xml index 6a5f40e1a..7b1b5669c 100644 --- a/app/src/main/res/values-pa/strings.xml +++ b/app/src/main/res/values-pa/strings.xml @@ -542,7 +542,7 @@ ਸਥਾਨਕ ਭਾਸ਼ਾ ਐਪ ਨੂੰ ਦੋਬਾਰਾ ਚਲਾਉਣ \'ਤੇ ਬਦਲੇਗੀ ਪਲੇ-ਸੂਚੀ ਚੁਣੋ - ਹੋ ਗਿਆ + ਹੋ ਗਿਆ ਹੱਲ ਕਰੋ ਹੱਲ ਹੋਣ \'ਤੇ \"ਹੋ ਗਿਆ\" ਨੱਪੋ ਹਾਲੇ ਕੋਈ ਡਾਊਨਲੋਡ ਫੋਲਡਰ ਸੈੱਟ ਨਹੀਂ ਕੀਤਾ ਹੋਇਆ, ਹੁਣੇ ਡਿਫ਼ਾਲਟ ਡਾਊਨਲੋਡ ਫੋਲਡਰ ਚੁਣੋ diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 8b6701564..bd1c62465 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -455,7 +455,7 @@ Język aplikacji Domyślny systemowy Po rozwiązaniu naciśnij „Gotowe” - Gotowe + Gotowe Wideo %d sekunda diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 53bd19e28..b4d902cbf 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -451,7 +451,7 @@ Idioma do app Padrão do sistema Toque em \"Pronto\" ao resolver - Pronto + Pronto Vídeos %d segundo diff --git a/app/src/main/res/values-pt-rPT/strings.xml b/app/src/main/res/values-pt-rPT/strings.xml index abf504406..86465dc57 100644 --- a/app/src/main/res/values-pt-rPT/strings.xml +++ b/app/src/main/res/values-pt-rPT/strings.xml @@ -537,7 +537,7 @@ Toque para detalhes em pausa Mostrar comentários - Aceitar + Aceitar Desativar modo rápido Nunca Apenas em Wi-Fi diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index f8f06b15a..400d04bbb 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -451,7 +451,7 @@ Idioma da aplicação Predefinição do sistema Prima \"Feito\" ao resolver - Aceitar + Aceitar Acha que a fonte demora muito tempo a carregar\? Se sim, tente ativar o carregamento rápido (pode alterar a opção nas definições ou no botão abaixo). \n \nNewPipe oferece duas estratégias de carregamento: diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index a31dde7aa..a44f44200 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -337,7 +337,7 @@ Selectați instanțele PeerTube preferate Instanțe PeerTube Durată derulare rapidă înainte/înapoi - Gata + Gata Apăsați \"Gata\" după ce ați rezolvat problema Raportați pe GitHub Ștergeți cookie-urile pe care NewPipe le stochează atunci când rezolvați un reCAPTCHA diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index fc226c37c..849463c2b 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -457,7 +457,7 @@ Язык интерфейса Как в системе По завершении нажмите Готово - Готово + Готово Видео %d секунда diff --git a/app/src/main/res/values-ryu/strings.xml b/app/src/main/res/values-ryu/strings.xml index 53df30d2f..43fbd45ad 100644 --- a/app/src/main/res/values-ryu/strings.xml +++ b/app/src/main/res/values-ryu/strings.xml @@ -446,7 +446,7 @@ アプリぬぎんぐ システムぬっちうぅい とぅきーねー「かんりょう」うちくぃみそーれー - かんりょう + かんりょう ちゃーしが %dびょう diff --git a/app/src/main/res/values-sc/strings.xml b/app/src/main/res/values-sc/strings.xml index f26907158..e68d5fbd2 100644 --- a/app/src/main/res/values-sc/strings.xml +++ b/app/src/main/res/values-sc/strings.xml @@ -115,7 +115,7 @@ Sos caràteres non vàlidos benint remplasados cun custu valore Caràteres permìtidos in sos nùmenes de sos documentos Iscàrriga - Fatu + Fatu B\'at bisòngiu de risòlvere unu reCAPTCHA Incarca \"Fatu\" cando est risoltu Disafiu reCAPTCHA diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml index b6c823e68..3ad8a7023 100644 --- a/app/src/main/res/values-sk/strings.xml +++ b/app/src/main/res/values-sk/strings.xml @@ -451,7 +451,7 @@ Jazyk aplikácie Predvolený Vyrieš a stlač \"Hotovo\" - Hotovo + Hotovo Videá Pre obmedzenie ExoPlayera bolo prehľadávania nastavené na %d sekúnd Stlmiť diff --git a/app/src/main/res/values-sl/strings.xml b/app/src/main/res/values-sl/strings.xml index cf96136a6..4912db031 100644 --- a/app/src/main/res/values-sl/strings.xml +++ b/app/src/main/res/values-sl/strings.xml @@ -264,7 +264,7 @@ Preberi pravilnik zasebnosti NewPipe-ovi pravilnik zasebnosti Obiščite spletno mesto od NewPipe za več informacij in novic. - Končano + Končano Ni komantarjev Nobeden ne posluša Nobeden ne gleda diff --git a/app/src/main/res/values-so/strings.xml b/app/src/main/res/values-so/strings.xml index 4ba720595..247ff682a 100644 --- a/app/src/main/res/values-so/strings.xml +++ b/app/src/main/res/values-so/strings.xml @@ -189,7 +189,7 @@ Xarfaha aan la taageerin waxaa lagu bdadali midkan Xarafyada magaca shayga loo ogol yahay Dajinta - Dhameeyay + Dhameeyay Tijaabada reCAPTCHA ayaa la codsaday Taabo \"Dhameeyay\" ✅ markaad xaliso Tijaabada reCAPTCHA diff --git a/app/src/main/res/values-sq/strings.xml b/app/src/main/res/values-sq/strings.xml index 334f516db..dc8ca02f4 100644 --- a/app/src/main/res/values-sq/strings.xml +++ b/app/src/main/res/values-sq/strings.xml @@ -255,7 +255,7 @@ Karakteret e palejuara zëvendësohen me këtë vlerë Karakteret e lejuara në emrat e skedarëve Shkarko - U bë + U bë sfida reCAPTCHA u kërkua Shtyp \"U bë\" kur ta zgjidhni sfida reCAPTCHA diff --git a/app/src/main/res/values-sr/strings.xml b/app/src/main/res/values-sr/strings.xml index 380fa05f8..4680942b6 100644 --- a/app/src/main/res/values-sr/strings.xml +++ b/app/src/main/res/values-sr/strings.xml @@ -387,7 +387,7 @@ Пројекат NewPipe веома озбиљно схвата вашу приватност. Стога, апликација не прикупља никакве податке без вашег пристанка. \nПолитика приватности NewPipe-а детаљно објашњава који се подаци шаљу и чувају када пошаљете извештај о отказивању апликације. Политика приватности NewPipe-а - Готово + Готово Реши Притисните „Готово“ када решите Избрисана је 1 ставка. diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index 66d6896f7..5532001e8 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -434,7 +434,7 @@ Mest gillade Nyligen tillagd Lokala - Klar + Klar Slå på YouTubes \"Begränsat läge\" Språket ändras när appen startas om Det gick inte att läsa in kommentarerna diff --git a/app/src/main/res/values-te/strings.xml b/app/src/main/res/values-te/strings.xml index edfb85ade..aaf1bf4cb 100644 --- a/app/src/main/res/values-te/strings.xml +++ b/app/src/main/res/values-te/strings.xml @@ -345,7 +345,7 @@ 1 అంశం తొలగించబడింది. పరిష్కరించబడినప్పుడు \"పూర్తయింది\" నొక్కండి పరిష్కరించండి - పూర్తి + పూర్తి చాలా ప్రత్యేక పాత్రలు ఆండ్రాయిడ్‌లో లిబ్రే తేలికపాటి స్ట్రీమింగ్. వాలంటీర్లు తమ ఖాళీ సమయాన్ని వెచ్చిస్తూ మీకు ఉత్తమ వినియోగదారు అనుభవాన్ని అందించడం ద్వారా NewPipe అభివృద్ధి చేయబడింది. డెవలపర్‌లు ఒక కప్పు కాఫీని ఆస్వాదిస్తున్నప్పుడు న్యూపైప్‌ని మరింత మెరుగ్గా చేయడంలో సహాయపడటానికి తిరిగి ఇవ్వండి. diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index 3df4c90b0..bfc6661c0 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -445,7 +445,7 @@ Uygulama dili Sistem öntanımlısı Çözüldüğünde \"Bitti\" düğmesine basın - Bitti + Bitti Videolar %d saniye diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index dd3632f66..f7c8c8d41 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -448,7 +448,7 @@ Мова Мова телефону Розв\'язавши натисніть «Готово» - Готово + Готово Нова Бажаєте видалити цю групу\? Підписки не вибрані diff --git a/app/src/main/res/values-ur/strings.xml b/app/src/main/res/values-ur/strings.xml index 8f66fd836..1cd5de013 100644 --- a/app/src/main/res/values-ur/strings.xml +++ b/app/src/main/res/values-ur/strings.xml @@ -513,7 +513,7 @@ %s نئی اسٹریمز ابھی تک کوئی ڈاؤن لوڈ فولڈر سیٹ نہیں ہے، ابھی ڈیفالٹ ڈاؤن لوڈ فولڈر کا انتخاب کریں - Done + Done قطار چلائیں آڈیو: %s آڈیو ٹریک diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index 885487489..7f1273c85 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -443,7 +443,7 @@ Thêm vào gần đây Ngôn ngữ sẽ thay đổi khi ứng dụng khởi động lại Bấm \"Xong\" khi hoàn thành - Đã hoàn thành + Đã hoàn thành ∞ video 100+ video diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 7bf14e520..a1051bb93 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -441,7 +441,7 @@ 应用语言 系统默认 完成后请点击“完成” - 完成 + 完成 视频 %d 秒 diff --git a/app/src/main/res/values-zh-rHK/strings.xml b/app/src/main/res/values-zh-rHK/strings.xml index 1292aeaf9..0cead2277 100644 --- a/app/src/main/res/values-zh-rHK/strings.xml +++ b/app/src/main/res/values-zh-rHK/strings.xml @@ -317,7 +317,7 @@ 未設定下載資料夾,請立即揀選預設嘅下載資料夾 刪除咗 1 個項目。 執執佢 - 搞掂 + 搞掂 NewPipe 專案非常著重你嘅私隱。因此,呢個 app 未得你同意係唔會收集任何資料。 \nNewPipe 嘅私隱政策會詳述,當你傳送彈 app 報告嗰陣,有咩資料會傳送同保存。 最近播放 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 458332272..b91cbe994 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -441,7 +441,7 @@ 應用程式語言 系統預設值 解決後請按「完成」 - 完成 + 完成 影片 %d 秒 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index d2d4a2314..7e93a2ee4 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -348,7 +348,7 @@ Press \"Done\" when solved reCAPTCHA challenge requested Solve - Done + Done Download Allowed characters in filenames From d62299348380b8cc8bdf222e93481eb05db60d54 Mon Sep 17 00:00:00 2001 From: TobiGr Date: Sat, 17 Jun 2023 20:41:38 +0200 Subject: [PATCH 125/172] Add workflow "PR size labeler" to label PRs based on the number of changed lines This should help reviewers to determine which PRs to review. --- .github/changed-lines-count-labeler.yml | 17 +++++++++++++++++ .github/workflows/pr-labeler.yml | 13 +++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 .github/changed-lines-count-labeler.yml create mode 100644 .github/workflows/pr-labeler.yml diff --git a/.github/changed-lines-count-labeler.yml b/.github/changed-lines-count-labeler.yml new file mode 100644 index 000000000..902f376c0 --- /dev/null +++ b/.github/changed-lines-count-labeler.yml @@ -0,0 +1,17 @@ +# Add 'size/small' label to any changes with less than 50 lines +size/small: + max: 49 + +# Add 'size/medium' label to any changes between 50 and 249 lines +size/medium: + min: 50 + max: 249 + +# Add 'size/large' label to any changes between 250 and 749 lines +size/large: + min: 250 + max: 749 + +# Add 'size/giant' label to any changes for more than 749 lines +size/giant: + min: 750 diff --git a/.github/workflows/pr-labeler.yml b/.github/workflows/pr-labeler.yml new file mode 100644 index 000000000..8aad9b125 --- /dev/null +++ b/.github/workflows/pr-labeler.yml @@ -0,0 +1,13 @@ +name: "PR size labeler" +on: [pull_request] + +jobs: + changed-lines-count-labeler: + runs-on: ubuntu-latest + name: Automatically labelling pull requests based on the changed lines count + steps: + - name: Set a label + uses: vkirilichev/changed-lines-count-labeler@v0.2 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + configuration-path: .github/changed-lines-count-labeler.yml From cdb79ef78a54e57121e5627ea03dbaaa6c52b1ba Mon Sep 17 00:00:00 2001 From: AudricV <74829229+AudricV@users.noreply.github.com> Date: Sun, 24 Sep 2023 18:15:36 +0200 Subject: [PATCH 126/172] Make isLimitingDataUsage method of ListHelper package-private and fix some typos in the class --- .../java/org/schabi/newpipe/util/ListHelper.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/util/ListHelper.java b/app/src/main/java/org/schabi/newpipe/util/ListHelper.java index 5918ece25..90e344fae 100644 --- a/app/src/main/java/org/schabi/newpipe/util/ListHelper.java +++ b/app/src/main/java/org/schabi/newpipe/util/ListHelper.java @@ -46,10 +46,10 @@ public final class ListHelper { List.of(MediaFormat.MP3, MediaFormat.M4A, MediaFormat.WEBMA); // Use a Set for better performance private static final Set HIGH_RESOLUTION_LIST = Set.of("1440p", "2160p"); - // Audio track types in order of priotity. 0=lowest, n=highest + // Audio track types in order of priority. 0=lowest, n=highest private static final List AUDIO_TRACK_TYPE_RANKING = List.of(AudioTrackType.DESCRIPTIVE, AudioTrackType.DUBBED, AudioTrackType.ORIGINAL); - // Audio track types in order of priotity when descriptive audio is preferred. + // Audio track types in order of priority when descriptive audio is preferred. private static final List AUDIO_TRACK_TYPE_RANKING_DESCRIPTIVE = List.of(AudioTrackType.ORIGINAL, AudioTrackType.DUBBED, AudioTrackType.DESCRIPTIVE); @@ -689,7 +689,7 @@ public final class ListHelper { } } - private static boolean isLimitingDataUsage(final Context context) { + static boolean isLimitingDataUsage(@NonNull final Context context) { return getResolutionLimit(context) != null; } @@ -731,7 +731,7 @@ public final class ListHelper { /** * Get a {@link Comparator} to compare {@link AudioStream}s by their format and bitrate. * - *

The prefered stream will be ordered last.

+ *

The preferred stream will be ordered last.

* * @param context app context * @return Comparator @@ -746,7 +746,7 @@ public final class ListHelper { /** * Get a {@link Comparator} to compare {@link AudioStream}s by their format and bitrate. * - *

The prefered stream will be ordered last.

+ *

The preferred stream will be ordered last.

* * @param defaultFormat the default format to look for * @param limitDataUsage choose low bitrate audio stream @@ -788,7 +788,7 @@ public final class ListHelper { *
  • Language is English
  • * * - *

    The prefered track will be ordered last.

    + *

    The preferred track will be ordered last.

    * * @param context App context * @return Comparator @@ -825,7 +825,7 @@ public final class ListHelper { *
  • Language is English
  • * * - *

    The prefered track will be ordered last.

    + *

    The preferred track will be ordered last.

    * * @param preferredLanguage Preferred audio stream language * @param preferOriginalAudio Get the original audio track regardless of its language From 77bbbc88f8e1cefca0a4d2ec9b1a6a0c6a592637 Mon Sep 17 00:00:00 2001 From: AudricV <74829229+AudricV@users.noreply.github.com> Date: Sun, 24 Sep 2023 18:23:00 +0200 Subject: [PATCH 127/172] Use ListHelper to get secondary audio streams for video-only streams Instead of searching for the first audio stream matching a compatible media format, this change makes SecondaryStreamHelper.getAudioStreamFor use methods isLimitingDataUsage, getAudioFormatComparator and getAudioIndexByHighestRank of ListHelper to get an audio stream which can be muxed into a video-only stream, if available. This allows users to download videos with the highest audio quality available if no resolution limit on mobile data usage has been set. The order of formats used to search a compatible audio stream has been kept. --- .../newpipe/download/DownloadDialog.java | 4 +- .../newpipe/util/SecondaryStreamHelper.java | 46 +++++++++++-------- 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/download/DownloadDialog.java b/app/src/main/java/org/schabi/newpipe/download/DownloadDialog.java index 9e9909e85..2e0a421da 100644 --- a/app/src/main/java/org/schabi/newpipe/download/DownloadDialog.java +++ b/app/src/main/java/org/schabi/newpipe/download/DownloadDialog.java @@ -267,8 +267,8 @@ public class DownloadDialog extends DialogFragment if (!videoStreams.get(i).isVideoOnly()) { continue; } - final AudioStream audioStream = SecondaryStreamHelper - .getAudioStreamFor(audioStreams.getStreamsList(), videoStreams.get(i)); + final AudioStream audioStream = SecondaryStreamHelper.getAudioStreamFor( + context, audioStreams.getStreamsList(), videoStreams.get(i)); if (audioStream != null) { secondaryStreams.append(i, new SecondaryStreamHelper<>(audioStreams, audioStream)); diff --git a/app/src/main/java/org/schabi/newpipe/util/SecondaryStreamHelper.java b/app/src/main/java/org/schabi/newpipe/util/SecondaryStreamHelper.java index 9415135cf..42a6ca361 100644 --- a/app/src/main/java/org/schabi/newpipe/util/SecondaryStreamHelper.java +++ b/app/src/main/java/org/schabi/newpipe/util/SecondaryStreamHelper.java @@ -1,5 +1,7 @@ package org.schabi.newpipe.util; +import android.content.Context; + import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -9,6 +11,7 @@ import org.schabi.newpipe.extractor.stream.Stream; import org.schabi.newpipe.extractor.stream.VideoStream; import org.schabi.newpipe.util.StreamItemAdapter.StreamInfoWrapper; +import java.util.Comparator; import java.util.List; public class SecondaryStreamHelper { @@ -27,12 +30,14 @@ public class SecondaryStreamHelper { /** * Find the correct audio stream for the desired video stream. * + * @param context Android context * @param audioStreams list of audio streams * @param videoStream desired video ONLY stream * @return selected audio stream or null if a candidate was not found */ @Nullable - public static AudioStream getAudioStreamFor(@NonNull final List audioStreams, + public static AudioStream getAudioStreamFor(@NonNull final Context context, + @NonNull final List audioStreams, @NonNull final VideoStream videoStream) { final MediaFormat mediaFormat = videoStream.getFormat(); if (mediaFormat == null) { @@ -41,33 +46,36 @@ public class SecondaryStreamHelper { switch (mediaFormat) { case WEBM: - case MPEG_4:// ¿is mpeg-4 DASH? + case MPEG_4: // Is MPEG-4 DASH? break; default: return null; } - final boolean m4v = (mediaFormat == MediaFormat.MPEG_4); + final boolean m4v = mediaFormat == MediaFormat.MPEG_4; + final boolean isLimitingDataUsage = ListHelper.isLimitingDataUsage(context); - for (final AudioStream audio : audioStreams) { - if (audio.getFormat() == (m4v ? MediaFormat.M4A : MediaFormat.WEBMA)) { - return audio; + Comparator comparator = ListHelper.getAudioFormatComparator( + m4v ? MediaFormat.M4A : MediaFormat.WEBMA, isLimitingDataUsage); + int preferredAudioStreamIndex = ListHelper.getAudioIndexByHighestRank( + audioStreams, comparator); + + if (preferredAudioStreamIndex == -1) { + if (m4v) { + return null; + } + + comparator = ListHelper.getAudioFormatComparator( + MediaFormat.WEBMA_OPUS, isLimitingDataUsage); + preferredAudioStreamIndex = ListHelper.getAudioIndexByHighestRank( + audioStreams, comparator); + + if (preferredAudioStreamIndex == -1) { + return null; } } - if (m4v) { - return null; - } - - // retry, but this time in reverse order - for (int i = audioStreams.size() - 1; i >= 0; i--) { - final AudioStream audio = audioStreams.get(i); - if (audio.getFormat() == MediaFormat.WEBMA_OPUS) { - return audio; - } - } - - return null; + return audioStreams.get(preferredAudioStreamIndex); } public T getStream() { From 609f0a2eeee7eeac030a8da4226dd599e6e5090c Mon Sep 17 00:00:00 2001 From: Tobi Date: Sun, 24 Sep 2023 20:24:57 +0200 Subject: [PATCH 128/172] Add write permission to PR labeler workflow --- .github/workflows/pr-labeler.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/pr-labeler.yml b/.github/workflows/pr-labeler.yml index 8aad9b125..6d63ec505 100644 --- a/.github/workflows/pr-labeler.yml +++ b/.github/workflows/pr-labeler.yml @@ -1,5 +1,7 @@ name: "PR size labeler" on: [pull_request] +permissions: + pull-requests: write jobs: changed-lines-count-labeler: From db4619f5a4ac990e52d79dc95230ed7ffcb0964b Mon Sep 17 00:00:00 2001 From: Tobi Date: Tue, 26 Sep 2023 10:40:17 +0200 Subject: [PATCH 129/172] Add content: read permission to PR size labeler workflow --- .github/workflows/pr-labeler.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/pr-labeler.yml b/.github/workflows/pr-labeler.yml index 6d63ec505..5d7e48517 100644 --- a/.github/workflows/pr-labeler.yml +++ b/.github/workflows/pr-labeler.yml @@ -1,6 +1,7 @@ name: "PR size labeler" on: [pull_request] permissions: + contents: read pull-requests: write jobs: From e80b6b3057ac91aa42b71aa90f0e935fc6161d5c Mon Sep 17 00:00:00 2001 From: Siddhesh Naik <87667048+snaik20@users.noreply.github.com> Date: Tue, 26 Sep 2023 14:41:33 +0530 Subject: [PATCH 130/172] Add playlist name and video name to playlist sharing content (#10427) - Currently, only a list of videos separated by newline are added in the share content. - This makes it difficult to identify a specific video in a list of Urls. - Used string resources for the sharing content formats. - Added a confirmation dialog for users to choose between sharing playlist formats. - Added Playlist name as the header and corresponding video name for each video url in following format. Playlist - Music1: https://media-url1 - Music2: https://media-url2 - Music3: https://media-url3 Co-authored-by: TobiGr --- .../local/playlist/LocalPlaylistFragment.java | 48 ++++++++++++++++--- app/src/main/res/values/strings.xml | 8 +++- 2 files changed, 49 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java index 0d8f81334..28711c6fe 100644 --- a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java +++ b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java @@ -51,8 +51,8 @@ import org.schabi.newpipe.player.playqueue.SinglePlayQueue; import org.schabi.newpipe.util.Localization; import org.schabi.newpipe.util.NavigationHelper; import org.schabi.newpipe.util.OnClickGesture; -import org.schabi.newpipe.util.external_communication.ShareUtils; import org.schabi.newpipe.util.PlayButtonHelper; +import org.schabi.newpipe.util.external_communication.ShareUtils; import java.util.ArrayList; import java.util.Collections; @@ -346,7 +346,7 @@ public class LocalPlaylistFragment extends BaseLocalListFragment Single.just(playlist.stream() .map(PlaylistStreamEntry::getStreamEntity) - .map(StreamEntity::getUrl) + .map(streamEntity -> { + if (shouldSharePlaylistDetails) { + return context.getString(R.string.video_details_list_item, + streamEntity.getTitle(), streamEntity.getUrl()); + } else { + return streamEntity.getUrl(); + } + }) .collect(Collectors.joining("\n")))) .observeOn(AndroidSchedulers.mainThread()) - .subscribe(urlsText -> ShareUtils.shareText(requireContext(), name, urlsText), + .subscribe(urlsText -> ShareUtils.shareText( + context, name, shouldSharePlaylistDetails + ? context.getString(R.string.share_playlist_content_details, + name, urlsText) : urlsText), throwable -> showUiErrorSnackbar(this, "Sharing playlist", throwable))); } @@ -841,5 +858,24 @@ public class LocalPlaylistFragment extends BaseLocalListFragment + sharePlaylist(/* shouldSharePlaylistDetails= */ true) + ) + .setNegativeButton(R.string.share_playlist_with_list, (dialog, which) -> + sharePlaylist(/* shouldSharePlaylistDetails= */ false) + ) + .show(); + } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 9dfca8294..bf618739c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -832,4 +832,10 @@ Medium quality High quality \? - \ No newline at end of file + Share Playlist + Share playlist with details such as playlist name and video titles or as a simple list of video URLs + Share with Titles + Share URL list + - %s: %s + %s\n%s + From 0758cd6980d2cda88803930d34227b11f10d05d2 Mon Sep 17 00:00:00 2001 From: TobiGr Date: Tue, 26 Sep 2023 11:22:22 +0200 Subject: [PATCH 131/172] Fix wrongly formatted string ressources There were multiple substitutions specified in non-positional format in the ressources video_details_list_item and share_playlist_content_details --- app/src/main/res/values/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index bf618739c..435e9a382 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -836,6 +836,6 @@ Share playlist with details such as playlist name and video titles or as a simple list of video URLs Share with Titles Share URL list - - %s: %s - %s\n%s + - %1$s: %2$s + %1$s\n%2$s From fe7d1692c374b442801659ffa608866f12cabe55 Mon Sep 17 00:00:00 2001 From: Tobi Date: Wed, 27 Sep 2023 10:04:27 +0200 Subject: [PATCH 132/172] Fix PR labeler permissions Although the permission to modify PRs is granted to the entire workflow, the job still reports that it does not the permission to do so: GITHUB_TOKEN Permissions Contents: read Metadata: read PullRequests: read This adds the permission to the job directly --- .github/workflows/pr-labeler.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/pr-labeler.yml b/.github/workflows/pr-labeler.yml index 5d7e48517..1108b526c 100644 --- a/.github/workflows/pr-labeler.yml +++ b/.github/workflows/pr-labeler.yml @@ -8,6 +8,8 @@ jobs: changed-lines-count-labeler: runs-on: ubuntu-latest name: Automatically labelling pull requests based on the changed lines count + permissions: + pull-requests: write steps: - name: Set a label uses: vkirilichev/changed-lines-count-labeler@v0.2 From b50e3c07d2fbb4c2efe06b6a19e47a376bdc3e7e Mon Sep 17 00:00:00 2001 From: Tobi Date: Mon, 2 Oct 2023 02:12:24 +0200 Subject: [PATCH 133/172] Use PR labeler fork This updates some libs --- .github/workflows/pr-labeler.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pr-labeler.yml b/.github/workflows/pr-labeler.yml index 1108b526c..e0dba3111 100644 --- a/.github/workflows/pr-labeler.yml +++ b/.github/workflows/pr-labeler.yml @@ -12,7 +12,7 @@ jobs: pull-requests: write steps: - name: Set a label - uses: vkirilichev/changed-lines-count-labeler@v0.2 + uses: TeamNewPipe/changed-lines-count-labeler@main with: repo-token: ${{ secrets.GITHUB_TOKEN }} configuration-path: .github/changed-lines-count-labeler.yml From 1cf670dad95fd6f7c03b613a571885e11c1faa8b Mon Sep 17 00:00:00 2001 From: Yingwei Zheng Date: Mon, 18 Apr 2022 00:35:59 +0800 Subject: [PATCH 134/172] Fix inconsistency between user interaction and database commit order when re-adding videos to the playlist --- .../fragments/detail/VideoDetailFragment.java | 17 +++++++++++++++-- .../local/playlist/LocalPlaylistFragment.java | 9 +++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java index 0314c2540..fe8845742 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java @@ -54,6 +54,7 @@ import androidx.appcompat.content.res.AppCompatResources; import androidx.appcompat.widget.Toolbar; import androidx.coordinatorlayout.widget.CoordinatorLayout; import androidx.core.content.ContextCompat; +import androidx.fragment.app.Fragment; import androidx.preference.PreferenceManager; import com.google.android.exoplayer2.PlaybackException; @@ -89,6 +90,7 @@ import org.schabi.newpipe.fragments.list.videos.RelatedItemsFragment; import org.schabi.newpipe.ktx.AnimationType; import org.schabi.newpipe.local.dialog.PlaylistDialog; import org.schabi.newpipe.local.history.HistoryRecordManager; +import org.schabi.newpipe.local.playlist.LocalPlaylistFragment; import org.schabi.newpipe.player.Player; import org.schabi.newpipe.player.PlayerService; import org.schabi.newpipe.player.PlayerType; @@ -472,10 +474,21 @@ public final class VideoDetailFragment binding.detailControlsBackground.setOnClickListener(v -> openBackgroundPlayer(false)); binding.detailControlsPopup.setOnClickListener(v -> openPopupPlayer(false)); - binding.detailControlsPlaylistAppend.setOnClickListener(makeOnClickListener(info -> + binding.detailControlsPlaylistAppend.setOnClickListener(makeOnClickListener(info -> { + if (getFM() != null && currentInfo != null) { + final Fragment fragment = getParentFragmentManager(). + findFragmentById(R.id.fragment_holder); + + // commit previous pending changes to database + if (fragment instanceof LocalPlaylistFragment) { + ((LocalPlaylistFragment) fragment).commitChanges(); + } + disposables.add(PlaylistDialog.createCorrespondingDialog(requireContext(), List.of(new StreamEntity(info)), - dialog -> dialog.show(getParentFragmentManager(), TAG))))); + dialog -> dialog.show(getParentFragmentManager(), TAG))); + } + })); binding.detailControlsDownload.setOnClickListener(v -> { if (PermissionHelper.checkStoragePermissions(activity, PermissionHelper.DOWNLOAD_DIALOG_REQUEST_CODE)) { diff --git a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java index 28711c6fe..9a75c7dbe 100644 --- a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java +++ b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java @@ -158,6 +158,15 @@ public class LocalPlaylistFragment extends BaseLocalListFragment Date: Wed, 16 Aug 2023 23:28:02 +0200 Subject: [PATCH 135/172] Fix inconsistency when LocalPlaylist is used as MainFragment tab --- .../newpipe/fragments/MainFragment.java | 25 ++++++++++++++- .../fragments/detail/VideoDetailFragment.java | 3 ++ .../local/playlist/LocalPlaylistFragment.java | 32 +++++++++++++++---- 3 files changed, 52 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/fragments/MainFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/MainFragment.java index 023642955..96b13922b 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/MainFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/MainFragment.java @@ -38,6 +38,7 @@ import org.schabi.newpipe.R; import org.schabi.newpipe.databinding.FragmentMainBinding; import org.schabi.newpipe.error.ErrorUtil; import org.schabi.newpipe.extractor.exceptions.ExtractionException; +import org.schabi.newpipe.local.playlist.LocalPlaylistFragment; import org.schabi.newpipe.settings.tabs.Tab; import org.schabi.newpipe.settings.tabs.TabsManager; import org.schabi.newpipe.util.NavigationHelper; @@ -217,6 +218,12 @@ public class MainFragment extends BaseFragment implements TabLayout.OnTabSelecte setTitle(tabsList.get(tabPosition).getTabName(requireContext())); } + public void commitPlaylistTabs() { + pagerAdapter.getLocalPlaylistFragments() + .stream() + .forEach(LocalPlaylistFragment::commitChanges); + } + private void updateTabLayoutPosition() { final ScrollableTabLayout tabLayout = binding.mainTabLayout; final ViewPager viewPager = binding.pager; @@ -268,10 +275,18 @@ public class MainFragment extends BaseFragment implements TabLayout.OnTabSelecte updateTitleForTab(tab.getPosition()); } - private static final class SelectedTabsPagerAdapter + public static final class SelectedTabsPagerAdapter extends FragmentStatePagerAdapterMenuWorkaround { private final Context context; private final List internalTabsList; + /** + * Keep reference to LocalPlaylistFragments, because their data can be modified by the user + * during runtime and changes are not committed immediately. However, in some cases, + * the changes need to be committed immediately by calling + * {@link LocalPlaylistFragment#commitChanges()}. + * The fragments are removed when {@link LocalPlaylistFragment#onDestroy()} is called. + */ + private final List localPlaylistFragments = new ArrayList<>(); private SelectedTabsPagerAdapter(final Context context, final FragmentManager fragmentManager, @@ -298,9 +313,17 @@ public class MainFragment extends BaseFragment implements TabLayout.OnTabSelecte ((BaseFragment) fragment).useAsFrontPage(true); } + if (fragment instanceof LocalPlaylistFragment) { + localPlaylistFragments.add((LocalPlaylistFragment) fragment); + } + return fragment; } + public List getLocalPlaylistFragments() { + return localPlaylistFragments; + } + @Override public int getItemPosition(@NonNull final Object object) { // Causes adapter to reload all Fragments when diff --git a/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java index fe8845742..a25d0fae4 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java @@ -85,6 +85,7 @@ import org.schabi.newpipe.extractor.stream.VideoStream; import org.schabi.newpipe.fragments.BackPressable; import org.schabi.newpipe.fragments.BaseStateFragment; import org.schabi.newpipe.fragments.EmptyFragment; +import org.schabi.newpipe.fragments.MainFragment; import org.schabi.newpipe.fragments.list.comments.CommentsFragment; import org.schabi.newpipe.fragments.list.videos.RelatedItemsFragment; import org.schabi.newpipe.ktx.AnimationType; @@ -482,6 +483,8 @@ public final class VideoDetailFragment // commit previous pending changes to database if (fragment instanceof LocalPlaylistFragment) { ((LocalPlaylistFragment) fragment).commitChanges(); + } else if (fragment instanceof MainFragment) { + ((MainFragment) fragment).commitPlaylistTabs(); } disposables.add(PlaylistDialog.createCorrespondingDialog(requireContext(), diff --git a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java index 9a75c7dbe..51da52ae0 100644 --- a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java +++ b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java @@ -41,6 +41,7 @@ import org.schabi.newpipe.databinding.PlaylistControlBinding; import org.schabi.newpipe.error.ErrorInfo; import org.schabi.newpipe.error.UserAction; import org.schabi.newpipe.extractor.stream.StreamInfoItem; +import org.schabi.newpipe.fragments.MainFragment; import org.schabi.newpipe.fragments.list.playlist.PlaylistControlViewHolder; import org.schabi.newpipe.info_list.dialog.InfoItemDialog; import org.schabi.newpipe.info_list.dialog.StreamDialogDefaultEntry; @@ -71,7 +72,7 @@ import io.reactivex.rxjava3.subjects.PublishSubject; public class LocalPlaylistFragment extends BaseLocalListFragment, Void> implements PlaylistControlViewHolder { - // Save the list 10 seconds after the last change occurred + /** Save the list 10 seconds after the last change occurred. */ private static final long SAVE_DEBOUNCE_MILLIS = 10000; private static final int MINIMUM_INITIAL_DRAG_VELOCITY = 12; @State @@ -92,13 +93,20 @@ public class LocalPlaylistFragment extends BaseLocalListFragment debouncedSaveSignal; private CompositeDisposable disposables; - /* Has the playlist been fully loaded from db */ + /** Whether the playlist has been fully loaded from db. */ private AtomicBoolean isLoadingComplete; - /* Has the playlist been modified (e.g. items reordered or deleted) */ + /** Whether the playlist has been modified (e.g. items reordered or deleted) */ private AtomicBoolean isModified; - /* Flag to prevent simultaneous rewrites of the playlist */ + /** Flag to prevent simultaneous rewrites of the playlist. */ private boolean isRewritingPlaylist = false; + /** + * The pager adapter that the fragment is created from when it is used as frontpage, i.e. + * {@link #useAsFrontPage} is {@link true}. + */ + @Nullable + private MainFragment.SelectedTabsPagerAdapter tabsPagerAdapter = null; + public static LocalPlaylistFragment getInstance(final long playlistId, final String name) { final LocalPlaylistFragment instance = new LocalPlaylistFragment(); instance.setInitialData(playlistId, name); @@ -158,9 +166,11 @@ public class LocalPlaylistFragment extends BaseLocalListFragmentCommit changes immediately if the playlist has been modified.

    + * Delete operations and other modifications will be committed to ensure that the database + * is up to date, e.g. when the user adds the just deleted stream from another fragment. + */ public void commitChanges() { if (isModified != null && isModified.get()) { saveImmediate(); @@ -300,6 +310,9 @@ public class LocalPlaylistFragment extends BaseLocalListFragment Date: Mon, 2 Oct 2023 15:58:26 +0200 Subject: [PATCH 136/172] Create Serbian README (#10465) --- README.md | 2 +- doc/README.asm.md | 2 +- doc/README.de.md | 2 +- doc/README.es.md | 2 +- doc/README.fr.md | 2 +- doc/README.hi.md | 2 +- doc/README.it.md | 2 +- doc/README.ja.md | 2 +- doc/README.ko.md | 2 +- doc/README.pa.md | 2 +- doc/README.pl.md | 2 +- doc/README.pt_BR.md | 2 +- doc/README.ro.md | 2 +- doc/README.ru.md | 2 +- doc/README.ryu.md | 2 +- doc/README.so.md | 2 +- doc/README.sr.md | 141 ++++++++++++++++++++++++++++++++++++++++++++ doc/README.tr.md | 2 +- doc/README.zh_TW.md | 2 +- 19 files changed, 159 insertions(+), 18 deletions(-) create mode 100644 doc/README.sr.md diff --git a/README.md b/README.md index fe7154fe1..ed25bfa41 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@

    WebsiteBlogFAQPress


    -*Read this document in other languages: [Deutsch](doc/README.de.md), [English](README.md), [Español](doc/README.es.md), [Français](doc/README.fr.md), [हिन्दी](doc/README.hi.md), [Italiano](doc/README.it.md), [한국어](doc/README.ko.md), [Português Brasil](doc/README.pt_BR.md), [Polski](doc/README.pl.md), [ਪੰਜਾਬੀ ](doc/README.pa.md), [日本語](doc/README.ja.md), [Română](doc/README.ro.md), [Soomaali](doc/README.so.md), [Türkçe](doc/README.tr.md), [正體中文](doc/README.zh_TW.md), [অসমীয়া](doc/README.asm.md)* +*Read this document in other languages: [Deutsch](doc/README.de.md), [English](README.md), [Español](doc/README.es.md), [Français](doc/README.fr.md), [हिन्दी](doc/README.hi.md), [Italiano](doc/README.it.md), [한국어](doc/README.ko.md), [Português Brasil](doc/README.pt_BR.md), [Polski](doc/README.pl.md), [ਪੰਜਾਬੀ ](doc/README.pa.md), [日本語](doc/README.ja.md), [Română](doc/README.ro.md), [Soomaali](doc/README.so.md), [Türkçe](doc/README.tr.md), [正體中文](doc/README.zh_TW.md), [অসমীয়া](doc/README.asm.md), [Српски](doc/README.sr.md)* WARNING: THIS APP IS IN BETA, SO YOU MAY ENCOUNTER BUGS. IF YOU DO, OPEN AN ISSUE IN OUR GITHUB REPOSITORY BY FILLING OUT THE ISSUE TEMPLATE. diff --git a/doc/README.asm.md b/doc/README.asm.md index 8b2373514..4d03fbc8a 100644 --- a/doc/README.asm.md +++ b/doc/README.asm.md @@ -19,7 +19,7 @@ FAQPress


    -*Read this document in other languages: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](/README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md)* +*Read this document in other languages: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](/README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md), [Српски](doc/README.sr.md)* সতৰ্কবাণী: এই এপটো নিৰ্মিয়মান অৱস্থাত আছে, গতিকে আপুনি ব্যৱহাৰ কৰোঁতে কোনো অসুবিধাৰ সন্মুখীন হ'ব পাৰে। যদি আপুনি অসুবিধাৰ সন্মুখীন হয়, ইছ্যু টেমপ্লেট পূৰণ কৰি আমাৰ GITHUB ৰিপ'জিটৰিত এটা ইছ্যু খোলক। diff --git a/doc/README.de.md b/doc/README.de.md index e5aecca13..ba1e1ee81 100644 --- a/doc/README.de.md +++ b/doc/README.de.md @@ -20,7 +20,7 @@

    WebsiteBlogFAQÜber NewPipe


    -*Read this document in other languages: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md)* +*Read this document in other languages: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md), [Српски](doc/README.sr.md)* WARNUNG: DIESE APP BEFINDET SICH IN EINER BETA-PHASE, DAHER KÖNNTEST DU BUGS BEGEGNEN. FALLS DIES PASSIERT, ERSTELLE EIN ISSUE (AUF ENGLISCH) IN UNSEREM GITHUB REPOSITORY, INDEM DU DIE VORLAGE DORT AUSFÜLLST. diff --git a/doc/README.es.md b/doc/README.es.md index 29356cdcd..54c2b4253 100644 --- a/doc/README.es.md +++ b/doc/README.es.md @@ -18,7 +18,7 @@

    Sitio WebBlogPreguntas FrecuentesPrensa


    -*Read this document in other languages: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md)* +*Read this document in other languages: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md), [Српски](doc/README.sr.md)* AVISO: ESTA ES UNA VERSIÓN BETA, POR LO TANTO, PUEDES ENCONTRAR BUGS. SI ENCUENTRAS UNO ABRA UN ISSUE A TRAVÉS DE NUESTRO REPOSITORIO DE GITHUB. diff --git a/doc/README.fr.md b/doc/README.fr.md index dd752b051..d9b378f3c 100644 --- a/doc/README.fr.md +++ b/doc/README.fr.md @@ -17,7 +17,7 @@

    SiteBlogFAQPresse


    -*Read this document in other languages: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md)* +*Read this document in other languages: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md), [Српски](doc/README.sr.md)* ATTENTION: CETTE APP EST EN BETA, VOUS POUVEZ DONC RENCONTRER DES BUGS. SI C'EST LE CAS, OUVREZ UNE ISSUE DANS NOTRE DÉPÔT GITHUB EN REMPLISSANT LE MODÈLE D'ISSUE. diff --git a/doc/README.hi.md b/doc/README.hi.md index 7ce4605ea..c87b3626c 100644 --- a/doc/README.hi.md +++ b/doc/README.hi.md @@ -17,7 +17,7 @@

    वेबसाइटब्लॉगसाधारण सवाल-जवाबप्रेस


    -*Read this document in other languages: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md)* +*Read this document in other languages: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md), [Српски](doc/README.sr.md)* चेतावनी: यह एक बीटा संस्करण है, तो अगर आपको इसमें बग्स नज़र आते हैं, कृपया हमारे GitHub रिपॉज़िटरी के ज़रिए एक समस्या खोल दें। diff --git a/doc/README.it.md b/doc/README.it.md index 76b90318e..c5af6516f 100644 --- a/doc/README.it.md +++ b/doc/README.it.md @@ -17,7 +17,7 @@

    SitoBlogFAQStampa


    -*Read this document in other languages: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md)* +*Read this document in other languages: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md), [Српски](doc/README.sr.md)* ATTENZIONE: QUEST'APP È IN BETA, QUINDI POTRESTI IMBATTERTI IN BUG. SE COSÌ FOSSE, APRI UN'ISSUE SUL NOSTRO REPOSITORIO GITHUB COMPILANDO IL TEMPLATE ISSUE. diff --git a/doc/README.ja.md b/doc/README.ja.md index 81be7e0d1..abd697be7 100644 --- a/doc/README.ja.md +++ b/doc/README.ja.md @@ -17,7 +17,7 @@

    ウェブサイトブログFAQニュース


    -*Read this document in other languages: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md)* +*Read this document in other languages: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md), [Српски](doc/README.sr.md)* 注意: これはベータ版のため、バグが発生する可能性があります。もしバグが発生した場合、GitHub のリポジトリで Issue を開いてください。 diff --git a/doc/README.ko.md b/doc/README.ko.md index 03b6fdfbb..9ef54299f 100644 --- a/doc/README.ko.md +++ b/doc/README.ko.md @@ -17,7 +17,7 @@

    WebsiteBlogFAQPress


    -*Read this document in other languages: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md)* +*Read this document in other languages: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md), [Српски](doc/README.sr.md)* 경고: 이 버전은 베타 버전이므로, 버그가 발생할 수도 있습니다. 만약 버그가 발생하였다면, 우리의 GitHub 저장소에서 Issue를 열람하여 주십시오. diff --git a/doc/README.pa.md b/doc/README.pa.md index 65e817b4e..19d387de3 100644 --- a/doc/README.pa.md +++ b/doc/README.pa.md @@ -17,7 +17,7 @@

    ਵੈੱਬਸਾਈਟਬਲੌਗਆਮ ਸਵਾਲ ਜਵਾਬਪ੍ਰੈਸ


    -*Read this document in other languages: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md)* +*Read this document in other languages: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md), [Српски](doc/README.sr.md)* ਚੇਤਾਵਨੀ: ਇਹ ਐਪ ਬੀਟਾ ਵਿੱਚ ਹੈ, ਇਸ ਲਈ ਤੁਸੀਂ ਬੱਗ ਦਾ ਸਾਹਮਣਾ ਕਰ ਸਕਦੇ ਹੋ। ਜੇਕਰ ਤੁਸੀਂ ਅਜਿਹਾ ਕਰਦੇ ਹੋ, ਤਾਂ ਟੈਮਪਲੇਟ ਨੂੰ ਭਰ ਕੇ ਸਾਡੀ ਗਿਟਹੱਬ ਰਿਪੋਜ਼ਟਰੀ ਵਿੱਚ ਇੱਕ ਮੁੱਦਾ ਖੋਲ੍ਹੋ diff --git a/doc/README.pl.md b/doc/README.pl.md index 16577cb4d..e09e38943 100644 --- a/doc/README.pl.md +++ b/doc/README.pl.md @@ -17,7 +17,7 @@

    StronaBlogFAQPress


    -*Read this document in other languages: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md)* +*Read this document in other languages: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md), [Српски](doc/README.sr.md)* UWAGA: TO JEST WERSJA BETA, WIĘC MOŻESZ NAPOTKAĆ BŁĘDY. JEŚLI TAK SIĘ STANIE, OTWÓRZ NOWY "ISSUE" NA GITHUBIE. diff --git a/doc/README.pt_BR.md b/doc/README.pt_BR.md index 7e1605dcd..a1ff260f2 100644 --- a/doc/README.pt_BR.md +++ b/doc/README.pt_BR.md @@ -18,7 +18,7 @@

    SiteBlogFAQPress


    -*Read this document in other languages: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md)* +*Read this document in other languages: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md), [Српски](doc/README.sr.md)* AVISO: ESTA É UMA VERSÃO BETA, PORTANTO, VOCÊ PODE ENCONTRAR BUGS. ENCONTROU ALGUM, ABRA UM ISSUE ATRAVÉS DO NOSSO REPOSITÓRIO GITHUB. diff --git a/doc/README.ro.md b/doc/README.ro.md index f7d5db9d5..aa16fdfa5 100644 --- a/doc/README.ro.md +++ b/doc/README.ro.md @@ -17,7 +17,7 @@

    WebsiteBlogFAQPresă


    -*Read this document in other languages: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md)* +*Read this document in other languages: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md), [Српски](doc/README.sr.md)* Atenţionare: ACEASTA ESTE O VERSIUNE BETA, AŞA CĂ S-AR PUTE SĂ ÎNTÂLNIŢI ERORI. DACĂ SE ÎNTÂMPLĂ ACEST LUCRU, DESCHIDEŢI UN ISSUE PRIN REPSITORY-UL NOSTRU GITHUB. diff --git a/doc/README.ru.md b/doc/README.ru.md index d13a04776..9ede76bc8 100644 --- a/doc/README.ru.md +++ b/doc/README.ru.md @@ -17,7 +17,7 @@

    СайтБлогЧЗВПресса


    -*Read this document in other languages: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md)* +*Read this document in other languages: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md), [Српски](doc/README.sr.md)* ВНИМАНИЕ: ЭТО ПРИЛОЖЕНИЕ НАХОДИТСЯ В СТАДИИ БЕТА, ПОЭТОМУ ВЫ МОЖЕТЕ ОБНАРУЖИТЬ ОШИБКИ. ЕСЛИ ЭТО СЛУЧИТСЯ, ОТКРОЙТЕ ВОПРОС В НАШЕМ РЕПОЗИТОРИИ GITHUB, ЗАПОЛНЯ ЕГО ПО ШАБЛОНУ. diff --git a/doc/README.ryu.md b/doc/README.ryu.md index f68645b07..b74f18f95 100644 --- a/doc/README.ryu.md +++ b/doc/README.ryu.md @@ -17,7 +17,7 @@

    ウェブサイトブログFAQニュース


    -*ふかぬぎんぐっしゆむん: [English](../README.md), [Español](README.es.md), [हिन्दी](README.hi.md), [한국어](README.ko.md), [Soomaali](README.so.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [日本語](README.ja.md), [Română](README.ro.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [うちなーぐち](README.ryu.md)。* +*ふかぬぎんぐっしゆむん: [English](../README.md), [Español](README.es.md), [हिन्दी](README.hi.md), [한국어](README.ko.md), [Soomaali](README.so.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [日本語](README.ja.md), [Română](README.ro.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [うちなーぐち](README.ryu.md), [Српски](doc/README.sr.md)* ちゅうい:くれーベータばんぬたみ、バグぬはっせいすがのうゆいがあいびーん。むしバグぬはっせいさーあい、GitHubぬリポジトリっしIssueふぃらちくぃみそーれー。 diff --git a/doc/README.so.md b/doc/README.so.md index 5407b1ab4..19b66286b 100644 --- a/doc/README.so.md +++ b/doc/README.so.md @@ -17,7 +17,7 @@

    Website-kaMaqaaladaSu'aalaha Aalaa La-iswaydiiyoWarbaahinta


    -*Read this document in other languages: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](doc/README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md)* +*Read this document in other languages: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](doc/README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md), [Српски](doc/README.sr.md)* DIGNIIN: MIDKAN, NOOCA APP-KA EE HADDA WALI TIJAABO AYUU KU JIRAA, SIDAA DARTEED CILLADO AYAAD LA KULMI KARTAA. HADAAD LA KULANTO, KA FUR ARIN SHARAXAYA QAYBTANADA ARRIMAHA EE GITHUB-KA. diff --git a/doc/README.sr.md b/doc/README.sr.md new file mode 100644 index 000000000..77daacacc --- /dev/null +++ b/doc/README.sr.md @@ -0,0 +1,141 @@ +

    Планирамо да препишемо велике делове кода, како бисмо створили нови, модеран и стабилан NewPipe!

    +

    Немојте сада слати захтеве за нове функције, прихватаће се само захтеви за исправљање грешака.

    + +

    +

    NewPipe

    +

    Бесплатна и лагана апликација за стримовање за Android.

    + +

    Набавите на F-Droid

    + +

    + + + + + + +

    +
    +

    Снимци екранаПодржане услугеОписКарактеристикеИнсталација и ажурирањаДоприносДонацијаЛиценца

    +

    Веб-сајтБлогЧППШтампа

    +
    + +*Прочитајте овај документ на другим језицима: [Deutsch](doc/README.de.md), [English](README.md), [Español](doc/README.es.md), [Français](doc/README.fr.md), [हिन्दी](doc/README.hi.md), [Italiano](doc/README.it.md), [한국어](doc/README.ko.md), [Português Brasil](doc/README.pt_BR.md), [Polski](doc/README.pl.md), [ਪੰਜਾਬੀ ](doc/README.pa.md), [日本語](doc/README.ja.md), [Română](doc/README.ro.md), [Soomaali](doc/README.so.md), [Türkçe](doc/README.tr.md), [正體中文](doc/README.zh_TW.md), [অসমীয়া](doc/README.asm.md), [Српски](doc/README.sr.md)* + +УПОЗОРЕЊЕ: ОВА АПЛИКАЦИЈА ЈЕ У БЕТА ВЕРЗИЈИ, ТАКО ДА МОЖЕТЕ НАИЋИ НА ГРЕШКЕ. АКО НАИЂЕТЕ, НАПИШИТЕ ИЗВЕШТАЈ У НАШЕМ GITHUB РЕПОЗИТОРИЈУМУ ПОПУЊАВАЊЕМ ШАБЛОНА ИЗВЕШТАЈА. + +ПОСТАВЉАЊЕ АПЛИКАЦИЈЕ NEWPIPE ИЛИ БИЛО КОГ ЊЕНОГ ФОРКА, У GOOGLE PLAY ПРОДАВНИЦУ КРШИ ЊИХОВЕ УСЛОВЕ И ОДРЕДБЕ. + +## Снимци екрана + +[](../fastlane/metadata/android/en-US/images/phoneScreenshots/00.png) +[](../fastlane/metadata/android/en-US/images/phoneScreenshots/01.png) +[](../fastlane/metadata/android/en-US/images/phoneScreenshots/02.png) +[](../fastlane/metadata/android/en-US/images/phoneScreenshots/03.png) +[](../fastlane/metadata/android/en-US/images/phoneScreenshots/04.png) +[](../fastlane/metadata/android/en-US/images/phoneScreenshots/05.png) +[](../fastlane/metadata/android/en-US/images/phoneScreenshots/06.png) +[](../fastlane/metadata/android/en-US/images/phoneScreenshots/07.png) +[](../fastlane/metadata/android/en-US/images/phoneScreenshots/08.png) +

    +[](../fastlane/metadata/android/en-US/images/tenInchScreenshots/09.png) +[](../fastlane/metadata/android/en-US/images/tenInchScreenshots/10.png) + +### Подржане услуге + +NewPipe тренутно подржава ове услуге: + + +* YouTube ([веб-сајт](https://www.youtube.com/)) и YouTube Music ([веб-сајт](https://music.youtube.com/)) ([вики](https://en.wikipedia.org/wiki/YouTube)) +* PeerTube ([веб-сајт](https://joinpeertube.org/)) и све његове инстанце (отворите веб-сајт да бисте сазнали шта то значи!) ([вики](https://en.wikipedia.org/wiki/PeerTube)) +* Bandcamp ([веб-сајт](https://bandcamp.com/)) ([вики](https://en.wikipedia.org/wiki/Bandcamp)) +* SoundCloud ([веб-сајт](https://soundcloud.com/)) ([вики](https://en.wikipedia.org/wiki/SoundCloud)) +* media.ccc.de ([веб-сајт](https://media.ccc.de/)) ([вики](https://en.wikipedia.org/wiki/Chaos_Computer_Club)) + +Као што видите, NewPipe подржава више видео и аудио услуга. Иако је почело са YouTube-ом, други људи су додали више услуга током година, чинећи NewPipe све разноврснијим! + +Делимично због околности, а делимично због своје популарности, YouTube је најбоље подржан од ових услуга. Ако користите или сте упознати са било којом од ових других услуга, помозите нам да побољшамо подршку за њих! Тражимо одржаваоце за SoundCloud и PeerTube. + +Ако намеравате да додате нову услугу, прво нас контактирајте! Наши [документи](https://teamnewpipe.github.io/documentation/) пружају више информација о томе како се нова услуга може додати у апликацију и у [NewPipe Extractor](https://github.com/TeamNewPipe/NewPipeExtractor). + +## Опис + +NewPipe ради тако што преузима потребне податке из званичног API-ја (нпр. PeerTube) услуге коју користите. Ако је званични API ограничен (нпр. YouTube) за наше сврхе или је власнички, апликација анализира веб-сајт или уместо тога користи унутрашњи API. То значи да вам није потребан налог ни на једној услузи да бисте користили NewPipe. + +Такође, пошто су бесплатни и отвореног кода, ни апликација, ни Extractor не користе никакве власничке библиотеке или радне оквире, као што су Google Play услуге. То значи да можете да користите NewPipe на уређајима или прилагођеним ROM-овима који немају инсталиране Google апликације. + +### Карактеристике + + * Гледајте видео снимке у резолуцијама до 4К + * Слушајте аудио снимке у позадини, само учитавајући аудио стрим да бисте сачували податке + * Искачући режим (плутајући плејер, познат као „Слика у слици”) + * Гледајте стримове уживо + * Прикажите/сакријте титлове/скривене титлове + * Претражујте видео и аудио снимке (на YouTube-у можете одредити и језик садржаја) + * Ставите видео снимке у ред чекања (и опционо их сачувајте као локалне плејлисте) + * Прикажите/сакријте опште информације о видео снимцима (као што су опис и ознаке) + * Прикажите/сакријте следеће/сродне видео снимке + * Прикажите/сакријте коментаре + * Претражујте видео снимке, аудио снимке, канале, плејлисте и албуме + * Прегледајте видео и аудио снимке унутар канала + * Претплатите се на канале (да, без пријављивања на било који налог!) + * Добијајте обавештења о новим видео снимцима са канала на које сте претплаћени + * Креирајте и уређујте групе канала (за лакше прегледање и управљање) + * Прегледајте фидове видео снимака генерисане из ваших група канала + * Прегледајте и претражујте историју гледања + * Претражујте и гледајте плејлисте (ово су даљинске плејлисте, што значи да се преузимају са услуге коју прегледате) + * Направите и уређујте локалне плејлисте (оне се креирају и чувају у апликацији и немају никакве везе са било којом услугом) + * Преузмите видео снимке/аудио снимке/титлове (скривене титлове) + * Отварајте у Kodi-ју + * Гледајте/блокирајте старосно ограничени материјал + +## Инсталација и ажурирања +Можете да инсталирате NewPipe користећи један од следећих начина: + 1. Додајте наш прилагођени репозиторијум на F-Droid и инсталирајте га одатле. Упутства су овде: https://newpipe.net/FAQ/tutorials/install-add-fdroid-repo/ + 2. Преузмите APK са [GitHub издања](https://github.com/TeamNewPipe/NewPipe/releases) и инсталирајте га. + 3. Ажурирајте преко F-Droid-а. Ово је најспорији начин добијања ажурирања, јер F-Droid мора да препозна промене, да направи сам APK, да га потпише, а затим да ажурирање пошаље корисницима. + 4. Сами направите APK за отклањање грешака. Ово је најбржи начин да добијете нове функције на свом уређају, али је много компликованији, па препоручујемо да користите неки од других начина. + 5. Ако сте заинтересовани за одређену функцију или исправку грешке која се налази у захтеву за повлачење у овом репозиторијуму, такође можете преузети његов APK из захтева за повлачење. Прочитајте опис захтева за повлачење за упутства. Одлична ствар у вези са APK-овима специфичним за захтев за повлачење је то што су инсталирани упоредо са званичном апликацијом, тако да не морате да бринете да ћете изгубити своје податке или нешто забрљати. + +Препоручујемо 1. начин за већину корисника. APK-ови инсталирани коришћењем 1. или 2. начина су компатибилни један са другим (што значи да ако сте инсталирали NewPipe користећи било који 1. или 2. начин, можете, такође, да ажурирате NewPipe користећи други начин), али не и са онима инсталираним коришћењем 3. начина. То је због истог кључа за потписивање (нашег) који се користи за 1. и 2. начин, али се други кључ за потписивање (F-Droid-ови) користи за 3. начин. Израда APK-а за отклањање грешака коришћењем 4. начина искључује кључ у потпуности. Кључеви за потписивање помажу да се осигура да корисник не буде преварен да инсталира злонамерно ажурирање за апликацију. Када користите 5. начин, сваки APK је потписан различитим, насумичним кључем који обезбеђује GitHub Actions, тако да не можете ни да га ажурирате. Мораћете да направите резервну копију и вратите податке апликације сваки пут када желите да користите нови APK. + +У међувремену, ако желите да промените изворе из неког разлога (нпр. основна функционалност NewPipe-а се прекида, а F-Droid још увек нема најновије ажурирање), препоручујемо вам да следите ову процедуру: 1. Направите резервну копију података преко Подешавања > Садржај > Извези базу података, да бисте задржали своју историју, претплате и листе песама 2. Деинсталирајте NewPipe 3. Преузмите APK са новог извора и инсталирајте га 4. Увезите податке из 1. корака преко Подешавања > Садржај > Увези базу података + +Напомена: када увозите базу података у званичну апликацију, увек се уверите да је то она коју сте извезли _из_ званичне апликације. Ако увезете базу података извезену из APK-а, који није званична апликација, то може покварити ствари. Таква радња није подржана и требало би да то урадите само када сте потпуно сигурни да знате шта радите. + +## Допринос +Без обзира да ли имате идеје, преводе, промене дизајна, чишћење кода или чак велике промене кода, помоћ је увек добродошла. Апликација постаје све боља и боља са сваким доприносом, без обзира колико је он велики или мали! Ако желите да се укључите, погледајте наше [напомене о доприносима](.github/CONTRIBUTING.md). + + +Статус превода + + +## Донација +Ако вам се свиђа NewPipe, можете послати донацију. Више волимо Liberapay, јер је отвореног кода и непрофитан. За више информација о донирању апликацији NewPipe, посетите наш [веб-сајт](https://newpipe.net/donate). + + + + + + + + + + + + + + + + + +
    LiberapayVisit NewPipe at liberapay.comDonate via Liberapay
    BitcoinBitcoin QR code16A9J59ahMRqkLSZjhYj33n9j3fMztFxnh
    BountysourceVisit NewPipe at bountysource.comCheck out how many bounties you can earn.
    + +## Политика приватности + +Пројекат NewPipe има за циљ да обезбеди приватно, анонимно искуство за коришћење медијских услуга заснованих на вебу. Стога, апликација не прикупља никакве податке без вашег пристанка. Политика приватности апликације NewPipe детаљно објашњава који се подаци шаљу и чувају када пошаљете извештај о отказивању или оставите коментар на нашем блогу. Документ можете пронаћи [овде](https://newpipe.net/legal/privacy/). + +## Лиценца +[![GNU GPLv3 Image](https://www.gnu.org/graphics/gplv3-127x51.png)](https://www.gnu.org/licenses/gpl-3.0.en.html) + +NewPipe је бесплатан софтвер: можете га користити, проучавати, делити и побољшавати по жељи. Конкретно, можете га редистрибуирати и/или модификовати под условима [GNU General Public License](https://www.gnu.org/licenses/gpl.html), коју је објавила Фондација за слободни софтвер, било верзију 3 лиценце или (по вашем избору) било коју каснију верзију. diff --git a/doc/README.tr.md b/doc/README.tr.md index d51144e56..2f68ecffe 100644 --- a/doc/README.tr.md +++ b/doc/README.tr.md @@ -17,7 +17,7 @@

    Web sitesiBlogSSSBasın


    -*Read this document in other languages: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](doc/README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md)* +*Read this document in other languages: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](doc/README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md), [Српски](doc/README.sr.md)* UYARI: BU SÜRÜM BETA SÜRÜMÜDÜR, BU NEDENLE HATALARLA KARŞILAŞABİLİRSİNİZ. HATA BULURSANIZ BU GITHUB DEPOSUNDA BUNU BİLDİRİN. diff --git a/doc/README.zh_TW.md b/doc/README.zh_TW.md index 476bd9eb8..be98869b2 100644 --- a/doc/README.zh_TW.md +++ b/doc/README.zh_TW.md @@ -17,7 +17,7 @@

    網站部落格FAQ媒體


    -*Read this document in other languages: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](doc/README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md)* +*Read this document in other languages: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](doc/README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md), [Српски](doc/README.sr.md)* 警告:這是測試版本,可能會發生錯誤。如果遇到錯誤,請在我們的 GITHUB REPO 開 ISSUE 回報。 From 49ce9ba387cc431570916b45800b46b69e07cb30 Mon Sep 17 00:00:00 2001 From: Tobi Date: Mon, 2 Oct 2023 16:00:25 +0200 Subject: [PATCH 137/172] Fix links to other READMEs in README.sr.md --- doc/README.sr.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/README.sr.md b/doc/README.sr.md index 77daacacc..5c36f804b 100644 --- a/doc/README.sr.md +++ b/doc/README.sr.md @@ -20,7 +20,7 @@

    Веб-сајтБлогЧППШтампа


    -*Прочитајте овај документ на другим језицима: [Deutsch](doc/README.de.md), [English](README.md), [Español](doc/README.es.md), [Français](doc/README.fr.md), [हिन्दी](doc/README.hi.md), [Italiano](doc/README.it.md), [한국어](doc/README.ko.md), [Português Brasil](doc/README.pt_BR.md), [Polski](doc/README.pl.md), [ਪੰਜਾਬੀ ](doc/README.pa.md), [日本語](doc/README.ja.md), [Română](doc/README.ro.md), [Soomaali](doc/README.so.md), [Türkçe](doc/README.tr.md), [正體中文](doc/README.zh_TW.md), [অসমীয়া](doc/README.asm.md), [Српски](doc/README.sr.md)* +*Прочитајте овај документ на другим језицима: [Deutsch](README.de.md), [English](README.md), [Español](README.es.md), [Français](README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [Српски](README.sr.md)* УПОЗОРЕЊЕ: ОВА АПЛИКАЦИЈА ЈЕ У БЕТА ВЕРЗИЈИ, ТАКО ДА МОЖЕТЕ НАИЋИ НА ГРЕШКЕ. АКО НАИЂЕТЕ, НАПИШИТЕ ИЗВЕШТАЈ У НАШЕМ GITHUB РЕПОЗИТОРИЈУМУ ПОПУЊАВАЊЕМ ШАБЛОНА ИЗВЕШТАЈА. From d963b69d5c6db85b31fabb0ce824032e1318b270 Mon Sep 17 00:00:00 2001 From: TobiGr Date: Mon, 2 Oct 2023 16:06:33 +0200 Subject: [PATCH 138/172] Fix links to README.sr.md --- doc/README.asm.md | 2 +- doc/README.de.md | 2 +- doc/README.es.md | 2 +- doc/README.fr.md | 2 +- doc/README.hi.md | 2 +- doc/README.it.md | 2 +- doc/README.ja.md | 2 +- doc/README.ko.md | 2 +- doc/README.pa.md | 2 +- doc/README.pl.md | 2 +- doc/README.pt_BR.md | 2 +- doc/README.ro.md | 2 +- doc/README.ru.md | 2 +- doc/README.ryu.md | 2 +- doc/README.so.md | 2 +- doc/README.tr.md | 2 +- doc/README.zh_TW.md | 2 +- 17 files changed, 17 insertions(+), 17 deletions(-) diff --git a/doc/README.asm.md b/doc/README.asm.md index 4d03fbc8a..1c7de43bf 100644 --- a/doc/README.asm.md +++ b/doc/README.asm.md @@ -19,7 +19,7 @@ FAQPress


    -*Read this document in other languages: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](/README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md), [Српски](doc/README.sr.md)* +*Read this document in other languages: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](/README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md), [Српски](README.sr.md)* সতৰ্কবাণী: এই এপটো নিৰ্মিয়মান অৱস্থাত আছে, গতিকে আপুনি ব্যৱহাৰ কৰোঁতে কোনো অসুবিধাৰ সন্মুখীন হ'ব পাৰে। যদি আপুনি অসুবিধাৰ সন্মুখীন হয়, ইছ্যু টেমপ্লেট পূৰণ কৰি আমাৰ GITHUB ৰিপ'জিটৰিত এটা ইছ্যু খোলক। diff --git a/doc/README.de.md b/doc/README.de.md index ba1e1ee81..296f835e8 100644 --- a/doc/README.de.md +++ b/doc/README.de.md @@ -20,7 +20,7 @@

    WebsiteBlogFAQÜber NewPipe


    -*Read this document in other languages: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md), [Српски](doc/README.sr.md)* +*Read this document in other languages: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md), [Српски](README.sr.md)* WARNUNG: DIESE APP BEFINDET SICH IN EINER BETA-PHASE, DAHER KÖNNTEST DU BUGS BEGEGNEN. FALLS DIES PASSIERT, ERSTELLE EIN ISSUE (AUF ENGLISCH) IN UNSEREM GITHUB REPOSITORY, INDEM DU DIE VORLAGE DORT AUSFÜLLST. diff --git a/doc/README.es.md b/doc/README.es.md index 54c2b4253..78c44b9fb 100644 --- a/doc/README.es.md +++ b/doc/README.es.md @@ -18,7 +18,7 @@

    Sitio WebBlogPreguntas FrecuentesPrensa


    -*Read this document in other languages: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md), [Српски](doc/README.sr.md)* +*Read this document in other languages: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md), [Српски](README.sr.md)* AVISO: ESTA ES UNA VERSIÓN BETA, POR LO TANTO, PUEDES ENCONTRAR BUGS. SI ENCUENTRAS UNO ABRA UN ISSUE A TRAVÉS DE NUESTRO REPOSITORIO DE GITHUB. diff --git a/doc/README.fr.md b/doc/README.fr.md index d9b378f3c..4ca1f1e94 100644 --- a/doc/README.fr.md +++ b/doc/README.fr.md @@ -17,7 +17,7 @@

    SiteBlogFAQPresse


    -*Read this document in other languages: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md), [Српски](doc/README.sr.md)* +*Read this document in other languages: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md), [Српски](README.sr.md)* ATTENTION: CETTE APP EST EN BETA, VOUS POUVEZ DONC RENCONTRER DES BUGS. SI C'EST LE CAS, OUVREZ UNE ISSUE DANS NOTRE DÉPÔT GITHUB EN REMPLISSANT LE MODÈLE D'ISSUE. diff --git a/doc/README.hi.md b/doc/README.hi.md index c87b3626c..ec9965be6 100644 --- a/doc/README.hi.md +++ b/doc/README.hi.md @@ -17,7 +17,7 @@

    वेबसाइटब्लॉगसाधारण सवाल-जवाबप्रेस


    -*Read this document in other languages: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md), [Српски](doc/README.sr.md)* +*Read this document in other languages: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md), [Српски](README.sr.md)* चेतावनी: यह एक बीटा संस्करण है, तो अगर आपको इसमें बग्स नज़र आते हैं, कृपया हमारे GitHub रिपॉज़िटरी के ज़रिए एक समस्या खोल दें। diff --git a/doc/README.it.md b/doc/README.it.md index c5af6516f..ec5361dc0 100644 --- a/doc/README.it.md +++ b/doc/README.it.md @@ -17,7 +17,7 @@

    SitoBlogFAQStampa


    -*Read this document in other languages: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md), [Српски](doc/README.sr.md)* +*Read this document in other languages: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md), [Српски](README.sr.md)* ATTENZIONE: QUEST'APP È IN BETA, QUINDI POTRESTI IMBATTERTI IN BUG. SE COSÌ FOSSE, APRI UN'ISSUE SUL NOSTRO REPOSITORIO GITHUB COMPILANDO IL TEMPLATE ISSUE. diff --git a/doc/README.ja.md b/doc/README.ja.md index abd697be7..fa26efa0d 100644 --- a/doc/README.ja.md +++ b/doc/README.ja.md @@ -17,7 +17,7 @@

    ウェブサイトブログFAQニュース


    -*Read this document in other languages: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md), [Српски](doc/README.sr.md)* +*Read this document in other languages: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md), [Српски](README.sr.md)* 注意: これはベータ版のため、バグが発生する可能性があります。もしバグが発生した場合、GitHub のリポジトリで Issue を開いてください。 diff --git a/doc/README.ko.md b/doc/README.ko.md index 9ef54299f..9ebc66be2 100644 --- a/doc/README.ko.md +++ b/doc/README.ko.md @@ -17,7 +17,7 @@

    WebsiteBlogFAQPress


    -*Read this document in other languages: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md), [Српски](doc/README.sr.md)* +*Read this document in other languages: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md), [Српски](README.sr.md)* 경고: 이 버전은 베타 버전이므로, 버그가 발생할 수도 있습니다. 만약 버그가 발생하였다면, 우리의 GitHub 저장소에서 Issue를 열람하여 주십시오. diff --git a/doc/README.pa.md b/doc/README.pa.md index 19d387de3..2a3ae69af 100644 --- a/doc/README.pa.md +++ b/doc/README.pa.md @@ -17,7 +17,7 @@

    ਵੈੱਬਸਾਈਟਬਲੌਗਆਮ ਸਵਾਲ ਜਵਾਬਪ੍ਰੈਸ


    -*Read this document in other languages: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md), [Српски](doc/README.sr.md)* +*Read this document in other languages: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md), [Српски](README.sr.md)* ਚੇਤਾਵਨੀ: ਇਹ ਐਪ ਬੀਟਾ ਵਿੱਚ ਹੈ, ਇਸ ਲਈ ਤੁਸੀਂ ਬੱਗ ਦਾ ਸਾਹਮਣਾ ਕਰ ਸਕਦੇ ਹੋ। ਜੇਕਰ ਤੁਸੀਂ ਅਜਿਹਾ ਕਰਦੇ ਹੋ, ਤਾਂ ਟੈਮਪਲੇਟ ਨੂੰ ਭਰ ਕੇ ਸਾਡੀ ਗਿਟਹੱਬ ਰਿਪੋਜ਼ਟਰੀ ਵਿੱਚ ਇੱਕ ਮੁੱਦਾ ਖੋਲ੍ਹੋ diff --git a/doc/README.pl.md b/doc/README.pl.md index e09e38943..5ba201eb0 100644 --- a/doc/README.pl.md +++ b/doc/README.pl.md @@ -17,7 +17,7 @@

    StronaBlogFAQPress


    -*Read this document in other languages: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md), [Српски](doc/README.sr.md)* +*Read this document in other languages: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md), [Српски](README.sr.md)* UWAGA: TO JEST WERSJA BETA, WIĘC MOŻESZ NAPOTKAĆ BŁĘDY. JEŚLI TAK SIĘ STANIE, OTWÓRZ NOWY "ISSUE" NA GITHUBIE. diff --git a/doc/README.pt_BR.md b/doc/README.pt_BR.md index a1ff260f2..850d03e89 100644 --- a/doc/README.pt_BR.md +++ b/doc/README.pt_BR.md @@ -18,7 +18,7 @@

    SiteBlogFAQPress


    -*Read this document in other languages: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md), [Српски](doc/README.sr.md)* +*Read this document in other languages: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md), [Српски](README.sr.md)* AVISO: ESTA É UMA VERSÃO BETA, PORTANTO, VOCÊ PODE ENCONTRAR BUGS. ENCONTROU ALGUM, ABRA UM ISSUE ATRAVÉS DO NOSSO REPOSITÓRIO GITHUB. diff --git a/doc/README.ro.md b/doc/README.ro.md index aa16fdfa5..11319b5a0 100644 --- a/doc/README.ro.md +++ b/doc/README.ro.md @@ -17,7 +17,7 @@

    WebsiteBlogFAQPresă


    -*Read this document in other languages: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md), [Српски](doc/README.sr.md)* +*Read this document in other languages: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md), [Српски](README.sr.md)* Atenţionare: ACEASTA ESTE O VERSIUNE BETA, AŞA CĂ S-AR PUTE SĂ ÎNTÂLNIŢI ERORI. DACĂ SE ÎNTÂMPLĂ ACEST LUCRU, DESCHIDEŢI UN ISSUE PRIN REPSITORY-UL NOSTRU GITHUB. diff --git a/doc/README.ru.md b/doc/README.ru.md index 9ede76bc8..a226b72a8 100644 --- a/doc/README.ru.md +++ b/doc/README.ru.md @@ -17,7 +17,7 @@

    СайтБлогЧЗВПресса


    -*Read this document in other languages: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md), [Српски](doc/README.sr.md)* +*Read this document in other languages: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md), [Српски](README.sr.md)* ВНИМАНИЕ: ЭТО ПРИЛОЖЕНИЕ НАХОДИТСЯ В СТАДИИ БЕТА, ПОЭТОМУ ВЫ МОЖЕТЕ ОБНАРУЖИТЬ ОШИБКИ. ЕСЛИ ЭТО СЛУЧИТСЯ, ОТКРОЙТЕ ВОПРОС В НАШЕМ РЕПОЗИТОРИИ GITHUB, ЗАПОЛНЯ ЕГО ПО ШАБЛОНУ. diff --git a/doc/README.ryu.md b/doc/README.ryu.md index b74f18f95..ce1a38bd9 100644 --- a/doc/README.ryu.md +++ b/doc/README.ryu.md @@ -17,7 +17,7 @@

    ウェブサイトブログFAQニュース


    -*ふかぬぎんぐっしゆむん: [English](../README.md), [Español](README.es.md), [हिन्दी](README.hi.md), [한국어](README.ko.md), [Soomaali](README.so.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [日本語](README.ja.md), [Română](README.ro.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [うちなーぐち](README.ryu.md), [Српски](doc/README.sr.md)* +*ふかぬぎんぐっしゆむん: [English](../README.md), [Español](README.es.md), [हिन्दी](README.hi.md), [한국어](README.ko.md), [Soomaali](README.so.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [日本語](README.ja.md), [Română](README.ro.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [うちなーぐち](README.ryu.md), [Српски](README.sr.md)* ちゅうい:くれーベータばんぬたみ、バグぬはっせいすがのうゆいがあいびーん。むしバグぬはっせいさーあい、GitHubぬリポジトリっしIssueふぃらちくぃみそーれー。 diff --git a/doc/README.so.md b/doc/README.so.md index 19b66286b..1e400b219 100644 --- a/doc/README.so.md +++ b/doc/README.so.md @@ -17,7 +17,7 @@

    Website-kaMaqaaladaSu'aalaha Aalaa La-iswaydiiyoWarbaahinta


    -*Read this document in other languages: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](doc/README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md), [Српски](doc/README.sr.md)* +*Read this document in other languages: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md), [Српски](README.sr.md)* DIGNIIN: MIDKAN, NOOCA APP-KA EE HADDA WALI TIJAABO AYUU KU JIRAA, SIDAA DARTEED CILLADO AYAAD LA KULMI KARTAA. HADAAD LA KULANTO, KA FUR ARIN SHARAXAYA QAYBTANADA ARRIMAHA EE GITHUB-KA. diff --git a/doc/README.tr.md b/doc/README.tr.md index 2f68ecffe..b2d4f2c56 100644 --- a/doc/README.tr.md +++ b/doc/README.tr.md @@ -17,7 +17,7 @@

    Web sitesiBlogSSSBasın


    -*Read this document in other languages: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](doc/README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md), [Српски](doc/README.sr.md)* +*Read this document in other languages: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md), [Српски](README.sr.md)* UYARI: BU SÜRÜM BETA SÜRÜMÜDÜR, BU NEDENLE HATALARLA KARŞILAŞABİLİRSİNİZ. HATA BULURSANIZ BU GITHUB DEPOSUNDA BUNU BİLDİRİN. diff --git a/doc/README.zh_TW.md b/doc/README.zh_TW.md index be98869b2..d5def26b2 100644 --- a/doc/README.zh_TW.md +++ b/doc/README.zh_TW.md @@ -17,7 +17,7 @@

    網站部落格FAQ媒體


    -*Read this document in other languages: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](doc/README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md), [Српски](doc/README.sr.md)* +*Read this document in other languages: [Deutsch](README.de.md), [English](../README.md), [Español](README.es.md), [Français](README.fr.md), [हिन्दी](README.hi.md), [Italiano](README.it.md), [한국어](README.ko.md), [Português Brasil](README.pt_BR.md), [Polski](README.pl.md), [ਪੰਜਾਬੀ ](README.pa.md), [日本語](README.ja.md), [Română](README.ro.md), [Soomaali](README.so.md), [Türkçe](README.tr.md), [正體中文](README.zh_TW.md), [অসমীয়া](README.asm.md), [うちなーぐち](README.ryu.md), [Српски](README.sr.md)* 警告:這是測試版本,可能會發生錯誤。如果遇到錯誤,請在我們的 GITHUB REPO 開 ISSUE 回報。 From d3c783832af3584af2fe926d1751f183e8e51714 Mon Sep 17 00:00:00 2001 From: TobiGr Date: Mon, 2 Oct 2023 16:16:33 +0200 Subject: [PATCH 139/172] Fix screenshot URLs in multiple READMEs --- doc/README.asm.md | 2 +- doc/README.de.md | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/doc/README.asm.md b/doc/README.asm.md index 1c7de43bf..010b72d82 100644 --- a/doc/README.asm.md +++ b/doc/README.asm.md @@ -27,7 +27,7 @@ ## স্ত্ৰীনশ্বট -[](fastlane/metadata/android/en-US/images/phoneScreenshots/shot_01.png)[](fastlane/metadata/android/en-US/images/phoneScreenshots/shot_02.png)[](fastlane/metadata/android/en-US/images/phoneScreenshots/shot_03.png)[](fastlane/metadata/android/en-US/images/phoneScreenshots/shot_04.png)[](fastlane/metadata/android/en-US/images/phoneScreenshots/shot_05.png)[](fastlane/metadata/android/en-US/images/phoneScreenshots/shot_06.png)[](fastlane/metadata/android/en-US/images/phoneScreenshots/shot_07.png)[](fastlane/metadata/android/en-US/images/phoneScreenshots/shot_08.png)[](fastlane/metadata/android/en-US/images/phoneScreenshots/shot_09.png)[](fastlane/metadata/android/en-US/images/phoneScreenshots/shot_10.png)[](fastlane/metadata/android/en-US/images/tenInchScreenshots/shot_11.png)[](fastlane/metadata/android/en-US/images/tenInchScreenshots/shot_12.png) +[](../fastlane/metadata/android/en-US/images/phoneScreenshots/shot_01.png)[](../fastlane/metadata/android/en-US/images/phoneScreenshots/shot_02.png)[](../fastlane/metadata/android/en-US/images/phoneScreenshots/shot_03.png)[](../fastlane/metadata/android/en-US/images/phoneScreenshots/shot_04.png)[](../fastlane/metadata/android/en-US/images/phoneScreenshots/shot_05.png)[](../fastlane/metadata/android/en-US/images/phoneScreenshots/shot_06.png)[](../fastlane/metadata/android/en-US/images/phoneScreenshots/shot_07.png)[](../fastlane/metadata/android/en-US/images/phoneScreenshots/shot_08.png)[](../fastlane/metadata/android/en-US/images/phoneScreenshots/shot_09.png)[](../fastlane/metadata/android/en-US/images/phoneScreenshots/shot_10.png)[](../fastlane/metadata/android/en-US/images/tenInchScreenshots/shot_11.png)[](../fastlane/metadata/android/en-US/images/tenInchScreenshots/shot_12.png) ### সমৰ্থিত সেৱাসমূহ diff --git a/doc/README.de.md b/doc/README.de.md index 296f835e8..b84fadeae 100644 --- a/doc/README.de.md +++ b/doc/README.de.md @@ -28,18 +28,18 @@ ## Screenshots -[](fastlane/metadata/android/en-US/images/phoneScreenshots/00.png) -[](fastlane/metadata/android/en-US/images/phoneScreenshots/01.png) -[](fastlane/metadata/android/en-US/images/phoneScreenshots/02.png) -[](fastlane/metadata/android/en-US/images/phoneScreenshots/03.png) -[](fastlane/metadata/android/en-US/images/phoneScreenshots/04.png) -[](fastlane/metadata/android/en-US/images/phoneScreenshots/05.png) -[](fastlane/metadata/android/en-US/images/phoneScreenshots/06.png) -[](fastlane/metadata/android/en-US/images/phoneScreenshots/07.png) -[](fastlane/metadata/android/en-US/images/phoneScreenshots/08.png) +[](../fastlane/metadata/android/en-US/images/phoneScreenshots/00.png) +[](../fastlane/metadata/android/en-US/images/phoneScreenshots/01.png) +[](../fastlane/metadata/android/en-US/images/phoneScreenshots/02.png) +[](../fastlane/metadata/android/en-US/images/phoneScreenshots/03.png) +[](../fastlane/metadata/android/en-US/images/phoneScreenshots/04.png) +[](../fastlane/metadata/android/en-US/images/phoneScreenshots/05.png) +[](../fastlane/metadata/android/en-US/images/phoneScreenshots/06.png) +[](../fastlane/metadata/android/en-US/images/phoneScreenshots/07.png) +[](../fastlane/metadata/android/en-US/images/phoneScreenshots/08.png)

    -[](fastlane/metadata/android/en-US/images/tenInchScreenshots/09.png) -[](fastlane/metadata/android/en-US/images/tenInchScreenshots/10.png) +[](../fastlane/metadata/android/en-US/images/tenInchScreenshots/09.png) +[](../fastlane/metadata/android/en-US/images/tenInchScreenshots/10.png) ## Unterstützte Dienste From 64e64f72f715931bdace4c2afe255d6d7c8d03eb Mon Sep 17 00:00:00 2001 From: Tobi Date: Mon, 2 Oct 2023 16:18:54 +0200 Subject: [PATCH 140/172] Update README.asm.md --- doc/README.asm.md | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/doc/README.asm.md b/doc/README.asm.md index 010b72d82..98253371e 100644 --- a/doc/README.asm.md +++ b/doc/README.asm.md @@ -27,8 +27,18 @@ ## স্ত্ৰীনশ্বট -[](../fastlane/metadata/android/en-US/images/phoneScreenshots/shot_01.png)[](../fastlane/metadata/android/en-US/images/phoneScreenshots/shot_02.png)[](../fastlane/metadata/android/en-US/images/phoneScreenshots/shot_03.png)[](../fastlane/metadata/android/en-US/images/phoneScreenshots/shot_04.png)[](../fastlane/metadata/android/en-US/images/phoneScreenshots/shot_05.png)[](../fastlane/metadata/android/en-US/images/phoneScreenshots/shot_06.png)[](../fastlane/metadata/android/en-US/images/phoneScreenshots/shot_07.png)[](../fastlane/metadata/android/en-US/images/phoneScreenshots/shot_08.png)[](../fastlane/metadata/android/en-US/images/phoneScreenshots/shot_09.png)[](../fastlane/metadata/android/en-US/images/phoneScreenshots/shot_10.png)[](../fastlane/metadata/android/en-US/images/tenInchScreenshots/shot_11.png)[](../fastlane/metadata/android/en-US/images/tenInchScreenshots/shot_12.png) - +[](../fastlane/metadata/android/en-US/images/phoneScreenshots/00.png) +[](../fastlane/metadata/android/en-US/images/phoneScreenshots/01.png) +[](../fastlane/metadata/android/en-US/images/phoneScreenshots/02.png) +[](../fastlane/metadata/android/en-US/images/phoneScreenshots/03.png) +[](../fastlane/metadata/android/en-US/images/phoneScreenshots/04.png) +[](../fastlane/metadata/android/en-US/images/phoneScreenshots/05.png) +[](../fastlane/metadata/android/en-US/images/phoneScreenshots/06.png) +[](../fastlane/metadata/android/en-US/images/phoneScreenshots/07.png) +[](../fastlane/metadata/android/en-US/images/phoneScreenshots/08.png) +

    +[](../fastlane/metadata/android/en-US/images/tenInchScreenshots/09.png) +[](../fastlane/metadata/android/en-US/images/tenInchScreenshots/10.png) ### সমৰ্থিত সেৱাসমূহ NewPipe এ বৰ্তমান এই সেৱাসমূহ সমৰ্থন কৰে: From ed33d1d4f7d13fe077d3237797ee23d803f1c42b Mon Sep 17 00:00:00 2001 From: Tobi Date: Mon, 2 Oct 2023 16:21:27 +0200 Subject: [PATCH 141/172] Fix images in README.sr.md --- doc/README.sr.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/README.sr.md b/doc/README.sr.md index 5c36f804b..320558fc9 100644 --- a/doc/README.sr.md +++ b/doc/README.sr.md @@ -116,17 +116,17 @@ NewPipe ради тако што преузима потребне податк - - + + - + - +
    LiberapayVisit NewPipe at liberapay.comDonate via LiberapayVisit NewPipe at liberapay.comDonate via Liberapay
    BitcoinBitcoin QR codeBitcoin QR code 16A9J59ahMRqkLSZjhYj33n9j3fMztFxnh
    BountysourceVisit NewPipe at bountysource.comVisit NewPipe at bountysource.com Check out how many bounties you can earn.
    From 5dee7a526225dcdbc703bf16e517609f63c921bd Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Thu, 5 Oct 2023 03:09:31 +0200 Subject: [PATCH 142/172] Translated using Weblate (Portuguese) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 100.0% (725 of 725 strings) Translated using Weblate (Portuguese) Currently translated at 100.0% (725 of 725 strings) Translated using Weblate (Serbian) Currently translated at 100.0% (725 of 725 strings) Translated using Weblate (Thai) Currently translated at 29.3% (213 of 725 strings) Translated using Weblate (Belarusian) Currently translated at 100.0% (725 of 725 strings) Translated using Weblate (Azerbaijani) Currently translated at 95.0% (689 of 725 strings) Translated using Weblate (Turkish) Currently translated at 100.0% (725 of 725 strings) Translated using Weblate (Russian) Currently translated at 100.0% (725 of 725 strings) Translated using Weblate (Serbian) Currently translated at 100.0% (725 of 725 strings) Translated using Weblate (ryu (generated) (ryu)) Currently translated at 100.0% (725 of 725 strings) Translated using Weblate (Odia) Currently translated at 100.0% (725 of 725 strings) Translated using Weblate (Sardinian) Currently translated at 100.0% (725 of 725 strings) Translated using Weblate (Estonian) Currently translated at 100.0% (725 of 725 strings) Translated using Weblate (Punjabi) Currently translated at 100.0% (725 of 725 strings) Translated using Weblate (Hindi) Currently translated at 100.0% (725 of 725 strings) Translated using Weblate (Hebrew) Currently translated at 100.0% (725 of 725 strings) Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (725 of 725 strings) Translated using Weblate (Chinese (Simplified)) Currently translated at 100.0% (725 of 725 strings) Translated using Weblate (Polish) Currently translated at 100.0% (725 of 725 strings) Translated using Weblate (Ukrainian) Currently translated at 100.0% (725 of 725 strings) Translated using Weblate (Indonesian) Currently translated at 100.0% (725 of 725 strings) Translated using Weblate (Arabic) Currently translated at 100.0% (725 of 725 strings) Translated using Weblate (Czech) Currently translated at 100.0% (725 of 725 strings) Translated using Weblate (Greek) Currently translated at 100.0% (725 of 725 strings) Translated using Weblate (Portuguese) Currently translated at 99.7% (723 of 725 strings) Translated using Weblate (Italian) Currently translated at 100.0% (725 of 725 strings) Translated using Weblate (Japanese) Currently translated at 100.0% (725 of 725 strings) Translated using Weblate (Serbian) Currently translated at 100.0% (725 of 725 strings) Translated using Weblate (Dutch) Currently translated at 100.0% (725 of 725 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (725 of 725 strings) Translated using Weblate (German) Currently translated at 100.0% (725 of 725 strings) Translated using Weblate (Odia) Currently translated at 100.0% (719 of 719 strings) Translated using Weblate (Estonian) Currently translated at 100.0% (719 of 719 strings) Translated using Weblate (Portuguese) Currently translated at 95.2% (685 of 719 strings) Translated using Weblate (Odia) Currently translated at 100.0% (719 of 719 strings) Translated using Weblate (Arabic (Libya)) Currently translated at 99.1% (713 of 719 strings) Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (719 of 719 strings) Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (719 of 719 strings) Translated using Weblate (Greek) Currently translated at 100.0% (719 of 719 strings) Translated using Weblate (Italian) Currently translated at 100.0% (719 of 719 strings) Translated using Weblate (ryu (generated) (ryu)) Currently translated at 100.0% (719 of 719 strings) Translated using Weblate (German) Currently translated at 81.3% (61 of 75 strings) Translated using Weblate (Japanese) Currently translated at 100.0% (719 of 719 strings) Translated using Weblate (French) Currently translated at 98.4% (708 of 719 strings) Translated using Weblate (German) Currently translated at 100.0% (719 of 719 strings) Translated using Weblate (Arabic (Libya)) Currently translated at 99.3% (714 of 719 strings) Translated using Weblate (Punjabi) Currently translated at 100.0% (719 of 719 strings) Translated using Weblate (Indonesian) Currently translated at 99.8% (718 of 719 strings) Translated using Weblate (French) Currently translated at 97.7% (703 of 719 strings) Translated using Weblate (German) Currently translated at 99.4% (715 of 719 strings) Translated using Weblate (Punjabi) Currently translated at 100.0% (719 of 719 strings) Translated using Weblate (Hindi) Currently translated at 100.0% (719 of 719 strings) Translated using Weblate (Hebrew) Currently translated at 100.0% (719 of 719 strings) Translated using Weblate (Chinese (Simplified)) Currently translated at 100.0% (719 of 719 strings) Translated using Weblate (Polish) Currently translated at 100.0% (719 of 719 strings) Translated using Weblate (Ukrainian) Currently translated at 100.0% (719 of 719 strings) Translated using Weblate (Arabic) Currently translated at 100.0% (719 of 719 strings) Translated using Weblate (Czech) Currently translated at 95.5% (687 of 719 strings) Translated using Weblate (Greek) Currently translated at 99.8% (718 of 719 strings) Translated using Weblate (Japanese) Currently translated at 100.0% (719 of 719 strings) Translated using Weblate (Serbian) Currently translated at 100.0% (719 of 719 strings) Translated using Weblate (Dutch) Currently translated at 100.0% (719 of 719 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (719 of 719 strings) Translated using Weblate (German) Currently translated at 99.3% (714 of 719 strings) Co-authored-by: Agnieszka C Co-authored-by: Ajeje Brazorf Co-authored-by: Alexthegib Co-authored-by: AudricV Co-authored-by: ButterflyOfFire Co-authored-by: Emin Tufan Çetin Co-authored-by: Eric Co-authored-by: Fjuro Co-authored-by: GET100PERCENT Co-authored-by: Hosted Weblate Co-authored-by: Ihor Hordiichuk Co-authored-by: Jeff Huang Co-authored-by: Linerly Co-authored-by: NEXI Co-authored-by: Nidi Co-authored-by: Peter Dave Hello Co-authored-by: Philip Goto Co-authored-by: Priit Jõerüüt Co-authored-by: Random Co-authored-by: Retrial Co-authored-by: Rex_sa Co-authored-by: Sergio Marques Co-authored-by: ShareASmile Co-authored-by: TobiGr Co-authored-by: Vasilis K Co-authored-by: VfBFan Co-authored-by: Yaron Shahrabani Co-authored-by: bowornsin Co-authored-by: gallegonovato Co-authored-by: kuragehime Co-authored-by: nautilusx Co-authored-by: zmni Co-authored-by: Макар Разин Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/de/ Translation: NewPipe/Metadata --- app/src/main/res/values-ar-rLY/strings.xml | 842 +++++++++++++++++- app/src/main/res/values-ar/strings.xml | 19 + app/src/main/res/values-az/strings.xml | 7 + app/src/main/res/values-be/strings.xml | 53 +- app/src/main/res/values-cs/strings.xml | 44 + app/src/main/res/values-de/strings.xml | 23 +- app/src/main/res/values-el/strings.xml | 19 + app/src/main/res/values-es/strings.xml | 19 + app/src/main/res/values-et/strings.xml | 44 + app/src/main/res/values-fr/strings.xml | 26 + app/src/main/res/values-he/strings.xml | 21 +- app/src/main/res/values-hi/strings.xml | 19 + app/src/main/res/values-in/strings.xml | 19 + app/src/main/res/values-it/strings.xml | 30 + app/src/main/res/values-ja/strings.xml | 19 + app/src/main/res/values-nl/strings.xml | 44 + app/src/main/res/values-or/strings.xml | 46 +- app/src/main/res/values-pa/strings.xml | 25 +- app/src/main/res/values-pl/strings.xml | 21 +- app/src/main/res/values-pt/strings.xml | 120 ++- app/src/main/res/values-ru/strings.xml | 44 + app/src/main/res/values-ryu/strings.xml | 19 + app/src/main/res/values-sc/strings.xml | 51 +- app/src/main/res/values-sr/strings.xml | 52 +- app/src/main/res/values-th/strings.xml | 6 +- app/src/main/res/values-tr/strings.xml | 64 +- app/src/main/res/values-uk/strings.xml | 19 + app/src/main/res/values-zh-rCN/strings.xml | 19 + app/src/main/res/values-zh-rTW/strings.xml | 19 + .../metadata/android/de/changelogs/994.txt | 15 + 30 files changed, 1692 insertions(+), 76 deletions(-) create mode 100644 fastlane/metadata/android/de/changelogs/994.txt diff --git a/app/src/main/res/values-ar-rLY/strings.xml b/app/src/main/res/values-ar-rLY/strings.xml index 1fd5b15c9..2b18bb238 100644 --- a/app/src/main/res/values-ar-rLY/strings.xml +++ b/app/src/main/res/values-ar-rLY/strings.xml @@ -2,11 +2,11 @@ استخدم مشغل فيديو خارجي مشاركة مع - اعدادات + الإعدادات بحث تنزيل ملف البث تحميل - مشاركه + إعادة النشر فتح في نافدة منبثقة افتح في المتصفح إلغاء @@ -14,5 +14,841 @@ لم يتم العثور على مشغل بث (يمكنك تثبيت VLC لتشغيله). لم يتم العثور على مشغل بث. يرجى تثبيت VLC؟ تم النشر في %1$s - انقر على \"بحث\" للبدء + اضغط على عدسة المكبرة للبدء. + جودة الصورة + لا تتوفر تدفقات فيديو للاعبين الخارجيين + تعطيل تحديد النص في الوصف + + + + + + + + + زر الإجراء الثاني + الافتراضي + الفيديوهات + إلغاء + تطبيق مجاني خفيف البث على أندرويد. + التاريخ + إيقاف التحميل مؤقتًا + قم بقص الصورة المصغرة للفيديو الموضحة في الإشعار من نسبة العرض إلى الارتفاع 16: 9 إلى 1: 1 + التحديثات + تعليق مثبت + إزالة ما تمت مشاهدته + استرد + قم بتشغيل \"وضع تقييد المحتوى\" في يوتيوب + + + + + + + + + حذف سجل المشاهدة بالكامل؟ + تشغيل بواسطة كودي + تم حذف عنصر واحد. + ضع في اعتبارك أن هذه العملية يمكن أن تكون مكلفة اذا كنت تستخدم بيانات اشتراك انترنت. +\n +\nهل تريد الاستمرار؟ + إغلاق + يأخذ مشروع NewPipe خصوصيتك على محمل الجد. لذلك، لا يجمع التطبيق أي بيانات دون موافقتك. +\nتوضح سياسة خصوصية NewPipe بالتفصيل البيانات التي يتم إرسالها وتخزينها عند إرسال تقرير الأعطال. + + لاشيء مُحدّد + واحدة محددة + إثنتان محدَّدتان + %d محددة + %d محددة + %d محددة + + لا يوجد بث متاح للتنزيل + هل تريد استعادة الإعدادات الافتراضية؟ + تحميل المحتوى المطلوب + إضافة نموذج + تراخيص الجهات الخارجية + حذف كل مواقف التشغيل + عن التطبيق والأسئلة الشائعة + استيراد الاشتراكات أو تصديرها من القائمة المكونة من 3 نقاط + الملفات المحملة + لا يوجد مثل هذا الملف/مصدر المحتوى + الأكثر إعجابًا + بليون + تعذر تحميل موجز \'%s\'. + ؟ + التحقق من وجود تحديثات + مثيلات خوادم پيرتيوب + +100 فيديو + ألف + مثيل الخادم موجود بالفعل + طلب تأكيد قبل مسح قائمة الانتظار + المشتركون + تمت مشاهدتها جزئيا + إضافة إلى + رابط غير مدعوم + تبرَّع + الحصول على إشعار + إذاعة + + لا تنزيل اكتَمَل + اكتَمَل تنزيل واحد + تنزيلان اكتَمَلَا + %s تنزيلات اكتَمَلت + %s تنزيلًا اكتَمَل + %s تنزيل اكتَمَل + + سرعة الأداء + إزالة الإشارة المرجعية + تم إنشاء قائمة التشغيل + وحدة التخزين الخارجية غير متوفرة + عرض المعلومات + الشائعة + تم إلغاء الاشتراك في القناة + تخزين طلبات البحث محليًّا + تلوين الإشعارات + توليد تلقائي + لا يمكن التحقق من صحة المثال + عرض خيار التشغيل بواسطة كودي + الوضع السريع + إظهار الموجزات التالية + معظم الأحرف الخاصة + إزالة جميع بيانات صفحات الويب المخزنة مؤقّتًا + محو سجل البحث + إظهار تفاصيل القناة + + لا مُشاهِد + مُشاهِد واحد + مُشاهِدان + %s مُشاهِدين + %s مُشاهِدًا + %s مُشاهِد + + عرض تلميح عند الضغط على زر استخدام المشغل الخلفي أو النافذة المنبثقة في صفحة تفاصيل الفديو + نعم، ومقاطع الفيديو التي تمت مشاهدتها جزئيًا + انتهى وقت الاتصال + غير معروف + تشغيل تلقائي + الإجراء الافتراضي عند فتح المحتوى — %s + إعدادات الصوت + إشعارات أحداث البث الجديدة + الحد الأقصى لعدد المحاولات قبل إلغاء التحميل + تفضيل قائمة التشغيل + الألسنة التي سيتم عرضها على صفحات القناة + إزالة التكرارات؟ + تعليقك (باللغة الإنجليزية): + تصدير إلى + حساب التجزئة + إظهار/إخفاء الموجزات + مِن الأفضل فتحه بـ + الخصوصيّة + لا يمكن الكتابة فوق الملف + الفيديوهات + اسحب لإعادة ترتيب + إظهار \"تعطل المشغل\" + يمكنك الآن تحديد نص داخل الوصف. لاحظ أن الصفحة قد تومض وقد لا تكون الروابط قابلة للنقر أثناء وضع التحديد. + تم وضع التالي على قائمة الانتظار + اسحب العناصر لإزالتها + معلومات: + حساب منشئ المحتوى قد تم إنهائه. +\nلن يتمكن NewPipe من تحميل هذه الخلاصة في المستقبل. +\nهل تريد إلغاء الاشتراك من هذه القناة؟ + تصغير إلى مشغل منبثق + تم إغلاق NewPipe أثناء العمل على الملف + مشغل الخلفية + وصفي + تذكر خصائص النوافذ المنبثقة + الإبلاغ عن طريق البريد الإلكتروني + عذرًا، لم ينبغِ أن يحدث ذلك. + إنشاء قائمة تشغيل جديدة + حدث خطأٌ ما: %1$s + لم يتم العثور على نتائج + فتح الموقع + + + + + + + + + وضع الجهاز اللوحي + تعذر التعرف على الرابط. فتح باستخدام تطبيق آخر؟ + تم مسح ملفات تعريف الارتباط reCAPTCHA + التفاصيل + تشغيل قائمة الانتظار + تعيين كصورة مصغرة لقائمة التشغيل + العدد الأقصى للمحاولات + عذرًا، حدث خطأ ما. + عرض على GitHub + التفاصيل: + تردد الصوت + هل تعتقد أن تحميل التغذية بطيءٌ جدًا؟ إذا كان الأمر كذلك، فحاول تمكين التحميل السريع (يمكنك تغييره في الإعدادات أو بالضغط على الزر أدناه). +\n +\nيقدم NewPipe استراتيجيتين لتحميل الخلاصة: +\n• جلب قناة الاشتراك بأكملها، وهي بطيئة ولكنها كاملة. +\n• استخدام نقطة نهاية خدمة مخصصة، وهي سريعة ولكنها عادةً لا تكتمل. +\n +\nالفرق بين الاثنين هو أن العنصر السريع عادة ما يفتقر إلى بعض المعلومات، مثل مدة العنصر أو نوعه (لا يمكن التمييز بين مقاطع الفيديو المباشرة والأخرى العادية) وقد يعيد عناصر أقل. +\n +\nيوتيوب هو مثال على الخدمة التي تقدمها هذه طريقة سريعة مع تغذية RSS الخاصة بها. +\n +\nلذا فإن الاختيار يتلخص في ما تفضله: السرعة أو المعلومات الدقيقة. + تم حذف الملف + تنزيل + صفحة القناة + تصدير السجل، وقوائم تشغيل، والإعدادات، والاشتراكات + هل تريد حذف قائمة التشغيل هذه؟ + اللغة الإفتراضية للمحتوى + جاري المعالجة ... قد يستغرق لحظة + قراءة الرخصة + ألسنة القنوات + معاينة مصغرة على شريط التمرير + ما الجديد + آخر تحديث للموجز: %s + الخطأ + زر الإجراء الخامس + جديد وساخن + استعمال التقديم السريع الغير دقيق + التنزيل + امنح الإذن بالعرض فوق التطبيقات الأخرى + داخلي + مستوى الصوت + إزالة التكرارات + تبديل الكل + فشلت المعالجة الاولية + انقر للحصول على التفاصيل + اختر الاقتراحات التي تريد إظهارها عند البحث + إنشاء + الحروف والأرقام + هل تقصد \"%1$s\"؟ + عناصر الموجز الجديدة + المميزة + عرض المحتوى الذي يُحتمل أن يكون غير مناسب للأطفال لأن له حدًا عمريًا (مثل 18+) + بدأ التشغيل في الخلفية + ستتغير اللغة بمجرد إعادة تشغيل التطبيق + الفديوهات القصيرة + قوائم التشغيل + تنظيف + اختيار مثيل + كلها + مجموعات القنوات + جارٍ معالجة الموجز… + + لا فيديو + فيديو واحد + فيديوهاتان + %s فيديوهات + %s فيديوهات + %s فيديو + + جودة منخفضة (أصغر) + إظهار خطأ + عرض دقّات أعلى + تحتوي قوائم التشغيل رمادية اللون بالفعل على هذا العنصر. + تمت إضافتها إلى قائمة التشغيل + + + + + + + + + تقرير على GitHub + أسود + بث جديد + معرفك, soundcloud.com/هويتك + ضغط مطول للإدراج الى قائمة الانتظار + خاص + اغلق التطبيق قسريا + تعذر استيراد الاشتراكات + إيقاف مؤقت + تعذر تحميل التعليقات + اقتراحات البحث عن بعد + استخدم ميزة فك ترميز وحدة فك التشفير الاحتياطية في ExoPlayer + يلغي السجل الحالي والاشتراكات وقوائم التشغيل والإعدادات (اختياريًا) + تعطل التطبيق / واجهة المستخدم + إعادة التسمية + لم يتبقى مساحة في الجهاز + تعذر إعداد قائمة التنزيل + اختر مجلد التنزيل لملفات الفيديو + تم تعطيل الإشعارات + هل تريد حذف هذه المجموعة؟ + المظهر + تشغيل + يحذف تاريخ البحث عن الكلمات الرئيسية + التنبيهات المتعلقة بالإبلاغ عن الأخطاء + نسخة احتياطية + حدث خطأ للمشغل غير قابل للاسترداد + زر الإجراء الرابع + القادمة + [غير معروف] + الحُلّة الليلية + داكن + المحتوى الإفتراضي حسب البلد + رافع الصورة الرمزية المصغرة + بدون + استمر عند إنهاء قائمة التشغيل (الغير المتكررة) من خلال إلحاق التدفق المرتبط + ملء الشاشة + لم يُختر أي اشتراك + + لا مشارك + مٌشارِك واحد + مُشارِكان + %s مشارِكين + %s مشارِكون + %s مشارك + + جلب البيانات الوصفية… + إظهار مؤشرات الصور + انقر للتنزيل %s + تعطيل الوضع السريع + , + صفحة قائمة التشغيل + تبديل تدوير الشاشة + تحديث NewPipe متاح! + تم حذف سجل البحث + قم بإيقاف التشغيل لإخفاء مربعات المعلومات الوصفية بمعلومات إضافية حول منشئ البث أو محتوى البث أو طلب البحث + إشعارات لتقدم تجزئة الفيديو + تحطيم المشغل + الصوت + بدء التنزيلات + مشترك + لا يمكن إنشاء المجلد الوجهة + يتم تخزين الملفات الصوتية التي تم تنزيلها هنا + لا شيء + الإطلاع على سياسة الخصوصية + يوفر YouTube \"وضع تقييد المحتوى\" الذي يخفي المحتوى المحتمل للكبار + عطّله لإخفاء التعليقات + واجه NewPipe خطأ، اضغط للتقرير + الكشك الافتراضي + اقتراحات البحث + تسريع إلى الأمام أثناء الصمت + إدارة بعض إعدادات ExoPlayer. تتطلب هذه التغييرات إعادة تشغيل المشغل لتصبح سارية المفعول + تمت إضافة وقت (أوقات) مكررة %d + فقط بعض الأجهزة تدعم تشغيل مقاطع فيديو 2K/4K + استيراد قاعدة البيانات + جودة منخفضة + موضع الألسنة الرئيسية + استخدم مشغل صوت خارجي + تعذر تغيير حالة الاشتراك + أحذف + فصول + استخدام منتقي مجلد النظام (SAF) + متوفر في بعض الخدمات، وعادةً ما يكون أسرع بكثير ولكن قد يُرجع كمية محدودة من العناصر وغالبًا ما تكون معلومات غير مكتملة (مثلًا بدون مدة أو نوع عنصر أو حالة مباشرة) + اجعل أندرويد يخصص لون الإشعار وفقا للّون الرئيسي في الصورة المصغرة (لاحظ أن هذا غير متوفر على جميع الأجهزة) + يتم التشغيل في الخلفية + الخادم لا يقوم بإرسال البيانات + سياسة خصوصية NewPipe + طلب اختبار الكابتشا مطلوب + إذا كنت تواجه مشكلة في استخدام التطبيق ، فتأكد من مراجعة هذه الإجابات للأسئلة الشائعة! + التحميلات + هل تريد إزالة جميع التدفقات المكررة في قائمة التشغيل هذه؟ + قد تتسبب مراقبة تسرب الذاكرة في عدم استجابة التطبيق عند تفريغ السجلات + تم فقد التقدم بسبب حذف الملف + التسمية + الانتقال إلى وضع ملئ الشاشة + لا يمكن الاتصال بالخادم + إظهار تسرب الذاكرة + + صفر ثانية + ثانية واحدة + ثانيتان + %d ثوانٍ + %d ثانية + %d ثانية + + سيتم سؤالك عن مكان حفظ كل تنزيل. +\nتمكين منتقي مجلد النظام (SAF) إذا كنت تريد التنزيل إلى بطاقة SD خارجية + استئناف التشغيل + جودة غير معروفة + هذا المحتوى غير متوفر في بلدك. + خطأ في الشبكة + محتوى الشاشة الرئيسية + إيقاف + الوسوم + المضيف + ابحث عن مثيلات الخوادم التي تناسبك على %s + مطلوب اتصال الشبكة + تشغيل التحقق من وجود تدفقات جديدة + دون مشاهدات + بدأ التشغيل في نافذة منبثقة + قائمة انتظار تلقائيّة + غير محمل: %d + قائمة الانتظار + هذا الفيديو مقيد بالفئة العمرية. +\nنظرًا لسياسات YouTube الجديدة المتعلقة بمقاطع الفيديو المقيدة بالفئة العمرية، لا يمكن لـ NewPipe الوصول إلى أي من تدفقات الفيديو الخاصة به، وبالتالي لا يتمكن من تشغيلها. + إضافة إلى قائمة التشغيل + القنوات + لا تظهر + أدخل عنوان للمثيل + ماذا:\\nطلب:\\nلغة المحتوى:\\nبلد المحتوى:\\nلغة التطبيق:\\nالخدمات:\\nتوقيت جرينتش:\\nالحزمة:\\nالإصدار:\\nOS نسخة: + يزيل الصوت في بعض الجودات + جلب ألسنة القنوات + جودة عالية (أكبر) + أسئلة مكررة + لم يتم تعيين مجلد التحميل، الرجاء اختيار مجلد التحميل الافتراضي الآن + عتبة تحديث الموجز + يمكنك اختيار نسقك الليلي المفضل أدناه + أنت تقوم بتشغيل أحدث إصدار من NewPipe + احذف + رفض + ابدأ + تحليل + إظهار الوصف + مرة واحدة فقط + الصور الرمزية + معدل البحث + قم بتمكين هذا الخيار إذا كانت لديك مشكلات في تهيئة وحدة فك التشفير ، والتي تعود إلى أجهزة فك التشفير ذات الأولوية الأقل إذا فشلت تهيئة وحدات فك التشفير الأولية. قد ينتج عن ذلك أداء تشغيل ضعيف مقارنة باستخدام وحدات فك التشفير الأساسية + تم محو ذاكرة التخزين المؤقتّة للبيانات الوصفيّة + وضع علامة تمت مشاهدته + اجراء الإيماءة اليمنى + الرموز المسموح بها في أسماء الملفات + %1$s %2$s + آخر ما تم تشغيله + استخدم دائمًا الحل البديل لإعداد سطح إخراج فيديو ExoPlayer + البث التالي + تم تعطيل نفق وسائل الإعلام عن طريق التقصير على جهازك لأن نموذج جهازك معروف بأنه لا يدعمه. + الصور الرمزية للقناة الفرعية + بث مباشر + هل تريد أيضا استيراد الإعدادات؟ + امسح البيانات الوصفيّة المخزّنة مؤقّتًا + حذف الملفات المحملة + يقوم هذا الحل البديل بتحرير وإعادة إنشاء نماذج برامج ترميز الفيديو عند حدوث تغيير في السطح، بدلا من تعيين السطح إلى برنامج الترميز مباشرة. تم استخدام هذا الإعداد بالفعل بواسطة ExoPlayer على بعض الأجهزة التي تعاني من هذه المشكلة ، وهذا الإعداد له تأثير فقط على Android 6 والإصدارات الأحدث +\n +\nقد يؤدي تمكين هذا الخيار إلى منع أخطاء التشغيل عند تبديل مشغل الفيديو الحالي أو التبديل إلى وضع ملء الشاشة + موافق + تتبّع مقاطع الفيديو التي تمّت مشاهدتها + لم يتم العثور على أي بث صوتي + تم تغيير الصورة المصغرة لقائمة التشغيل. + توقف + فاتح + التاريخ + تشغيل في وضع منبثق + كتم الصوت + هذا الإذن مطلوب +\nللفتح في وضع النافذة المنبثقة + الموجز + ستتم إزالة مقاطع الفيديو التي تمت مشاهدتها قبل وبعد إضافتها إلى قائمة التشغيل. +\nهل أنت واثق؟ لا يمكن التراجع عن هذا! + عدم الإعجاب + مشاهدة على الموقع + هذا الخيار متاح فقط إذا تم تحديد %s للسمة + إعادة المحاولة + المشغل + الفنانين + بدأ التنزيل + يجب أن يكون هناك مسار صوتي موجود بالفعل في هذا البث + هذا المحتوى خاص، لذلك لا يمكن دفقه أو تنزيله بواسطة NewPipe. + الدقة الافتراضية للنوافذ المنبثقة + تم إفراغ مساحة ذاكرة التخزين المؤقتة الخاصة بالصور + إشعار الإبلاغ عن الأخطاء + لغة التطبيق + تحميل الموجز… + التحقق يدويا من وجود إصدارات جديدة + لم يتم العثور على مدير ملفات مناسب لهذا الإجراء. +\nالرجاء تثبيت مدير ملفات متوافق مع إطار عمل الوصول إلى التخزين + إظهار خيار تعطل عند استخدام المشغل + يرجى مراجعة ما إذا توجد بالفعل مشكلة تناقش التحطم الموجود بالفعل. عند إنشاء تذاكر مكررة، فإنك تستغرق منا وقتًا يمكن أن نقضيه في إصلاح الخطأ الفعلي. + فتح قائمة انتظار التسغيل + قم بتحرير كل إشعار أدناه من خلال النقر عليه. حدد ما يصل إلى ثلاثة منها لتظهر في الإشعار المضغوط باستخدام مربعات الاختيار الموجودة على اليمين + ماذا حدث: + ترجمات نصية توضيحية + الصورة الرمزية للقناة + جلب من موجز مخصص عندما يكون متاحًا + لا يمكن أن يكون اسم الملف فارغًا + حدد المسار الصوتي الأصلي بغض النظر عن اللغة + الإشعارات + الفيديو والصوت + جديد + إزالة مقاطع الفيديو التي تمت مشاهدتها؟ + الالبومات + المسارات + حدد مثيلات PeerTube المفضلة لديك + إشعار المشغل + خاصية التقديم الغير دقيق تسمح للمشغل بالقفز خلال الفديو بشكل أسرع مع دقة قفز أقل. خاصية القفز ل5، 15 او 25 لا تعمل مع القفز الغير دقيق + متوقف + نافذة منبثقة + قم باستيراد ملف تعريف SoundCloud عن طريق كتابة عنوان URL أو معرفك: +\n +\n1. تمكين \"وضع سطح المكتب\" في متصفح الويب (الموقع غير متاح للأجهزة المحمولة) +\n2. انتقل إلى عنوان URL هذا: %1$s +\n3. تسجيل الدخول عندما يطلب منك +\n4. انسخ عنوان URL للملف الشخصي الذي تمت إعادة توجيهك إليه. + اختر قائمة تشغيل + الحد العمري + لا يوجد تطبيق على جهازك يمكنه فتح هذا + يُرجى الإنتظار… + تبديل الخدمة، المحدد حاليًا: + سجل المشاهدة + لا تقم بتحميل الصور + الإخطار بأحداث البث الجديدة من الاشتراكات + اسم الملف + الملف غير موجود أو الإذن بالقراءة أو الكتابة إليه غير موجود + عرض مقاطع الفيديو \"التالية\" و \"المشابهة\" + الوقت بعد التحديث الأخير قبل اعتبار الاشتراك قديمًا — %s + استرداد المشغل من الخطأ + عالية الجودة + حدد الجودة للمشغلين الخارجيين + أُعجب بها منشئ المحتوى + عن + عرض نتائج ل: %s + افتح باستخدام + هل تريد حذف هذا العنصر من سجل البحث؟ + الأكثر تشغيلا + عرض الوقت الأصلي على العناصر + استعادة مِن + الدقة الافتراضية + استئناف التشغيل + تقديم المحتوى + قد يؤدي التبديل من مشغل إلى آخر إلى استبدال قائمة الانتظار الخاصة بك + يتم تخزين ملفات الفيديو التي تم تنزيلها هنا + إشعار تجزئة الفيديو + حدد مسار الصوت للمشغلات الخارجية + استخدم الصورة المصغرة لكل من خلفية شاشة القفل والإشعارات + تراجع + تنسيق غير معروف + الألبومات + لا توجد تدفقات صوتية متاحة للمشغلات الخارجية + محلي + إعادة المحتوى + سيميتون + إعادة التشغيل + يوجد ملف بهذا الاسم مسبقاً + قم بإيقاف التشغيل لإخفاء وصف الفيديو والمعلومات الإضافية + صيغة الفيديو الافتراضية + زر الإجراء الثالث + لا يمكن التنزيل على بطاقة SD الخارجية. هل تريد إعادة تعيين موقع مجلد التنزيل؟ + تعذر تحميل كافة الصور المصغرة + التيارات ذات الصلة + لا يمكن استرداد هذا التنزيل + إظهار الاشتراكات غير المجمعة فقط + حذف محفوظات البثوث التي تم تشغيلها ومواقف التشغيل + في قائمة الانتظار + تمكين الوضع السريع + مدبلجة + اقتراحات البحث المحلية + اقتصاص الصورة المصغرة إلى نسبة العرض إلى الارتفاع 1:1 + تم تعطيل التعليقات + موقع الويب + سجل البحث + فتح الدرج + ∞ فيديو + الخادم لا يقبل التنزيل المتعدد، إعادة المحاولة مع @string/msg_threads = 1 + إعادة تعيين + تذكر آخر مكان وحجم للنافذة المنبثقة + تمت عملية التصدير + تعذر تحليل الموقع + الألسنة التي سيتم جلبها عند تحديث الموجز. ليس لهذا الخيار أي تأثير إذا تم تحديث القناة باستخدام الوضع السريع. + قم بإنشاء تنبيه بالخطأ + إشعارات لإصدار NewPipe الجديد + استعادة الضبط الافتراضي + المقاطعة على الشبكات المقيسة + هذا سوف يُزيل إعداداتك الحالية. + + لا مشاهدة + مشاهدة واحدة + مُشاهَدتان + %s مُشاهَدات + %s مُشاهَدةً + %s مُشاهَدة + + إستيراد + الأحداث + حذف مواقف التشغيل + زر الإجراء الأول + لاشيء + تلقائي (سمة الجهاز) + يتم الآن استخدام الألسنة الافتراضية بعد حدوث خطأ أثناء قراءة الألسنة المحفوظة + تعديل مشغل نص التسمية التوضيحية وأنماط الخلفية. يتطلب إعادة تشغيل التطبيق لتصبح التغييرات سارية المفعول + المحتوى غير متوفر + دائماً + حدد مسارًا صوتيًا يحتوي على أوصاف للأشخاص ضعاف البصر إذا كان ذلك متاحًا + لا حدود + مدة, تشغيل الفيديو: + محو سجل المشاهدة + إجراء الإيماءة اليسرى + لاتوجد فيديوهات + تنبيهات NewPipe + محو جميع الملفات التي تم تنزيلها من القرص؟ + اضغط على \"تم\" عند حلها + لا أحد يستمع + تكرار + إضافة إلى قائمة الانتظار + يقوم نيوبايب بالتنزيل + النوعية متوسطة + يسمح \"Storage Access Framework\" بالتنزيل على بطاقة SD خارجية + تنبيه: تعذر استيراد كافة الملفات. + مجلد الصوتيات المحفوظة + الإشارات المرجعية + حذف كل مواقف التشغيل؟ + تفضل الصوت الوصفي + خلط + بدء التشغيل تلقائياً — %s + إغلاق الدرج + هذا المحتوى ليس مدعومًا من قبل NewPipe. +\n +\nنأمل أن يكون مدعومًا في التحديثات القادمة. + + + + + + + + + المشغل المنبثق + الصورة الرمزية للرفع + التوقيع + محتوى مقيد للبالغين + متابعة التشغيل بعد المقاطعات (مثل المكالمات الهاتفية) + عملية الاستعادة جارية … + قم بتغيير حجم الفاصل الزمني للتحميل على المحتويات التدريجية (حاليا %s). قد تؤدي القيمة المنخفضة إلى تسريع التحميل الأولي + تفضيل الصوت الأصلي + الإعجابات + خطأ + اختر مجلد التنزيل للملفات الصوتية + استيراد اشتراكات YouTube من Google takeout: +\n +\n1. انتقل إلى عنوان URL هذا: %1$s +\n2. تسجيل الدخول عند سؤالك +\n3. انقر على \"جميع البيانات المدرجة\"، ثم على \"إلغاء تحديد جميع\"، ثم حدد فقط \"الاشتراكات\" وانقر على \"موافق\" +\n4. انقر على \"الخطوة التالية\" ثم على \"إنشاء التصدير\" +\n5. انقر على زر \"تحميل\" بعد ظهوره +\n6. انقر على IMPORT FILE أدناه وحدد الملف البريدي تحميلها +\n7. [إذا فشل استيراد الرمز البريدي] استخراج ملف .csv (عادة تحت عنوان \"يوتيوب ويوتيوب الموسيقى / الاشتراكات / الاشتراكات.csv\")، انقر على IMPORT FILE أدناه وحدد ملف csv المستخرج + جارٍ التحميل + هذا مسار SoundCloud Go+، على الأقل في بلدك، لذلك لا يمكن دفقه أو تنزيله بواسطة NewPipe. + فقط على شبكة Wi-Fi + إظهار الصورة المصغرة + ضوابط سرعة التشغيل + رد الجميل + تم حذف سجل المشاهدة + سجل المشاهَدة و ذاكرة التخزين المؤقتة + النسبة المئوية + تحدي الكابتشا + ليس هناك مشترِكون + يتوفر هذا المحتوى فقط للمستخدمين الذين قاموا بالدفع، لذلك لا يمكن بثه أو تنزيله عبر NewPipe. + حديثة + تعذر تحديث الاشتراك + سيتم استبدال قائمة انتظار للمشغل النشط + التقسيم + اشتراك + أنشأها %s + الحرف الإستبدالي + وضع مظهر ”عرض القائمة“ + بدء تشغيل المشغل الرئيسي في وضع ملء الشاشة + تصغير عند تبديل التطبيق + الصوت : %s + خطوة + حل + %s يقدم هذا السبب: + الدفق المحدد غير مدعوم من قبل المشغلون الخارجيون + عن تطبيق نيوپايپ + تسريع إلى الأمام/-ترجيع وقت البحث + تم رفضها من قبل النظام + ليس هناك تعليقات + مليون + جاري التحقق من وجود تحديثات… + المحتوى + اسأل عن مكان التنزيل + معطل + خطأ في تحميل الخلاصة + الإخطارات حول التدفقات الجديدة للاشتراكات + لا توجد مشاهدة + الإنتقال إلى التشغيل في الخلفية + المستخدمين + القائمة + لا يمكن تشغيل هذا البث + امسح ملفات تعريف الارتباط reCAPTCHA + اللافتات + ساهم + الإجراء عند التبديل إلى تطبيق آخر من مشغل الفيديو الرئيسي — %s + قوائم التشغيل + عامة + قم بتعطيل نفق الوسائط إذا واجهت شاشة سوداء أو تقطيع اثناء تشغيل الفيديو. + يوجد ملف تحميل بهذا الاسم موجود مسبقاً + تلقائي + هل تريد محو سجل التنزيل، أم تريد حذف جميع الملفات التي تم تنزيلها؟ + أفضل دقة + فرز + الشبكة + استعادة آخر موقف تشغيل + تم إنهاء الحساب + اختر إيماءة للنصف الأيمن من شاشة المشغل + الحصول على المعلومات… + الكتابة فوق + نقل الملف أو حذفه + الأغاني + تطبيق Kore غير موجود. هل تريد تثبيته؟ + هنالك تحميل قيد التقدم بهذا الاسم + الإنتقال إلى الرئيسية + صيغة الصوت الافتراضية + حدث خطأ، انظر للإشعار + الفيديو + مفيد عند التبديل إلى بيانات الجوال، ولكن لا يمكن تعليق بعض التنزيلات + انقل محدد اللسان الرئيسي إلى الأسفل + LeakCanary غير متوفر + عدد المشتركين غير متاح + حدد الاشتراكات + الاشتراكات + NewPipe هو برنامج مفتوح المصدر وبحقوق متروكة: يمكنك استخدام الكود ودراسته وتحسينه كما شئت. وعلى وجه التحديد يمكنك إعادة توزيعه / أو تعديله تحت شروط رخصة GNU العمومية والتي نشرتها مؤسسة البرمجيات الحرة، سواء الإصدار 3 من الرخصة، أو (باختيارك) أي إصدار أحدث. + اعرض خيار لتشغيل الفيديو عبر مركز وسائط Kodi + قيد المعالجة + إعادة تسمية + لا يمكن إنشاء الملف + حد قائمة انتظار التنزيل + أي شبكة + فشل التنزيل + الافتراضي ExoPlayer + تنظيف تاريخ التحميل + هناك تنزيل معلق بهذا الاسم + انتهى + أُضيف مؤخرًا + يتم استبدال الرموز غير المسموح بها بهذه القيمة + لا شيء هنا سوى الصراصير + مُنشأة تلقائيًا (لم يتم العثور على رافع) + المسار الصوتي + مفيد ، على سبيل المثال ، إذا كنت تستخدم سماعة رأس بأزرار مادية مكسورة + المشغل الخارجي لا يدعم هذه الأنواع من الروابط + ستكون النصوص الأصلية من الخدمات مرئية في عناصر البث + الإنتقال إلى التشغيل في النافذة المنبثقة + تعذر العثور على الخادم + تقرير الأخطاء خارج دورة الحياة + البطاقة + حدد كشك + لا يوفر وضع الموجز السريع مزيدًا من المعلومات حول هذا الموضوع. + يرجى تحديد مجلد التنزيل لاحقا في الإعدادات + سيتم سؤالك عن مكان حفظ كل تنزيل + لاتوجد بثوث مباشرة + صفحة فارغة + أبدا + فشل النسخ إلى الحافظة + من أجل الامتثال للائحة الأوروبية العامة لحماية البيانات (GDPR)، فإننا نلفت انتباهك إلى سياسة خصوصية NewPipe. يرجى قراءتها بعناية. +\nويجب عليك قبولها لإرسال تقرير الأخطاء إلينا. + فرض الإبلاغ عن استثناءات Rx غير القابلة للتسليم خارج دورة حياة الجزء أو النشاط بعد التخلص منها + ضبط إشعار مشغل البث الحالي + تصدير قاعدة البيانات + إلغاء تعيين الصورة المصغرة الدائمة + تعليقات + تكبير + الصنف + تناسب مع الشاشة + إظهار مؤشّرات وضع التشغيل في القوائم + اختر جودة الصور وما إذا كنت تريد تحميل الصور على الإطلاق، لتقليل استخدام البيانات والذاكرة. تؤدي التغييرات إلى مسح ذاكرة التخزين المؤقت للصور الموجودة في الذاكرة وعلى القرص — %s + حجم الفاصل الزمني لتحميل التشغيل + حذف سِجل البحث بالكامل؟ + اللغة + السلوك + لا يوجد مثل هذا المجلد + شغِّل + إلغاء الإرتباط (قد يسبب تشويه) + امسح البيانات + لا توجد إشارات مرجعية لقائمة التشغيل بعدُ + يتم تطوير NewPipe من قبل متطوعين يقضون وقت فراغهم لتقديم أفضل تجربة لك. حان الوقت لرد المساعدة مع المطورين وجعل NewPipe أكثر و أفضل بينما يستمتعون بفنجان من القهوة. + إظهار التعليقات + تم نسخه إلى الحافظة + المزيد من الخيارات + وضع البث القادم تلقائيا في قائمة الإنتظار + الدعم + ملف مضغوط ZIP غير صالح + غير موجود + حدد موضوعك الليلي المفضل — %s + صفحة الكشك + + لا مُستمِع + مُستَمِع واحد + مُستمِعان + %s مُستَمِعين + %s مُستَمِعًا + %s مستمع + + غير مدرج + المؤتمرات + إستيراد ملف + إظهار خطأ snackbar + قم بزيارة موقع NewPipe لمزيد من المعلومات والمستجدات. + لم يتم الاشتراك في أي قناة بعد + لا تبدأ تشغيل مقاطع الفيديو في المشغل المصغر، ولكن قم بتدوير وضع ملء الشاشة مباشرة، إذا تم تأمين التدوير التلقائي. لا يزال بإمكانك الوصول إلى المشغل المصغر عن طريق الخروج من ملء الشاشة + تراخيص NewPipe + تحديث دائمًا + التراخيص + عملية التصدير جارية … + تصغير إلى مشغل الخلفية + تنبيهات مشغل NewPipe + تمَّت عملية الإستيراد + الصور المصغرة + تحميل تفاصيل البث… + إظهار تلميح \"اضغط للفتح\" + الحد من جودة الفيديو عند استخدام بيانات الهاتف المحمول + سيتم تشغيل تنزيل واحد في نفس الوقت + قبول + إعدادات ExoPlayer + تنبيه تحديث التطبيق + غير صامت + امسح ملفات تعريف الارتباط التي يخزنها NewPipe عند حل reCAPTCHA + نظرا لقيود مشغل ExoPlayer مدة التقديم تم ضبطها الى %d ثانية + أفضل ٥٠ + السطوع + تمكين تحديد نص في الوصف + شاهَدتَها بالكامل + بدون ترجمات نصية توضيحية + المواضع في القوائم + الملف + التحديثات + النظام الافتراضي + لا يتم عرض التدفقات التي لم يدعمها برنامج التنزيل بعد + لم يتم العثور على أي بث مرئي + وضع التالي على قائمة الانتظار + إظهار معلومات التعريف + اختر قناة + © %1$sبواسطة%2$sتحت%3$s + تعطيل نفق الوسائط + المسارات + اسم المجموعة فارغ + يتم دعم عناوين URL HTTPS فقط + المدة + لا يمكن تصدير الاشتراكات + لاتوجد بثوث + يمكنك تحديد ثلاثة إجراءات كحد أقصى لإظهارها في الإشعار المضغوط! + إذا كانت لديك أفكار؛ أو ترجمة، أو تغييرات تخص التصميم، أو تنظيف و تحسين الشفرة البرمجية، أو تعديلات عميقة عليها، فتذكر أنّ مساعدتك دائما موضع ترحيب. وكلما أتممنا شيئا كلما كان ذلك أفضل! + اختار الألسنة التي تودّ ظهورها على الصفحة الرئيسية + مجلد تحميل الفيديو + هذا الفيديو مقيد بالفئة العمرية. +\n +\nقم بتفيل \"%1$s\" في الإعدادات إذا كنت تريد رؤيته. + تجاهل أحداث ازرار الوسائط الأجهزة + اختر لسانًا + الصوت + تم حذف كل مواقف التشغيل + في الخلفية + القنوات + الرخصة + إلغاء الاشتراك + لقد اشتركت الآن في هذه القناة + بدءًا من Android 10، يتم دعم \"Storage Access Framework\" فقط + إنشاء اسم فريد + أظهر أشرطة ملونة لبيكاسو أعلى الصور تشير إلى مصدرها: الأحمر للشبكة والأزرق للقرص والأخضر للذاكرة + فشل الاتصال الآمن + يتوفر هذا الفيديو فقط لأعضاء YouTube Music Premium، لذلك لا يمكن بثه أو تنزيله من قبل NewPipe. + البث السابق + تشغيل الكل + السمة + أبلِغ + اختر إيماءة للنصف الأيسر من شاشة المشغل + نسخ التقرير مُنسق + مباشر + إظهار تنبيه للمطالبة بتحديث التطبيق عندما يتوفر إصدار جديد + السؤال دائماً + منجز + تقرير عن المشكلة + أُضيفَ إلى قائمة الانتظار + لم يتم العثور على مدير ملفات مناسب لهذا الإجراء. +\nيرجى تثبيت مدير ملفات أو محاولة تعطيل \"%s\" في إعدادات التنزيل + مشغل الفيديو + بواسطة %s + وصف + ريثما \ No newline at end of file diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index 980859710..6bfe11eaa 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -839,4 +839,23 @@ القنوات البث السابق مباشر + جودة الصورة + ؟ + جودة منخفضة + الصور الرمزية + الصور الرمزية للقناة الفرعية + لا تقم بتحميل الصور + عالية الجودة + النوعية متوسطة + الصورة الرمزية للرفع + اللافتات + اختر جودة الصور وما إذا كنت تريد تحميل الصور على الإطلاق، لتقليل استخدام البيانات والذاكرة. تؤدي التغييرات إلى مسح ذاكرة التخزين المؤقت للصور الموجودة في الذاكرة وعلى القرص — %s + الصور المصغرة + مشاركة عنوان القائمة + مشاركة العناوين + %1$s +\n%2$s + مشاركة قائمة التشغيل + شارك تفاصيل قائمة التشغيل مثل اسم قائمة التشغيل وعناوين الفيديو أو كقائمة بسيطة من عناوين URL للفيديو + - %1$s: %2$s \ No newline at end of file diff --git a/app/src/main/res/values-az/strings.xml b/app/src/main/res/values-az/strings.xml index d4b1076a1..e3de4f4d2 100644 --- a/app/src/main/res/values-az/strings.xml +++ b/app/src/main/res/values-az/strings.xml @@ -762,4 +762,11 @@ %1$s %2$s Əsas səhifə mövqeyi Əsas səhifə seçicini aşağıya köçür + Üst Məlumat Yüklənir… + Kanal səhifələrin əldə et + Avatarlar + Alt kanal avatarları + Axın yenilənərkən əldə edilən səhifələr.Kanal sürətli rejim istifadə edərək yenilənirsə, bu seçimin heç bir təsiri yoxdur. + Yükləyici avatarları + Miniatürlər \ No newline at end of file diff --git a/app/src/main/res/values-be/strings.xml b/app/src/main/res/values-be/strings.xml index f13a7093f..38905ed7f 100644 --- a/app/src/main/res/values-be/strings.xml +++ b/app/src/main/res/values-be/strings.xml @@ -331,7 +331,7 @@ Пры згортванні плэера Дзеянне пры пераключэнні са стандартнага плэера на іншае прыкладанне — %s Нічога не рабіць - Фонавы плэер + Згарнуць у фонавы плэер Плэер у акне Адпісацца Абярыце ўкладку @@ -623,7 +623,7 @@ Дублікат дададзены %d раз LeakCanary недаступны Паказаць уцечкі памяці - Адключыце мультымедыйнае тунэляванне, калі ў вас з\'яўляецца чорны экран або заіканне падчас прайгравання відэа + Адключыце мультымедыйнае тунэляванне, калі ў вас з\'яўляецца чорны экран або заіканне падчас прайгравання відэа. Не ўдалося скапіраваць у буфер абмену Папка спампоўкі пакуль не ўстаноўлена, выберыце папку спампоўкі па змаўчанні Часта задаюць пытанні @@ -781,4 +781,53 @@ Гэты абыходны шлях вызваляе і паўторна стварае відэакодэкі, калі адбываецца змяненне паверхні, замест таго, каб усталёўваць паверхню непасрэдна для кодэка. ExoPlayer ужо выкарыстоўваецца на некаторых прыладах з гэтай праблемай, гэты параметр мае ўплыў толькі на прыладах з Android 6 і вышэй \n \nУключэнне гэтай опцыі можа прадухіліць памылкі прайгравання пры пераключэнні бягучага відэаплэера або пераключэнні ў поўнаэкранны рэжым + Якасць выявы + Відэа + \? + Падпісчыкі + Якія ўкладкі паказаны на старонках канала + Падзяліцца спісам URL-адрасоў + Падзяліцца назвамі + %1$s +\n%2$s + Ўкладкі канала + Shorts + Загрузка метаданых… + Змяніць арыентацыю экрана + Нізкая якасць + Размяшчэнне асноўных укладак + Пераключыцца ў поўнаэкранны рэжым + Атрыманне ўкладак канала + Аватары + Наступны стрым + Медыятунэляванне было адключана па змаўчанні на вашай прыладзе, таму што ваша мадэль не падтрымлівае яго. + Аватары падканалаў + Адкрыйце чаргу прайгравання + Не загружаць выявы + Высокая якасць + Аб канале + Падзеліцца падборкай + Пераматаць наперад + Альбомы + Пераматаць назад + Паўтарыць + Атрыманыя ўкладкі пры абнаўленні стужкі. Гэты параметр не прымяняецца, калі канал абнаўляецца ў хуткім рэжыме. + Падзяліцца падборкай з такімі дэталямі, як назва спіса прайгравання і назвы відэа, або проста спіс URL-адрасоў відэа + Сярэдняя якасць + Загрузнік аватараў + Банеры + Падборкі + - %1$s: %2$s + Перамясціць селектар галоўнай укладкі ўніз + Няма жывых трансляцый + Выберыце якасць выявы і ці спампоўваць выявы ўвогуле, каб паменшыць выкарыстанне дадзеных і памяці. Змены ачышчаюць кэш малюнкаў як у памяці, так і на дыску - %s + Прайграць + Іншыя опцыі + Мініяцюры + Дарожкі + Працягласць + Няма трансляцый + Каналы + Папярэдні стрым + Жывая трансляцыя \ No newline at end of file diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index d8ff56daf..5c3997d45 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -775,4 +775,48 @@ Na vašem zařízení byl zakázán media tunelling, protože model vašeho zařízení jej nepodporuje. Žádná videa Žádné živé přenosy + Načítání metadat… + Karty kanálu k načtení + Karty, které načíst při aktualizaci odběrů. Tato možnost nemá žádný účinek, pokud je kanál aktualizován pomocí rychlého režimu. + Nahrané avatary + Náhledy + Kvalita obrázků + Videa + \? + Odběratelé + Které karty mají být zobrazeny na stránkách kanálů + Sdílet URL seznamu + Sdílet s názvy + %1$s +\n%2$s + Karty kanálu + Shorts + Přepnout orientaci obrazovky + Nízká kvalita + Přepnout celou obrazovku + Avatary + Další stream + Subkanálové avatary + Otevřít frontu přehrávání + Nenačítat obrázky + Vysoká kvalita + Informace + Sdílet playlist + Přetočení vpřed + Alba + Přetočení zpět + Znovu přehrát + Sdílejte playlist s podrobnostmi jako je jeho název a názvy videí, nebo jako jednoduchý seznam adres videí + Střední kvalita + Bannery + Playlisty + - %1$s: %2$s + Zvolte si kvalitu obrázků a volbu, zda se mají obrázky vůbec načítat, abyste snížili spotřebu dat a paměti. Změny vymažou mezipaměť obrázků v paměti i na disku — %s + Přehrát + Další možnosti + Skladby + Trvání + Kanály + Předchozí stream + Živě \ No newline at end of file diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 918fbe3af..2fa308a00 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -27,7 +27,7 @@ Video und Audio Bevorzugte Sprache des Inhalts Video abspielen, Dauer: - Avatarbild des Benutzers + Profilbild des Benutzers Gefällt mir nicht Gefällt mir Externen Video-Player verwenden @@ -598,7 +598,7 @@ Lösen Download hat begonnen Du kannst dein bevorzugtes Nachtdesign unten auswählen - Wähle dein bevorzugtes Nachtdesign – %s + Wähle dein bevorzugtes Nachtdesign — %s Automatisch (Gerätedesign) Nachtdesign Kanaldetails anzeigen @@ -787,4 +787,23 @@ Mehr Optionen Dauer Vorheriger Stream + Bildqualität + \? + Geringe Qualität + Bilder nicht laden + Hohe Qualität + Mittlere Qualität + Banner + Vorschaubilder + Profilbilder + Profilbilder des Unterkanals + Profilbilder des Benutzers + Wähle die Bildqualität und ob überhaupt Bilder geladen werden sollen, um die Daten- und Speichernutzung zu reduzieren. Änderungen löschen sowohl den Bilder-Cache im Speicher als auch auf der Festplatte — %s + URL-Liste teilen + Mit Titeln teilen + %1$s +\n%2$s + Wiedergabeliste teilen + Teile die Wiedergabeliste mit Details wie dem Namen der Wiedergabeliste und den Videotiteln oder als einfache Liste von Video-URLs + - %1$s: %2$s \ No newline at end of file diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index ed74240f5..c2ab656fe 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -787,4 +787,23 @@ Περισσότερες επιλογές Διάρκεια Προηγούμενη ροή + Ποιότητα εικόνας + ; + Χαμηλή ποιότητα + Άβαταρ + Άβαταρ υπο-καναλιών + Μη φόρτωση εικόνων + Υψηλή ποιότητα + Μέτρια ποιότητα + Άβαταρ δημιουργών + Επιλέξτε την ποιότητα των εικόνων και εάν δε θέλετε να φορτώσετε εικόνες, για να μειώσετε τη χρήση δεδομένων και μνήμης. Οι αλλαγές εκκαθαρίζουν την κρυφή μνήμη εικόνων, τόσο στη μνήμη όσο και στον δίσκο — %s + Μικρογραφίες + Ταμπέλες + Κοινοποίηση λίστας URL + Κοινοποίηση με τίτλους + %1$s +\n%2$s + Κοινοποίηση λίστας + Μοιραστείτε τη λίστα αναπαραγωγής με λεπτομέρειες όπως το όνομα της λίστας αναπαραγωγής και τους τίτλους βίντεο ή ως μια απλή λίστα διευθύνσεων URL βίντεο + - %1$s: %2$s \ No newline at end of file diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 83260fcd5..499610d9b 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -803,4 +803,23 @@ Más opciones Duración Retransmisión anterior + Calidad de la imagen + \? + Baja calidad + Avatares + Avatares de los subcanales + No cargar las imágenes + Calidad alta + Calidad media + avatares subidos + Banners + Elige la calidad de las imágenes y si cargar imágenes en su totalidad, para reducir el uso de datos y memoria. Los cambios borran la caché de las imágenes en la memoria y en el disco - %s + Miniaturas + Compartir la lista de la dirección URL + Compartir con los títulos + %1$s +\n%2$s + Compartir la lista de reproducción + Compartir las listas de reproducción con los detalles como el nombre de la lista y los títulos de los vídeos o como una simple lista de una dirección URL con los vídeos + - %1$s: %2$s \ No newline at end of file diff --git a/app/src/main/res/values-et/strings.xml b/app/src/main/res/values-et/strings.xml index cb34d1226..fd84e5d45 100644 --- a/app/src/main/res/values-et/strings.xml +++ b/app/src/main/res/values-et/strings.xml @@ -762,4 +762,48 @@ Kuna on teada, et see seade ei toeta meedia tunneldamist, siis on see funktsionaalsus vaikimisi välja lülitatud. Meediavoogusid ei leidu Otseeetris meediavoogusid ei leidu + Pildikvaliteet + Videod + \? + Tellijad + Kanali lehel kuvatavad kaardid + Kanali kaardid + Lühivideod + Laadime metateavet… + Vaheta ekraani paigutust + Madal kvaliteet + Lülita täisekraan sisse/välja + Laadi kanali kaardid + Tunnuspildid + Järgmine meediavoog + Alamkanali tunnuspilt + Ava esitusjärjekord + Ära laadi pilte + Parim kvaliteet + Kanali teave + Keri edasi + Albumid + Keri tagasi + Korda esitust + Andmevoo uuendamisel laaditavad kanali kaardid. Kui kanalite uuendamine toimub kiirrežiimis, siis see eelistus ei ole kasutusel. + Keskmine kvaliteet + Üleslaadija tunnuspilt + Reklaampildid + Esitusloendid + Vali soovitud pildikvaliteet või sootuks ära luba piltide laadimist ning nii saad muuta võrguliikluse ja mälu mahtu. Muudatusega eemaldatakse puhverdatud pildid nii mälust kui andmekandjalt — %s + Esita + Lisavalikud + Pisipildid + Palad + Kestus + Kanalid + Eelmine meediavoog + Otseeeter + Jaga url\'ide loendina + Jagamisel lisa pealkirjad + %1$s +\n%2$s + Jaga esitusloendit + Jaga esitusloendit kas väga detailse teabega palade kohta või lihtsa url\'ide loendina + - %1$s: %2$s \ No newline at end of file diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 9fac96903..442fe94b9 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -777,4 +777,30 @@ La tunnelisation multimédia a été désactivée par défaut sur votre appareil car votre modèle d\'appareil est connu pour ne pas la supporter. Aucun flux Aucun direct + Qualité de l’image + Vidéos + Onglets de chaîne + Chargement des métadonnées … + Basse qualité + Avatars + Flux suivant + Ne pas charger d’images + Haute qualité + À propos + Albums + Qualité moyenne + Bannières + Listes de lecture + Plus d’options + Miniatures + Pistes + Durée + Chaînes + Flux précédent + Direct + \? + Abonnés + Shorts + Onglets de chaîne à récupérer + Onglets à récupérer lors de la mise à jour du flux. Cette option n’a aucun effet si une chaîne est mise à jour en utilisant le mode rapide. \ No newline at end of file diff --git a/app/src/main/res/values-he/strings.xml b/app/src/main/res/values-he/strings.xml index ed9f50f52..729db00b6 100644 --- a/app/src/main/res/values-he/strings.xml +++ b/app/src/main/res/values-he/strings.xml @@ -792,7 +792,7 @@ מנויים אין לשוניות מופיעות בעמודי הערוץ לשוניות ערוץ - Shorts + Shorts‎ נתוני העל נטענים… משיכת לשוניות הערוץ על אודות @@ -813,4 +813,23 @@ אפשרויות נוספות משך התזרים הקודם + איכות תמונה + \? + איכות נמוכה + תמונות ייצוגיות + תמונות ייצוגיות של תת־ערוצים + לא לטעון תמונות + איכות גבוהה + איכות בינונית + תמונות ייצוגיות של מעלים + כרזות + נא לבחור את איכות התמונות והאם בכלל להוריד אותן כדי לחסוך בצריכת נתונים ושימוש בזיכרון. השינויים מפנים הן את מטמון השמירה בזיכרון והן בכונן — %s + תמונות ממוזערות + שיתוף רשימת כתובות + שיתוף עם כותרות + %1$s +\n%2$s + שיתוף רשימת נגינה + שיתוף רשימת נגינה עם פרטים כגון שם רשימת נגינה וכותרות סרטונים או כרשימה פשוטה של כתובות סרטונים + - %1$s: %2$s \ No newline at end of file diff --git a/app/src/main/res/values-hi/strings.xml b/app/src/main/res/values-hi/strings.xml index c8954c394..ceb07ca18 100644 --- a/app/src/main/res/values-hi/strings.xml +++ b/app/src/main/res/values-hi/strings.xml @@ -787,4 +787,23 @@ अधिक विकल्प अवधि पिछली स्ट्रीम + छवि की गुणवत्ता + \? + कम गुणवत्ता + अवतार + उप-चैनल अवतार + छवियाँ लोड न करें + उच्च गुणवत्ता + मध्यम गुणवत्ता + अपलोडर अवतार + बैनर + डेटा और मेमोरी उपयोग को कम करने के लिए छवियों की गुणवत्ता और छवियों को लोड करना है या नहीं, चुनें। परिवर्तन इन-मेमोरी और ऑन-डिस्क छवि कैश दोनों को साफ़ करते हैं - %s + थंमनेल + URL सूची साझा करें + शीर्षकों के साथ साझा करें + %1$s +\n%2$s + प्लेलिस्ट साझा करें + प्लेलिस्ट को प्लेलिस्ट नाम और वीडियो शीर्षक जैसे विवरण के साथ या वीडियो यूआरएल की एक सरल सूची के रूप में साझा करें + - %1$s: %2$s \ No newline at end of file diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index 7082a2b22..9da696627 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -774,4 +774,23 @@ Opsi tambahan Durasi Saluran sebelumnya + Kualitas gambar + \? + Kualitas rendah + Avatar + Avatar sub-channel + Jangan tampilkan gambar + Kualitas tinggi + Kualitas sedang + Avatar pengunggah + Pilih kualitas dan visibilitas gambar, untuk mengurangi penggunaan data dan memori. Perubahan menghapus cache dalam diska dan memori - %s + Thumbnail + Bagikan daftar URL + Bagikan dengan Judul + %1$s +\n%2$s + Bagikan Daftar Putar + Bagikan daftar putar dengan detail seperti nama daftar putar dan judul video atau sebagai daftar video URL yang sederhana + Banner + - %1$s: %2$s \ No newline at end of file diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 820fa6eb5..71b656234 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -789,4 +789,34 @@ Tracce Canali Dirette + Qualità immagine + \? + Cambia orientamento schermo + Qualità bassa + Attiva/disattiva schermo intero + Avatar + Video successivo + Avatar del sotto-canale + Apri coda di riproduzione + Non caricare immagini + Qualità alta + Avanti + Riavvolgi + Ricomincia + Qualità media + Avatar dell\'autore + Banner + Scegli la qualità delle immagini e se caricarle o meno, per ridurre l\'utilizzo di dati e memoria. Le modifiche svuotano la cache immagini sia in memoria che su disco — %s + Riproduci + Altre opzioni + Miniature + Durata + Video precedente + Condividi elenco URL + Condividi con i titoli + %1$s +\n%2$s + Condividi playlist + Condividi la playlist con dettagli come il suo nome e i titoli video o come un semplice elenco di URL video + - %1$s: %2$s \ No newline at end of file diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 2a082955f..796c6d650 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -774,4 +774,23 @@ その他のオプション 期間 前のストリーム + 品質 + + 低品質 + アバター + サブチャンネルのアバター + 画像を読み込まない + 高品質 + 中品質 + アップローダーのアバター + バナー + 画像の品質と画像を読み込むかどうかを選択して、データとメモリの使用量を削減します。 変更により、メモリ内とディスク上の画像キャッシュの両方がクリアされます — %s + サムネイル + URLリストで共有 + タイトル付きで共有 + %1$s +\n%2$s + プレイリストを共有 + プレイリスト名やビデオタイトルなどの詳細を含むプレイリスト、またはビデオURLのみのシンプルなリストとしてプレイリストを共有します + - %1$s: %2$s \ No newline at end of file diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 0c2497f0d..b49526071 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -762,4 +762,48 @@ Geen streams Geen live-streams Media-tunneling is standaard uitgeschakeld op uw apparaat omdat uw apparaatmodel dit niet ondersteunt. + Afbeeldings­kwaliteit + Video\'s + \? + Abonnees + Welke tabbladen worden getoond op kanaal­pagina\'s + Kanaal­tabbladen + Shorts + Metagegevens laden… + Scherm­oriëntatie omschakelen + Lage kwaliteit + Volledig scherm omschakelen + Kanaal­tabbladen ophalen + Profielfoto\'s + Volgende stream + Subkanaal-profielfoto\'s + Wachtrij openen + Afbeeldingen niet laden + Hoge kwaliteit + Over + Vooruitspoelen + Albums + Terugspoelen + Opnieuw afspelen + Tabbladen om op te halen bij het bijwerken van de feed. Deze optie heeft geen effect als een kanaal wordt bingewerkt via de snelle modus. + Gemiddelde kwaliteit + Uploader-profielfoto\'s + Banieren + Afspeellijsten + Kies de kwaliteit van afbeeldingen en of deze überhaupt geladen moeten worden, om gegevens- en geheugengebruik te verminderen. Wijzigingen wissen de afbeeldings­cache — %s + Afspelen + Meer opties + Miniaturen + Nummers + Duur + Kanalen + Vorige stream + Live + URL-lijst delen + Delen met titels + %1$s +\n%2$s + Afspeellijst delen + Deel afspeellijst met details zoals afspeellijstnaam en videotitels of als een eenvoudige lijst met video-URL\'s + - %1$s: %2$s \ No newline at end of file diff --git a/app/src/main/res/values-or/strings.xml b/app/src/main/res/values-or/strings.xml index bfbd901d1..aefbdc914 100644 --- a/app/src/main/res/values-or/strings.xml +++ b/app/src/main/res/values-or/strings.xml @@ -83,7 +83,7 @@ ଡିଫଲ୍ଟ ରେଜୋଲୁସନ କୋଡି ସହିତ ଖୋଲନ୍ତୁ ଦ୍ୱିତୀୟ କୃତ୍ୟ ବଟନ୍ - ପୁନରାବୃତ୍ତି କରନ୍ତୁ + ପୁନର୍ବାର କରନ୍ତୁ ବିଜ୍ଞପ୍ତିକୁ ରଙ୍ଗ କରନ୍ତୁ ପପ୍ଅପ୍ ର ଶେଷ ଆକାର ଏବଂ ସ୍ଥିତି ମନେରଖ ଦ୍ରୁତ ନିଷ୍କ୍ରିୟ ସନ୍ଧାନ ବ୍ୟବହାର କରନ୍ତୁ @@ -762,4 +762,48 @@ \nଏହି ବିକଳ୍ପକୁ ସକ୍ରିୟ କରିବା ସାମ୍ପ୍ରତିକ ଭିଡିଓ ପ୍ଲେୟାରକୁ ବଦଳାଇବା କିମ୍ବା ସମ୍ପୂର୍ଣ୍ଣ ପରଦାକୁ ପରିବର୍ତ୍ତନ କରିବା ସମୟରେ ପ୍ଲେବ୍ୟାକ ତ୍ରୁଟିକୁ ପ୍ରତିରୋଧ କରିପାରେ
    କୌଣସି ସ୍ରୋତ ନାହିଁ କୌଣସି ଲାଇଭ ଷ୍ଟ୍ରିମ୍ ନାହିଁ + ପ୍ରତିଛବି ଗୁଣବତ୍ତା + ଭିଡିଓଗୁଡିକ + \? + ଗ୍ରାହକଗଣ + ଚ୍ୟାନେଲ ପୃଷ୍ଠାଗୁଡ଼ିକରେ କେଉଁ ଟ୍ୟାବଗୁଡ଼ିକ ଦେଖାଯାଏ + ଚ୍ୟାନେଲ ଟ୍ୟାବଗୁଡ଼ିକ + ସର୍ଟସ୍ + ମେଟାଡାଟା ଧାରଣ କରୁଅଛି… + ସ୍କ୍ରିନ୍ ଆରିଏଣ୍ଟେସନ୍ ଟୋଗଲ୍ କରନ୍ତୁ + ନିମ୍ନମାନର + ଫୁଲ୍ ସ୍କ୍ରିନ୍ ଟୋଗଲ୍ କରନ୍ତୁ + ଚ୍ୟାନେଲ ଟ୍ୟାବଗୁଡ଼ିକୁ ଆଣନ୍ତୁ + ଅବତାର + ପରବର୍ତ୍ତୀ ଷ୍ଟ୍ରିମ୍ + ଉପ-ଚାନେଲ ଅବତାରଗୁଡ଼ିକ + ଖେଳ ଧାଡ଼ି ଖୋଲନ୍ତୁ + ପ୍ରତିଛବିଗୁଡ଼ିକୁ ଧାରଣ କରନ୍ତୁ ନାହିଁ + ଉଚ୍ଚ ଗୁଣବତ୍ତା + ବିଷୟରେ + ଆଗକୁ + ଆଲବମ୍ + ପୁନରାବୃତ୍ତି କରନ୍ତୁ + ପୁନର୍ବାର ଚଲାନ୍ତୁ + ଫିଡକୁ ଅଦ୍ୟତନ କରିବା ସମୟରେ ଆଣିବା ପାଇଁ ଟ୍ୟାବଗୁଡ଼ିକ । ଫାଷ୍ଟ ମୋଡ ବ୍ୟବହାର କରି ଚ୍ୟାନେଲକୁ ଅଦ୍ୟତନ କରାଗଲେ ଏହି ବିକଳ୍ପର କୌଣସି ପ୍ରଭାବ ପଡ଼ିବ ନାହିଁ । + ମଧ୍ୟମ ଗୁଣବତ୍ତା + ଅପଲୋଡର ଅବତାରଗୁଡ଼ିକ + ବ୍ୟାନରଗୁଡିକ + ପ୍ଲେଲିଷ୍ଟଗୁଡିକ + ତଥ୍ୟ ଏବଂ ସ୍ମୃତିଶକ୍ତି ବ୍ୟବହାରକୁ ହ୍ରାସ କରିବା ପାଇଁ ପ୍ରତିଛବିଗୁଡ଼ିକର ଗୁଣବତ୍ତା ଏବଂ ସମ୍ପୂର୍ଣ୍ଣ ଭାବରେ ପ୍ରତିଛବିଗୁଡ଼ିକୁ ଧାରଣ କରିବା ଉଚିତ କି ନୁହଁ ବାଛନ୍ତୁ । ପରିବର୍ତ୍ତନଗୁଡ଼ିକ ସ୍ମରଣୀୟ ଏବଂ ଡିସ୍କ ପ୍ରତିଛବି କ୍ୟାଶେ ଉଭୟକୁ ସଫା କରିଥାଏ — %s + ଚଲାନ୍ତୁ + ଅଧିକ ବିକଳ୍ପ + ଥମ୍ବନେଲଗୁଡିକ + ଟ୍ରାକଗୁଡିକ + ଅବଧି + ଚ୍ୟାନେଲଗୁଡିକ + ପୂର୍ବ ଷ୍ଟ୍ରିମ୍ + ଲାଇଭ୍ + URL ତାଲିକା ସହଭାଗ କରନ୍ତୁ + ଶୀର୍ଷକଗୁଡ଼ିକ ସହିତ ଅଂଶୀଦାର କରନ୍ତୁ + %1$s +\n%2$s + ଖେଳ ତାଲିକା ସହଭାଗ କରନ୍ତୁ + ପ୍ଲେ-ଲିଷ୍ଟ ନାମ ଏବଂ ଭିଡିଓ ଶୀର୍ଷକ କିମ୍ବା ଭିଡିଓ URLଗୁଡ଼ିକର ଏକ ସରଳ ତାଲିକା ଭାବରେ ବିବରଣୀ ସହିତ ପ୍ଲେ-ଲିଷ୍ଟ ଅଂଶୀଦାର କରନ୍ତୁ + - %1$s: %2$s \ No newline at end of file diff --git a/app/src/main/res/values-pa/strings.xml b/app/src/main/res/values-pa/strings.xml index 7b1b5669c..c723bf331 100644 --- a/app/src/main/res/values-pa/strings.xml +++ b/app/src/main/res/values-pa/strings.xml @@ -48,9 +48,9 @@ ਡੀਫ਼ਾਲਟ ਆਡੀਓ ਫ਼ਾਰਮੈਟ ਡੀਫ਼ਾਲਟ ਵੀਡੀਓ ਫ਼ਾਰਮੈਟ ਥੀਮ - ਸਫੈਦ - ਗੂੜਾ - ਕਾਲ੍ਹਾ + ਸਫ਼ੈਦ + ਗੂੜ੍ਹਾ + ਕਾਲ਼ਾ ਪੌਪ-ਅਪ ਦਾ ਆਕਾਰ ਅਤੇ ਸਥਿਤੀ ਯਾਦ ਰੱਖੋ ਪੌਪ-ਅਪ ਦਾ ਆਖਰੀ ਅਕਾਰ ਅਤੇ ਸਥਿਤੀ ਯਾਦ ਰੱਖੋ ਤੇਜ਼ ਪਰ ਅਸਪੱਸ਼ਟ ਸੀਕ ਵਰਤੋ @@ -787,4 +787,23 @@ ਹੋਰ ਵਿਕਲਪ ਮਿਆਦ ਪਿਛਲੀ ਸਟ੍ਰੀਮ + ਚਿੱਤਰ ਕੁਆਲਿਟੀ + \? + ਘੱਟ ਕੁਆਲਿਟੀ + ਅਵਤਾਰ + ਉਪ-ਚੈਨਲ ਅਵਤਾਰ + ਚਿੱਤਰ ਲੋਡ ਨਾ ਕਰੋ + ਉੱਚ ਕੁਆਲਿਟੀ + ਦਰਮਿਆਨੀ ਕੁਆਲਿਟੀ + ਅਪਲੋਡਰ ਅਵਤਾਰ + ਬੈਨਰ + ਡਾਟਾ ਅਤੇ ਮੈਮੋਰੀ ਵਰਤੋਂ ਨੂੰ ਘਟਾਉਣ ਲਈ ਚਿੱਤਰਾਂ ਦੀ ਗੁਣਵੱਤਾ ਅਤੇ ਚਿੱਤਰਾਂ ਨੂੰ ਬਿਲਕੁਲ ਲੋਡ ਕਰਨਾ ਹੈ ਜਾਂ ਨਹੀਂ, ਚੁਣੋ। ਤਬਦੀਲੀਆਂ ਇਨ-ਮੈਮੋਰੀ ਅਤੇ ਆਨ-ਡਿਸਕ ਚਿੱਤਰ ਕੈਸ਼ ਨੂੰ ਸਾਫ਼ ਕਰਦੀਆਂ ਹਨ — %s + ਥੰਮਨੇਲ + URL ਸੂਚੀ ਸਾਂਝੀ ਕਰੋ + ਸਿਰਲੇਖਾਂ ਨਾਲ ਸਾਂਝਾ ਕਰੋ + %1$s +\n%2$s + ਪਲੇਲਿਸਟ ਸਾਂਝੀ ਕਰੋ + ਪਲੇਲਿਸਟ ਦੇ ਨਾਮ ਅਤੇ ਵੀਡੀਓ ਸਿਰਲੇਖਾਂ ਜਾਂ ਵੀਡੀਓ URL ਦੀ ਇੱਕ ਸਧਾਰਨ ਸੂਚੀ ਦੇ ਰੂਪ ਵਿੱਚ ਵੇਰਵਿਆਂ ਨਾਲ ਪਲੇਲਿਸਟ ਨੂੰ ਸਾਂਝਾ ਕਰੋ + - %1$s: %2$s \ No newline at end of file diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index bd1c62465..8c7a28ddc 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -253,7 +253,7 @@ Wymuś raportowanie niedostarczonych wyjątków Rx poza cyklem życia fragmentu lub aktywności po usunięciu Używaj szybkiego, niedokładnego przewijania Niedokładne przewijanie umożliwia szybsze przewijanie ze zmniejszoną dokładnością. Przewijanie o 5, 15 lub 25 sekund nie działa w tym przypadku - Wyczyszczono pamięć podręczną miniatur + Wyczyszczono pamięć podręczną obrazów Wyczyść pamięć podręczną metadanych Usuwa całą pamięć podręczną stron Wyczyszczono pamięć podręczną metadanych @@ -808,4 +808,23 @@ Więcej opcji Czas trwania Poprzedni strumień + Jakość obrazów + \? + Niska jakość + Awatary + Awatary podkanału + Nie ładuj + Wysoka jakość + Średnia jakość + Awatary przesyłającego + Banery + Wybierz jakość obrazów albo czy w ogóle je ładować, aby zmniejszyć zużycie danych i pamięci. Zmiana czyści pamięć podręczną obrazów zarówno w pamięci, jak i na dysku — %s + Miniatury + Udostępnij listę URL-i + Udostępnij z tytułami + %1$s +\n%2$s + Udostępnij playlistę + Udostępnij playlistę ze szczegółami, takimi jak nazwa playlisty i tytuły wideo, lub jako prostą listę adresów URL wideo. + – %1$s: %2$s \ No newline at end of file diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index 400d04bbb..f20bc05b0 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -13,14 +13,14 @@ Partilhar com Utilizar reprodutor de vídeo externo Utilizar reprodutor de áudio externo - Pasta para ficheiros de vídeo + Pasta para os ficheiros de vídeo Os ficheiros de vídeo descarregados serão guardados aqui - Escolha a pasta para colocar os ficheiros de vídeo + Escolha a pasta para guardar os ficheiros de vídeo Resolução padrão Reproduzir no Kodi Instalar Kore\? Mostrar opção \"Reproduzir no Kodi\" - Mostrar uma opção para reproduzir o vídeo no Kodi + Mostrar opção para reproduzir o vídeo no Kodi Áudio Formato padrão de áudio Descarregar @@ -38,9 +38,9 @@ Aparência Reprodução em segundo plano Erro de rede - Pasta para ficheiros de áudio + Pasta para os ficheiros de áudio Os ficheiros de áudio descarregados serão guardados aqui - Escolha a pasta para colocar os ficheiros de áudio + Escolha a pasta para guardar os ficheiros de áudio Erro Não foi possível carregar todas as miniaturas Não foi possível processar o site @@ -61,8 +61,8 @@ Tentar novamente Toque na lupa para começar. Em direto - Transferências - Transferências + Descargas + Descargas Relatório de erro Iniciar Pausa @@ -82,7 +82,7 @@ Abrir no modo popup Preto Tudo - k + K M MM Esta permissão é necessária @@ -122,7 +122,7 @@ Não foi possível atualizar a subscrição Subscrições Novidades - Histórico de pesquisa + Pesquisar histórico Guardar termos de pesquisa localmente Histórico de visualizações Manter histórico dos vídeos visualizados @@ -131,7 +131,7 @@ Reprodutor Comportamento Histórico e cache - Anular + Desfazer Notificação NewPipe Notificações para o reprodutor do NewPipe Sem resultados @@ -193,13 +193,13 @@ Mudar para popup Mudar para principal Não foi possível reproduzir este vídeo - Os reprodutores externos não suportam este tipo de hiperligações + Os reprodutores externos não possuem suporte a este tipo de ligações Arraste para reordenar Criar Mudar nome Doar Reprodutor de vídeo não encontrado (pode instalar VLC para o efeito). - Descarregar ficheiro de vídeo + Descarregar ficheiro Adicionar a Utilizar pesquisa rápida Este tipo de pesquisa e mais rápida mas reduz a precisão. Procurar por 5, 15 ou 25 segundos não funciona corretamente @@ -280,16 +280,16 @@ Ritmo Limpar histórico de visualizações Continuar (sem repetição) a fila de reprodução anexando um vídeo relacionado - Mostrar dica \"Toque longo para enfileirar\" - Mostrar dica ao premir em segundo plano ou no botão \"Detalhes:\" da janela popup + Mostrar dica \"Toque longo para colocar na fila\" + Mostrar dica ao premir em segundo plano ou no botão \"Detalhes\" da janela popup Canais Listas de reprodução Faixas Utilizadores Remove o histórico dos vídeos reproduzidos e as posições de reprodução Remover todo o histórico de visualizações\? - Histórico de vídeos apagado - Limpar histórico de pesquisas + Histórico de vídeos eliminado + Remover histórico de pesquisas Remove o histórico de pesquisas Remover todo o histórico de pesquisas\? Histórico de pesquisa removido @@ -340,7 +340,7 @@ Notificações para novas versões do NewPipe Armazenamento externo indisponível Não é possível guardar no cartão SD. Repor pasta de descargas\? - Não foi possível ler as guias gravadas, portanto usando as guias predefinidas + Não foi possível ler os separadores guardados e vamos usar os separadores padrão Repor predefinições Deseja repor as predefinições\? Contagem de subscrições indisponível @@ -411,7 +411,7 @@ \nAtive o seletor de pastas do sistema (SAF) se quiser transferir para um cartão SD externo Utilizar seletor de pastas do sistema (SAF) \'Storage Access Framework\' permite transferências para um cartão SD externo - Limpar posições de reprodução + Remover posições de reprodução Remove todas as posições de reprodução Remover todas as posições de reprodução\? Alternar serviço atualmente selecionado: @@ -431,12 +431,12 @@ O idioma será alterado assim que reiniciar a app Duração da pesquisa de avanço/recuo rápido Instâncias PeerTube - Defina as suas instâncias favoritas PeerTube + Defina as suas instâncias PeerTube preferidas Encontre as instâncias que gosta em %s Adicionar instância Digite o URL da instância Falha ao validar a instância - Apenas os URL HTTPS são suportados + Apenas são suportados os URL HTTPS Instância já existe Local Recentes @@ -451,7 +451,7 @@ Idioma da aplicação Predefinição do sistema Prima \"Feito\" ao resolver - Aceitar + Concluído Acha que a fonte demora muito tempo a carregar\? Se sim, tente ativar o carregamento rápido (pode alterar a opção nas definições ou no botão abaixo). \n \nNewPipe oferece duas estratégias de carregamento: @@ -518,7 +518,7 @@ Artistas Álbuns Músicas - Este vídeo está restringido a idades. + Este vídeo está restringido a adultos. \n \nPara o poder ver, tem que ativar \"%1$s\" nas definições. Os vídeos que tenham sido vistos antes e depois de serem adicionados à lista de reprodução serão removidos. @@ -557,7 +557,7 @@ Apenas em Wi-Fi Nada Mudar de um reprodutor para outro pode substituir a sua fila - Pedir confirmação antes de limpar uma fila + Pedir confirmação antes de limpar a fila Edite cada ação de notificação abaixo com um toque. Selecione até três para serem mostradas na notificação compacta utilizando as caixas de seleção à direita Pode selecionar, no máximo, três ações para mostrar na notificação compacta! Repetir @@ -568,14 +568,14 @@ Limpar cookies que NewPipe armazena quando resolve um reCAPTCHA Os cookies reCAPTCHA foram limpos Limpar cookies reCAPTCHA - O YouTube fornece um \"Modo restrito\" que oculta o conteúdo destinado a adultos + O YouTube fornece um \"Modo restrito\" que oculta conteúdo, potencialmente, destinado a adultos Mostrar conteúdo possivelmente impróprio para crianças porque tem um limite de idade (como 18+) - Personalizar a cor da notificação conforme a cor principal na miniatura (esta opção não está disponível em todos os dispositivos) - Colorir notificação + Personalizar cor da notificação com a cor principal da miniatura (esta opção não está disponível em todos os dispositivos) + Notificação colorida Usar miniaturas no fundo do ecrã de bloqueio e em notificações Mostrar miniatura A calcular \'hash\' - Notificar sobre o progresso das \'hash\' de vídeos + Notificar sobre o progresso das \'hash\' dos vídeos Notificação \'hash\' do vídeo Recentes Desative para ocultar as caixas com informações adicionais acerca do criador, do conteúdo ou de um pedido de pesquisa @@ -590,7 +590,7 @@ Abrir com A app travou Este vídeo tem uma restrição de idade. -\nDevido às novas políticas do YouTube quanto a vídeos com restrição de idade, o NewPipe não pode aceder as estes vídeos, por isso não consegue reproduzi-lo. +\nDevido às novas políticas do YouTube quanto a restrição de alguns vídeos, o NewPipe não pode aceder a estes vídeos e, por isso, não os consegue reproduzir. Este conteúdo só está disponível para utilizadores que pagaram, portanto não pode ser transmitido ou descarregado pelo NewPipe. Este vídeo está disponível apenas para os membros do YouTube Music Premium, portanto não pode ser transmitido ou descarregado pelo NewPipe. Este conteúdo é privado, portanto não pode ser transmitido ou descarregado pelo NewPipe. @@ -659,7 +659,7 @@ %s descargas concluídas
    Deslizar itens para removê-los - Não iniciar vídeos no reprodutor mini, mas ir diretamente ao ecrã completo se a rotação automática estiver bloqueada. Ainda pode aceder o reprodutor mini se sair do modo de ecrã completo + Não iniciar vídeos em mini-reprodutor e ativar ecrã completo, se a rotação automática estiver bloqueada. Pode aceder ao mini-reprodutor se sair do modo de ecrã completo. Iniciar reprodutor principal em ecrã completo Enfileirado o próximo Pôr na fila o próximo @@ -671,9 +671,9 @@ Travar o reprodutor Mostrar \"Travar o reprodutor\" Mostra uma opção de travamento ao usar o reprodutor - Notificação de relatório de erros + Notificação para relatórios de erro Notificações para reportar erros - NewPipe encontrou um erro, toque para relatar + NewPipe encontrou um erro, toque para reportar Ocorreu um erro, veja a notificação Mostrar um snackbar de erro Criar uma notificação de erro @@ -685,7 +685,7 @@ LeakCanary não está disponível Predefinido do ExoPlayer Notificação do reprodutor - Configurar a notificação da reprodução do vídeo atual + Configurar notificação da reprodução do vídeo atual Notificações A carregar detalhes do vídeo… Verificar se há novos vídeos @@ -698,7 +698,7 @@ Alternar tudo Apagar todos os ficheiros descarregados do disco\? Novos vídeos - Notificações sobre novos vídeos para assinaturas + Notificações sobre novos vídeos nas subscrições %s vídeo novo %s vídeos novos @@ -722,7 +722,7 @@ Se está a ter problemas a usar a aplicação, veja estas respostas para perguntas mais comuns! Ordenação Modo rápido - Importar ou exportar subscrições do menu de 3 pontos + Importe ou exporte subscrições no menu 3 pontos Já está a executar a versão mais recente do NewPipe Toque para descarregar %s Esta opção só está disponível se estiver selecionado %s para o tema @@ -732,7 +732,7 @@ As listas de reprodução acinzentadas já contêm este item. Duplicar adicionado %d vez(es) Ignorar eventos com botões físicos - Útil por exemplo se estiver a utilizar auscultadores com botões físicos danificados + Útil, por exemplo, se estiver a utilizar auscultadores com botões físicos danificados Remover duplicados Remover duplicados\? Mostrar/ocultar vídeos @@ -754,7 +754,7 @@ \nA activação desta opção pode evitar erros de reprodução ao mudar o leitor de vídeo atual ou ao mudar para ecrã inteiro
    Altera o tamanho do intervalo de carregamento progressivo (o atual é %s). Um valor menor pode acelerar o carregamento inicial do vídeo Dar preferência ao áudio original - Selecionar o áudio original independentemente do idioma + Seleciona o áudio original, independentemente do idioma Dar preferência ao áudio descritivo Áudio: %s Faixa de áudio @@ -770,9 +770,53 @@ original dobrado descritivo - Mova o seletor da guia principal para a parte inferior - Posição das guias principais + Mova o seletor do separador principal para a parte inferior + Posição dos separadores principais O túnel multimédia foi desativado por predefinição no seu dispositivo porque se sabe que o modelo do dispositivo não o suporta. Nenhum vídeo em direto Nenhum vídeo + A carregar metadados… + Obter separadores de canais + Separadores a obter ao atualizar o feed. Esta opção não tem efeito se um canal for atualizado utilizando o modo rápido. + Qualidade da imagem + Vídeos + \? + Subscritores + Os separadores a mostrar na página Canal + Partilhar URL + Partilhar com título + %1$s +\n%2$s + Separadores do canal + Curtos + Alternar orientação do ecrã + Baixa qualidade + Alternar ecrã completo + Avatars + Fluxo seguinte + Avatar de subcanais + Abrir fila de reprodução + Não carregar imagens + Alta qualidade + Acerca + Partilhar lista de reprodução + Avançar + Álbuns + Recuar + Repetição + Média qualidade + Avatar dos publicadores + Banners + Listas de reprodução + - %1$s: %2$s + Reproduzir + Mais opções + Miniaturas + Faixas + Duração + Canais + Fluxo anterior + Direto + Partilhe a lista de reprodução com detalhes como o nome da lista de reprodução e os títulos dos vídeos ou como uma simples lista de URLs de vídeos + Escolha a qualidade das imagens e se pretende carregar imagens, para reduzir a utilização de dados e de memória. As alterações limpam a cache de imagens na memória e no disco - %s \ No newline at end of file diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 849463c2b..63d576594 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -779,4 +779,48 @@ Нет стримов Нет прямых трансляций Медиа-туннелирование на вашем устройстве отключено по умолчанию, поскольку известно, что ваша модель устройства его не поддерживает. + Качество изображения + Видео + \? + Подписчики + Какие вкладки отображаются на страницах каналов + Поделиться списком URL-адресов + Поделиться названиями + %1$s +\n%2$s + Вкладки канала + Shorts + Загрузка метаданных… + Изменить ориентацию экрана + Низкое качество + Переключить полноэкранный режим + Получение вкладок канала + Аватары + Следующий стрим + Аватары подканалов + Открыть очередь воспроизведения + Не загружать изображения + Высокое качество + О канале + Поделиться подборкой + Перемотать вперёд + Альбомы + Перемотать назад + Повторить + Получаемые вкладки при обновлении ленты. Эта функция не применяется, если канал обновляется с помощью быстрого режима. + Поделиться подборкой с подробностями, такими как название подборки и названия видео, или просто списком URL видео + Среднее качество + Загрузчик аватаров + Баннеры + Подборки + - %1$s: %2$s + Выберите качество изображений и загружать ли изображения вообще, чтобы снизить использование данных и памяти. Изменения очищают кэш изображений как в памяти, так и на диске – %s + Воспроизвести + Другие опции + Миниатюры + Дорожки + Продолжительность + Каналы + Предыдущий стрим + Живая трансляция \ No newline at end of file diff --git a/app/src/main/res/values-ryu/strings.xml b/app/src/main/res/values-ryu/strings.xml index 43fbd45ad..abd1f089b 100644 --- a/app/src/main/res/values-ryu/strings.xml +++ b/app/src/main/res/values-ryu/strings.xml @@ -787,4 +787,23 @@ うぬふかぬオプション ちかん めーぬストリーム + ふぃんしち + + ていふぃんしち + アバター + サブチャンネルぬアバター + やしがぞうゆみくまん + かんふぃんしち + ちゅうふぃんしち + アップローダーぬアバター + バナー + やしがぞうぬふぃんしちとぅぬぞうゆみくむがちゃーがさんたくち、データとぅメモリぬしようりょうさくぎんさびーん。 へんかんにゆり、メモリねーんとぅディスクじょうぬがぞうキャッシュぬりょうほうがクリアさりやびーん — %s + サムネイル + URLリストっしちゅーゆーいん + タイトルちきっしちゅーゆーいん + %1$s +\n%2$s + プレイリストちゅーゆーいん + プレイリストめいてぃがろービデオタイトルんでーぬしょうさいくくむるプレイリスト、あらんでぃビデオURLぬみぬシンプルやるリストとぅしてぃプレイリストちゅーゆーいんさびーん + - %1$s: %2$s \ No newline at end of file diff --git a/app/src/main/res/values-sc/strings.xml b/app/src/main/res/values-sc/strings.xml index e68d5fbd2..b9178cf87 100644 --- a/app/src/main/res/values-sc/strings.xml +++ b/app/src/main/res/values-sc/strings.xml @@ -595,7 +595,7 @@ Automàticu (tema de su dispositivu) Tema pro sa note Ammustra sos detàllios de su canale - 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 + 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. Disabìlita sa tunnellizatzione de sos mèdios Internu No elencadu @@ -757,4 +757,53 @@ Una rasta àudio diat dèpere èssere giai presente in custu flussu Impostatziones pro ExoPlayer Abìlita custa optzione si tenes problemas de initzializatzione de su decodificadore, chi colat a decodificadores a prioridade prus bassa si s\'initzializatzione de sos decodificadores primàrios fallit. Custu diat pòdere causare unu rendimentu de riprodutzione bassu cunfronta a s\'impreu de decodificadores primàrios + Calidade de s\'immàgine + Vìdeos + \? + Iscritos + Ite ischedas benint ammustradas in sas pàginas de su canale + Cumpartzi una lista de URL + Cumpartzi cun sos tìtulos + %1$s +\n%2$s + Ischedas de su canale + Curtzos + Carrighende sos metadatos… + Càmbia s\'orientamentu de s\'ischermu + Calidade bassa + Positzione de sas ischedas printzipales + Allughe/istuda s\'ischermu intreu + Recùpera sas ischedas de su canale + Avatars + Flussu imbeniente + Sa tunnellizatzione multimediale est istada disabilitada comente cunfiguratzione predefinida ca su modellu de dispositivu tuo s\'ischit chi non la suportat. + Avatars de sos suta-canales + Aberi sa lista de riprodutzione + Non càrrighes immàgines + Calidade arta + Informatziones + Cumpartzi s\'iscalita + A dae in antis + Albums + Torra in segus + Torra a reprodùere + Ischedas de recuperare cando agiornas sa fonte. Custa optzione non tenet efetu si unu canale benit agiornadu impreende sa modalidade lestra. + Cumpartzi s\'iscalita cun detàllios che a su nùmene de s\'iscalita e sos tìtulos de sos vìdeos o che a una lista simpre de URL de vìdeos + Calidade mesana + Avatars de su carrigadore + Insignas + Iscalitas + - %1$s: %2$s + Moe su seletzionadore de s\'ischeda printzipale a fundu + Perunu flussu in direta + Issèbera sa calidade de sas immàgines e si las carrigare, pro minimare s\'impreu de datos e memòria. Sas modìficas isbòidant sa memòria temporànea de sas immàgines siat in sa memòria siat in su discu — %s + Riprodue + Prus optziones + Miniaduras + Rastas + Longària + Perunu flussu + Canales + Flussu antepostu + Diretas \ No newline at end of file diff --git a/app/src/main/res/values-sr/strings.xml b/app/src/main/res/values-sr/strings.xml index 4680942b6..8bb8d1b3d 100644 --- a/app/src/main/res/values-sr/strings.xml +++ b/app/src/main/res/values-sr/strings.xml @@ -22,7 +22,7 @@ Аудио снимак Подразумевани формат аудио снимка Преузимање - URL није подржан + URL адреса није подржана Прикажи „следеће“ и „сличне“ видео снимке Подразумевани језик садржаја Видео и аудио снимци @@ -104,7 +104,7 @@ Предлози за претрагу Изаберите предлоге који ће се приказати приликом претраге Пратите - Прати + Запрати Праћења Шта је ново Историја претраге @@ -127,7 +127,7 @@ Дозвољени знакови у називима фајлова Слова и бројеви © %1$s од %2$s под %3$s - Отказано праћење канала + Прекинуто праћење канала Није могуће променити праћење Није могуће ажурирати праћење Плејер @@ -203,7 +203,7 @@ Очишћен кеш са сликама Уклони кеширане метаподатке Уклања све податке кешираних веб-страница - Откажи праћење + Прекини праћење Изаберите картицу Приказ коментара Искључите да бисте сакрили коментаре @@ -297,12 +297,12 @@ \n \nЖелите ли да наставите\? ВашID, soundcloud.com/yourid - Увезите SoundCloud профил тако што ћете откуцати URL или свој ID: + Увезите SoundCloud профил тако што ћете откуцати URL адресу или свој ID: \n -\n1. Омогућите „десктоп режим“ у веб-прегледачу (веб-локација није доступна за мобилне уређаје) +\n1. Омогућите „верзију сајта за рачунар“ у веб-прегледачу (сајт није доступан за мобилне уређаје) \n2. Идите на ову URL адресу: %1$s \n3. Пријавите се када се то од вас затражи -\n4. Копирајте URL профила на који сте преусмерени. +\n4. Копирајте URL адресу профила на који сте преусмерени. Увезите YouTube праћења из Google Takeout-а: \n \n1. Идите на ову URL адресу: %1$s @@ -483,12 +483,12 @@ Инстанца већ постоји Подржане су само HTTPS URL адресе Није могуће потврдити инстанцу - Унесите URL инстанце + Унесите URL адресу инстанце Додајте инстанцу Пронађите инстанце које Вам се свиђају на %s PeerTube инстанце Изаберите своје омиљене PeerTube инстанце - URL није препознат. Отворити помоћу друге апликације\? + URL адреса није препозната. Отворити помоћу друге апликације\? Аутоматско пуштање Очисти податке Прикажите индикаторе положаја репродукције на листама @@ -610,7 +610,7 @@ Отвори веб-сајт Унутрашње Приватно - Неизлистано + По позиву Јавно Домаћин Подршка @@ -628,7 +628,7 @@ Режим брзог фида не пружа више информација о овоме. Налог аутора је укинут. \nNewPipe убудуће неће моћи да учита овај фид. -\nЖелите ли да откажете праћење овог канала\? +\nЖелите ли да прекинете праћење овог канала\? Није могуће учитати фид за „%s“. Грешка при учитавању фида Од Android-а 10 само „Storage Access Framework“ је подржан @@ -789,4 +789,34 @@ Снимци Канали Уживо + Квалитет слике + \? + Укључи оријентацију екрана + Низак квалитет + Укључи цео екран + Аватари + Следећи стрим + Аватари потканала + Отвори ред чекања за пуштање + Не учитавај слике + Висок квалитет + Унапред + Премотавање + Поново пусти + Средњи квалитет + Аватари отпремаоца + Банери + Изаберите квалитет слика и да ли ћете уопште учитавати слике да бисте смањили потрошњу података и меморије. Промене бришу кеш слике у меморији и на диску — %s + Пусти + Више опција + Сличице + Трајање + Претходни стрим + Дели листу URL адреса + Дели са насловима + %1$s +\n%2$s + Дели плејлисту + Делите плејлисту са детаљима, као што су назив плејлисте и наслови видео снимака или као једноставна листа URL адреса видео снимака + -%1$s: %2$s \ No newline at end of file diff --git a/app/src/main/res/values-th/strings.xml b/app/src/main/res/values-th/strings.xml index f68e2f635..f54c55eae 100644 --- a/app/src/main/res/values-th/strings.xml +++ b/app/src/main/res/values-th/strings.xml @@ -33,10 +33,10 @@ เพิ่มไปยัง เส้นทางการดาวน์โหลดวิดีโอ เส้นทางในการจัดเก็บวิดีโอที่ดาวน์โหลดมา - ป้อนเส้นทางการดาวน์โหลดสำหรับวิดีโอ + เลือกเส้นทางการดาวน์โหลดสำหรับไฟล์วิดีโอ โฟลเดอร์ที่ดาวน์โหลดเสียง - เสียงที่ดาวน์โหลดจะถูกเก็บไว้ที่นี่ - ป้อนเส้นทางการดาวน์โหลดสำหรับไฟล์เสียง + ไฟล์เสียงที่ดาวน์โหลดไว้จะถูกเก็บไว้ที่นี่ + เลือกเส้นทางการดาวน์โหลดสำหรับไฟล์เสียง ความละเอียดเริ่มต้น ความละเอียดเริ่มต้นในโหมดป๊อปอัพ แสดงความละเอียดที่สูงขึ้น diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index bfc6661c0..aff2be32b 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -57,7 +57,7 @@ Ne oldu: Ne:\\nİstek:\\nİçerik Dili:\\nİçerik Ülkesi:\\nUygulama Dili:\\nHizmet:\\nGMT Zamanı:\\nPaket:\\nSürüm:\\nİşletim sistemi sürümü: Videoyu oynat, süre: - Yükleyicinin avatar küçük resmi + Yükleyenin avatar küçük resmi Beğeni Beğenmeme Video @@ -237,13 +237,13 @@ Doldur Yakınlaştır Hata ayıklama - Otomatik oluşturulan + Kendiliğinden oluşturulan Bellek sızıntısı izleme, yığın boşaltımı sırasında uygulamanın yanıtlamamasına neden olabilir Yaşam döngüsü dışı hatalarını bildir Parçanın dışında veya atımdan sonraki etkinlik yaşam döngüsündeki teslim edilemeyen Rx beklentilerinin bildirimini zorla Hızlı isabetsiz konumlama kullan İsabetsiz konumlama, oynatıcının daha düşük hassasiyetle daha hızlı konumlamasını sağlar. 5, 15 veya 25 saniyeye konumlama bununla birlikte çalışmamaktadır - Sonraki akışı otomatik kuyruğa ekle + Sonraki akışı kuyruğa kendiliğinden ekle İlgili bir akış ekleyerek sonlanacak (yinelemeyen) oynatma sırasını sürdür Dosya Böylesi klasör yok @@ -343,7 +343,7 @@ Liste görünümü kipi Liste Izgara - Otomatik + Kendiliğinden Tamamlandı durduruldu sırada @@ -375,7 +375,7 @@ Beklemede Yorumları göster Yorumları gizlemek için kapatın - Otomatik oynatma + Kendiliğinden oynat Yorum yok Yorumlar yüklenemedi Kapat @@ -435,7 +435,7 @@ Yerel Son eklenen En çok beğenilen - Otomatik oluşturulan (yükleyen bulunamadı) + Kendiliğinden oluşturulan (yükleyen bulunamadı) kurtarılıyor Bu indirme kurtarılamıyor Oluşum seçin @@ -531,10 +531,10 @@ Henüz oynatma listesi yer imleri yok Asla Yalnızca Wi-Fi - Oynatmayı otomatik başlat — %s + Oynatmayı kendiliğinden başlat — %s Oynatma kuyruğu URL tanınamadı. Başka bir uygulamayla açılsın mı\? - Otomatik kuyruğa alma + Kendiliğinden kuyruğa alış Etkin oynatıcının kuyruğu değiştirilecek Bir oynatıcıdan diğerine geçmek kuyruğunuzu değiştirebilir Bir kuyruğu temizlemeden önce onay iste @@ -591,7 +591,7 @@ İndirme başladı Gözde gece temanızı aşağıdan seçebilirsiniz Gözde gece temanızı seçin — %s - Otomatik (cihaz teması) + Kendiliğinden (aygıt teması) Gece teması Kanal ayrıntılarını göster Ortam yürütümünde siyah ekran veya tutukluk yaşıyorsanız ortam tünellemeyi devre dışı bırakın. @@ -646,7 +646,7 @@ %s indirme tamamlandı
    Ögeleri kaldırmak için kaydır - Videoları mini oynatıcıda başlatmayın, otomatik döndürme kilitliyse doğrudan tam ekran moduna geçin. Tam ekrandan çıkarak mini oynatıcıya erişmeye devam edebilirsiniz + Videoları küçük oynatıcıda başlatma, kendiliğinden döndürme kilitliyse doğrudan tam ekran kipine geç. Tam ekrandan çıkarak küçük oynatıcıya erişebilirsiniz Ana oynatıcıyı tam ekranda başlat Sonrakini sıraya ekle Sonraki sıraya eklendi @@ -762,4 +762,48 @@ Sol kaydırma eylemi Parmağınızı ekranın sağ yarısında kaydırırken ne yapılacağını seçin ExoPlayer\'ın çözücü yedek özelliğini kullan + Resim niteliği + Videolar + \? + Aboneler + Kanal sayfalarında hangi sekmelerin gösterileceği + Adres Listesiyle Paylaş + Başlıklarla Paylaş + %1$s +\n%2$s + Kanal sekmeleri + Shorts + Üst Veri Yükleniyor… + Ekran yönelimini değiştir + Düşük nitelik + Tam ekranı değiştir + Kanal sekmelerini al + Avatarlar + Sonraki akış + Alt kanal avatarları + Oynatma kuyruğunu aç + Resimleri yükleme + Yüksek nitelik + Hakkında + Oynatma Listesini Paylaş + İleri sar + Albümler + Geri sar + Yeniden oynat + Besleme güncellenirken alınacak sekmeler. Hızlı kip kullanılırken kanal güncelleniyorsa bu seçeneğin etkisi yoktur. + Oynatma listesini, oynatma listesi adı ve video başlıkları gibi ayrıntılarla ya da video adreslerinin basit listesi olarak paylaş + Orta nitelik + Yükleyen avatarları + Afişler + Oynatma listeleri + - %1$s: %2$s + Veriyi ve bellek kullanımını düşürmek için resimlerin niteliğini ve tümünün yüklenip yüklenmemesini seçin. Değişiklikler bellek ve diskteki resim önbelleğini temizler — %s + Oynat + Daha çok seçenekler + Küçük resimler + Parçalar + Süre + Kanallar + Önceki akış + Canlı \ No newline at end of file diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index f7c8c8d41..16212c933 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -804,4 +804,23 @@ Інші опції Тривалість Попередній стрим + Якість зображення + \? + Низька якість + Аватари + Аватари підканалів + Не завантажувати зображення + Висока якість + Середня якість + Вивантажувач аватарів + Банери + Виберіть якість зображень і чи завантажувати зображення взагалі, щоб знизити використання даних і пам\'яті. Зміни очищують кеш зображень як у пам\'яті, так і на диску — %s + Мініатюри + Поділитися списком URL-адрес + Поділитися з назвами + %1$s +\n%2$s + Поділитися добіркою + Поділитися добіркою з подробицями, такими як назва добірки та назви відео, або просто списком URL-адрес відео + - %1$s: %2$s \ No newline at end of file diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index a1051bb93..47752a150 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -774,4 +774,23 @@ 更多选项 持续时间 上一条串流 + 图片质量 + + 低质量 + 头像 + 子频道头像 + 不加载图片 + 高质量 + 中等质量 + 上传者头像 + 横幅 + 选择图片质量以及是否根本不加载图片来降低数据和内存使用。更改选项会清除内存中和磁盘上的图片缓存 - %s + 缩略图 + 只包含视频网址 + 分享时带视频标题 + %1$s +\n%2$s + 分享播放列表 + 分享详细的播放列表(带名称和视频标题等信息)或只分享视频网址列表 + - %1$s: %2$s \ No newline at end of file diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index b91cbe994..761e8e46b 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -774,4 +774,23 @@ 更多選項 持續時間 上一個串流 + 畫質 + 不要載入圖片 + 影片縮圖 + + 低品質 + 大頭照 + 子頻道大頭照 + 高品質 + 中等品質 + 上傳者大頭照 + 橫幅 + 選擇影像品質以及是否載入影像,以減少資料與記憶體使用。變更會清除記憶體中與磁碟上的影像快取 — %s + 分享 URL 清單 + 分享標題 + %1$s +\n%2$s + 分享播放清單 + 分享包含播放清單名稱與影片標題等詳細資訊的播放清單,或是僅作為簡單的影片 URL 清單 + - %1$s:%2$s \ No newline at end of file diff --git a/fastlane/metadata/android/de/changelogs/994.txt b/fastlane/metadata/android/de/changelogs/994.txt new file mode 100644 index 000000000..9ff45d8d3 --- /dev/null +++ b/fastlane/metadata/android/de/changelogs/994.txt @@ -0,0 +1,15 @@ +Neu +• Unterstützung mehrerer Audiospuren/Sprachen +• Lautstärke- und Helligkeitsgesten auf jeder Bildschirmseite ermöglicht +• Unterstützung für die Anzeige von Haupttabs am unteren Bildschirmrand + +Verbessert +• [Bandcamp] Handhabung von Titeln hinter der Bezahlschranke + +Behoben +• [YouTube] 403-HTTP-Fehler bei Streams +• Schwarzer Player beim Wechsel von der Wiedergabeliste zum Hauptplayer +• Speicherleck im Playerdienst +• [PeerTube] Benutzer- und Unterkanal-Profilbilder getauscht + +und mehr From be47609405b026c594baec09c00493b4a4c5c8a0 Mon Sep 17 00:00:00 2001 From: TobiGr Date: Thu, 5 Oct 2023 14:49:35 +0200 Subject: [PATCH 143/172] Add changelog for NewPipe 0.26.0 (995) --- fastlane/metadata/android/en-US/changelogs/995.txt | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 fastlane/metadata/android/en-US/changelogs/995.txt diff --git a/fastlane/metadata/android/en-US/changelogs/995.txt b/fastlane/metadata/android/en-US/changelogs/995.txt new file mode 100644 index 000000000..fe47aae1e --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/995.txt @@ -0,0 +1,14 @@ +New +• Support channel tabs +• Select image quality +• Get URLs to all images + +Improved +• Accessibility of player interfaces +• Option to option to add playlist name and video name to playlist sharing content +• Internal improvements and dependencies updates + +Fixed +• Selection of wrong languages in language picker +• Player audio focus was not respecting mute +• Adding items to playlists not working in specific cases From 2ab2185e0abd6a744ba8d9f9a253346fe6a10638 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Sat, 7 Oct 2023 17:21:24 +0200 Subject: [PATCH 144/172] Translated using Weblate (Odia) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 100.0% (725 of 725 strings) Translated using Weblate (Serbian) Currently translated at 17.1% (13 of 76 strings) Translated using Weblate (Portuguese (Portugal)) Currently translated at 100.0% (725 of 725 strings) Translated using Weblate (Arabic (Libya)) Currently translated at 100.0% (725 of 725 strings) Translated using Weblate (Finnish) Currently translated at 98.0% (711 of 725 strings) Translated using Weblate (French) Currently translated at 98.2% (712 of 725 strings) Translated using Weblate (Indonesian) Currently translated at 94.7% (72 of 76 strings) Translated using Weblate (Arabic) Currently translated at 100.0% (76 of 76 strings) Translated using Weblate (Hebrew) Currently translated at 51.3% (39 of 76 strings) Translated using Weblate (Hindi) Currently translated at 100.0% (76 of 76 strings) Translated using Weblate (Punjabi) Currently translated at 100.0% (76 of 76 strings) Translated using Weblate (Punjabi) Currently translated at 100.0% (725 of 725 strings) Translated using Weblate (Hindi) Currently translated at 100.0% (725 of 725 strings) Translated using Weblate (Korean) Currently translated at 100.0% (725 of 725 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (76 of 76 strings) Translated using Weblate (Ukrainian) Currently translated at 100.0% (76 of 76 strings) Translated using Weblate (Italian) Currently translated at 100.0% (76 of 76 strings) Translated using Weblate (Polish) Currently translated at 61.8% (47 of 76 strings) Translated using Weblate (Czech) Currently translated at 100.0% (76 of 76 strings) Co-authored-by: Agnieszka C Co-authored-by: ButterflyOfFire Co-authored-by: Fjuro Co-authored-by: GET100PERCENT Co-authored-by: Hoseok Seo Co-authored-by: Hosted Weblate Co-authored-by: Ihor Hordiichuk Co-authored-by: Linerly Co-authored-by: NEXI Co-authored-by: Random Co-authored-by: Rex_sa Co-authored-by: ShareASmile Co-authored-by: Yaron Shahrabani Co-authored-by: gallegonovato Co-authored-by: ssantos Co-authored-by: Åzze Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/ar/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/cs/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/es/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/he/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/hi/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/id/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/it/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/pa/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/pl/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/sr/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/uk/ Translation: NewPipe/Metadata --- app/src/main/res/values-ar-rLY/strings.xml | 69 ++++++------ app/src/main/res/values-fi/strings.xml | 103 +++++++++++++++++- app/src/main/res/values-fr/strings.xml | 5 + app/src/main/res/values-hi/strings.xml | 8 +- app/src/main/res/values-ko/strings.xml | 48 +++++++- app/src/main/res/values-or/strings.xml | 2 +- app/src/main/res/values-pa/strings.xml | 2 +- app/src/main/res/values-pt-rPT/strings.xml | 46 +++++++- .../metadata/android/ar/changelogs/995.txt | 14 +++ .../metadata/android/cs/changelogs/995.txt | 14 +++ .../metadata/android/es/changelogs/995.txt | 14 +++ .../metadata/android/he/changelogs/995.txt | 14 +++ .../metadata/android/hi/changelogs/995.txt | 14 +++ .../metadata/android/id/changelogs/65.txt | 2 +- .../metadata/android/id/changelogs/66.txt | 33 ++++++ .../metadata/android/id/changelogs/974.txt | 5 + .../metadata/android/id/changelogs/975.txt | 17 +++ .../metadata/android/id/changelogs/976.txt | 10 ++ .../metadata/android/id/changelogs/977.txt | 10 ++ .../metadata/android/id/changelogs/978.txt | 1 + .../metadata/android/id/changelogs/979.txt | 2 + .../metadata/android/id/changelogs/980.txt | 13 +++ .../metadata/android/id/changelogs/981.txt | 2 + .../metadata/android/id/changelogs/982.txt | 1 + .../metadata/android/id/changelogs/983.txt | 9 ++ .../metadata/android/id/changelogs/984.txt | 7 ++ .../metadata/android/id/changelogs/985.txt | 1 + .../metadata/android/id/changelogs/987.txt | 12 ++ .../metadata/android/id/changelogs/988.txt | 2 + .../metadata/android/id/changelogs/989.txt | 3 + .../metadata/android/id/changelogs/990.txt | 15 +++ .../metadata/android/it/changelogs/995.txt | 14 +++ .../metadata/android/pa/changelogs/995.txt | 14 +++ .../metadata/android/pl/changelogs/995.txt | 14 +++ .../metadata/android/sr/changelogs/995.txt | 14 +++ .../metadata/android/uk/changelogs/995.txt | 14 +++ 36 files changed, 524 insertions(+), 44 deletions(-) create mode 100644 fastlane/metadata/android/ar/changelogs/995.txt create mode 100644 fastlane/metadata/android/cs/changelogs/995.txt create mode 100644 fastlane/metadata/android/es/changelogs/995.txt create mode 100644 fastlane/metadata/android/he/changelogs/995.txt create mode 100644 fastlane/metadata/android/hi/changelogs/995.txt create mode 100644 fastlane/metadata/android/id/changelogs/66.txt create mode 100644 fastlane/metadata/android/id/changelogs/974.txt create mode 100644 fastlane/metadata/android/id/changelogs/975.txt create mode 100644 fastlane/metadata/android/id/changelogs/976.txt create mode 100644 fastlane/metadata/android/id/changelogs/977.txt create mode 100644 fastlane/metadata/android/id/changelogs/978.txt create mode 100644 fastlane/metadata/android/id/changelogs/979.txt create mode 100644 fastlane/metadata/android/id/changelogs/980.txt create mode 100644 fastlane/metadata/android/id/changelogs/981.txt create mode 100644 fastlane/metadata/android/id/changelogs/982.txt create mode 100644 fastlane/metadata/android/id/changelogs/983.txt create mode 100644 fastlane/metadata/android/id/changelogs/984.txt create mode 100644 fastlane/metadata/android/id/changelogs/985.txt create mode 100644 fastlane/metadata/android/id/changelogs/987.txt create mode 100644 fastlane/metadata/android/id/changelogs/988.txt create mode 100644 fastlane/metadata/android/id/changelogs/989.txt create mode 100644 fastlane/metadata/android/id/changelogs/990.txt create mode 100644 fastlane/metadata/android/it/changelogs/995.txt create mode 100644 fastlane/metadata/android/pa/changelogs/995.txt create mode 100644 fastlane/metadata/android/pl/changelogs/995.txt create mode 100644 fastlane/metadata/android/sr/changelogs/995.txt create mode 100644 fastlane/metadata/android/uk/changelogs/995.txt diff --git a/app/src/main/res/values-ar-rLY/strings.xml b/app/src/main/res/values-ar-rLY/strings.xml index 2b18bb238..aa7f3e53a 100644 --- a/app/src/main/res/values-ar-rLY/strings.xml +++ b/app/src/main/res/values-ar-rLY/strings.xml @@ -19,12 +19,12 @@ لا تتوفر تدفقات فيديو للاعبين الخارجيين تعطيل تحديد النص في الوصف - - - - - - + لم يتم حذف أي تنزيل + تم حذف تنزيل واحد + تم حذف تنزيلَيْن + تم حذف %1$s تنزيلات + تم حذف %1$s تنزيلاً + تم حذف %1$s تنزيل زر الإجراء الثاني الافتراضي @@ -40,12 +40,12 @@ استرد قم بتشغيل \"وضع تقييد المحتوى\" في يوتيوب - - - - - - + لا ساعة + ساعة واحدة + ساعتان + %d ساعات + %d ساعة + %d ساعة حذف سجل المشاهدة بالكامل؟ تشغيل بواسطة كودي @@ -166,12 +166,12 @@ لم يتم العثور على نتائج فتح الموقع - - - - - - + لا موجَزات + موجَز واحد + موجَزان + %s موجَزات + %s موجَزًا + %s موجز وضع الجهاز اللوحي تعذر التعرف على الرابط. فتح باستخدام تطبيق آخر؟ @@ -228,7 +228,7 @@ عرض المحتوى الذي يُحتمل أن يكون غير مناسب للأطفال لأن له حدًا عمريًا (مثل 18+) بدأ التشغيل في الخلفية ستتغير اللغة بمجرد إعادة تشغيل التطبيق - الفديوهات القصيرة + القصيرة قوائم التشغيل تنظيف اختيار مثيل @@ -249,12 +249,12 @@ تحتوي قوائم التشغيل رمادية اللون بالفعل على هذا العنصر. تمت إضافتها إلى قائمة التشغيل - - - - - - + اليوم + منذ يوم واحد + منذ يومَين + منذ %d أيام + منذ %d يومًا + منذ %d يوم تقرير على GitHub أسود @@ -592,12 +592,12 @@ \n \nنأمل أن يكون مدعومًا في التحديثات القادمة. - - - - - - + لا دقيقة + دقيقة واحدة + دقيقتان + %d دقائق + %d دقيقة + %d دقيقة المشغل المنبثق الصورة الرمزية للرفع @@ -851,4 +851,11 @@ بواسطة %s وصف ريثما + شارك الرابط التشعبي للقائمة + شارِكها بالترجمات النصية + %1$s +\n%2$s + شارِك قائمة التشغيل + شارِك قائمة التشغيل بتفاصيليها مثل اسم قائمة التشغيل وعناوين الفيديو أو كقائمة بسيطة من عناوين تشعّبيّة للفيديوهات + - %1$s: %2$s \ No newline at end of file diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml index 0ac6813ba..930c41afa 100644 --- a/app/src/main/res/values-fi/strings.xml +++ b/app/src/main/res/values-fi/strings.xml @@ -87,7 +87,7 @@ Latausvalikkoa ei voitu asettaa Sovellus/UI kaatui Pahoittelut, noin ei olisi pitänyt käydä. - Raportoi tämä virhe sähköpostin kautta + Raportoi sähköpostin kautta Pahoittelut, jokin meni vikaan. Raportti Mitä tapahtui: @@ -145,7 +145,7 @@ Suurin osa erikoismerkeistä Tietoja NewPipe Kolmannen osapuolen Lisenssit - Tietoja + Tietoja & UKK Lisenssit Vapaata ja kevyttä suoratoistoa Androidilla. Näytä GitHub:ssa @@ -598,7 +598,7 @@ Voit nyt valita tekstin kuvauskentän sisältä. Huomioithan, että valintatilan aikana sivu voi vilkkua ja linkit eivät ehkä ole klikattavia. %s tuo tämän syyn: Säätövivun kuvakkeen esikatselu - Poista median tunnelointi käytöstä, jos havaitset mustan näyttöruudun tai änkytystä videon toistossa + Poista median tunnelointi käytöstä, jos havaitset mustan näyttöruudun tai änkytystä videon toistossa. Poista median tunnelointi käytöstä Nopea syötetila ei tarjoa enempää tietoa tästä. \'Storage Access Framework\' on tuettu vain Android 10:stä alkaen @@ -667,7 +667,7 @@ Toiminnolle ei löytynyt sopivaa tiedostonhallintaohjelmaa. \nAsenna tiedostonhallintaohjelma, joka on yhteensopiva Storage Access Frameworkin kanssa. Toiminnolle ei löytynyt sopivaa tiedostonhallintaohjelmaa. -\nAsenna tiedostonhallintaohjelma tai kokeile asettaa \'%s\' pois käytöstä latausasetuksista. +\nAsenna tiedostonhallintaohjelma tai kokeile asettaa \'%s\' pois käytöstä latausasetuksista Näytä soitinta käytettäessä soittimen kaatamisen vaihtoehto Näytä virheen ponnahdusilmoitus Uudet syötteet @@ -695,4 +695,99 @@ Uusia lähetysvirtoja Muuta progressiivisen sisällön latausvälin kokoa (tällä hetkellä %s). Pienempi arvo saattaa nopeuttaa ensimmäistä latausta. Tästä on hyötyä esim. silloin, jos käyttämiesi kuulokkeiden fyysiset painikkeet eivät toimi. + Kuvanlaatu + Ulkoisille soittimille ei ole saatavilla videostriimiä + Videot + Tuo tai vie tilauksia kolmen pisteen valikosta + Tilaajat + Osittain katsottu + Nopea tila + Näytä seuraavat streamit + Tuntematon + Ilmoitukset uusista streameista + Mitä välilehtiä kanavasivuilla näytetään + Poistetaanko kaksoiskappaleet\? + Näytä/piilota streamit + Jaa URL-luettelo + + %s uusi streami + %s uudet streamit + + Jaa otsikoiden kanssa + Poista kaksoiskappaleet + Shortsit + Harmaana näkyvät soittolistat sisältävät jo tämän kohteen. + Käytä ExoPlayerin dekooderin varatoimintoa + Ilmoitukset on poistettu käytöstä + Tuleva + Ladataan Metadata… + Lataa %s napauttamalla + , + Vaihda näytön suuntaa + Hallitse joitain ExoPlayer-asetuksia. Nämä muutokset edellyttävät soittimen uudelleenkäynnistystä tullakseen voimaan + Kopio lisätty %d kertaa + Heikkolaatu + Päävälilehtien sijainti + Jos sinulla on ongelmia sovelluksen käytössä, muista katsoa nämä vastaukset yleisiin kysymyksiin! + Koko näyttö päälle/pois + Tuntematon laatu + Vaadittu verkkoyhteys + Suorita uusien streamien tarkistaminen + Hae kanavavälilehdet + Usein Kysytyt Kysymykset + Käytät uusinta NewPipen versiota + Avatarit + Ota tämä vaihtoehto käyttöön, jos sinulla on dekooderin alustusongelmia, jotka liittyvät alemman prioriteetin dekooderiin, jos ensisijaisen dekooderin alustus epäonnistuu. Tämä voi heikentää toiston suorituskykyä kuin käytettäessä ensisijaisia dekoodeja + Seuraava stream + Mediatunnelointi oli oletuksena poistettu käytöstä laitteessasi, koska laitemallisi ei tue sitä. + Alikanavan avatarit + Katso verkkosivuilla + Tämä vaihtoehto on käytettävissä vain, jos %s on valittu teemaksi + Tässä streamissa pitäisi jo olla ääniraita + Avaa soittojono + Älä lataa kuvia + Ilmoita tilausten uusista streameista + Korkealaatu + Valitse laatu ulkoisille soittimille + Tietoja + Jaa soittolista + Eteenpäin + Valitse ääniraita ulkoisille soittimille + Tuntematon muoto + Albumit + Ulkoisille soittimille ei ole saatavilla äänistreameja + Kelaa taaksepäin + Noudettavat välilehdet syötettä päivitettäessä. Tällä valinnalla ei ole vaikutusta, jos kanava päivitetään käyttämällä nopeaa tilaa. + Poistetaanko kaikki ladatut tiedostot levyltä\? + Jaa soittolista, jossa on tietoja, kuten soittolistan nimi ja videon nimi, tai yksinkertainen luettelo videoiden URL-osoitteista + Keskilaatu + Lataajan avatarit + Prosentti + Audio: %s + Ulkoiset soittimet eivät tue valittua suoratoistoa + Ilmoitukset uusista tilausten striimeistä + Bannerit + Soittolistat + Järjestä + Siirrä päävälilehden valitsin alas + Mikä tahansa verkko + ExoPlayer oletusarvo + Ääniraita + Kortti + Ei live streamejä + Kopioiminen leikepöydälle epäonnistui + Poista pysyvä pikkukuva + Valitse kuvien laatu ja lataako kuvia ollenkaan, jotta tiedon- ja muistin käyttö vähenee. Muutokset tyhjentävät sekä muistin että levyn kuvavälimuistin – %s + Toista + Lisää vaihtoehtoja + Pikkukuvat + Ladataan streamin tietoja… + ExoPlayerin asetukset + Täysin katsottu + Kesto + Ei streamejä + Kanavat + Olet nyt tilannut tämän kanavan + Edellinen stream + \ No newline at end of file diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 442fe94b9..ff98bc464 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -803,4 +803,9 @@ Shorts Onglets de chaîne à récupérer Onglets à récupérer lors de la mise à jour du flux. Cette option n’a aucun effet si une chaîne est mise à jour en utilisant le mode rapide. + Partager l’URL de la liste + %1$s +\n%2$s + Partager la liste de lecture + - %1$s : %2$s \ No newline at end of file diff --git a/app/src/main/res/values-hi/strings.xml b/app/src/main/res/values-hi/strings.xml index ceb07ca18..9111f9444 100644 --- a/app/src/main/res/values-hi/strings.xml +++ b/app/src/main/res/values-hi/strings.xml @@ -172,7 +172,7 @@ मुख्य पृष्ठ की विषयवस्तु खाली पन्ना कियोस्क पन्ना - चैनल पेज + चैनल पन्ना चैनल चुनें अभी तक किसी चैनल की सब्सक्रिप्शन नहीं है कियोस्क चुनें @@ -277,7 +277,7 @@ \nन्यूपाइप की गोपनीयता नीति विस्तार से समझाती है कि कौनसा डेटा भेजा और संग्रह किया जाता है जब आप क्रेश विवरण भेजते हैं। गोपनीयता नीति पढें क्या आप सेटिंग्स भी आयात करना चाहते हैं\? - तरजीही \'open\' एक्शन + \'खोलने\' पर तरजीही एक्शन सामग्री खोलते समय डिफ़ॉल्ट कारवाही — %s अनुशीर्षक प्लेयर कैप्शन टेक्स्ट स्केल और पृष्ठभूमि शैलियों को संशोधित करें। प्रभावी होने के लिए ऐप को पुनरारंभ करना आवश्यक है @@ -321,7 +321,7 @@ पॉपअप प्लेयर में बदलें न्यूपाइप एक काॅपीलेफ़्ट फ़्री साॅफ़्टवेर है: इसे आप अपनी इच्छा के अनुसार इस्तेमाल, जाँच, बाँट तथा और बेहतर बना सकते है। खास तौर पर आप इसे फ़्री साॅफ़्टवेर फ़ाउंडेशन के द्वारा जारी जीएनयू जनरल पब्लिक लाइसेंस के तीसरे या उसके बाद आने वाले कोई भी वर्णन के शर्तों के मुताबिक फिर से बाँट या बदल सकते हैं। अनसब्सक्राईब करें - टैब चुने + टैब चुनें कतारबद्ध करें अपडेटस फाइल मिटा दी गयी @@ -387,7 +387,7 @@ एक ही समय में एक डाउनलोड चलेगा डाउनलोड प्रारंभ करें डाउनलोड रोकें - डाउनलोड कहाँ करने के लिए पूछे + डाउनलोड कहाँ करना है, के लिए पूछें आपको हर डाउनलोड का स्थान पूछा जाएगा \nयदि आप बाहरी एसडी कार्ड में डाउनलोड करना चाहते हैं तो सिस्टम फोल्डर पिकर (SAF) को सक्षम करें सिस्टम फोल्डर पिकर (SAF) का प्रयोग करें diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index 2ded4d484..e8651d966 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -699,7 +699,7 @@ 빠른 모드 점 3개 메뉴에서 구독 가져오기 또는 내보내기 최신 버전의 NewPipe를 실행 중입니다 - %s를 다운로드하려면 탭하세요. + %s를 다운로드하려면 탭하세요 영구 썸네일 설정 해제 이 옵션은 %s가 테마로 선택되었을 경우에만 사용할 수 있습니다 중복 추가 %d 번 @@ -747,4 +747,50 @@ %1$s %2$s 메인 탭 위치 장치 모델에서 미디어 터널링을 지원하지 않는 것으로 알려져 있기 때문에 장치에서 기본적으로 미디어 터널링이 비활성화되었습니다. + 이미지 품질 + 동영상 + \? + 구독자 + 채널 페이지에 표시되는 탭 + URL 목록 공유 + 타이틀로 공유 + %1$s +\n%2$s + 채널 탭 + 쇼츠 + 메타데이터 불러오기 중… + 화면 방향 전환 + 낮은 품질 + 전체화면 전환 + 채널 탭 가져오기 + 아바타 + 다음 스트림 + 하위 채널 아바타 + 재생 대기열 열기 + 이미지를 불러오지 마세요 + 높은 품질 + 정보 + 재생목록 공유 + 앞으로 + 앨범 + 되감기 + 다시 재생 + 피드를 업데이트할 때 가져올 탭입니다. 빠른 모드를 사용하여 채널을 업데이트하는 경우 이 옵션은 효과가 없습니다. + 재생목록 이름, 동영상 제목 등의 세부정보 또는 간단한 동영상 URL 목록으로 재생목록을 공유하세요 + 중간 품질 + 업로더 아바타 + 배너 + 재생목록 + - %1$s: %2$s + 실시간 스트림 없음 + 데이터 및 메모리 사용량을 줄이기 위해 이미지 품질과 이미지 불러오기 여부를 선택하세요. 변경 사항이 메모리 내 및 디스크 내 이미지 캐시를 모두 지움 — %s + 재생 + 추가 옵션 + 썸네일 + 트랙 + 지속 + 스트림 없음 + 채널 + 이전 스트림 + 실시간 \ No newline at end of file diff --git a/app/src/main/res/values-or/strings.xml b/app/src/main/res/values-or/strings.xml index aefbdc914..fb2cfd675 100644 --- a/app/src/main/res/values-or/strings.xml +++ b/app/src/main/res/values-or/strings.xml @@ -44,7 +44,7 @@ ଏଥିରେ ଖୋଲନ୍ତୁ ବାତିଲ୍ କରନ୍ତୁ ଦେଖାଯାଇଥିବା ପରି ଚିହ୍ନିତ କର - ଡାଉନଲୋଡ୍ କରିବା + ଡାଉନଲୋଡ୍ କରନ୍ତୁ ସେଟିଂ ତୁମେ ଏହା ଚାଂହ କି \"%1$s\"\? ଫାଇଲ୍ ଡାଉନଲୋଡ କରନ୍ତୁ diff --git a/app/src/main/res/values-pa/strings.xml b/app/src/main/res/values-pa/strings.xml index c723bf331..0cad15f71 100644 --- a/app/src/main/res/values-pa/strings.xml +++ b/app/src/main/res/values-pa/strings.xml @@ -243,7 +243,7 @@ ਪੌਪ-ਅਪ ਵਿੱਚ ਚਲਾਉਣਾ ਸ਼ੁਰੂ ਕਰੋ ਡਰਾਅਰ ਖੋਲੋ ਡਰਾਅਰ ਬੰਦ ਕਰੋ - ਤਰਜੀਹੀ \'ਖੋਲ੍ਹੋ\' ਐਕਸ਼ਨ + \'ਖੋਲ੍ਹਣ\' ਤੇ ਤਰਜੀਹੀ ਐਕਸ਼ਨ ਸਮੱਗਰੀ ਖੋਲ੍ਹਣ ਸਮੇਂ ਡਿਫ਼ਾਲਟ ਕਾਰਵਾਈ — %s ਵੀਡੀਓ ਪਲੇਅਰ ਬੈਕਗ੍ਰਾਊਂਡ ਪਲੇਅਰ diff --git a/app/src/main/res/values-pt-rPT/strings.xml b/app/src/main/res/values-pt-rPT/strings.xml index 86465dc57..fa88d003c 100644 --- a/app/src/main/res/values-pt-rPT/strings.xml +++ b/app/src/main/res/values-pt-rPT/strings.xml @@ -537,7 +537,7 @@ Toque para detalhes em pausa Mostrar comentários - Aceitar + Concluído Desativar modo rápido Nunca Apenas em Wi-Fi @@ -775,4 +775,48 @@ O túnel multimédia foi desativado por predefinição no seu dispositivo porque se sabe que o modelo do dispositivo não o suporta. Nenhum vídeo em direto Nenhum vídeo + Qualidade da imagem + Vídeos + \? + Subscritores + Os separadores a mostrar na página Canal + Partilhar lista de URLs + Partilhar com títulos + %1$s +\n%2$s + Separadores do canal + Curtos + A carregar metadados… + Alternar orientação do ecrã + Baixa qualidade + Alternar ecrã completo + Obter separadores de canais + Avatars + Fluxo seguinte + Avatar de subcanais + Abrir fila de reprodução + Não carregar imagens + Alta qualidade + Acerca + Partilhar lista de reprodução + Avançar + Álbuns + Recuar + Repetição + Separadores a obter ao atualizar o feed. Esta opção não tem efeito se um canal for atualizado utilizando o modo rápido. + Partilhe a lista de reprodução com detalhes como o nome da lista de reprodução e os títulos dos vídeos ou como uma simples lista de URLs de vídeos + Média qualidade + Avatar dos publicadores + Bandeiras + Listas de reprodução + - %1$s: %2$s + Escolha a qualidade das imagens e se pretende carregar imagens, para reduzir a utilização de dados e de memória. As alterações limpam a cache de imagens na memória e no disco - %s + Reproduzir + Mais opções + Miniaturas + Faixas + Duração + Canais + Fluxo anterior + Direto \ No newline at end of file diff --git a/fastlane/metadata/android/ar/changelogs/995.txt b/fastlane/metadata/android/ar/changelogs/995.txt new file mode 100644 index 000000000..82acc602b --- /dev/null +++ b/fastlane/metadata/android/ar/changelogs/995.txt @@ -0,0 +1,14 @@ +جديد +• دعم علامات التبويب القناة +• حدد جودة الصورة +• الحصول على عناوين URL لجميع الصور + +تحسين +• إمكانية الوصول إلى واجهات المشغل +• خيار إضافة اسم قائمة التشغيل واسم الفيديو إلى محتوى مشاركة قائمة التشغيل +• التحسينات الداخلية وتحديثات التبعيات + +مُثَبَّت +• اختيار لغات خاطئة في منتقي اللغة +• تركيز صوت المشغل لم يكن يحترم كتم الصوت +• إضافة عناصر إلى قوائم التشغيل لا تعمل في حالات معينة diff --git a/fastlane/metadata/android/cs/changelogs/995.txt b/fastlane/metadata/android/cs/changelogs/995.txt new file mode 100644 index 000000000..325cef51e --- /dev/null +++ b/fastlane/metadata/android/cs/changelogs/995.txt @@ -0,0 +1,14 @@ +Nové +• Podpora karet kanálů +• Výběr kvality obrázků +• Získání URL všech obrázků + +Vylepšeno +• Přístupnost rozhraní přehrávače +• Možnost přidat název playlistu a název videa do sdíleného obsahu playlistu +• Interní vylepšení a aktualizace závislostí + +Opraveno +• Výběr nesprávných jazyků ve výběru jazyka +• Zaměření zvuku přehrávače nerespektovalo ztlumení +• Přidávání položek do playlistů v určitých případech nefungovalo diff --git a/fastlane/metadata/android/es/changelogs/995.txt b/fastlane/metadata/android/es/changelogs/995.txt new file mode 100644 index 000000000..5c13533fa --- /dev/null +++ b/fastlane/metadata/android/es/changelogs/995.txt @@ -0,0 +1,14 @@ +Nuevo +• Pestañas del canal +• Calidad de la imagen +• URLs a todas las imágenes + +Mejorado +• Accesibilidad de las interfaces de los reproductores +• Opción para añadir el nombre de la lista de reproducción y el nombre del vídeo a la lista de reproducción compartida +• Mejoras internas y actualizaciones de dependencias + +Fijo +• Idiomas incorrectos en el selector de idiomas +• El audio del reproductor no se silenciaba +• Agregar elementos a listas de reproducción que no funcionan en casos específicos diff --git a/fastlane/metadata/android/he/changelogs/995.txt b/fastlane/metadata/android/he/changelogs/995.txt new file mode 100644 index 000000000..c0fab1e52 --- /dev/null +++ b/fastlane/metadata/android/he/changelogs/995.txt @@ -0,0 +1,14 @@ +חדש +• תמיכה בלשוניות ערוצים +• בחירת איכות תמונה +• קבלת כתובות לכל התמונות + +משופר +• גישה למנשקי הנגן +• אפשרות להוספת שם רשימת נגינה ושם סרטון לתוכן שמשותף ברשימת נגינה +• שיפורים פנימיים ועדכוני תלויות + +תוקן +• בחירה בשפה הלא נכונה בבורר השפות +• מיקוד השמע של הנגן לא כיבד השתקה +• הוספת פריטים לרשימות נגינה לא עבדה במקרים מסוימים diff --git a/fastlane/metadata/android/hi/changelogs/995.txt b/fastlane/metadata/android/hi/changelogs/995.txt new file mode 100644 index 000000000..ecba503d9 --- /dev/null +++ b/fastlane/metadata/android/hi/changelogs/995.txt @@ -0,0 +1,14 @@ +नया +• चैनल टैब्स का समर्थन करें +• छवि गुणवत्ता का चयन करें +• सभी छवियों के यूआरएल प्राप्त करें + +सुधार किए +• प्लेयर इंटरफ़ेस की पहुंच +• प्लेलिस्ट साझाकरण सामग्री में प्लेलिस्ट का नाम और वीडियो का नाम जोड़ने का विकल्प +• आंतरिक सुधार और निर्भरता अद्यतन + +ठीक किए +• भाषा चयनकर्ता में गलत भाषाओं का चयन +• प्लेयर ऑडियो फोकस म्यूट का सम्मान नहीं कर रहा था +• प्लेलिस्ट में आइटम जोड़ना विशिष्ट मामलों में काम नहीं कर रहा था diff --git a/fastlane/metadata/android/id/changelogs/65.txt b/fastlane/metadata/android/id/changelogs/65.txt index 34cf20dec..4fad1200f 100644 --- a/fastlane/metadata/android/id/changelogs/65.txt +++ b/fastlane/metadata/android/id/changelogs/65.txt @@ -1,4 +1,4 @@ -###Peningkatan +### peningkatan - Nonaktifkan Animasi Ikon burgermenu #1486 - Kembali (undo) hapus unduhan #1472 diff --git a/fastlane/metadata/android/id/changelogs/66.txt b/fastlane/metadata/android/id/changelogs/66.txt new file mode 100644 index 000000000..62c8fd3e7 --- /dev/null +++ b/fastlane/metadata/android/id/changelogs/66.txt @@ -0,0 +1,33 @@ +# Catatan perubahan v0.13.7 + +### Diperbaiki +- Perbaiki masalah filter pengurutan v0.13.6 + +# Changelog v0.13.6 + +### Perbaikan + +- Nonaktifkan animasi ikon menu burger #1486 +- batalkan penghapusan unduhan #1472 +- Opsi unduh di menu berbagi #1498 +- Menambahkan opsi berbagi ke menu ketuk panjang #1454 +- Minimalkan pemain utama di pintu keluar #1354 +- Pembaruan versi perpustakaan dan perbaikan cadangan basis data #1510 +- Pembaruan ExoPlayer 2.8.2 #1392 + - Mengolah ulang dialog kontrol kecepatan pemutaran untuk mendukung ukuran langkah yang berbeda untuk perubahan kecepatan yang lebih cepat. + - Menambahkan tombol untuk maju cepat selama hening di kontrol kecepatan pemutaran. Ini akan berguna untuk buku audio dan genre musik tertentu, dan dapat menghadirkan pengalaman yang benar-benar mulus (dan dapat memecah lagu dengan banyak keheningan =\\). + - Resolusi sumber media yang difaktorkan ulang untuk memungkinkan penyampaian metadata bersama media secara internal di pemutar, daripada melakukannya secara manual. Sekarang kami memiliki satu sumber metadata dan langsung tersedia saat pemutaran dimulai. + - Memperbaiki metadata daftar putar jarak jauh yang tidak diperbarui ketika metadata baru tersedia ketika fragmen daftar putar dibuka. + - Berbagai perbaikan UI: #1383, kontrol notifikasi pemutar latar belakang kini selalu berwarna putih, lebih mudah untuk mematikan pemutar popup melalui lemparan +- Gunakan ekstraktor baru dengan arsitektur yang difaktorkan ulang untuk multilayanan + +### Perbaikan + +- Perbaiki #1440 Tata Letak Info Video Rusak #1491 +- Lihat perbaikan riwayat #1497 + - #1495, dengan memperbarui metadata (thumbnail, judul, dan jumlah video) segera setelah pengguna mengakses playlist. + - #1475, dengan mendaftarkan tampilan di database saat pengguna memulai video di pemutar eksternal pada fragmen detail. +- Perbaiki batas waktu layar jika ada mode popup. #1463 (Diperbaiki #640) +- Perbaikan pemutar video utama #1509 + - [#1412] Memperbaiki mode pengulangan yang menyebabkan NPE pemain ketika niat baru diterima saat aktivitas pemain berada di latar belakang. + - Memperbaiki meminimalkan pemain ke popup tidak menghancurkan pemain ketika izin popup tidak diberikan. diff --git a/fastlane/metadata/android/id/changelogs/974.txt b/fastlane/metadata/android/id/changelogs/974.txt new file mode 100644 index 000000000..4cdc5ab55 --- /dev/null +++ b/fastlane/metadata/android/id/changelogs/974.txt @@ -0,0 +1,5 @@ +Perbaikan terbaru +• Memperbaiki masalah buffering yang disebabkan oleh pembatasan YouTube +• Memperbaiki ekstraksi komentar YouTube dan kerusakan pada komentar yang dinonaktifkan +• Perbaiki pencarian musik YouTube +• Perbaiki streaming langsung PeerTube diff --git a/fastlane/metadata/android/id/changelogs/975.txt b/fastlane/metadata/android/id/changelogs/975.txt new file mode 100644 index 000000000..65e6bcebd --- /dev/null +++ b/fastlane/metadata/android/id/changelogs/975.txt @@ -0,0 +1,17 @@ +Baru +• Tampilkan pratinjau thumbnail saat mencari +• Mendeteksi komentar yang dinonaktifkan +• Izinkan menandai item feed sebagai ditonton +• Tampilkan komentar hati + +Ditingkatkan +• Memperbaiki metadata dan tata letak tag +• Menerapkan warna layanan ke komponen UI + +Tetap +• Perbaiki thumbnail di mini player +• Memperbaiki buffering tanpa akhir pada item antrian duplikat +• Beberapa perbaikan pemain seperti rotasi dan penutupan lebih cepat +• Perbaiki ReCAPTCHA yang tersisa dimuat di latar belakang +• Nonaktifkan klik saat menyegarkan feed +• Memperbaiki beberapa pengunduh yang mogok diff --git a/fastlane/metadata/android/id/changelogs/976.txt b/fastlane/metadata/android/id/changelogs/976.txt new file mode 100644 index 000000000..d76b10e91 --- /dev/null +++ b/fastlane/metadata/android/id/changelogs/976.txt @@ -0,0 +1,10 @@ +• Ditambahkan opsi untuk langsung membuka pemutar dalam layar penuh +• Izinkan memilih jenis saran pencarian yang akan ditampilkan +• Tema gelap kini lebih gelap + layar splash gelap ditambahkan +• Peningkatan pemilih file untuk menghilangkan file yang tidak diinginkan +• Memperbaiki impor langganan YouTube +• Memutar ulang streaming memerlukan ketukan pada tombol putar ulang lagi +• Memperbaiki sesi audio penutup +• [Android TV] Memperbaiki lompatan seekbar yang panjang saat menggunakan DPad + +Untuk melihat perubahan lebih lanjut, lihat log perubahan (dan postingan blog) dari tab Tautan di bawah. diff --git a/fastlane/metadata/android/id/changelogs/977.txt b/fastlane/metadata/android/id/changelogs/977.txt new file mode 100644 index 000000000..11df38bd9 --- /dev/null +++ b/fastlane/metadata/android/id/changelogs/977.txt @@ -0,0 +1,10 @@ +• Menambahkan tombol "mainkan berikutnya" ke menu tekan lama +• Menambahkan awalan jalur pendek YouTube ke filter maksud +• Impor Pengaturan Tetap +• Tukar posisi seekbar dengan tombol pemutar di layar Antrian +• Berbagai perbaikan terkait MediasessionManager +• Memperbaiki bilah pencari yang tidak selesai setelah video berakhir +• Menonaktifkan terowongan media di RealtekATV +• Memperluas area yang dapat diklik tombol pemutar yang diperkecil + +Untuk melihat perubahan lebih lanjut, lihat log perubahan (dan postingan blog) dari tab Tautan di bawah. diff --git a/fastlane/metadata/android/id/changelogs/978.txt b/fastlane/metadata/android/id/changelogs/978.txt new file mode 100644 index 000000000..6b452521a --- /dev/null +++ b/fastlane/metadata/android/id/changelogs/978.txt @@ -0,0 +1 @@ +Memperbaiki pelaksanaan pemeriksaan untuk versi NewPipe baru. Pemeriksaan ini terkadang dilakukan terlalu dini sehingga menyebabkan aplikasi mogok. Itu harus diperbaiki sekarang. diff --git a/fastlane/metadata/android/id/changelogs/979.txt b/fastlane/metadata/android/id/changelogs/979.txt new file mode 100644 index 000000000..abc741c86 --- /dev/null +++ b/fastlane/metadata/android/id/changelogs/979.txt @@ -0,0 +1,2 @@ +- Memperbaiki melanjutkan pemutaran +- Perbaikan untuk memastikan bahwa layanan yang menentukan apakah NewPipe harus memeriksa pemeriksaan versi baru tidak dimulai di latar belakang diff --git a/fastlane/metadata/android/id/changelogs/980.txt b/fastlane/metadata/android/id/changelogs/980.txt new file mode 100644 index 000000000..13a173f5d --- /dev/null +++ b/fastlane/metadata/android/id/changelogs/980.txt @@ -0,0 +1,13 @@ +Baru +• Menambahkan opsi "Tambahkan ke playlist" untuk berbagi menu +• Menambahkan dukungan untuk tautan pendek y2u.be dan PeerTube + +Ditingkatkan +• Membuat Kontrol Kecepatan Pemutaran menjadi lebih ringkas +• Feed menyoroti item baru sekarang +• Opsi "Tampilkan item yang ditonton" di feed kini disimpan + +Tetap +• Memperbaiki ekstraksi suka dan tidak suka YouTube +• Memperbaiki pemutaran ulang otomatis setelah kembali dari latar belakang +Dan banyak lagi diff --git a/fastlane/metadata/android/id/changelogs/981.txt b/fastlane/metadata/android/id/changelogs/981.txt new file mode 100644 index 000000000..f3b556443 --- /dev/null +++ b/fastlane/metadata/android/id/changelogs/981.txt @@ -0,0 +1,2 @@ +Menghapus dukungan MediaParser untuk memperbaiki pemutaran yang gagal dilanjutkan setelah buffering di Android 11+. +Menonaktifkan terowongan media pada Philips QM16XE untuk memperbaiki masalah pemutaran. diff --git a/fastlane/metadata/android/id/changelogs/982.txt b/fastlane/metadata/android/id/changelogs/982.txt new file mode 100644 index 000000000..871132855 --- /dev/null +++ b/fastlane/metadata/android/id/changelogs/982.txt @@ -0,0 +1 @@ +Memperbaiki YouTube yang tidak memutar streaming apa pun. diff --git a/fastlane/metadata/android/id/changelogs/983.txt b/fastlane/metadata/android/id/changelogs/983.txt new file mode 100644 index 000000000..3ee5449c2 --- /dev/null +++ b/fastlane/metadata/android/id/changelogs/983.txt @@ -0,0 +1,9 @@ +Tambahkan UI dan perilaku ketuk dua kali untuk mencari +Jadikan pengaturan dapat dicari +Sorot komentar yang disematkan seperti itu +Tambahkan dukungan terbuka dengan aplikasi untuk instance PeerTube FSFE +Tambahkan pemberitahuan kesalahan +Perbaiki pemutaran ulang item antrian pertama saat pergantian pemain +Tunggu lebih lama saat melakukan buffering selama streaming langsung sebelum gagal +Perbaiki urutan hasil pencarian lokal +Perbaiki bidang item kosong di antrian putar diff --git a/fastlane/metadata/android/id/changelogs/984.txt b/fastlane/metadata/android/id/changelogs/984.txt new file mode 100644 index 000000000..f0e1b2970 --- /dev/null +++ b/fastlane/metadata/android/id/changelogs/984.txt @@ -0,0 +1,7 @@ +Muat item awal secukupnya dalam daftar untuk memenuhi seluruh layar dan untuk memperbaiki pengguliran di tablet dan TV +Perbaiki kerusakan acak saat menelusuri daftar +Minta pemain untuk mencari overlay dengan cepat di bawah UI sistem +Mengembalikan perubahan pada potongan saat memutar di multi jendela, menyebabkan regresi pemutar salah tempat di beberapa ponsel +Tingkatkan kompilasiSdk dari 30 menjadi 31 +Perbarui pustaka pelaporan kesalahan +Refactor beberapa kode di pemutar diff --git a/fastlane/metadata/android/id/changelogs/985.txt b/fastlane/metadata/android/id/changelogs/985.txt new file mode 100644 index 000000000..d3fea84ab --- /dev/null +++ b/fastlane/metadata/android/id/changelogs/985.txt @@ -0,0 +1 @@ +Memperbaiki YouTube yang tidak memutar streaming apa pun diff --git a/fastlane/metadata/android/id/changelogs/987.txt b/fastlane/metadata/android/id/changelogs/987.txt new file mode 100644 index 000000000..b31a40dc0 --- /dev/null +++ b/fastlane/metadata/android/id/changelogs/987.txt @@ -0,0 +1,12 @@ +Baru +• Mendukung metode pengiriman selain HTTP progresif: waktu pemuatan pemutaran lebih cepat, perbaikan untuk PeerTube dan SoundCloud, pemutaran streaming langsung YouTube yang baru saja berakhir +• Tombol Tambah untuk menambahkan playlist jarak jauh ke playlist lokal +• Pratinjau gambar di lembar berbagi Android 10+ + +Ditingkatkan +• Meningkatkan dialog parameter pemutaran +• Pindahkan tombol ekspor-impor langganan ke menu tiga titik + +Tetap +• Perbaiki penghapusan video yang ditonton sepenuhnya dari daftar putar +• Perbaiki tema menu berbagi dan entri "tambahkan ke daftar putar". diff --git a/fastlane/metadata/android/id/changelogs/988.txt b/fastlane/metadata/android/id/changelogs/988.txt new file mode 100644 index 000000000..6433bfa54 --- /dev/null +++ b/fastlane/metadata/android/id/changelogs/988.txt @@ -0,0 +1,2 @@ +[YouTube] Perbaiki kesalahan "Tidak dapat memperoleh streaming apa pun" saat mencoba memutar video apa pun +[YouTube] Perbaiki "Konten berikut tidak tersedia di aplikasi ini." pesan ditampilkan alih-alih video yang diminta diff --git a/fastlane/metadata/android/id/changelogs/989.txt b/fastlane/metadata/android/id/changelogs/989.txt new file mode 100644 index 000000000..d388366dd --- /dev/null +++ b/fastlane/metadata/android/id/changelogs/989.txt @@ -0,0 +1,3 @@ +• [YouTube] Perbaiki pemuatan tanpa batas saat mencoba memutar video apa pun +• [YouTube] Memperbaiki pembatasan pada beberapa video +• Tingkatkan perpustakaan jsoup ke 1.15.3, yang mencakup perbaikan keamanan diff --git a/fastlane/metadata/android/id/changelogs/990.txt b/fastlane/metadata/android/id/changelogs/990.txt new file mode 100644 index 000000000..ac117f405 --- /dev/null +++ b/fastlane/metadata/android/id/changelogs/990.txt @@ -0,0 +1,15 @@ +Rilis ini menghilangkan dukungan untuk Android 4.4 KitKat, sekarang versi minimumnya adalah Android 5 Lollipop! + +Baru +• Download dari menu tekan lama +• Sembunyikan video mendatang di feed +• Bagikan playlist lokal + +Ditingkatkan +• Memfaktorkan ulang kode pemutar menjadi komponen-komponen kecil: lebih sedikit RAM yang digunakan, lebih sedikit bug +• Meningkatkan mode skala thumbnail +• Placeholder gambar berukuran vektor + +Tetap +• Memperbaiki berbagai masalah dengan notifikasi pemutar: info media yang ketinggalan jaman, gambar mini yang terdistorsi +• Perbaiki layar penuh menggunakan 1/4 layar diff --git a/fastlane/metadata/android/it/changelogs/995.txt b/fastlane/metadata/android/it/changelogs/995.txt new file mode 100644 index 000000000..8da9a7ee7 --- /dev/null +++ b/fastlane/metadata/android/it/changelogs/995.txt @@ -0,0 +1,14 @@ +Novità +• Supporto a schede dei canali +• Selezione qualità dell'immagine +• Ottieni URL per tutte le immagini + +Migliorato +• Accessibilità delle interfacce del player +• Opzione per aggiungere il nome della playlist e il nome video al contenuto di condivisione della playlist +• Miglioramenti interni e aggiornamenti delle dipendenze + +Corretto +• Selezione di lingue errate nel selettore +• Il focus audio del player non rispettava il muto +• Aggiungere elementi a playlist non funzionava in casi specifici diff --git a/fastlane/metadata/android/pa/changelogs/995.txt b/fastlane/metadata/android/pa/changelogs/995.txt new file mode 100644 index 000000000..dc9c576c9 --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/995.txt @@ -0,0 +1,14 @@ +ਨਵਾਂ +• ਚੈਨਲ ਟੈਬਾਂ ਦਾ ਸਮਰਥਨ ਕਰੋ +• ਚਿੱਤਰ ਗੁਣਵੱਤਾ ਚੁਣੋ +• ਸਾਰੀਆਂ ਤਸਵੀਰਾਂ ਲਈ URL ਪ੍ਰਾਪਤ ਕਰੋ + +ਸੁਧਾਰ +• ਪਲੇਅਰ ਇੰਟਰਫੇਸ ਦੀ ਪਹੁੰਚਯੋਗਤਾ +• ਪਲੇਲਿਸਟ ਸ਼ੇਅਰਿੰਗ ਸਮੱਗਰੀ ਵਿੱਚ ਪਲੇਲਿਸਟ ਨਾਮ ਅਤੇ ਵੀਡੀਓ ਨਾਮ ਜੋੜਨ ਲਈ ਵਿਕਲਪ +• ਅੰਦਰੂਨੀ ਸੁਧਾਰ ਅਤੇ ਨਿਰਭਰਤਾ ਅੱਪਡੇਟ + +ਠੀਕ ਕੀਤੇ +• ਭਾਸ਼ਾ ਚੋਣਕਾਰ ਵਿੱਚ ਗਲਤ ਭਾਸ਼ਾਵਾਂ ਦੀ ਚੋਣ +• ਪਲੇਅਰ ਆਡੀਓ ਫੋਕਸ ਮਿਊਟ ਦਾ ਆਦਰ ਨਹੀਂ ਕਰ ਰਿਹਾ ਸੀ +• ਖਾਸ ਮਾਮਲਿਆਂ ਵਿੱਚ ਪਲੇਲਿਸਟਾਂ ਵਿੱਚ ਆਈਟਮਾਂ ਨੂੰ ਜੋੜਨਾ ਕੰਮ ਨਹੀਂ ਕਰ ਰਿਹਾ ਸੀ diff --git a/fastlane/metadata/android/pl/changelogs/995.txt b/fastlane/metadata/android/pl/changelogs/995.txt new file mode 100644 index 000000000..ffbcbf374 --- /dev/null +++ b/fastlane/metadata/android/pl/changelogs/995.txt @@ -0,0 +1,14 @@ +Nowe +• Obsługa kart kanałów +• Wybieranie jakości obrazów +• Uzyskiwanie adresów URL do wszystkich obrazów + +Ulepszone +• Dostępność interfejsów odtwarzacza +• Opcja dodania nazwy playlisty i tytułów wideo do udostępnianej zawartości playlisty +• Wewnętrzne ulepszenia i aktualizacje zależności + +Naprawione +• Wybór błędnych języków w selektorze języków +• Skupienie na dźwięku odtwarzacza nie uwzględniało wyciszenia +• Dodawanie pozycji do playlist nie działało w określonych przypadkach diff --git a/fastlane/metadata/android/sr/changelogs/995.txt b/fastlane/metadata/android/sr/changelogs/995.txt new file mode 100644 index 000000000..fd8da6381 --- /dev/null +++ b/fastlane/metadata/android/sr/changelogs/995.txt @@ -0,0 +1,14 @@ +Ново +• Подршка за картице канала +• Могућност бирања квалитета слике +• Набавите URL адресе за све слике + +Побољшано +• Приступачност интерфејса плејера +• Опција за опцију додавања назива плејлисте и назива видео снимка у садржај листе за дељење +• Интерна побољшања и ажурирања зависности + +Поправљено +• Избор погрешних језика у бирачу језика +• Аудио фокус плејера није поштовао искључен звук +• Додавање ставки на плејлисте не функционише у одређеним случајевима diff --git a/fastlane/metadata/android/uk/changelogs/995.txt b/fastlane/metadata/android/uk/changelogs/995.txt new file mode 100644 index 000000000..1cd40224a --- /dev/null +++ b/fastlane/metadata/android/uk/changelogs/995.txt @@ -0,0 +1,14 @@ +Нове +• Підтримка вкладок каналів +• Вибір якості зображення +• Отримання URL всіх зображень + +Поліпшено +• Доступність інтерфейсів програвачів +• Додано можливість додавати назву добірки й назву відео поширюваного вмісту добірки +• Внутрішні вдосконалення й оновлення залежностей + +Виправлено +• Вибір неправильних мов у перемикачі мов +• Фокусування звуку програвача не враховувало вимкнення звуку +• Додавання елементів у добірки не працювало у певних випадках From b18ccffeb4a00519df3f10da4cd3f152356a0d02 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Sat, 7 Oct 2023 15:39:43 +0000 Subject: [PATCH 145/172] Added translation using Weblate (English (Middle)) Deleted translation using Weblate (German (Low)) Deleted translation using Weblate (English (Old)) Deleted translation using Weblate (English (Middle)) Deleted translation using Weblate (Burmese) Deleted translation using Weblate (Aymara) Deleted translation using Weblate (Arabic (Najdi)) Co-authored-by: TobiGr Co-authored-by: Weblate --- app/src/main/res/values-ang/strings.xml | 2 -- app/src/main/res/values-ars/strings.xml | 2 -- app/src/main/res/values-ay/strings.xml | 2 -- app/src/main/res/values-my/strings.xml | 2 -- app/src/main/res/values-nds/strings.xml | 2 -- 5 files changed, 10 deletions(-) delete mode 100644 app/src/main/res/values-ang/strings.xml delete mode 100644 app/src/main/res/values-ars/strings.xml delete mode 100644 app/src/main/res/values-ay/strings.xml delete mode 100644 app/src/main/res/values-my/strings.xml delete mode 100644 app/src/main/res/values-nds/strings.xml diff --git a/app/src/main/res/values-ang/strings.xml b/app/src/main/res/values-ang/strings.xml deleted file mode 100644 index a6b3daec9..000000000 --- a/app/src/main/res/values-ang/strings.xml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/app/src/main/res/values-ars/strings.xml b/app/src/main/res/values-ars/strings.xml deleted file mode 100644 index a6b3daec9..000000000 --- a/app/src/main/res/values-ars/strings.xml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/app/src/main/res/values-ay/strings.xml b/app/src/main/res/values-ay/strings.xml deleted file mode 100644 index a6b3daec9..000000000 --- a/app/src/main/res/values-ay/strings.xml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/app/src/main/res/values-my/strings.xml b/app/src/main/res/values-my/strings.xml deleted file mode 100644 index a6b3daec9..000000000 --- a/app/src/main/res/values-my/strings.xml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/app/src/main/res/values-nds/strings.xml b/app/src/main/res/values-nds/strings.xml deleted file mode 100644 index a6b3daec9..000000000 --- a/app/src/main/res/values-nds/strings.xml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file From 626daf89c135d2d9f5611d8a74183857069c5926 Mon Sep 17 00:00:00 2001 From: TobiGr Date: Sat, 7 Oct 2023 17:39:44 +0200 Subject: [PATCH 146/172] Deleted translation using Weblate (Kashmiri) --- app/src/main/res/values-ks/strings.xml | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 app/src/main/res/values-ks/strings.xml diff --git a/app/src/main/res/values-ks/strings.xml b/app/src/main/res/values-ks/strings.xml deleted file mode 100644 index a6b3daec9..000000000 --- a/app/src/main/res/values-ks/strings.xml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file From 6f51c47dc9edcfa7e176606ba1edd7c4c8c757ab Mon Sep 17 00:00:00 2001 From: TobiGr Date: Sat, 7 Oct 2023 17:39:49 +0200 Subject: [PATCH 147/172] Deleted translation using Weblate (Sicilian) --- app/src/main/res/values-scn/strings.xml | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 app/src/main/res/values-scn/strings.xml diff --git a/app/src/main/res/values-scn/strings.xml b/app/src/main/res/values-scn/strings.xml deleted file mode 100644 index a6b3daec9..000000000 --- a/app/src/main/res/values-scn/strings.xml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file From 6d0bb02544ae182328ca29d6189d8846613ab283 Mon Sep 17 00:00:00 2001 From: akko Date: Fri, 13 Oct 2023 11:28:09 +0700 Subject: [PATCH 148/172] adds quotation to create filename util replacement char --- app/src/main/java/org/schabi/newpipe/util/FilenameUtils.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/schabi/newpipe/util/FilenameUtils.java b/app/src/main/java/org/schabi/newpipe/util/FilenameUtils.java index edcb565a0..bc15f3f02 100644 --- a/app/src/main/java/org/schabi/newpipe/util/FilenameUtils.java +++ b/app/src/main/java/org/schabi/newpipe/util/FilenameUtils.java @@ -7,6 +7,7 @@ import androidx.preference.PreferenceManager; import org.schabi.newpipe.R; +import java.util.regex.Matcher; import java.util.regex.Pattern; public final class FilenameUtils { @@ -51,7 +52,7 @@ public final class FilenameUtils { final Pattern pattern = Pattern.compile(charset); - return createFilename(title, pattern, replacementChar); + return createFilename(title, pattern, Matcher.quoteReplacement(replacementChar)); } /** From 995986ecc756ec2558b08d9eaded4b50b2fc2283 Mon Sep 17 00:00:00 2001 From: TobiGr Date: Fri, 13 Oct 2023 17:26:15 +0200 Subject: [PATCH 149/172] [README] Remove Bitcoin and Bountysource donation options --- README.md | 10 ---------- doc/README.asm.md | 2 +- doc/README.de.md | 10 ---------- doc/README.es.md | 10 ---------- doc/README.fr.md | 10 ---------- doc/README.hi.md | 10 ---------- doc/README.it.md | 10 ---------- doc/README.ja.md | 10 ---------- doc/README.ko.md | 10 ---------- doc/README.pa.md | 10 ---------- doc/README.pl.md | 10 ---------- doc/README.pt_BR.md | 10 ---------- doc/README.ro.md | 10 ---------- doc/README.ru.md | 10 ---------- doc/README.ryu.md | 10 ---------- doc/README.so.md | 10 ---------- doc/README.sr.md | 10 ---------- doc/README.tr.md | 10 ---------- doc/README.zh_TW.md | 10 ---------- 19 files changed, 1 insertion(+), 181 deletions(-) diff --git a/README.md b/README.md index ed25bfa41..58ac79886 100644 --- a/README.md +++ b/README.md @@ -126,16 +126,6 @@ If you like NewPipe, you're welcome to send a donation. We prefer Liberapay, as Visit NewPipe at liberapay.com Donate via Liberapay - - Bitcoin - Bitcoin QR code - 16A9J59ahMRqkLSZjhYj33n9j3fMztFxnh - - - Bountysource - Visit NewPipe at bountysource.com - Check out how many bounties you can earn. - ## Privacy Policy diff --git a/doc/README.asm.md b/doc/README.asm.md index 98253371e..8f39d26a1 100644 --- a/doc/README.asm.md +++ b/doc/README.asm.md @@ -110,7 +110,7 @@ NewPipe এ আপুনি ব্যৱহাৰ কৰা সেৱাৰ অ ## অনুদান -যদি আপুনি NewPipe ভাল পায় তেন্তে অনুদান প্ৰেৰণ কৰিব পাৰে। আমি Liberapay পছন্দ কৰো, কাৰণ ই মুক্ত উৎস(Open Source) আৰু অলাভজনক(Non-profit) দুয়োটা। NewPipe লৈ দান দিয়াৰ বিষয়ে অধিক তথ্যৰ বাবে অনুগ্ৰহ কৰি আমাৰ [ৱেবচাইট](https://newpipe.net/donate) চাওক.
    Liberapay Visit NewPipe at liberapay.com Donate via Liberapay
    Bitcoin Bitcoin QR code 16A9J59ahMRqkLSZjhYj33n9j3fMztFxnh
    Bountysource Visit NewPipe at bountysource.com Check out how many bounties you can earn.
    +যদি আপুনি NewPipe ভাল পায় তেন্তে অনুদান প্ৰেৰণ কৰিব পাৰে। আমি Liberapay পছন্দ কৰো, কাৰণ ই মুক্ত উৎস(Open Source) আৰু অলাভজনক(Non-profit) দুয়োটা। NewPipe লৈ দান দিয়াৰ বিষয়ে অধিক তথ্যৰ বাবে অনুগ্ৰহ কৰি আমাৰ [ৱেবচাইট](https://newpipe.net/donate) চাওক.
    Liberapay Visit NewPipe at liberapay.com Donate via Liberapay
    ## গোপনীয়তা নীতি diff --git a/doc/README.de.md b/doc/README.de.md index b84fadeae..cc9c313fa 100644 --- a/doc/README.de.md +++ b/doc/README.de.md @@ -143,16 +143,6 @@ Für weitere Informationen über Spenden an NewPipe, besuche unsere [Website](ht Gehe zu NewPipe auf liberapay.com Spenden mit Liberapay - - Bitcoin - Bitcoin QR Code - 16A9J59ahMRqkLSZjhYj33n9j3fMztFxnh - - - Bountysource - Gehe zu NewPipe auf bountysource.com - Sieh nach, wie viel Bounties du bekommen kannst. - ## Privacy Policy diff --git a/doc/README.es.md b/doc/README.es.md index 78c44b9fb..c2959fe04 100644 --- a/doc/README.es.md +++ b/doc/README.es.md @@ -115,21 +115,11 @@ Si quiere involucrarse, fíjese en nuestras [notas de contribución](../.github/ Si te gusta NewPipe, estaremos felices con una donación. Puede enviar bitcoin o donar a través de Bountysource o Liberapay. Visita nuestro [sitio web](https://newpipe.net/donate) para más información. - - - - - - - - - -
    BitcoinCódigo QR del Bitcoin16A9J59ahMRqkLSZjhYj33n9j3fMztFxnh
    Liberapay Visita NewPipe en liberapay.com Dona vía Liberapay
    BountysourceVisita NewPipe en bountysource.comRevisa cuántas recompensas puedes obtener.
    ## Política de Privacidad diff --git a/doc/README.fr.md b/doc/README.fr.md index 4ca1f1e94..2e56e7ff1 100644 --- a/doc/README.fr.md +++ b/doc/README.fr.md @@ -123,16 +123,6 @@ Si vous aimez NewPipe, vous êtes invités à envoyer un don. Nous préferons Li Visitez NewPipe sur liberapay.com Donnez via Liberapay - - Bitcoin - QR code Bitcoin - 16A9J59ahMRqkLSZjhYj33n9j3fMztFxnh - - - Bountysource - Visitez NewPipe sur bountysource.com - Regardez combien de primes vous pouvez gagner. - ## Politique de confidentialité diff --git a/doc/README.hi.md b/doc/README.hi.md index ec9965be6..36669cc19 100644 --- a/doc/README.hi.md +++ b/doc/README.hi.md @@ -115,21 +115,11 @@ NewPipe पर कई सेवाएँ उपलब्ध हैं। हम अगर आपको NewPipe पसंद है, एक छोटे-से दान से हम खुश होंगे। आप या तो बिटकॉइन भेज सकते हैं या फिर Bountysource या Liberapay से दान कर सकते हैं। NewPipe को दान करने के बारे में अधिक जानकारी के लिए कृपया हमारी [वेबसाइट](https://newpipe.net/donate) देखें। - - - - - - - - - -
    Bitcoinबिटकॉइन पर दान करने के लिए QR कोड16A9J59ahMRqkLSZjhYj33n9j3fMztFxnh
    Liberapay liberapay.com पर NewPipe को देखें Liberapay के ज़रिए दान करें
    Bountysourcebountysource.com पर NewPipe को देखेंदेखें कि आप कितने बाउंटी कमा सकते हैं।
    ## गोपनीयता और शर्तें diff --git a/doc/README.it.md b/doc/README.it.md index ec5361dc0..cd8cb10a8 100644 --- a/doc/README.it.md +++ b/doc/README.it.md @@ -123,16 +123,6 @@ Se ti piace NewPipe, le donazioni sono benvenute. Preferiamo Liberapay, siccome Visita NewPipe su liberapay.com Dona via Liberapay - - Bitcoin - Codice QR Bitcoin - 16A9J59ahMRqkLSZjhYj33n9j3fMztFxnh - - - Bountysource - Visita NewPipe su bountysource.com - Scopri quanti <i>bounty</i> puoi guadagnare. - ## Privacy Policy diff --git a/doc/README.ja.md b/doc/README.ja.md index fa26efa0d..317d39766 100644 --- a/doc/README.ja.md +++ b/doc/README.ja.md @@ -120,21 +120,11 @@ NewPipe は複数のサービスに対応しています。[ドキュメント]( もし、NewPipe を気に入っていただけたら、寄付をしていただけると嬉しいです。Bitcoin または Bountysource, Liberapay から寄付をすることができます。NewPipe への寄付については、[ウェブサイト](https://newpipe.net/donate)からお願いします。 - - - - - - - - - -
    BitcoinBitcoin QR コード16A9J59ahMRqkLSZjhYj33n9j3fMztFxnh
    Liberapay liberapay.com で NewPipe を訪れる Liberapay で寄付
    Bountysourcebountysource.com で NewPipe を訪れるあなたがどれほどの寄付を得られるのか確認しましょう。
    ## プライバシーポリシー diff --git a/doc/README.ko.md b/doc/README.ko.md index 9ebc66be2..b690e659a 100644 --- a/doc/README.ko.md +++ b/doc/README.ko.md @@ -115,21 +115,11 @@ NewPipe는 서비스의 공식 API를 이용하여 정보를 받아오는 방식 만약 NewPipe가 마음에 들었다면, 우리는 기부에 대해 기꺼이 환영합니다. bitcoin을 보내거나, Bountysource 또는 Liberapay를 통해 기부할 수 있습니다. NewPipe에 기부하는 것에 대한 자세한 정보를 원한다면, 우리의 [웹사이트](https://newpipe.net/donate)를 방문하여 주십시오. - - - - - - - - - -
    BitcoinBitcoin QR code16A9J59ahMRqkLSZjhYj33n9j3fMztFxnh
    Liberapay Visit NewPipe at liberapay.com Donate via Liberapay
    BountysourceVisit NewPipe at bountysource.comCheck out how many bounties you can earn.
    ## 개인정보 보호 정책 diff --git a/doc/README.pa.md b/doc/README.pa.md index 2a3ae69af..ac52e3b31 100644 --- a/doc/README.pa.md +++ b/doc/README.pa.md @@ -120,16 +120,6 @@ NewPipe ਤੁਹਾਡੇ ਦੁਆਰਾ ਵਰਤੀ ਜਾ ਰਹੀ ਸੇ liberapay.com 'ਤੇ NewPipe ਨੂੰ ਵੇਖੋ Donate via Liberapay - - Bitcoin - ਬਿਟਕੋਇਨ 'ਤੇ ਦਾਨ ਕਰਨ ਲਈ QR ਕੋਡ - 16A9J59ahMRqkLSZjhYj33n9j3fMztFxnh - - - Bountysource - bountysource.com 'ਤੇ NewPipe ਨੂੰ ਵੇਖੋ - ਦੇਖੋ ਕਿ ਤੁਸੀਂ ਕਿੰਨੇ ਇਨਾਮ ਕਮਾ ਸਕਦੇ ਹੋ। - ## ਗੋਪਨੀਅਤਾ ਨੀਤੀ diff --git a/doc/README.pl.md b/doc/README.pl.md index 5ba201eb0..bcd37e515 100644 --- a/doc/README.pl.md +++ b/doc/README.pl.md @@ -112,21 +112,11 @@ Jeśli chcesz pomóc, przeczytaj [Notkę o wkładzie](../.github/CONTRIBUTING.md Jeśli podoba Ci się NewPipe, bardzo ucieszylibyśmy się z dotacji. Możesz wysłać bitcoin lub przekazać darowiznę przez Bountysource lub Liberapay. Po więcej informacji o darowiznach dla NewPipe, proszę zobacz naszą [stronę](https://newpipe.net/donate). - - - - - - - - - -
    BitcoinBitcoin QR code16A9J59ahMRqkLSZjhYj33n9j3fMztFxnh
    Liberapay Visit NewPipe at liberapay.com Donate via Liberapay
    BountysourceVisit NewPipe at bountysource.comCheck out how many bounties you can earn.
    ## Polityka prywatności diff --git a/doc/README.pt_BR.md b/doc/README.pt_BR.md index 850d03e89..9945a3969 100644 --- a/doc/README.pt_BR.md +++ b/doc/README.pt_BR.md @@ -112,21 +112,11 @@ Se você quiser se envolver, verifique nossa [notas de contribuição](../.githu Se você gosta de NewPipe, ficaríamos felizes com uma doação. Você pode enviar bitcoin ou doar via Bountysource ou Liberapay. Para obter mais informações sobre como doar para a NewPipe, visite nosso [site](https://newpipe.net/donate). - - - - - - - - - -
    BitcoinBitcoin QR code16A9J59ahMRqkLSZjhYj33n9j3fMztFxnh
    Liberapay Visit NewPipe at liberapay.com Donate via Liberapay
    BountysourceVisit NewPipe at bountysource.comCheck out how many bounties you can earn.
    ## Política de Privacidade diff --git a/doc/README.ro.md b/doc/README.ro.md index 11319b5a0..3eac39563 100644 --- a/doc/README.ro.md +++ b/doc/README.ro.md @@ -115,21 +115,11 @@ Dacă doriţi să vă implicaţi, accesaţi [notele noastre de contribuţie](../ Dacă vă place NewPipe, am fi bucuroşi să primim o donaţie. Puteţi să ne trimiteţi bitcoin sau să ne donaţi cu Bountysource sau Liberapay. Pentru mai multe informaţii în legătură cu donaţiile către NewPipe, vă rugăm vizitaţi [website-ul nostru](https://newpipe.net/donate). - - - - - - - - - -
    BitcoinBitcoin QR code16A9J59ahMRqkLSZjhYj33n9j3fMztFxnh
    Liberapay Visit NewPipe at liberapay.com Donate via Liberapay
    BountysourceVisit NewPipe at bountysource.comCheck out how many bounties you can earn.
    ## Politica de Confidenţialitate diff --git a/doc/README.ru.md b/doc/README.ru.md index a226b72a8..a11e88783 100644 --- a/doc/README.ru.md +++ b/doc/README.ru.md @@ -121,16 +121,6 @@ NewPipe работает, извлекая необходимые данные Посетите NewPipe на liberapay.com Пожертвование через Liberapay - - Bitcoin - QR-код Bitcoin - 16A9J59ahMRqkLSZjhYj33n9j3fMztFxnh - - - Bountysource - Посетите NewPipe на bountysource.com - Проверьте, сколько наград вы можете заработать. - ## Политика конфиденциальности diff --git a/doc/README.ryu.md b/doc/README.ryu.md index ce1a38bd9..56e037541 100644 --- a/doc/README.ryu.md +++ b/doc/README.ryu.md @@ -120,21 +120,11 @@ NewPipeーふくすんぬサービスんかいたいおうそーいびーん。[ むし、NewPipeちーがんじいただけいねー、ちーふしいただけいねーうっさいびーん。BitcoinあらんでぃBountysource,Liberapayからちーふするくとぅがなやびーん。NewPipeんかいどぅちふにちいてー、[ウェブサイト](https://newpipe.net/donate)からうにげーさびら。 - - - - - - - - - -
    BitcoinBitcoin QR コード16A9J59ahMRqkLSZjhYj33n9j3fMztFxnh
    Liberapay liberapay.comっしNewPipeちゅーん Liberapayなちーふ
    Bountysourcebountysource.comっしNewPipeちゅーんうんじゅがじるふどぅどぅちふいらりーるぬがかくにんさびら。
    ## プライバシーポリシー diff --git a/doc/README.so.md b/doc/README.so.md index 1e400b219..fdcc11fe6 100644 --- a/doc/README.so.md +++ b/doc/README.so.md @@ -110,21 +110,11 @@ Hadaad jeceshahay inaad qayb ka noqoto, fiiri [ogaysiisyada kusoo kordhinta](../ Hadaad jeceshahay NewPipe waan ku faraxsanaan lahayn deeq. Waxaad soo diri kartaa bitcoin ama sidoo kale waxaad deeqda kusoo diri kartaa xaga Bountysource ama Liberapay. Faahfaahin dheeraad ah oo kusaabsan ugu deeqida NewPipe, fadlan booqo [website-kanaga](https://newpipe.net/donate). - - - - - - - - - -
    BitcoinBitcoin QR code16A9J59ahMRqkLSZjhYj33n9j3fMztFxnh
    Liberapay Visit NewPipe at liberapay.com Donate via Liberapay
    BountysourceVisit NewPipe at bountysource.comCheck out how many bounties you can earn.
    ## Siyaasada Sirdhawrka diff --git a/doc/README.sr.md b/doc/README.sr.md index 320558fc9..930eccd33 100644 --- a/doc/README.sr.md +++ b/doc/README.sr.md @@ -119,16 +119,6 @@ NewPipe ради тако што преузима потребне податк Visit NewPipe at liberapay.com Donate via Liberapay - - Bitcoin - Bitcoin QR code - 16A9J59ahMRqkLSZjhYj33n9j3fMztFxnh - - - Bountysource - Visit NewPipe at bountysource.com - Check out how many bounties you can earn. - ## Политика приватности diff --git a/doc/README.tr.md b/doc/README.tr.md index b2d4f2c56..3ff88c81a 100644 --- a/doc/README.tr.md +++ b/doc/README.tr.md @@ -114,21 +114,11 @@ Eğer yer almak istiyorsanız, [katkı sağlayanlar için hazırladığımız no NewPipe'ı beğendiyseniz, yapacağınız bağışlar bizi motive eder. Bitcoin gönderebilir veya Bountysource veya Liberapay aracılığıyla bağış yapabilirsiniz. NewPipe'a bağış yapma hakkında daha fazla bilgi için lütfen [web sitemizi](https://newpipe.net/donate) ziyaret edin. - - - - - - - - - -
    BitcoinBitcoin QR kodu16A9J59ahMRqkLSZjhYj33n9j3fMztFxnh
    Liberapay liberapay.com üzerinde NewPipe'ı ziyaret edin Liberapay aracılığıyla bağış yapın
    Bountysourcebountysource.com üzerinde NewPipe'ı ziyaret edinNe kadar ödül kazanabileceğinizi kontrol edin.
    ## Gizlilik politikası diff --git a/doc/README.zh_TW.md b/doc/README.zh_TW.md index d5def26b2..13963087d 100644 --- a/doc/README.zh_TW.md +++ b/doc/README.zh_TW.md @@ -120,21 +120,11 @@ NewPipe 支援多種服務。我們的[使用文件](https://teamnewpipe.github. 若你喜歡 NewPipe 我們歡迎捐款。你可以使用 bitcoin ,也能在 Bountysource 或 Liberapay 上捐款。 更多關於捐款資訊,請見我們的[網站](https://newpipe.net/donate)。 - - - - - - - - - -
    BitcoinBitcoin QR code16A9J59ahMRqkLSZjhYj33n9j3fMztFxnh
    Liberapay Visit NewPipe at liberapay.com Donate via Liberapay
    BountysourceVisit NewPipe at bountysource.comCheck out how many bounties you can earn.
    ## 隱私權政策 From d10a93fe4fab0992aefa4d5f58723db1fae92eb3 Mon Sep 17 00:00:00 2001 From: TobiGr Date: Fri, 13 Oct 2023 17:30:01 +0200 Subject: [PATCH 150/172] [README] Remove Bountysource badge --- README.md | 1 - doc/README.asm.md | 1 - doc/README.de.md | 1 - doc/README.es.md | 1 - doc/README.fr.md | 1 - doc/README.hi.md | 1 - doc/README.it.md | 1 - doc/README.ja.md | 1 - doc/README.ko.md | 1 - doc/README.pa.md | 1 - doc/README.pl.md | 1 - doc/README.pt_BR.md | 1 - doc/README.ro.md | 1 - doc/README.ru.md | 1 - doc/README.ryu.md | 1 - doc/README.so.md | 1 - doc/README.sr.md | 1 - doc/README.tr.md | 1 - doc/README.zh_TW.md | 1 - 19 files changed, 19 deletions(-) diff --git a/README.md b/README.md index 58ac79886..f26048ddc 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,6 @@ -


    ScreenshotsSupported ServicesDescriptionFeaturesInstallation and updatesContributionDonateLicense

    diff --git a/doc/README.asm.md b/doc/README.asm.md index 8f39d26a1..af855c4cd 100644 --- a/doc/README.asm.md +++ b/doc/README.asm.md @@ -7,7 +7,6 @@

    -


    স্ক্ৰীণশ্বট • diff --git a/doc/README.de.md b/doc/README.de.md index cc9c313fa..3714020ff 100644 --- a/doc/README.de.md +++ b/doc/README.de.md @@ -13,7 +13,6 @@ -


    ScreenshotsUnterstützte DiensteBeschreibungFeaturesInstallation und UpdatesBeitragSpendenLizenz

    diff --git a/doc/README.es.md b/doc/README.es.md index c2959fe04..5aa5eb55c 100644 --- a/doc/README.es.md +++ b/doc/README.es.md @@ -10,7 +10,6 @@ -


    diff --git a/doc/README.fr.md b/doc/README.fr.md index 2e56e7ff1..b68c1e321 100644 --- a/doc/README.fr.md +++ b/doc/README.fr.md @@ -10,7 +10,6 @@ -


    Captures d'écranServices SupportésDescriptionFonctionnalitésInstallation et mises à jourContribuerDonsLicence

    diff --git a/doc/README.hi.md b/doc/README.hi.md index 36669cc19..536be4d43 100644 --- a/doc/README.hi.md +++ b/doc/README.hi.md @@ -10,7 +10,6 @@ -


    ऐप कैसी दिखती हैविवरणसुविधाएँस्थापित करना और अपडेट करनायोगदान करेंआर्थिक योगदान करेंलाइसेंस

    diff --git a/doc/README.it.md b/doc/README.it.md index cd8cb10a8..bca6a23d2 100644 --- a/doc/README.it.md +++ b/doc/README.it.md @@ -10,7 +10,6 @@ -


    ScreenshotServizi SupportatiDescrizioneFunzionalitàInstallazione e aggiornamentiContribuireDonareLicenza

    diff --git a/doc/README.ja.md b/doc/README.ja.md index 317d39766..e4eb74694 100644 --- a/doc/README.ja.md +++ b/doc/README.ja.md @@ -10,7 +10,6 @@ -


    スクリーンショット説明機能インストールと更新貢献寄付ライセンス

    diff --git a/doc/README.ko.md b/doc/README.ko.md index b690e659a..0ba15ab43 100644 --- a/doc/README.ko.md +++ b/doc/README.ko.md @@ -10,7 +10,6 @@ -


    ScreenshotsDescriptionFeaturesUpdatesContributionDonateLicense

    diff --git a/doc/README.pa.md b/doc/README.pa.md index ac52e3b31..d40e1b84f 100644 --- a/doc/README.pa.md +++ b/doc/README.pa.md @@ -10,7 +10,6 @@ -


    ਸਕਰੀਨਸ਼ਾਟਸੇਵਾਵਾਂਵਰਣਨਵਿਸ਼ੇਸ਼ਤਾਵਾਂਇੰਸਟਾਲੇਸ਼ਨ ਅਤੇ ਅੱਪਡੇਟਯੋਗਦਾਨਦਾਨਲਾਈਸੈਂਸ

    diff --git a/doc/README.pl.md b/doc/README.pl.md index bcd37e515..6412e10f5 100644 --- a/doc/README.pl.md +++ b/doc/README.pl.md @@ -10,7 +10,6 @@ -


    ScreenshotyOpisFunkcjeInstalacja i aktualizacjeWkładWesprzyjLicencja

    diff --git a/doc/README.pt_BR.md b/doc/README.pt_BR.md index 9945a3969..a439adc68 100644 --- a/doc/README.pt_BR.md +++ b/doc/README.pt_BR.md @@ -11,7 +11,6 @@ -


    ScreenshotsDescriçãoCaracterísticasAtualizaçõesContribuiçãoDoarLicença

    diff --git a/doc/README.ro.md b/doc/README.ro.md index 3eac39563..77a6798bf 100644 --- a/doc/README.ro.md +++ b/doc/README.ro.md @@ -10,7 +10,6 @@ -


    Capturi de ecranDescriereFuncţiiInstalare şi actualizăriContribuţieDonaţiLicenţă

    diff --git a/doc/README.ru.md b/doc/README.ru.md index a11e88783..1590b2399 100644 --- a/doc/README.ru.md +++ b/doc/README.ru.md @@ -10,7 +10,6 @@ -


    СкриншотыПоддерживаемые сервисыОписаниеВозможностиУстановка и обновленияУчастиеПожертвованиеЛицензия

    diff --git a/doc/README.ryu.md b/doc/README.ryu.md index 56e037541..fe30a9ba9 100644 --- a/doc/README.ryu.md +++ b/doc/README.ryu.md @@ -10,7 +10,6 @@ -


    スクリーンショットしちめいちぬーインストールとぅこうしんこうきんちーふライセンス

    diff --git a/doc/README.so.md b/doc/README.so.md index fdcc11fe6..56a696db3 100644 --- a/doc/README.so.md +++ b/doc/README.so.md @@ -10,7 +10,6 @@ -


    Sawir-shaashadeedFaahfaahinWaxqabadkaKushubida iyo cusboonaysiintaKusoo KordhinUgu DeeqLaysinka

    diff --git a/doc/README.sr.md b/doc/README.sr.md index 930eccd33..775585f1a 100644 --- a/doc/README.sr.md +++ b/doc/README.sr.md @@ -13,7 +13,6 @@ -


    Снимци екранаПодржане услугеОписКарактеристикеИнсталација и ажурирањаДоприносДонацијаЛиценца

    diff --git a/doc/README.tr.md b/doc/README.tr.md index 3ff88c81a..a9c91bfbd 100644 --- a/doc/README.tr.md +++ b/doc/README.tr.md @@ -10,7 +10,6 @@ -


    Ekran fotoğraflarıAçıklamaÖzelliklerKurulum ve güncellemelerKatkıda bulunmaBağışLisans

    diff --git a/doc/README.zh_TW.md b/doc/README.zh_TW.md index 13963087d..a21f2ca4c 100644 --- a/doc/README.zh_TW.md +++ b/doc/README.zh_TW.md @@ -10,7 +10,6 @@ -


    截圖說明功能安裝與更新貢獻捐款授權憑證

    From 5265b767cb50005fc6346d5cc93ea1d5f7f5523b Mon Sep 17 00:00:00 2001 From: TobiGr Date: Sat, 14 Oct 2023 18:31:33 +0200 Subject: [PATCH 151/172] Fix notifiying about old "new" streams Add tests for `FeedDAO.unlinkStreamsOlderThan(:offsetDateTime) ` Closes #10237 --- .../schabi/newpipe/database/FeedDAOTest.kt | 124 ++++++++++++++++++ .../newpipe/database/feed/dao/FeedDAO.kt | 30 +++-- 2 files changed, 144 insertions(+), 10 deletions(-) create mode 100644 app/src/androidTest/java/org/schabi/newpipe/database/FeedDAOTest.kt diff --git a/app/src/androidTest/java/org/schabi/newpipe/database/FeedDAOTest.kt b/app/src/androidTest/java/org/schabi/newpipe/database/FeedDAOTest.kt new file mode 100644 index 000000000..9fa87c31b --- /dev/null +++ b/app/src/androidTest/java/org/schabi/newpipe/database/FeedDAOTest.kt @@ -0,0 +1,124 @@ +package org.schabi.newpipe.database + +import android.content.Context +import androidx.room.Room +import androidx.test.core.app.ApplicationProvider +import io.reactivex.rxjava3.core.Single +import org.junit.After +import org.junit.Assert.assertEquals +import org.junit.Assert.assertNotNull +import org.junit.Before +import org.junit.Test +import org.schabi.newpipe.database.feed.dao.FeedDAO +import org.schabi.newpipe.database.feed.model.FeedEntity +import org.schabi.newpipe.database.feed.model.FeedGroupEntity +import org.schabi.newpipe.database.stream.StreamWithState +import org.schabi.newpipe.database.stream.dao.StreamDAO +import org.schabi.newpipe.database.stream.model.StreamEntity +import org.schabi.newpipe.database.subscription.SubscriptionDAO +import org.schabi.newpipe.database.subscription.SubscriptionEntity +import org.schabi.newpipe.extractor.ServiceList +import org.schabi.newpipe.extractor.channel.ChannelInfo +import org.schabi.newpipe.extractor.stream.StreamType +import java.io.IOException +import java.time.OffsetDateTime +import kotlin.streams.toList + +class FeedDAOTest { + private lateinit var db: AppDatabase + private lateinit var feedDAO: FeedDAO + private lateinit var streamDAO: StreamDAO + private lateinit var subscriptionDAO: SubscriptionDAO + + private val serviceId = ServiceList.YouTube.serviceId + + private val stream1 = StreamEntity(1, serviceId, "https://youtube.com/watch?v=1", "stream 1", StreamType.VIDEO_STREAM, 1000, "channel-1", "https://youtube.com/channel/1", "https://i.ytimg.com/vi/1/hqdefault.jpg", 100, "2023-01-01", OffsetDateTime.parse("2023-01-01T00:00:00Z")) + private val stream2 = StreamEntity(2, serviceId, "https://youtube.com/watch?v=2", "stream 2", StreamType.VIDEO_STREAM, 1000, "channel-1", "https://youtube.com/channel/1", "https://i.ytimg.com/vi/1/hqdefault.jpg", 100, "2023-01-02", OffsetDateTime.parse("2023-01-02T00:00:00Z")) + private val stream3 = StreamEntity(3, serviceId, "https://youtube.com/watch?v=3", "stream 3", StreamType.LIVE_STREAM, 1000, "channel-1", "https://youtube.com/channel/1", "https://i.ytimg.com/vi/1/hqdefault.jpg", 100, "2023-01-03", OffsetDateTime.parse("2023-01-03T00:00:00Z")) + private val stream4 = StreamEntity(4, serviceId, "https://youtube.com/watch?v=4", "stream 4", StreamType.VIDEO_STREAM, 1000, "channel-2", "https://youtube.com/channel/2", "https://i.ytimg.com/vi/1/hqdefault.jpg", 100, "2023-08-10", OffsetDateTime.parse("2023-08-10T00:00:00Z")) + private val stream5 = StreamEntity(5, serviceId, "https://youtube.com/watch?v=5", "stream 5", StreamType.VIDEO_STREAM, 1000, "channel-2", "https://youtube.com/channel/2", "https://i.ytimg.com/vi/1/hqdefault.jpg", 100, "2023-08-20", OffsetDateTime.parse("2023-08-20T00:00:00Z")) + private val stream6 = StreamEntity(6, serviceId, "https://youtube.com/watch?v=6", "stream 6", StreamType.VIDEO_STREAM, 1000, "channel-3", "https://youtube.com/channel/3", "https://i.ytimg.com/vi/1/hqdefault.jpg", 100, "2023-09-01", OffsetDateTime.parse("2023-09-01T00:00:00Z")) + private val stream7 = StreamEntity(7, serviceId, "https://youtube.com/watch?v=7", "stream 7", StreamType.VIDEO_STREAM, 1000, "channel-4", "https://youtube.com/channel/4", "https://i.ytimg.com/vi/1/hqdefault.jpg", 100, "2023-08-10", OffsetDateTime.parse("2023-08-10T00:00:00Z")) + + private val allStreams = listOf( + stream1, stream2, stream3, stream4, stream5, stream6, stream7 + ) + + @Before + fun createDb() { + val context = ApplicationProvider.getApplicationContext() + db = Room.inMemoryDatabaseBuilder( + context, AppDatabase::class.java + ).build() + feedDAO = db.feedDAO() + streamDAO = db.streamDAO() + subscriptionDAO = db.subscriptionDAO() + } + + @After + @Throws(IOException::class) + fun closeDb() { + db.close() + } + + @Test + fun testUnlinkStreamsOlderThan_KeepOne() { + setupUnlinkDelete("2023-08-15T00:00:00Z") + val streams = feedDAO.getStreams( + FeedGroupEntity.GROUP_ALL_ID, includePlayed = true, includePartiallyPlayed = true, null + ) + .blockingGet() + val allowedStreams = listOf(stream3, stream5, stream6, stream7) + assertEqual(streams, allowedStreams) + } + + @Test + fun testUnlinkStreamsOlderThan_KeepMultiple() { + setupUnlinkDelete("2023-08-01T00:00:00Z") + val streams = feedDAO.getStreams( + FeedGroupEntity.GROUP_ALL_ID, includePlayed = true, includePartiallyPlayed = true, null + ) + .blockingGet() + val allowedStreams = listOf(stream3, stream4, stream5, stream6, stream7) + assertEqual(streams, allowedStreams) + } + + private fun assertEqual(streams: List?, allowedStreams: List) { + assertNotNull(streams) + assertEquals(allowedStreams, streams!!.stream().map { it.stream }.toList().sortedBy { it.uid }) + } + + private fun setupUnlinkDelete(time: String) { + clearAndFillTables() + Single.fromCallable { + feedDAO.unlinkStreamsOlderThan(OffsetDateTime.parse(time)) + }.blockingSubscribe() + Single.fromCallable { + streamDAO.deleteOrphans() + }.blockingSubscribe() + } + + private fun clearAndFillTables() { + db.clearAllTables() + streamDAO.insertAll(allStreams) + subscriptionDAO.insertAll( + listOf( + SubscriptionEntity.from(ChannelInfo(serviceId, "1", "https://youtube.com/channel/1", "https://youtube.com/channel/1", "channel-1")), + SubscriptionEntity.from(ChannelInfo(serviceId, "2", "https://youtube.com/channel/2", "https://youtube.com/channel/2", "channel-2")), + SubscriptionEntity.from(ChannelInfo(serviceId, "3", "https://youtube.com/channel/3", "https://youtube.com/channel/3", "channel-3")), + SubscriptionEntity.from(ChannelInfo(serviceId, "4", "https://youtube.com/channel/4", "https://youtube.com/channel/4", "channel-4")), + ) + ) + feedDAO.insertAll( + listOf( + FeedEntity(1, 1), + FeedEntity(2, 1), + FeedEntity(3, 1), + FeedEntity(4, 2), + FeedEntity(5, 2), + FeedEntity(6, 3), + FeedEntity(7, 4), + ) + ) + } +} diff --git a/app/src/main/java/org/schabi/newpipe/database/feed/dao/FeedDAO.kt b/app/src/main/java/org/schabi/newpipe/database/feed/dao/FeedDAO.kt index 6947f66af..028ef04f7 100644 --- a/app/src/main/java/org/schabi/newpipe/database/feed/dao/FeedDAO.kt +++ b/app/src/main/java/org/schabi/newpipe/database/feed/dao/FeedDAO.kt @@ -93,18 +93,28 @@ abstract class FeedDAO { uploadDateBefore: OffsetDateTime? ): Maybe> + /** + * Remove links to streams that are older than the given date + * **but keep at least one stream per uploader**. + * + * One stream per uploader is kept because it is needed as reference + * when fetching new streams to check if they are new or not. + * @param offsetDateTime the newest date to keep, older streams are removed + */ @Query( """ - DELETE FROM feed WHERE - - feed.stream_id IN ( - SELECT s.uid FROM streams s - - INNER JOIN feed f - ON s.uid = f.stream_id - - WHERE s.upload_date < :offsetDateTime - ) + DELETE FROM feed + WHERE feed.stream_id IN (SELECT uid from ( + SELECT s.uid, + (SELECT MAX(upload_date) + FROM streams + WHERE uploader_url = s.uploader_url) max_upload_date + FROM streams s + INNER JOIN feed f + ON s.uid = f.stream_id + + WHERE s.upload_date < :offsetDateTime + AND s.upload_date <> max_upload_date)) """ ) abstract fun unlinkStreamsOlderThan(offsetDateTime: OffsetDateTime) From 9fab0ec94f84b2f8cba03f6d6e1b00a048633796 Mon Sep 17 00:00:00 2001 From: AudricV <74829229+AudricV@users.noreply.github.com> Date: Wed, 15 Nov 2023 00:37:05 +0100 Subject: [PATCH 152/172] Fix crash when setting the masking of the new feed items button if the context is null As the fragment context can be null in some cases, we have to make sure that the context is not null before calling DeviceUtils.hasAnimationsAnimatorDurationEnabled. If the context is null, the button will now not be hidden automatically. --- .../java/org/schabi/newpipe/local/feed/FeedFragment.kt | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/local/feed/FeedFragment.kt b/app/src/main/java/org/schabi/newpipe/local/feed/FeedFragment.kt index 83882d35f..0b61f45fb 100644 --- a/app/src/main/java/org/schabi/newpipe/local/feed/FeedFragment.kt +++ b/app/src/main/java/org/schabi/newpipe/local/feed/FeedFragment.kt @@ -607,9 +607,13 @@ class FeedFragment : BaseStateFragment() { execOnEnd = { // Disabled animations would result in immediately hiding the button // after it showed up - if (DeviceUtils.hasAnimationsAnimatorDurationEnabled(context)) { - // Hide the new items-"popup" after 10s - hideNewItemsLoaded(true, 10000) + // Context can be null in some cases, so we have to make sure it is not null in + // order to avoid a NullPointerException + context?.let { + if (DeviceUtils.hasAnimationsAnimatorDurationEnabled(it)) { + // Hide the new items button after 10s + hideNewItemsLoaded(true, 10000) + } } } ) From 2cf77647146f8f839032c0fb9862c8da54aac77c Mon Sep 17 00:00:00 2001 From: AudricV <74829229+AudricV@users.noreply.github.com> Date: Wed, 15 Nov 2023 19:22:49 +0100 Subject: [PATCH 153/172] Fix crash when building the play queue audio track menu if the player is null As the player can be null in some cases, we have to make sure that the player is not null, by using Optionals on the player itself instead of its methods returning Optionals. If the player is null, the play queue audio track menu will now be hidden. --- .../java/org/schabi/newpipe/player/PlayQueueActivity.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/player/PlayQueueActivity.java b/app/src/main/java/org/schabi/newpipe/player/PlayQueueActivity.java index defc8ba21..c012f6008 100644 --- a/app/src/main/java/org/schabi/newpipe/player/PlayQueueActivity.java +++ b/app/src/main/java/org/schabi/newpipe/player/PlayQueueActivity.java @@ -619,11 +619,13 @@ public final class PlayQueueActivity extends AppCompatActivity final MenuItem audioTrackSelector = menu.findItem(R.id.action_audio_track); final List availableStreams = - Optional.ofNullable(player.getCurrentMetadata()) + Optional.ofNullable(player) + .map(Player::getCurrentMetadata) .flatMap(MediaItemTag::getMaybeAudioTrack) .map(MediaItemTag.AudioTrack::getAudioStreams) .orElse(null); - final Optional selectedAudioStream = player.getSelectedAudioStream(); + final Optional selectedAudioStream = Optional.ofNullable(player) + .flatMap(Player::getSelectedAudioStream); if (availableStreams == null || availableStreams.size() < 2 || selectedAudioStream.isEmpty()) { From 84d50da009b5f82bdb6df54addc13b72c6e69f5b Mon Sep 17 00:00:00 2001 From: AudricV <74829229+AudricV@users.noreply.github.com> Date: Sun, 17 Sep 2023 20:49:13 +0200 Subject: [PATCH 154/172] Restore player service start handling before player UI separation This behavior was present before 0.24.0 and the player UI separation and avoided crashes for which their exception contained "Context.startForegroundService() did not then call Service.startForeground()". Some player nullability checks have been also added, and the player service is now stopped when it has been started from a media button and there is nothing to play. --- .../schabi/newpipe/player/PlayerService.java | 47 +++++++++++++++---- .../notification/NotificationPlayerUi.java | 14 ++---- 2 files changed, 43 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/player/PlayerService.java b/app/src/main/java/org/schabi/newpipe/player/PlayerService.java index ad6c9405d..e7abf4320 100644 --- a/app/src/main/java/org/schabi/newpipe/player/PlayerService.java +++ b/app/src/main/java/org/schabi/newpipe/player/PlayerService.java @@ -29,6 +29,7 @@ import android.os.IBinder; import android.util.Log; import org.schabi.newpipe.player.mediasession.MediaSessionPlayerUi; +import org.schabi.newpipe.player.notification.NotificationPlayerUi; import org.schabi.newpipe.util.ThemeHelper; import java.lang.ref.WeakReference; @@ -59,6 +60,14 @@ public final class PlayerService extends Service { ThemeHelper.setTheme(this); player = new Player(this); + /* + Create the player notification and start immediately the service in foreground, + otherwise if nothing is played or initializing the player and its components (especially + loading stream metadata) takes a lot of time, the app would crash on Android 8+ as the + service would never be put in the foreground while we said to the system we would do so + */ + player.UIs().get(NotificationPlayerUi.class) + .ifPresent(NotificationPlayerUi::createNotificationAndStartForeground); } @Override @@ -68,16 +77,38 @@ public final class PlayerService extends Service { + "], flags = [" + flags + "], startId = [" + startId + "]"); } + /* + Be sure that the player notification is set and the service is started in foreground, + otherwise, the app may crash on Android 8+ as the service would never be put in the + foreground while we said to the system we would do so + The service is always requested to be started in foreground, so always creating a + notification if there is no one already and starting the service in foreground should + not create any issues + If the service is already started in foreground, requesting it to be started shouldn't + do anything + */ + if (player != null) { + player.UIs().get(NotificationPlayerUi.class) + .ifPresent(NotificationPlayerUi::createNotificationAndStartForeground); + } + if (Intent.ACTION_MEDIA_BUTTON.equals(intent.getAction()) - && player.getPlayQueue() == null) { - // No need to process media button's actions if the player is not working, otherwise the - // player service would strangely start with nothing to play + && (player == null || player.getPlayQueue() == null)) { + /* + No need to process media button's actions if the player is not working, otherwise + the player service would strangely start with nothing to play + Stop the service in this case, which will be removed from the foreground and its + notification cancelled in its destruction + */ + stopSelf(); return START_NOT_STICKY; } - player.handleIntent(intent); - player.UIs().get(MediaSessionPlayerUi.class) - .ifPresent(ui -> ui.handleMediaButtonIntent(intent)); + if (player != null) { + player.handleIntent(intent); + player.UIs().get(MediaSessionPlayerUi.class) + .ifPresent(ui -> ui.handleMediaButtonIntent(intent)); + } return START_NOT_STICKY; } @@ -87,7 +118,7 @@ public final class PlayerService extends Service { Log.d(TAG, "stopForImmediateReusing() called"); } - if (!player.exoPlayerIsNull()) { + if (player != null && !player.exoPlayerIsNull()) { // Releases wifi & cpu, disables keepScreenOn, etc. // We can't just pause the player here because it will make transition // from one stream to a new stream not smooth @@ -98,7 +129,7 @@ public final class PlayerService extends Service { @Override public void onTaskRemoved(final Intent rootIntent) { super.onTaskRemoved(rootIntent); - if (!player.videoPlayerSelected()) { + if (player != null && !player.videoPlayerSelected()) { return; } onDestroy(); diff --git a/app/src/main/java/org/schabi/newpipe/player/notification/NotificationPlayerUi.java b/app/src/main/java/org/schabi/newpipe/player/notification/NotificationPlayerUi.java index 4b1fc417f..75b27545c 100644 --- a/app/src/main/java/org/schabi/newpipe/player/notification/NotificationPlayerUi.java +++ b/app/src/main/java/org/schabi/newpipe/player/notification/NotificationPlayerUi.java @@ -17,7 +17,6 @@ import org.schabi.newpipe.player.helper.PlayerHelper; import org.schabi.newpipe.player.ui.PlayerUi; public final class NotificationPlayerUi extends PlayerUi { - private boolean foregroundNotificationAlreadyCreated = false; private final NotificationUtil notificationUtil; public NotificationPlayerUi(@NonNull final Player player) { @@ -25,15 +24,6 @@ public final class NotificationPlayerUi extends PlayerUi { notificationUtil = new NotificationUtil(player); } - @Override - public void initPlayer() { - super.initPlayer(); - if (!foregroundNotificationAlreadyCreated) { - notificationUtil.createNotificationAndStartForeground(); - foregroundNotificationAlreadyCreated = true; - } - } - @Override public void destroy() { super.destroy(); @@ -122,4 +112,8 @@ public final class NotificationPlayerUi extends PlayerUi { super.onPlayQueueEdited(); notificationUtil.createNotificationIfNeededAndUpdate(false); } + + public void createNotificationAndStartForeground() { + notificationUtil.createNotificationAndStartForeground(); + } } From e5fda35c51ad07136bb4d9803bb8b1aafc1ac859 Mon Sep 17 00:00:00 2001 From: AudricV <74829229+AudricV@users.noreply.github.com> Date: Wed, 15 Nov 2023 22:52:57 +0100 Subject: [PATCH 155/172] Remove OPUS HLS streams from playable streams This format is not supported by ExoPlayer when returned as HLS streams, so we can't play streams using this format and this delivery method. Also improve the Javadoc of ListHelper.getPlayableStreams. --- .../org/schabi/newpipe/util/ListHelper.java | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/util/ListHelper.java b/app/src/main/java/org/schabi/newpipe/util/ListHelper.java index 5918ece25..534d4fddd 100644 --- a/app/src/main/java/org/schabi/newpipe/util/ListHelper.java +++ b/app/src/main/java/org/schabi/newpipe/util/ListHelper.java @@ -189,13 +189,16 @@ public final class ListHelper { /** * Return a {@link Stream} list which only contains streams which can be played by the player. - *
    - * Some formats are not supported. For more info, see {@link #SUPPORTED_ITAG_IDS}. - * Torrent streams are also removed, because they cannot be retrieved. + * + *

    + * Some formats are not supported, see {@link #SUPPORTED_ITAG_IDS} for more details. + * Torrent streams are also removed, because they cannot be retrieved, like OPUS streams using + * HLS as their delivery method, since they are not supported by ExoPlayer. + *

    * * @param the item type's class that extends {@link Stream} * @param streamList the original stream list - * @param serviceId + * @param serviceId the service ID from which the streams' list comes from * @return a stream list which only contains streams that can be played the player */ @NonNull @@ -204,6 +207,8 @@ public final class ListHelper { final int youtubeServiceId = YouTube.getServiceId(); return getFilteredStreamList(streamList, stream -> stream.getDeliveryMethod() != DeliveryMethod.TORRENT + && (stream.getDeliveryMethod() != DeliveryMethod.HLS + || stream.getFormat() != MediaFormat.OPUS) && (serviceId != youtubeServiceId || stream.getItagItem() == null || SUPPORTED_ITAG_IDS.contains(stream.getItagItem().id))); @@ -295,7 +300,9 @@ public final class ListHelper { final Comparator cmp = getAudioFormatComparator(context); for (final AudioStream stream : audioStreams) { - if (stream.getDeliveryMethod() == DeliveryMethod.TORRENT) { + if (stream.getDeliveryMethod() == DeliveryMethod.TORRENT + || (stream.getDeliveryMethod() == DeliveryMethod.HLS + && stream.getFormat() == MediaFormat.OPUS)) { continue; } From b4a0e08d9de66994d8b6dd0404f8ac5dbb870e5e Mon Sep 17 00:00:00 2001 From: Tobi Date: Thu, 23 Nov 2023 17:12:16 +0100 Subject: [PATCH 156/172] Update app/src/main/java/org/schabi/newpipe/database/feed/dao/FeedDAO.kt Co-authored-by: Stypox --- .../java/org/schabi/newpipe/database/feed/dao/FeedDAO.kt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/database/feed/dao/FeedDAO.kt b/app/src/main/java/org/schabi/newpipe/database/feed/dao/FeedDAO.kt index 028ef04f7..e7ed93497 100644 --- a/app/src/main/java/org/schabi/newpipe/database/feed/dao/FeedDAO.kt +++ b/app/src/main/java/org/schabi/newpipe/database/feed/dao/FeedDAO.kt @@ -107,8 +107,10 @@ abstract class FeedDAO { WHERE feed.stream_id IN (SELECT uid from ( SELECT s.uid, (SELECT MAX(upload_date) - FROM streams - WHERE uploader_url = s.uploader_url) max_upload_date + FROM streams s1 + INNER JOIN feed f1 + ON s1.uid = f1.stream_id + WHERE f1.subscription_id = f.subscription_id) max_upload_date FROM streams s INNER JOIN feed f ON s.uid = f.stream_id From ddd6d03e0b2555024daff560a879a01ac1657e05 Mon Sep 17 00:00:00 2001 From: opusforlife2 <53176348+opusforlife2@users.noreply.github.com> Date: Wed, 6 Dec 2023 18:34:43 +0000 Subject: [PATCH 157/172] Add Matrix room link to ReadMe (#10632) --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f26048ddc..ecfa19eb6 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ +


    ScreenshotsSupported ServicesDescriptionFeaturesInstallation and updatesContributionDonateLicense

    From edbd623e2145f6ba5bf1ea1e4446370231b7bf46 Mon Sep 17 00:00:00 2001 From: Stypox Date: Thu, 7 Dec 2023 16:11:59 +0100 Subject: [PATCH 158/172] Fix Matrix channel link #newpipe:matrix.org is unofficial, #newpipe:libera.chat is the official one --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ecfa19eb6..9fabb5ac7 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ - +


    ScreenshotsSupported ServicesDescriptionFeaturesInstallation and updatesContributionDonateLicense

    From ce30108efc917ab7edb0b90ac8b44d5efbb7180b Mon Sep 17 00:00:00 2001 From: Stypox Date: Thu, 7 Dec 2023 16:40:32 +0100 Subject: [PATCH 159/172] Improve javadoc for `getAudioStreamFor` --- .../org/schabi/newpipe/util/SecondaryStreamHelper.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/util/SecondaryStreamHelper.java b/app/src/main/java/org/schabi/newpipe/util/SecondaryStreamHelper.java index 42a6ca361..75d9a3892 100644 --- a/app/src/main/java/org/schabi/newpipe/util/SecondaryStreamHelper.java +++ b/app/src/main/java/org/schabi/newpipe/util/SecondaryStreamHelper.java @@ -28,12 +28,15 @@ public class SecondaryStreamHelper { } /** - * Find the correct audio stream for the desired video stream. + * Finds an audio stream compatible with the provided video-only stream, so that the two streams + * can be combined in a single file by the downloader. If there are multiple available audio + * streams, chooses either the highest or the lowest quality one based on + * {@link ListHelper#isLimitingDataUsage(Context)}. * * @param context Android context * @param audioStreams list of audio streams - * @param videoStream desired video ONLY stream - * @return selected audio stream or null if a candidate was not found + * @param videoStream desired video-ONLY stream + * @return the selected audio stream or null if a candidate was not found */ @Nullable public static AudioStream getAudioStreamFor(@NonNull final Context context, From 096115def79dbdef60aa2566fed2c936bfab52dc Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Fri, 8 Dec 2023 15:31:19 +0100 Subject: [PATCH 160/172] Translated using Weblate (Bengali) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 78.7% (571 of 725 strings) Translated using Weblate (Basque) Currently translated at 95.0% (689 of 725 strings) Translated using Weblate (Turkish) Currently translated at 43.4% (33 of 76 strings) Translated using Weblate (Lithuanian) Currently translated at 92.9% (674 of 725 strings) Translated using Weblate (Portuguese (Brazil)) Currently translated at 30.2% (23 of 76 strings) Translated using Weblate (Swedish) Currently translated at 100.0% (725 of 725 strings) Translated using Weblate (Swedish) Currently translated at 100.0% (725 of 725 strings) Translated using Weblate (Portuguese (Brazil)) Currently translated at 99.8% (724 of 725 strings) Translated using Weblate (Interlingua) Currently translated at 32.0% (232 of 725 strings) Translated using Weblate (Norwegian Bokmål) Currently translated at 94.6% (686 of 725 strings) Translated using Weblate (Norwegian Bokmål) Currently translated at 94.6% (686 of 725 strings) Translated using Weblate (Romanian) Currently translated at 89.3% (648 of 725 strings) Translated using Weblate (German) Currently translated at 81.5% (62 of 76 strings) Translated using Weblate (German) Currently translated at 100.0% (725 of 725 strings) Translated using Weblate (Filipino) Currently translated at 32.1% (233 of 725 strings) Translated using Weblate (Filipino) Currently translated at 32.1% (233 of 725 strings) Translated using Weblate (Vietnamese) Currently translated at 100.0% (725 of 725 strings) Translated using Weblate (Swedish) Currently translated at 72.3% (55 of 76 strings) Translated using Weblate (Esperanto) Currently translated at 3.9% (3 of 76 strings) Translated using Weblate (Swedish) Currently translated at 99.7% (723 of 725 strings) Translated using Weblate (Esperanto) Currently translated at 71.0% (515 of 725 strings) Translated using Weblate (Esperanto) Currently translated at 2.6% (2 of 76 strings) Translated using Weblate (Tigrinya) Currently translated at 8.4% (61 of 725 strings) Translated using Weblate (Vietnamese) Currently translated at 43.4% (33 of 76 strings) Translated using Weblate (German) Currently translated at 81.5% (62 of 76 strings) Translated using Weblate (Finnish) Currently translated at 98.3% (713 of 725 strings) Translated using Weblate (Vietnamese) Currently translated at 100.0% (725 of 725 strings) Translated using Weblate (Esperanto) Currently translated at 70.0% (508 of 725 strings) Added translation using Weblate (English (Old)) Added translation using Weblate (Aymara) Added translation using Weblate (English (Middle)) Added translation using Weblate (Arabic (Najdi)) Added translation using Weblate (German (Low)) Added translation using Weblate (Sicilian) Added translation using Weblate (Kashmiri) Added translation using Weblate (Burmese) Translated using Weblate (Tigrinya) Currently translated at 3.5% (26 of 725 strings) Translated using Weblate (Georgian) Currently translated at 91.1% (661 of 725 strings) Translated using Weblate (French) Currently translated at 98.8% (717 of 725 strings) Translated using Weblate (Vietnamese) Currently translated at 42.1% (32 of 76 strings) Translated using Weblate (Vietnamese) Currently translated at 100.0% (725 of 725 strings) Translated using Weblate (Interlingua) Currently translated at 31.3% (227 of 725 strings) Translated using Weblate (Vietnamese) Currently translated at 35.5% (27 of 76 strings) Translated using Weblate (Esperanto) Currently translated at 69.2% (502 of 725 strings) Translated using Weblate (Esperanto) Currently translated at 69.2% (502 of 725 strings) Translated using Weblate (German) Currently translated at 81.5% (62 of 76 strings) Translated using Weblate (Punjabi) Currently translated at 100.0% (725 of 725 strings) Translated using Weblate (Bulgarian) Currently translated at 63.8% (463 of 725 strings) Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (725 of 725 strings) Translated using Weblate (Esperanto) Currently translated at 66.3% (481 of 725 strings) Translated using Weblate (French) Currently translated at 98.6% (715 of 725 strings) Translated using Weblate (Vietnamese) Currently translated at 100.0% (725 of 725 strings) Translated using Weblate (Turkish) Currently translated at 31.5% (24 of 76 strings) Translated using Weblate (Vietnamese) Currently translated at 97.3% (706 of 725 strings) Translated using Weblate (Swedish) Currently translated at 98.4% (714 of 725 strings) Translated using Weblate (Turkish) Currently translated at 100.0% (725 of 725 strings) Translated using Weblate (Turkish) Currently translated at 100.0% (725 of 725 strings) Translated using Weblate (Portuguese) Currently translated at 100.0% (76 of 76 strings) Translated using Weblate (Russian) Currently translated at 100.0% (76 of 76 strings) Translated using Weblate (Vietnamese) Currently translated at 94.6% (686 of 725 strings) Translated using Weblate (Portuguese) Currently translated at 100.0% (76 of 76 strings) Translated using Weblate (Chinese (Traditional, Hong Kong)) Currently translated at 21.0% (16 of 76 strings) Translated using Weblate (Chinese (Traditional, Hong Kong)) Currently translated at 100.0% (725 of 725 strings) Translated using Weblate (French) Currently translated at 98.2% (712 of 725 strings) Deleted translation using Weblate (English (Middle)) Co-authored-by: /dev/urandom Co-authored-by: A Co-authored-by: Aitor Salaberria Co-authored-by: Alexthegib Co-authored-by: Allan Nordhøy Co-authored-by: Ans Virlis Co-authored-by: AudricV Co-authored-by: Cem TÜRKER Co-authored-by: Edward Co-authored-by: Erik Matson Co-authored-by: Giorgi Taba K'obakhidze Co-authored-by: Hosted Weblate Co-authored-by: Jener Gomes Co-authored-by: Kristoffer Grundström Co-authored-by: LiftedStarfish Co-authored-by: Napstaguy04 Co-authored-by: P.O Co-authored-by: PiryusQ Co-authored-by: Ray Co-authored-by: ShareASmile Co-authored-by: Software In Interlingua Co-authored-by: TXRdev Archive Co-authored-by: TobiGr Co-authored-by: Translator Co-authored-by: VfBFan Co-authored-by: Weblate Co-authored-by: bittin1ddc447d824349b2 Co-authored-by: ferarilalon Co-authored-by: fsbat0 Co-authored-by: ngocanhtve Co-authored-by: notlin4 Co-authored-by: sum1tookshoe Co-authored-by: trunars Co-authored-by: İbrahim Dinç Co-authored-by: Макар Разин Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/de/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/eo/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/pt/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/pt_BR/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/ru/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/sv/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/tr/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/vi/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/zh_Hant_HK/ Translation: NewPipe/Metadata --- app/src/main/res/values-ang/strings.xml | 2 + app/src/main/res/values-ars/strings.xml | 2 + app/src/main/res/values-ay/strings.xml | 2 + app/src/main/res/values-bg/strings.xml | 15 + app/src/main/res/values-bn/strings.xml | 54 +-- app/src/main/res/values-de/strings.xml | 6 +- app/src/main/res/values-eo/strings.xml | 72 ++- app/src/main/res/values-eu/strings.xml | 121 +++-- app/src/main/res/values-fi/strings.xml | 4 +- app/src/main/res/values-fil/strings.xml | 15 +- app/src/main/res/values-fr/strings.xml | 19 +- app/src/main/res/values-ia/strings.xml | 13 +- app/src/main/res/values-ka/strings.xml | 38 +- app/src/main/res/values-ks/strings.xml | 2 + app/src/main/res/values-lt/strings.xml | 2 +- app/src/main/res/values-my/strings.xml | 2 + app/src/main/res/values-nb-rNO/strings.xml | 40 +- app/src/main/res/values-nds/strings.xml | 2 + app/src/main/res/values-pa/strings.xml | 6 +- app/src/main/res/values-pt-rBR/strings.xml | 211 ++++---- app/src/main/res/values-ro/strings.xml | 2 +- app/src/main/res/values-scn/strings.xml | 2 + app/src/main/res/values-sv/strings.xml | 94 +++- app/src/main/res/values-ti/strings.xml | 56 ++- app/src/main/res/values-tr/strings.xml | 12 +- app/src/main/res/values-vi/strings.xml | 450 ++++++++++-------- app/src/main/res/values-zh-rHK/strings.xml | 86 +++- app/src/main/res/values-zh-rTW/strings.xml | 112 ++--- .../metadata/android/de/changelogs/63.txt | 2 +- .../metadata/android/de/changelogs/65.txt | 12 +- .../metadata/android/de/changelogs/968.txt | 8 +- .../metadata/android/de/changelogs/970.txt | 2 +- .../metadata/android/de/changelogs/993.txt | 10 +- .../metadata/android/de/changelogs/995.txt | 14 + .../metadata/android/eo/changelogs/63.txt | 8 + .../metadata/android/eo/full_description.txt | 1 + .../metadata/android/pt-BR/changelogs/954.txt | 14 +- .../metadata/android/pt-BR/changelogs/994.txt | 15 + .../metadata/android/pt-BR/changelogs/995.txt | 14 + .../metadata/android/pt/changelogs/995.txt | 14 + .../metadata/android/ru/changelogs/994.txt | 13 + .../metadata/android/ru/changelogs/995.txt | 14 + .../metadata/android/sv/changelogs/954.txt | 9 + .../metadata/android/tr/changelogs/68.txt | 48 +- .../metadata/android/tr/changelogs/69.txt | 19 + .../metadata/android/tr/changelogs/70.txt | 25 + .../metadata/android/tr/changelogs/71.txt | 10 + .../metadata/android/tr/changelogs/730.txt | 2 + .../metadata/android/tr/changelogs/740.txt | 22 + .../metadata/android/tr/changelogs/750.txt | 21 + .../metadata/android/tr/changelogs/760.txt | 40 ++ .../metadata/android/tr/changelogs/770.txt | 3 + .../metadata/android/tr/changelogs/780.txt | 12 + .../metadata/android/tr/changelogs/790.txt | 14 + .../metadata/android/tr/full_description.txt | 2 +- .../metadata/android/vi/changelogs/65.txt | 9 + .../metadata/android/vi/changelogs/987.txt | 12 + .../metadata/android/vi/changelogs/988.txt | 2 + .../metadata/android/vi/changelogs/989.txt | 3 + .../metadata/android/vi/changelogs/990.txt | 15 + .../metadata/android/vi/changelogs/991.txt | 13 + .../metadata/android/vi/changelogs/994.txt | 15 + .../metadata/android/vi/changelogs/995.txt | 14 + .../android/zh_Hant_HK/changelogs/994.txt | 15 + .../android/zh_Hant_HK/changelogs/995.txt | 14 + 65 files changed, 1363 insertions(+), 559 deletions(-) create mode 100644 app/src/main/res/values-ang/strings.xml create mode 100644 app/src/main/res/values-ars/strings.xml create mode 100644 app/src/main/res/values-ay/strings.xml create mode 100644 app/src/main/res/values-ks/strings.xml create mode 100644 app/src/main/res/values-my/strings.xml create mode 100644 app/src/main/res/values-nds/strings.xml create mode 100644 app/src/main/res/values-scn/strings.xml create mode 100644 fastlane/metadata/android/de/changelogs/995.txt create mode 100644 fastlane/metadata/android/eo/changelogs/63.txt create mode 100644 fastlane/metadata/android/eo/full_description.txt create mode 100644 fastlane/metadata/android/pt-BR/changelogs/994.txt create mode 100644 fastlane/metadata/android/pt-BR/changelogs/995.txt create mode 100644 fastlane/metadata/android/pt/changelogs/995.txt create mode 100644 fastlane/metadata/android/ru/changelogs/994.txt create mode 100644 fastlane/metadata/android/ru/changelogs/995.txt create mode 100644 fastlane/metadata/android/sv/changelogs/954.txt create mode 100644 fastlane/metadata/android/tr/changelogs/69.txt create mode 100644 fastlane/metadata/android/tr/changelogs/70.txt create mode 100644 fastlane/metadata/android/tr/changelogs/71.txt create mode 100644 fastlane/metadata/android/tr/changelogs/730.txt create mode 100644 fastlane/metadata/android/tr/changelogs/740.txt create mode 100644 fastlane/metadata/android/tr/changelogs/750.txt create mode 100644 fastlane/metadata/android/tr/changelogs/760.txt create mode 100644 fastlane/metadata/android/tr/changelogs/770.txt create mode 100644 fastlane/metadata/android/tr/changelogs/780.txt create mode 100644 fastlane/metadata/android/tr/changelogs/790.txt create mode 100644 fastlane/metadata/android/vi/changelogs/65.txt create mode 100644 fastlane/metadata/android/vi/changelogs/987.txt create mode 100644 fastlane/metadata/android/vi/changelogs/988.txt create mode 100644 fastlane/metadata/android/vi/changelogs/989.txt create mode 100644 fastlane/metadata/android/vi/changelogs/990.txt create mode 100644 fastlane/metadata/android/vi/changelogs/991.txt create mode 100644 fastlane/metadata/android/vi/changelogs/994.txt create mode 100644 fastlane/metadata/android/vi/changelogs/995.txt create mode 100644 fastlane/metadata/android/zh_Hant_HK/changelogs/994.txt create mode 100644 fastlane/metadata/android/zh_Hant_HK/changelogs/995.txt diff --git a/app/src/main/res/values-ang/strings.xml b/app/src/main/res/values-ang/strings.xml new file mode 100644 index 000000000..a6b3daec9 --- /dev/null +++ b/app/src/main/res/values-ang/strings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/app/src/main/res/values-ars/strings.xml b/app/src/main/res/values-ars/strings.xml new file mode 100644 index 000000000..a6b3daec9 --- /dev/null +++ b/app/src/main/res/values-ars/strings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/app/src/main/res/values-ay/strings.xml b/app/src/main/res/values-ay/strings.xml new file mode 100644 index 000000000..a6b3daec9 --- /dev/null +++ b/app/src/main/res/values-ay/strings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/app/src/main/res/values-bg/strings.xml b/app/src/main/res/values-bg/strings.xml index 08a6bd93b..fc845fdf9 100644 --- a/app/src/main/res/values-bg/strings.xml +++ b/app/src/main/res/values-bg/strings.xml @@ -555,4 +555,19 @@ Наскоро добавено Буфериране Разбийте плейъра + Изключете, за да скриете полетата с мета информация с допълнителна информация за създателя на потока, съдържанието на потока или заявка за търсене + Автоматично поставяне в опашка + Редактирайте всяко действие за известяване по-долу, като го докоснете. Изберете до три от тях, които да бъдат показани в компактното известие, като използвате квадратчетата за отметка вдясно + Изберете оригиналния аудио запис независимо от езика + Превключването от един плейър на друг може да замени вашата опашка + Изберете аудиозапис с описания за хора с увредено зрение, ако има такъв + Действие с жест наляво + Предпочитай описателно аудио + Променете размера на интервала на зареждане на прогресивно съдържание (в момента %s). По-ниска стойност може да ускори първоначалното им зареждане + Предпочитай оригинално аудио + Опашката на активния плейър ще бъде заменена + Полезно, например, ако използвате слушалки със счупени физически бутони + Размер на интервала на зареждане при възпроизвеждане + Игнорирайте събитията с хардуерни медийни бутони + Изберете жест за лявата половина на екрана на плейъра \ No newline at end of file diff --git a/app/src/main/res/values-bn/strings.xml b/app/src/main/res/values-bn/strings.xml index fd80afacf..13bda43ae 100644 --- a/app/src/main/res/values-bn/strings.xml +++ b/app/src/main/res/values-bn/strings.xml @@ -243,17 +243,17 @@ প্রথম ক্রিয়া বোতাম থাম্বনেলে ১:১ অনুপাতে করো Kodi মিডিয়া সেন্টারে এর মাধ্যমে ভিডিও প্লে করার জন্য একটি বিকল্প প্রদর্শন কর - \"Kodi দ্বারা চালান\" বিকল্পটি প্রদর্শন কর - অনুপস্থিত কোড অ্যাপ ইনস্টল করবেন\? - Kodi দ্বারা চালাও + \"Kodi-তে প্লে করুন\" দেখান + Kodi ইনস্টল করবেন? + Kodi-তে প্লে করুন শুধুমাত্র কিছু ডিভাইস 2K/4K ভিডিও চালাতে পারে - উচ্চতর রেজুলেশন প্রদর্শন করা হবে - সহজাত ভাসমান আকার - সহজাত আকার - অডিও ফাইলগুলির জন্য ডাউনলোডের ফোল্ডার নির্বাচন করুন - ডাউনলোড করা অডিও ফাইলগুলি এখানে সঞ্চিত থাকে + উচ্চতর রেজুলেশন দেখান + স্বাভাবিক পপ-আপ রেজুলেশন + স্বাভাবিক রেজুলেশন + অডিও ডাউনলোডের জন্য ফোল্ডার নির্বাচন করুন + ডাউনলোড করা অডিও এখানে থাকবে অডিও ডাউনলোড ফোল্ডার - ভিডিওগুলি ডাউনলোডের জন্য ফোল্ডার নির্বাচন করুন + ভিডিও ডাউনলোডের জন্য ফোল্ডার নির্বাচন করুন ডাউনলোড করা ভিডিওগুলো এখানে থাকে ভিডিও ডাউনলোড করার ফোল্ডার যুক্ত করুন @@ -261,33 +261,33 @@ ব্যাকগ্রাউন্ড ট্যাব পছন্দ করুন বুকমার্ক করা প্লেলিস্টসমূহ - সদস্যতা + সাবস্ক্রিবশন তথ্য দেখুন - সদস্যতা হালনাগাদে ব্যর্থ - সদস্যতা পরিবর্তন করা যায়নি - চ্যানেল থেকে আনসাবস্ক্রাইব্ড + সাবস্ক্রিবশন হালনাগাদ করা সম্ভব হয়নি + সাবস্ক্রিবশন পরিবর্তন করা সম্ভব হয়নি + চ্যানেল আনসাবস্ক্রাইব করা হয়েছে আনসাবস্ক্রাইব - সাবস্ক্রাইব করা আছে + পূর্ব-সাবস্ক্রাইবকৃত সাবস্ক্রাইব - বহির্গত অডিও প্লেয়ার ব্যবহার করুন - কিছু রেজোলিউশনে অডিও অপসারণ করে দেয় - বাইরের ভিডিও প্লেয়ার ব্যবহার করুন + অন্যান্য অডিও প্লেয়ার ব্যবহার করুন + কিছু কিছু রেজুলেশনে অডিও ঠিকঠাক থাকবে না + অন্যান্য ভিডিও প্লেয়ার ব্যবহার করুন শেয়ার করুন - রেজাল্ট দেখানো হচ্ছেঃ %s - তুমি কি বুঝিয়েছো ‘%1$s’\? + ফলাফল দেখানো হচ্ছেঃ %s + আপনি কি ‘%1$s’ বোঝাচ্ছেন? সেটিংস খুঁজুন - স্ট্রিম ফাইল ডাউনলোড করুন + ডাউনলোড করুন ডাউনলোড শেয়ার - ভাসমান অবস্থায় খুলো - ব্রাউজারে খুলো + পপআপ মুডে চালু করুন + ব্রাউজারে চালু করুন বাতিল ইনস্টল - কোনো ধারা চালক পাওয়া যায়নি (প্লে করতে VLC ইন্সটল করতে পারো)। - কোন স্ট্রিম প্লেয়ার পাওয়া যায়নি। VLC ইনস্টল করতে চান\? + কোনো মিডিয়া প্লেয়ার পাওয়া যায়নি (মিডিয়া প্লে করতে VLC ইন্সটল করতে পারেন)। + কোন স্ট্রিম প্লেয়ার পাওয়া যায়নি। VLC ইনস্টল করতে চান কি? প্রকাশকাল %1$s - আতশী কাঁচে টিপ দিয়ে শুরু করো। + আতশ কাঁচে চাপ দিয়ে শুরু করো। বাফারিং সাফল পঞ্চম অ্যাকশন বাটন @@ -432,7 +432,7 @@ অধ্যায় মতামত বর্ণনা - দিয়ে খুলো + অন্য অ্যাপে ওপেন করুন ফিড হালনাগাদ সীমা খালি গ্রুপ নাম কোনো সদস্যতা নির্বাচিত হয়নি @@ -570,7 +570,7 @@ ডাউনলোড শেষ %sটি ডাউনলোড শেষ
    - দেখা হয়েছে চিহ্নিত করো + দেখা হয়েছে বলে চিহ্নিত করুন চালক বিজ্ঞপ্তি নিম্ন মান(ছোট) মূল তৈরিকারকের পছন্দ করা diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 2fa308a00..5260287c1 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -99,7 +99,7 @@ Nur manche Geräte können Videos in 2K/4K abspielen Hintergrund Pop-up - Pop-up Eigenschaften merken + Eigenschaften des Pop-ups merken Entfernt Tonspur bei manchen Auflösungen Letzte Größe und Position des Pop-ups merken Suchvorschläge @@ -178,10 +178,10 @@ Wiederherstellen nach einem Wiedergabefehler Kiosk-Seite Kiosk auswählen - Tipp anzeigen, wenn der Hintergrundwiedergabe- oder Pop-up-Knopf „Details:“ im Video gedrückt wird + Tipp anzeigen, wenn die Hintergrundwiedergabe- oder Pop-up-Schaltfläche „Details:“ im Video gedrückt wird Neu und Heiß Halten, um zur Wiedergabeliste hinzuzufügen - „Halten zum Einreihen“ Tipp anzeigen + „Halten zum Einreihen“-Tipp anzeigen [Unbekannt] Wiedergabe im Hintergrund starten Wiedergabe in einem Pop-up starten diff --git a/app/src/main/res/values-eo/strings.xml b/app/src/main/res/values-eo/strings.xml index 99e8f7589..44e3348ca 100644 --- a/app/src/main/res/values-eo/strings.xml +++ b/app/src/main/res/values-eo/strings.xml @@ -111,8 +111,8 @@ Konservi la historio de serĉo lokale Rigardu historion Spuri la viditajn filmetojn - NewPipe Sciigo - Sciigoj por NewPipe fonaj kaj ŝprucfenestraj ludiloj + Sciigo de NewPipe + Sciigoj por ludilo de NewPipe Ludilo Konduto Historio kaj kaŝmemoro @@ -201,8 +201,8 @@ Elektu ongleton Ĝisdatigoj Dosiero forviŝita - Sciigo por ĝisdatigi apon - Sciigo por nova versio de NewPipe + Sciigo por ĝisdatigo de apo + Sciigo por novaj versioj de NewPipe Ekstera konservejo malhavebla Elŝuti al ekstera SD-karto ne eblas. Ĉu vi volas restarigi la elŝutan dosierujon \? viciĝita @@ -546,4 +546,68 @@ Kraŝi la ludilo Envicigita Envicigi + Laŭteco + Neniu + Permesi al Android agordi koloron de sciigo laŭ la precipa koloro de videaĵminiaturo (noti, ke ĉi tio ne disponeblas en ĉiuj iloj) + Aŭtomata vicigado + Ago de dekstra gesto + Redakti ĉiun agon de sciigo per tuŝi gin. Elekti maksimume tri agon por montri en la kompakta sciigo per markobutonoj dekstre. + Elekti la originalan aŭdiotrakon malgraŭ lingvo + Elekti aŭdiotrakon kun priskriboj por vidmalkapabluloj kiam ebla + Ago de maldekstra gesto + Preferi priskribajn aŭdiotrakojn + Ŝangi la grandecon de elŝuta intervalo por progresiva enhavo (aktuale %s). Malplia valoro eble povas rapidigi ĝian komencan ŝargadon + Preferi originalan aŭdaĵon + Elekti geston por dekstra duono de ludil-ekrano + Utila, ekzemple, se vi uzas kaptelefonon, kiu havas difektajn fizikajn butonojn + Grandeco de intervalo de legada elŝuto + Heleco + Vi povas elekti maksimume tri agoj por montri en la kompakta sciigo! + Ignori eventoj de aparataroj plurmediaj butonoj + Elekti geston por maldekstra duono de ludil-ekrano + Ŝalti \"Limigitan Reĝimon\" de YouTube + Rapida reĝimo + Ne eblas rekoni la ligilon. Ĉu malfermi per alia apo\? + Kuketojn de reCAPTCHA estis forigita + Montri enhavon, kiu eble maltaŭgas por infanoj, ĉar ĝi havas aĝo-limon (kiel \"18+\") + Novaj fluoj + Foraj serĉsugestoj + Sciigoj por raporti erarojn + Ŝargante metadatumoj… + Sciigo por kreado de haketaĵoj de videoj + YouTube provizas \"Limigitan Reĝimon\", kiu kaŝas enhavon, kiu potence maltaŭgas por infanoj + Ĉi tiu video estas aĝo-limigita. +\nPro novaj reguloj de YouTube, kiuj aplikas al aĝo-limigitaj videoj, NewPipe ne povas atingi iun ajn video-fluoj de ĉi tiu video kaj konsekvence ne povas ludi ĝin. + Sciigo por erar-raportoj + Sciigoj + Ludila sciigo + Sciigo por haketado de videoj + Lokaj serĉsugestoj + Ŝalti ĉefan ludilon plenekrane + Sciigo por novaj fluoj de abonoj + Forigi kuketojn de reCAPTCHA + Agordi la sciigon por ĉi-momente ludantaj datumtorentoj + Ne komenci ludi videojn en la mini-ludilo, sed ŝalti plenekranan reĝimon rekte, se aŭtomata rotacio ŝlositas. Vi ankoraŭ povus atingi mini-ludilon, se vi elirus plenekranan reĝimon. + Forigi kuketojn, kiujn NewPipe konservas, kiam vi solvas reCAPTCHA-taskojn + NewPipe renkontis eraron, tuŝi por raporti + Pozicio de la ĉefaj langetoj + Transloki la ĉefan langet-elektilon al la malsupro + + %s nova fluo + %s novaj fluoj + + Raporti per GitHub + Komentoj malŝaltitas + Eraro okazis, vidu sciigon + Neniuj tujelsendoj + Neniuj fluoj + Kopii formatitan raporton + Importi aŭ eksporti abonojn per la tri-punkta menuo + Kalkulado de haketaĵo + Oftaj demandoj + Neniu dosierujo por elŝutoj agordita, bonvolu elekti la defaŭltan elŝuto-dosierujon nun + Bonvolu certigi, ĉu erarraporto, kiu diskutas pri via eraro, jam ekzistas. Kreado de duoblaĵaj erarraportoj forprenas tempon el ni, kiun ni povus uzi por ripari la veran eraron. + Rilatajn erojn + Solvi + Malsukcesis kopii al la tondujo \ No newline at end of file diff --git a/app/src/main/res/values-eu/strings.xml b/app/src/main/res/values-eu/strings.xml index ba0793db8..69a42d1c2 100644 --- a/app/src/main/res/values-eu/strings.xml +++ b/app/src/main/res/values-eu/strings.xml @@ -14,7 +14,7 @@ Aukeratu bideoak deskargatzeko karpeta Lehenetsitako bereizmena Jo Kodirekin - Kode aplikazioa instalatu\? + Falta den Kore aplikazioa instalatu nahi duzu? Erakutsi \"Jo Kodirekin\" aukera Erakutsi bideoa Kodi multimedia zentroarekin erreproduzitzeko aukera Audioa @@ -28,7 +28,7 @@ Igotzailearen abatarraren iruditxoa Ez dute gustoko Gustoko dute - Ez da jario erreproduzigailurik aurkitu. VLC instalatu\? + Ez da igorpen-erreproduzigailurik aurkitu. VLC instalatu? \"%1$s\" esan nahi al zenuen\? Erabili kanpo bideo-erreproduzigailua Erabili kanpo audio-erreproduzigailua @@ -109,7 +109,7 @@ © %1$s %2$s. %3$s Honi buruz eta ohiko galderak Lizentziak - Androiderako streaming libre eta arina. + Igorpen libre eta arinak Android-en. Ikusi GitHub zerbitzarian NewPipe Lizentzia Ideiak, itzulpenak, diseinu aldaketak, kode garbiketak, kode aldaketa sakonak badituzu, laguntza beti da ongi etorria. Eginaz hobetzen da! @@ -167,7 +167,7 @@ Aldatu bigarren planora Aldatu laster-leihora Aldatu nagusira - Ezin izan da jario hau erreproduzitu + Ezin izan da igorpen hau erreproduzitu Erreproduzigailuaren errore berreskuraezina gertatu da Erreproduzigailuaren erroretik berreskuratzen Dohaintza @@ -194,18 +194,18 @@ Laster-leihoan erreproduzitzen hasi Ireki tiradera Itxi tiradera - Ez da jario erreproduzigailurik aurkitu (VLC instalatu dezakezu edukia ikusi ahal izateko). + Ez da igorpen-erreproduzigailurik aurkitu (VLC instalatu dezakezu erreproduzitzeko). Beti Behin besterik ez Kanpo erreproduzigailuek ez dituzte mota honetako estekak onartzen - Ez da bideo jariorik aurkitu - Ez da audio jariorik aurkitu + Ez da bideo-igorpenik aurkitu + Ez da audio-igorpenik aurkitu Bideo erreproduzigailua Bigarren planoko erreproduzigailua Laster-leiho erreproduzigailua Informazioa eskuratzen… Kargatzen eskatutako edukia - Deskargatu jario fitxategia + Deskargatu igorpen-fitxategia Erakutsi informazioa Gogoko erreprodukzio-zerrendak Gehitu hona @@ -214,8 +214,8 @@ Ezabatu cacheko metadatuak Kendu cachetik webguneen datu guztiak Metadatuen cachea ezabatuta - Gehitu hurrengo jarioa ilarara - Jarraitu bukaerako (errepikapenik gabe) ilara erlazionatutako jario bat gehituz + Gehitu automatikoki hurrengo igorpena ilarara + Gehitu ilararen amaieran lotutako igorpen bat errepikatu gabe Arazketa Fitxategia Inportatu datu-basea @@ -223,7 +223,7 @@ Zure uneko historiala, harpidetzak eta (aukeran) ezarpenak gainidazten ditu Esportatu historiala, harpidetzak, erreprodukzio-zerrendak eta ezarpenak Garbitu ikusitakoaren historiala - Jotako jarioen historiala eta erreprodukzio puntuak ezabatzen ditu + Erreproduzitutako igorpen-historia eta erreprodukzio-kokapenak ezabatzen ditu Ezabatu ikusitakoaren historia osoa\? Ikusitakoaren historiala ezabatuta Garbitu bilaketa historiala @@ -235,7 +235,7 @@ Fitxategia ez dago edo ez dago baimenik irakurri edo idazteko Fitxategi izena ezin da hutsik egon Errore bat gertatu da: %1$s - Ez dago jariorik deskargatzeko eskuragarri + Ez dago igorpenik eskuragarri deskargatzeko Arrastatu ordena aldatzeko Sortu Baztertu @@ -260,7 +260,7 @@ Kendu gogokoa Erreprodukzio zerrenda hau ezabatu\? Erreprodukzio-zerrenda sortuta - Erreprodukzio-zerrendatua + Zerrendara gehitua Erreprodukzio zerrendaren iruditxoa aldatuta. Azpititulurik ez Doitu @@ -557,7 +557,7 @@ %s bilaketaren erantzunak erakusten Ilaran jarri da Jarri ilaran - Zerbitzuen jatorrizko testuak transmisioko elementuetan ikusgai egongo dira + Zerbitzuen jatorrizko testuak igorpenaren elementuetan ikusgai egongo dira Erakutsi «orain dela» jatorrizko denbora elementuetan Editatu beheko jakinarazpen ekintza bakoitza gainean sakatuz. Hautatu horietako hiru gehienez jakinarazpen trinkoan erakusteko eskuineko kontrol laukiak erabiliz Androidek miniaturako kolore nagusiaren arabera jakinarazpenaren kolorea pertsonalizatzea baimendu (kontuan izan ez dagoela gailu guztietan erabilgarri) @@ -568,7 +568,7 @@ Bideo hash jakinarazpena Hash-a kalkulatzen Azkenak - Desgaitu jario sortzailearen informazio gehigarria, jarioaren edukia edo bilaketa eskaera duten informazio koadroak ezkutatzeko + Desgaitu igorpen-sortzailearen informazio gehigarria, igorpenaren edukia edo bilaketa-eskaera duten metadatuen informazio-koadroak ezkutatzeko Erakutsi meta informazioa Ez dago zure gailuan hau ireki dezakeen aplikaziorik Kapituluak @@ -580,22 +580,22 @@ Ireki honekin Irratia Nabarmenduak - Eduki hau ordaindu duten erabiltzaileentzat soilik dago eskuragarri, eta NewPipe-k ezin du tramsmititu edo deskargatu. - Bideo hau YouTube Music Premium kideentzako soilik eskuragarri dago, eta NewPipe-k ezin du transmititu edo deskargatu. - Eduki hau pribatua da, eta NewPipe-k ezin du transmititu edo deskargatu. - Hau SoundCloud Go+ pista bat da, zure herrialdean gutxienez, eta NewPipe-k ezin du transmititu edo deskargatu. + Eduki hau ordaindu duten erabiltzaileentzat soilik dago erabilgarri, eta NewPipe-k ezin du igorri edo deskargatu. + Bideo hau YouTube Music Premium kideentzako soilik erabilgarri dago, eta NewPipe-k ezin du igorri edo deskargatu. + Eduki hau pribatua da, eta NewPipe-k ezin du igorri edo deskargatu. + Hau SoundCloud Go+ zerbitzuko pista bat da, zure herrialdean behintzat, eta NewPipe-k ezin du igorri edo deskargatu. Eduki hau ez dago eskuragarri zure herrialdean. Aplikazioa kraskatu Ebatzi Bideo hau adinez mugatua dago. -\nAdinez mugatutako bideoekiko YouTube-ren politika berriengatik, NewPipe-k ezin ditu bideo hauek atzitu eta ezin ditu erreproduzitu. +\nAdinez mugatutako bideoekiko YouTube-ren politika berriengatik, NewPipe-k ezin ditu bideoen igorpen hauek atzitu eta erreproduzitu. Deskarga hasi da Behean gaueko gai gogokoena hauta dezakezu Hautatu zure gaueko gai gogokoena — %s Automatikoa (gailuaren gaia) - Gau Gaia + Gauaren gaia kanalaren xehetasunak erakutsi - Desaktibatu hedabideen tunela bideo-erreprodukzioan pantaila beltz bat edo totelka ari bada + Desgaitu edukien tunela bideo-erreprodukzioan pantaila beltza badago edo bideoa totelka ari bada. Hedabideen tunela desaktibatu Itzalita Piztuta @@ -650,7 +650,7 @@ Ez hasi bideoak mini erreproduzitzailean eta hasi bideoak pantaila osoan zuzenean, auto biraketa blokeatuta badago. Mini erreproduzitzailea erabili dezakezu pantaila osotik irtetzean Hasi erreproduzitzaile nagusia pantaila osoan Isatsari bideo hau erantsita - Gehitu bideo hau isatsari + Gehitu jarraian Erakutsi \"Itxi erreproduzigailua\" Prozesatzen... Itxoin mesedez Erroreen txostenen jakinarazpena @@ -670,37 +670,37 @@ Erreproduzigailua erabiltzean ustekabean ixteko aukera ematen du Erakutsi errore barra bat Sortu errore jakinarazpen bat - Konfiguratu uneko erreprodukzioaren jakinarazpenak + Konfiguratu unean erreproduzitzen ari den igorpenaren jakinarazpena Jakinarazpenak Erreproduzigailuaren jakinarazpenak - Jario berriak - Egiaztatu jario berriak - Jario berrien jakinarazpenak + Igorpen berriak + Bilatu igorpen berriak + Igorpen berrien jakinarazpenak Edozein sare Jakinarazpenak desgaituta daude Kanal honetara harpidetu zara , Txandakatu denak - Harpidetzen jario berriei buruz jakinarazi + Harpidetzen igorpen berriei buruz jakinarazi Ezabatu deskargatutako fitxategi guztiak biltegitik\? - Harpidetzentzako jario berrien jakinarazpenak - Jarioaren xehetasunak kargatzen… + Harpidetzen igorpen berrien jakinarazpenak + Igorpenaren xehetasunak kargatzen… - jario berri %s - %s jario berri + igorpen berri %s + %s igorpen berri LeakCanary ez dago eskuragarri Egiaztapen maiztasuna Jakinarazi ExoPlayer lehenetsia - Beharrezko sare konexioa + Beharrezko sareko konexioa Portzentaia Semitonoa Erreprodukzioaren kargatze-tartearen tamaina - Deskargatzaileak onartzen ez dituen jarioak ez dira erakusten - Hautatutako jarioa ez dago kanpoko erreproduzigailu batengatik onartuta - Ez dago kanpoko erreproduzigailu batengatik onartuta dagoen audio jariorik - Ez dago kanpoko erreproduzigailu batengatik onartuta dagoen bideo jariorik + Deskargatzaileak onartzen ez dituen igorpenak ez dira erakusten + Hautatutako igorpena ez dute kanpoko erreproduzitzaileek onartzen + Ez dato erabilgarri audio-igorpenik kanpoko erreproduzitzaileentzat + Ez dago erabilgarri bideo-igorpenik kanpoko erreproduzitzaileentzat Formatu ezezaguna Kalitate ezezaguna Hautatu kanpoko erreproduzigailuen kalitatea @@ -711,7 +711,7 @@ Betiko miniatura kendu NewPipe-en azken bertsioa erabiltzen ari zara Sakatu %s deskargatzeko - Kopia %d behin/aldiz gehitua + Kopia %d aldiz gehitu da Txartela Aukera hau Gaiarako %s aukeratua badago soilik dago erabilgarri Ordenatu @@ -722,10 +722,49 @@ Erabilgarria, adibidez, botoi fisiko hautsiak dituen entzungailua erabiltzen ari bazara Kendu bikoiztuak Kendu bikoiztuak\? - Jario bikoiztu guztiak kendu nahi dituzu erreprodukzio-zerrenda honetatik\? - Erakutsi hurrengo jarioak - Erakutsi/Ezkutatu jarioak + Igorpen bikoiztu guztiak kendu nahi dituzu zerrenda honetatik? + Erakutsi hurrengo igorpenak + Erakutsi/Ezkutatu igorpenak Partzialki ikusita Guztiz ikusia Laster agertzeko + Harpidedunak + Ezezaguna + Bolumena + Erabili ExoPlayer-en deskodetzailearen ordezko eginbidea + Bat ere ez + Metadatuak kargatzen… + Kudeatu ExoPlayer-en ezarpen batzuk. Aldaketa hauek eragina izan dezaten, erreproduzitzailea berrabiarazi behar da. + Fitxa nagusien kokapena + Lortu kanalaren fitxak + Abatarrak + Gaitu aukera hau deskodetzailea hasieratzeko arazoak badituzu, hala nola, lehentasun gutxiago duen deskodetzailetara igarotzea deskodetzaile nagusiaren hasieratzeak huts egiten badu. Aukera honek erreprodukzioak kalitate urria izatea ekar dezake, deskodetzaile nagusiak erabiltzean ez bezala. + Eskuineko keinuaren ekintza + Erabili beti ExoPlayer-en bideo-irteeraren interfazeko ezarpenaren konponbidea + Hurrengo igorpena + Edukien tunela desgaitu da lehenespenez gailuan, gailuaren modeloak ez du onartzen eta. + Azpikanalen abatarrak + Audio-pista bat egon behar da igorpen honetan jada + Hautatu jatorrizko audioaren pista hizkuntza zein den kontuan hartu gabe + Hautatu kanpoko erreproduzitzailearen audio-pista + Lortuko diren fitxak jarioa eguneratzean. Aukera honek ez du eraginik kanal bat modu azkarra erabiliz eguneratzen bada. + Hautatu ikusmen-urritasuna dutenentzako azalpenak dituzten audio-pista bat erabilgarri badago + Ezkerreko keinuaren ekintza + Hobetsi audio deskribatzailea + Igotako abatarrak + Aldatu eduki progresiboen kargatze-tartearen tamaina (oraingoa: %s). Balio baxu batek hasierako kargatzea bizkortu dezake. + Hobetsi jatorrizko audioa + Audioa: %s + Bannerrak + Aukeratu erreproduzigailuaren pantailaren eskuin erdiaren keinua + Mugitu fitxa-hautatzaile nagusia azpira + Audio-pista + Zuzeneko igorpenik ez + Miniaturak + ExoPlayer-en ezarpenak + Distira + Igorpenik ez + Aurreko igorpena + Aukeratu erreproduzitzailearen pantailaren ezker erdiaren keinua + Zuzenekoa \ No newline at end of file diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml index 930c41afa..958c82d07 100644 --- a/app/src/main/res/values-fi/strings.xml +++ b/app/src/main/res/values-fi/strings.xml @@ -789,5 +789,7 @@ Kanavat Olet nyt tilannut tämän kanavan Edellinen stream - + + Haluatko poistaa kaikki ylimääräiset identtiset suoratoistot tästä soittolistasta\? + Suoratoistot, joita lataaja ei vielä tue, ei näytetä \ No newline at end of file diff --git a/app/src/main/res/values-fil/strings.xml b/app/src/main/res/values-fil/strings.xml index 28b344af3..c798a7aa8 100644 --- a/app/src/main/res/values-fil/strings.xml +++ b/app/src/main/res/values-fil/strings.xml @@ -26,10 +26,10 @@ Hindi ma-update ang pagsubaybay Ipakita ang impormasyon Mga Pagsubaybay - Mga naka-bookmark na playlist + Nakabookmark na Playlists Pumili ng Tab Anong Bago - Background + Likuran Palutangin Idagdag Sa Folder ng mga na-download na video @@ -251,4 +251,15 @@ Hangganan ng Edad Oo, pati na rin ang mga napanood nang video Kusa (tema ng device) + Tanggalin ang kabuuan ng watch history? + Walang mga stream na maaaring i-download + I-import o i-export ang mga subskripsyon galing sa 3-dot menu + Impormasyon: + Paumanhin, hindi dapat iyon nangyari. + Paumanhin, mayroon nagkamali. + Hindi maisaayos ang download menu + Ang search history ay tinanggal + Walang nanonood + Wala dito + Walang folder na ganoon \ No newline at end of file diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index ff98bc464..bad5cd7b9 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -663,8 +663,8 @@ Balayez un élément pour le supprimer Ne pas lancer les vidéos dans le mini lecteur mais directement en plein écran si la rotation automatique est verrouillée. Vous pouvez toujours accéder au mini-lecteur en quittant le mode plein écran Lancer le lecteur principal en plein écran - Ajouter à la file de lecture - Ajouté à la file de lecture + Placer en suivant dans la file + Placé en suivant dans la file Traitement en cours… Veuillez patienter Vérifier manuellement de nouvelles versions Vérification des mises à jour… @@ -803,9 +803,22 @@ Shorts Onglets de chaîne à récupérer Onglets à récupérer lors de la mise à jour du flux. Cette option n’a aucun effet si une chaîne est mise à jour en utilisant le mode rapide. - Partager l’URL de la liste + Partager une liste d\'URLs %1$s \n%2$s Partager la liste de lecture - %1$s : %2$s + Choisir quels onglets seront visibles sur les pages de chaîne + Changer l’orientation de l’écran + Basculer en plein écran + Partager avec les noms + Avatars de sous-chaîne + Ouvrir la file de lecture + En avant + Rembobiner + Relancer + Partager la liste de lecture avec des détails tel que son nom et le nom de ses vidéos ou simplement la liste des URL des vidéos + Mise en ligne des avatars + Sélectionnez la qualités des images et si les images doivent être chargées, pour réduire l\'utilisation de la mémoire et de données. Les modifications vide à la fois le cache des images en mémoire et sur le disque — %s + Lancer \ No newline at end of file diff --git a/app/src/main/res/values-ia/strings.xml b/app/src/main/res/values-ia/strings.xml index 2b85a1353..f6cc54e32 100644 --- a/app/src/main/res/values-ia/strings.xml +++ b/app/src/main/res/values-ia/strings.xml @@ -29,7 +29,7 @@ Initiar discargas Pausar le discargas Seliger un instantia - Non poteva connecter con le servitor + Non pote connecter con le servitor Publicate le %1$s Discargar le file de fluxo Resolution predefinite @@ -104,7 +104,7 @@ Vacuar le chronologia de reproductiones Videos Dele le chronologia del contenido observate e positiones de reproduction - Positiones de reproduction delite. + Positiones de reproduction delite Vacuar le chronologia de cerca Error de rete Contento non disponibile @@ -127,7 +127,7 @@ NewPipe discargante A proposito de NewPipe © %1$s per %2$s sub %3$s - A proposito de + FAQ e A proposito de Licentias Contribuer Vider in GitHub @@ -160,7 +160,7 @@ Chronologia Dele le chronologia de parolas clave de cerca Deler omne chronologia de cerca\? - Chronologia de cerca delite. + Chronologia de recerca delite Exportar le chronologia, subscriptiones, listas de reproduction e configurationes Reimplaciar tu chronologia, subscriptiones e (optionalmente) configurationes currente Le videos jam observate ante e post de esser addite al lista de reproduction essera removite. @@ -173,7 +173,7 @@ %s visualisationes
    Nemo is observante - Chronologia de reproductiones vacuate. + Chronologia de reproductiones vacuate Deler omne chronologia de reproductiones\? Pardono, qualcosa vadeva incorrecte. Pardono, illo non deberea haber ocurrite. @@ -242,4 +242,7 @@ Per %s Radio Create per %s + Marcar como reguardate + OK + Usar reproductor de video externe \ No newline at end of file diff --git a/app/src/main/res/values-ka/strings.xml b/app/src/main/res/values-ka/strings.xml index 8825b8f58..9f6227388 100644 --- a/app/src/main/res/values-ka/strings.xml +++ b/app/src/main/res/values-ka/strings.xml @@ -56,14 +56,14 @@ ჩამოტვირთვა თვალყური ადევნეთ ნანახ ვიდეოებს არ დაიწყოთ ვიდეოები მინი პლეერში, არამედ პირდაპირ გადადით სრულეკრანიან რეჟიმში, თუ ავტომატური როტაცია დაბლოკილია. თქვენ კვლავ შეგიძლიათ მინი პლეერზე წვდომა სრულეკრანიდან გასვლით - დასაწყებად შეეხეთ გამადიდებელ შუშას. - გამოქვეყნდა%1$s - დაინსტალირება + დასაწყებად შეეხეთ გამადიდებელს. + გამოქვეყნების თარიღი: %1$s + დაყენება კარგი - გახსენით ბრაუზერში + გახსენი ვებგვერდად მონიშნეთ ნანახად - გახსენით popup რეჟიმში - გახსნა როგორც + გახსენი ამომხტარ მდგომარეობაში + გახსენი რაღაცით გაზიარება გადმოწერა ნაკადის ფაილი ჩამოტვირთვა @@ -121,7 +121,7 @@ აჩვენეთ წვერი \"შეაჩერე რიგში\" რჩევის ჩვენება ფონზე ან ამომხტარ ღილაკზე დაჭერისას ვიდეოში \"დეტალები:\" URL მხარდაუჭერელია - ნაგულისხმევი კონტენტის ქვეყანა + ჩანაწერის სასურველი ქვეყანა ნაგულისხმევი შინაარსის ენა PeerTube-ის შემთხვევები იპოვეთ თქვენთვის სასურველი შემთხვევები %s-ზე @@ -139,9 +139,9 @@ მიმდინარე დამკვრელი ნაკადის შეტყობინების კონფიგურაცია ვუკრავ ფონზე ვუკრავ ამომხტარი ფანჯარაში - კონტენტი - ასაკით შეზღუდული კონტენტის ჩვენება - ბავშვებისთვის შესაძლოა შეუფერებელი კონტენტის ჩვენება, რადგან მას აქვს ასაკობრივი ზღვარი (როგორიცაა 18+) + მასალა + მაჩვენე ასაკით შეზღუდული მასალა + მაჩვენე ბავშვებისთვის შეუფერებელი მასალა (თუნდაც 18 წლის ქვევით შეზღუდული) YouTube გთავაზობთ „შეზღუდულ რეჟიმს“, რომელიც მალავს პოტენციურად ზრდასრულთა კონტენტს ჩამოტვირთვები ჩამოტვირთვები @@ -196,7 +196,7 @@ Ქსელის შეცდომა ყველა ესკიზის ჩატვირთვა ვერ მოხერხდა ვებსაიტის გარჩევა ვერ მოხერხდა - კონტენტი მიუწვდომელია + მასალა ხელმიუწვდომელია ჩამოტვირთვის მენიუს დაყენება ვერ მოხერხდა აპი/UI გათიშულია ამ ნაკადის დაკვრა ვერ მოხერხდა @@ -318,7 +318,7 @@ ისტორია გსურთ წაშალოთ ეს ელემენტი ძიების ისტორიიდან\? ბოლოს დაუკრა - უმეტესად დაკვრილი + ხშირად დაკრული მთავარი გვერდის შინაარსი რა ჩანართებია ნაჩვენები მთავარ გვერდზე გადაფურცლეთ ელემენტები მათი ამოსაშლელად @@ -358,7 +358,7 @@ ფონური დამკვრელი ამომხტარი დამკვრელი ყოველთვის იკითხე - მოთხოვნილი კონტენტის ჩატვირთვა + მოთხოვნილი მასალა მზადდება გადარქმევა სახელი დასაკრავ სიაში დამატება @@ -546,11 +546,11 @@ თქვენს მოწყობილობაზე არცერთ აპლიკაციას არ შეუძლია ამის გახსნა ამ მოქმედებისთვის შესაბამისი ფაილების მენეჯერი ვერ მოიძებნა. \n გთხოვთ, დააინსტალიროთ Storage Access Framework თავსებადი ფაილ მენეჯერი - ეს კონტენტი მიუწვდომელია თქვენს ქვეყანაში. - ეს კონტენტი პირადია, ამიტომ მისი სტრიმინგი ან ჩამოტვირთვა შეუძლებელია NewPipe-ის მიერ. + ეს ხელმიუწვდომელია თქვენი ქვეყნიდან. + ეს მასალა პირადულია, ამიტომაც NewPipe-ს მისი არც მთლიანად და არც თანდათანობით ჩამოწერა არ შეუძლია. ანგარიში შეწყვეტილია %s იძლევა ამ მიზეზს: - ეს კონტენტი ხელმისაწვდომია მხოლოდ მომხმარებლებისთვის, რომლებმაც გადაიხადეს, ამიტომ მისი სტრიმინგი ან ჩამოტვირთვა შეუძლებელია NewPipe-ის მიერ. + ეს მასალა ხელმისაწვდომია მხოლოდ გადამხდელებისთვის, ამიტომაც NewPipe-ს მისი არც მთლიანად და არც თანდათანობით ჩამოწერა არ შეუძლია. გამორჩეული რადიო აირჩიეთ თქვენი საყვარელი ღამის თემა — %s @@ -736,4 +736,10 @@ მუდმივი მინიატურის მოხსნა წავშალო დუბლიკატები\? ნაწილობრივ ნანახი + მზადდება ზედაპირული მახასიათებლები… + თავდაპირველი ხმის ჩანაწერი აირჩიე ენის მიუხედავად + აირჩიე მხედველობადაქვეითებულებისათვის დახასიათებული ხმის ჩანაწერი, თუ არის + არჩიე თავდაპირველი ხმის ჩანაწერი + ხმა: %s + ხმის ჩანაწერი \ No newline at end of file diff --git a/app/src/main/res/values-ks/strings.xml b/app/src/main/res/values-ks/strings.xml new file mode 100644 index 000000000..a6b3daec9 --- /dev/null +++ b/app/src/main/res/values-ks/strings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml index fefc04323..37345c38a 100644 --- a/app/src/main/res/values-lt/strings.xml +++ b/app/src/main/res/values-lt/strings.xml @@ -189,7 +189,7 @@ Išsami informacija Garso nustatymai Laikykite, kad įtrauktumėte į eilę - Pradėti groti foniniame rėžime + Pradėti groti foniniame režime Pradėti groti langelio grotuve Nerastas srauto grotuvas (galite įdiegti VLC kad grotumėte). Parsisiųsti srauto failą diff --git a/app/src/main/res/values-my/strings.xml b/app/src/main/res/values-my/strings.xml new file mode 100644 index 000000000..a6b3daec9 --- /dev/null +++ b/app/src/main/res/values-my/strings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/app/src/main/res/values-nb-rNO/strings.xml b/app/src/main/res/values-nb-rNO/strings.xml index f9287aeb1..1c8575d70 100644 --- a/app/src/main/res/values-nb-rNO/strings.xml +++ b/app/src/main/res/values-nb-rNO/strings.xml @@ -593,7 +593,7 @@ Radio Framhevet Løs - Nattema + Nattdrakt Vis kanaldetaljer Skru av media-tunnelering hvis du opplever svart skjerm eller videohakking Skru av media-tunnelering @@ -673,7 +673,7 @@ LeakCanary er ikke tilgjengelig ExoPlayer-forvalg Intervallstørrelse for avspillingsinnlasting - Bytt avspillinginnlastingens intervallstørrelse (for øyeblikket %s). En lavere verdi kan øke hastigheten på den første videoinnlastingen. Endringer krever en omstart av spilleren + Endre størrelsen på lasteintervallet på progressivt innhold (for øyeblikket %s). En lavere verdi kan øke hastigheten på den første videoinnlastingen. Endringer krever omstart av spilleren Spillervarsel Varsler Nye strømmer @@ -736,4 +736,40 @@ Delvis sett Nyttig hvis hodsettet ditt har knapper som fungerer dårlig Vis følgende strømmer + \? + Abonnenter + %1$s +\n%2$s + Kanalfaner + Laster inn metadata … + Lav kvalitet + Hent kanalfaner + Avatarer + Neste strøm + Underkanalavatarer + Åpne avspillingskø + Velg opprinnelig lydspor uavhengig av språk + Ikke last inn bilder + Høy kvalitet + Om + Del spilleliste + Album + Gjenta + Velg et lydspor med beskrivelser for synshemmede hvis tilgjengelig + Middels kvalitet + Foretrekk beskrivende lyd + Opplasteravatarer + Foretrekk opprinnelig lyd + Lyd: %s + Spillelister + Lydspor + Ingen direktestrømmer + Spill av + Flere alternativer + Miniatyrbilder + Spor + Varighet + Ingen strømmer + Kanaler + Forrige strøm \ No newline at end of file diff --git a/app/src/main/res/values-nds/strings.xml b/app/src/main/res/values-nds/strings.xml new file mode 100644 index 000000000..a6b3daec9 --- /dev/null +++ b/app/src/main/res/values-nds/strings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/app/src/main/res/values-pa/strings.xml b/app/src/main/res/values-pa/strings.xml index 0cad15f71..e74e747f4 100644 --- a/app/src/main/res/values-pa/strings.xml +++ b/app/src/main/res/values-pa/strings.xml @@ -11,7 +11,7 @@ ਸਾਂਝਾ ਕਰੋ ਡਾਊਨਲੋਡ ਕਰੋ ਸਟ੍ਰੀਮ ਫ਼ਾਈਲ ਡਾਊਨਲੋਡ ਕਰੋ - ਲੱਭੋ + ਖੋਜ ਕਰੋ ਸੈਟਿੰਗਾਂ ਕੀ ਤੁਹਾਡਾ ਮਤਲਬ ਸੀ \"%1$s\"\? ਇਸ ਨਾਲ਼ ਸਾਂਝਾ ਕਰੋ @@ -113,8 +113,8 @@ ਕੀ ਵੇਖੇ ਗਏ ਵੀਡੀਓਜ਼ ਦਾ ਇਤਿਹਾਸ ਮਿਟਾ ਦਿੱਤਾ ਜਾਵੇ\? ਖੋਜ ਸੂਚੀ ਦਾ ਇਤਿਹਾਸ ਮਿਟਾਓ ਖੋਜ ਸ਼ਬਦਾਂ ਦੀ ਸੂਚੀ ਮਿਟਾਉਂਦਾ ਹੈ - ਕੀ ਸਾਰੀ ਖੋਜ ਸੂਚੀ ਮਿਟਾ ਦਿਤੀ ਜਾਵੇ \? - ਖੋਜ ਸੂਚੀ ਦਾ ਇਤਿਹਾਸ ਮਿਟਾ ਦਿਤਾ ਗਿਆ + ਕੀ ਸਾਰੀ ਖੋਜ ਸੂਚੀ ਮਿਟਾ ਦਿੱਤੀ ਜਾਵੇ \? + ਖੋਜ ਸੂਚੀ ਦਾ ਇਤਿਹਾਸ ਮਿਟਾ ਦਿੱਤਾ ਗਿਆ ਤਰੁੱਟੀ ਨੈੱਟਵਰਕ ਤਰੁੱਟੀ ਸਾਰੇ ਥੰਮਨੇਲ ਲੋਡ ਨਹੀਂ ਹੋ ਸਕੇ diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index b4d902cbf..76c6b43fe 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -52,12 +52,12 @@ Iniciar Tema Publicado em %1$s - Link não suportado + URL não suportado Ao vivo Downloads Downloads Você quis dizer \"%1$s\"\? - App/IU parou + Aplicativo/IU parou Reproduzindo em segundo plano O menu de download não pôde ser configurado Reproduzir vídeo, duração: @@ -72,7 +72,7 @@ Toque na lupa para começar. Threads Por favor, defina uma pasta de download depois nas configurações - Sem reprodutor de vídeo. Instalar VLC\? + Sem reprodutor de transmissão. Instalar VLC? O site não pôde ser analisado Áudio Reproduzir com Kodi @@ -81,25 +81,25 @@ Usar reprodutor de áudio externo Usar reprodutor de vídeo externo Mostrar opção \"Reproduzir com Kodi\" - O que aconteceu:\\nPedido:\\nIdioma do conteúdo:\\nPaís do conteúdo:\\nIdioma do app:\\nServiço:\\nHora GMT:\\nPacote:\\nVersão:\\nVersão do Sistema Operacional: - Abrir no modo popup - Resolução padrão do popup + O que aconteceu:\\nPedido:\\nIdioma do conteúdo:\\nPaís do conteúdo:\\nIdioma do aplicativo:\\nServiço:\\nHora GMT:\\nPacote:\\nVersão:\\nVersão do SO: + Abrir no modo Popup + Resolução padrão do Popup Mostrar resoluções mais altas Apenas alguns dispositivos suportam vídeos em 2K/4K Formato de vídeo padrão - Reproduzindo em modo popup + Reproduzindo em modo Popup Tudo Desativado k M Bi Essa permissão é necessária -\npara abrir em modo popup +\npara abrir em modo Popup Limpar Popup Segundo plano - Lembrar propriedades do popup - Lembrar último tamanho e posição do popup + Lembrar propriedades do Popup + Lembrar último tamanho e posição do Popup Remove o som em algumas resoluções Sugestões de pesquisa Escolha as sugestões a serem exibidas enquanto estiver buscando @@ -107,7 +107,7 @@ Licenças de Terceiros Sobre & FAQ Licenças - Stream leve e livre no Android. + Transmissão leve e livre no Android. Ver no GitHub Licença do NewPipe Se você tem ideias de: tradução, mudança no design, limpeza de código ou grandes mudanças de código — ajuda é sempre bem-vinda. Quanto mais se faz, melhor fica! @@ -137,7 +137,7 @@ Histórico Histórico Notificação do NewPipe - Notificações para o player do NewPipe + Notificações para o reprodutor do NewPipe Comportamento Histórico e cache Desfazer @@ -160,7 +160,7 @@ %s vídeos %s vídeos
    - Player + Reprodutor Nada aqui além de grilos Deseja excluir este item do histórico de busca\? Conteúdo da página inicial @@ -174,50 +174,50 @@ Top 50 Novos e tendências Mostrar dica \"Segure para pôr na fila\" - Mostra dica ao tocar no botão segundo plano ou popup em \"Detalhes:\" do vídeo + Mostra dica ao tocar no botão segundo plano ou Popup em \"Detalhes:\" do vídeo Reproduzir tudo - Este stream não pôde ser reproduzido - Ocorreu um erro irrecuperável no player - Recuperando do erro do player + Não é possível reproduzir esta transmissão + Ocorreu um erro irrecuperável no reprodutor + Se recuperando do erro do reprodutor Remover Detalhes Configurações de áudio Segure para pôr na fila [Desconhecido] Reproduzir em segundo plano - Reproduzir em um popup + Reproduzir em um Popup Doar O NewPipe é desenvolvido por voluntários que usam seu tempo livre para trazer a você a melhor experiência de usuário. Retribua e ajude os desenvolvedores a tornarem o NewPipe ainda melhor enquanto eles desfrutam de uma xícara de café. Retribuir Site oficial Visite o site do NewPipe para mais informações e novidades. - Sem reprodutor de vídeo (você pode instalar o VLC). + Reprodutor de transmissão não encontrado (pode instalar o VLC para assistir). País padrão do conteúdo Sempre Uma vez Mudar para segundo plano - Mudar para popup + Mudar para Popup Mudar para principal - Players externos não suportam estes tipos de links - Nenhum stream de vídeo encontrado - Nenhum stream de áudio encontrado - Player de vídeo - Player em segundo plano - Player popup + Reprodutores externos não suportam estes tipos de URL + Nenhuma transmissão de vídeo encontrada + Nenhuma transmissão de áudio encontrada + Reprodutor de vídeo + Reprodutor em segundo plano + Reprodutor Popup Obtendo informação… Carregando conteúdo solicitado Importar base de dados Exportar base de dados - Substitui seu histórico atual, inscrições, playlists e (opcionalmente) configurações - Exporta histórico, inscrições, playlists e configurações + Substitui seu histórico atual, inscrições, listas de reprodução e (opcionalmente) configurações + Exporta histórico, inscrições, listas de reprodução e configurações Exportado Importado Nenhum arquivo ZIP válido Aviso: Não foi possível importar todos os arquivos. Isso irá sobrescrever suas configurações atuais. - Baixar arquivo + Baixar arquivo de transmissão Mostrar informação - Playlists favoritas + Listas de reprodução favoritas Adicionar a Arraste para ordenar Criar @@ -226,29 +226,29 @@ Último reproduzido Mais reproduzido Sempre perguntar - Nova Playlist + Nova lista de reprodução Renomear Nome - Adicionar à playlist - Definir como miniatura da playlist - Favoritar playlist + Adicionar à lista de reprodução + Definir como miniatura da lista de reprodução + Favoritar lista de reprodução Remover dos favoritos - Excluir esta playlist\? - Playlist criada - Adicionado à playlist - Miniatura da playlist alterada. + Excluir esta lista de reprodução? + lista de reprodução criada + Adicionado à lista de reprodução + Miniatura da lista de reprodução alterada. Sem legendas Ajustar Preencher Zoom Gerado automaticamente - O monitoramento de vazamento de memória pode tornar o app instável durante o heap dumping + O monitoramento de vazamento de memória pode tornar o aplicativo instável durante o despejo de pilha Reportar erros de out-of-lifecycle Forçar entrega de relatórios de erros Rx fora de um fragmento ou atividade de lifecycle após o descarte Usar busca de posição rápida (inexata) A busca inexata permite que o reprodutor de vídeo ache posições mais rápido com a precisão reduzida. Não funciona para voltar ou avançar 5, 15 ou 25 segundos - Pôr próximo vídeo na fila automaticamente - Continua a reprodução da fila (sem repetição) adicionando mais vídeos similares + Enfileirar a próxima transmissão automaticamente + Continua a reprodução da fila (sem repetição) adicionando mais transmissões similares Arquivo Pasta não existe Arquivo/fonte do conteúdo não existe @@ -266,7 +266,7 @@ Não foi possível exportar inscrições Importe inscrições do YouTube pelo Google takeout: \n -\n1. Acesse este link: %1$s +\n1. Acesse este URL: %1$s \n2. Faça login quando solicitado \n3. Clique em \"Todos os dados incluídos\", depois em \"Desmarcar todos\", em seguida, selecione apenas \"assinaturas\" e clique em \"OK\" \n4. Clique em \"Próximo passo\" e em seguida, em \"Criar exportação\" @@ -293,24 +293,24 @@ Desvincular (pode causar distorção) Ação de \'abrir\' preferida Ação padrão ao abrir conteúdo — %s - Nenhum stream disponível para baixar + Nenhuma transmissão disponível para baixar Abrir gaveta Fechar gaveta Legendas - Mudar tamanho da legenda e estilos de plano de fundo. Requer reiniciar o app para ter efeito + Mudar tamanho da legenda e estilos de plano de fundo. Requer reiniciar o aplicativo para ter efeito Excluir histórico de vídeo - Exclui o histórico de vídeos e as posições de reprodução + Exclui o histórico de transmissões exibidas e as posições de reprodução Excluir todo o histórico de vídeo\? Histórico de vídeos excluído Excluir histórico de pesquisa - Exclui o histórico de pesquisas feitas + Exclui o histórico de palavras-chave de pesquisa Excluir todo o histórico de pesquisa\? Histórico de busca limpo 1 item excluído. NewPipe é um copyleft de software livre: Você pode usar, estudar, compartilhar e melhorar a seu gosto. Especificamente você pode redistribuir e/ou modificá-lo sob os termos da GNU General Public License como publicado pela Fundação de Software Livre, na versão 3 da Licença, ou (a seu critério) qualquer versão posterior. Você também quer importar as configurações? Política de privacidade do NewPipe - O projeto NewPipe leva sua privacidade muito a sério. Por isso, o app não coleta nenhum dado sem seu consentimento. + O projeto NewPipe leva sua privacidade muito a sério. Por isso, o aplicativo não coleta nenhum dado sem seu consentimento. \nA política de privacidade do NewPipe explica em detalhes quais dados são envidados e salvos quando você manda um relatório de erro. Ler a política de privacidade A fim de cumprir com o Regulamento Geral sobre a Proteção de Dados da UE (RGPD), chamamos sua atenção para a política de privacidade do NewPipe. Por favor, leia com atenção. @@ -319,11 +319,11 @@ Recusar Ilimitado Limitar a resolução quando estiver usando dados móveis - Minimizar ao trocar entre apps - Ação ao mudar para outro app a partir do player de vídeo principal — %s + Minimizar ao trocar entre aplicativos + Ação ao mudar para outro aplicativo a partir do reprodutor de vídeo principal — %s Nenhum Minimizar para segundo plano - Minimizar para player popup + Minimizar para reprodutor Popup Avançar durante o silêncio Passo Redefinir @@ -348,7 +348,7 @@ Que abas são visíveis na página inicial Conferências Atualizações - Notificar quando uma nova versão do app estiver disponível + Notificar quando uma nova versão do aplicativo estiver disponível Modo de exibição em lista Lista Grade @@ -428,27 +428,27 @@ %s ouvintes %s ouvintes
    - O idioma será alterado após reiniciar o app + O idioma será alterado após reiniciar o aplicativo Duração do salto para avançar/retroceder Instâncias do PeerTube Escolha suas instâncias do PeerTube favoritas Encontre as instâncias que gosta em %s Adicionar instância - Insira o link da instância + Insira o URL da instância Erro ao validar a instância - Apenas links HTTPS são suportados + Apenas os URL HTTPS são suportados A instância já existe Local Adicionado recentemente Mais curtidos - Gerado automaticamente (nenhum uploader encontrado) + Gerado automaticamente (nenhum carregador encontrado) recuperando O download não pôde ser recuperado Escolha uma instância Limpar histórico de downloads Excluir arquivos baixados - Dar permissão para mostrar por cima de outros apps - Idioma do app + Dar permissão para mostrar por cima de outros aplicativos + Idioma do aplicativo Padrão do sistema Toque em \"Pronto\" ao resolver Pronto @@ -522,8 +522,8 @@ \n \nAtive \"%1$s\" nas configurações se quiser vê-lo. Sim, e vídeos parcialmente vistos - Os vídeos que foram vistos antes e depois de terem sidos adicionados à playlist serão removidos. -\nTem certeza\? Esta ação não pode ser desfeita! + Os vídeos que foram vistos antes e depois de terem sidos adicionados à lista de reprodução serão removidos. +\nTem certeza? Esta ação não pode ser desfeita! Remover vídeos vistos\? Remover vistos Textos originais dos serviços serão visíveis nos itens de transmissão @@ -534,9 +534,9 @@ Miniatura do avatar do canal Mostrar apenas inscrições não agrupadas Mostrando resultados para: %s - Ainda não há playlists favoritas - Página de playlist - Selecione uma playlist + Ainda não há listas de reprodução favoritas + Página da lista de reprodução + Selecione uma lista de reprodução Por favor verifique se uma issue discutindo este problema já existe. Ao criar tickets duplicados, você tira de nós um tempo no qual poderíamos estar usando para corrigir um bug real. Reporte no GitHub Copiar relatório formatado @@ -546,7 +546,7 @@ Reproduzir fila Não foi possível reconhecer a URL. Abrir com outro aplicativo\? Pôr na fila automaticamente - A fila do player ativo será substituída + A fila do reprodutor ativo será substituída Mudar de um reprodutor de vídeo para outro pode substituir sua fila Pedir confirmação antes de limpar uma fila Aleatório @@ -577,7 +577,7 @@ Calculando hash Notificações para o progresso do hash do vídeo Notificação de hash do vídeo - Desative para ocultar as caixas de informações de metadados com informações adicionais sobre o criador, conteúdo do stream ou uma solicitação de pesquisa + Desative para ocultar as caixas de informações de metadados com informações adicionais sobre o criador, conteúdo da transmissão ou uma solicitação de pesquisa Mostrar informação de metadados Recente Capítulos @@ -595,7 +595,7 @@ Esta é uma faixa do SoundCloud Go+, pelo menos no seu país, portanto não pode ser transmitida ou baixada pelo NewPipe. Este conteúdo não está disponível em seu país. Este vídeo tem restrição de idade. -\nDevido às novas políticas do YouTube sobre vídeos com restrição de idade, o NewPipe não pode acessar nenhum de seus streams de vídeo e assim ele não pode ser exibido. +\nDevido às novas políticas do YouTube sobre vídeos com restrição de idade, o NewPipe não pode acessar qualquer de suas transmissões de vídeo e assim ela não pode ser exibida. Rádio Destaque Resolvido @@ -621,7 +621,7 @@ Categoria Desativar seleção de texto na descrição Ativar seleção de texto na descrição - Agora você pode selecionar o texto dentro da descrição. Note que a página pode piscar e os links podem não ser clicáveis no modo de seleção. + Agora você pode selecionar o texto dentro da descrição. Note que a página pode piscar e os URL podem não ser clicáveis no modo de seleção. Abrir site %s fornece este motivo: Conta encerrada @@ -657,10 +657,10 @@
    Exibir indicadores com imagem Adicionado na próxima posição da fila - Adicionar a próxima posição da fila + Enfileira a próxima Deslize items para remove-los - Não inicia os vídeos no player reduzido, mas muda direto para o modo de tela cheia, se a rotação automática estiver travada. Você ainda consegue acessar o player reduzido saindo da tela cheia - Iniciar o player principal em tela cheia + Não inicia os vídeos no reprodutor reduzido, mas muda direto para o modo de tela cheia, se a rotação automática estiver travada. Você ainda consegue acessar o reprodutor reduzido saindo da tela cheia + Iniciar o reprodutor principal em tela cheia Sugestões de busca remotas Sugestões de busca locais Processando… Pode demorar um pouco @@ -668,8 +668,8 @@ Procurar manualmente por novas versões Procurando por atualizações… Travar o reprodutor de vídeo - Mostrar \"Travar o player\" - Mostra uma opção de travamento ao usar o player + Mostrar \"Fechar o reprodutor\" + Mostra uma opção de travamento ao usar o reprodutor Novos itens do feed Notificação de relatório de erro Notificações para reportar erros @@ -685,9 +685,9 @@ O LeakCanary não está disponível ExoPlayer padrão Notificação do reprodutor - Configurar a notificação do fluxo da reprodução atual + Configurar a notificação da reprodução da transmissão atual Notificações - Novos streams + Novas transmissões Notificações sobre novas transmissões para inscrições Notificações de novas transmissões Notificar sobre novas transmissões de inscrições @@ -703,17 +703,17 @@ %s novas transmissões %s novas transmissões
    - Executar verificação de novas transmissões + Verifica por novas transmissões Conexão de rede necessária As notificações estão desativadas Seja notificado Por cento Semitom - A transmissão selecionada não é compatível com players externos - Nenhum transmissão de áudio está disponível para players externos - Transmissões que ainda não são suportadas pelo downloader não são exibidos - Nenhum vídeo de transmissão está disponível para players externos - Selecione a qualidade para players externos + A transmissão selecionada não é compatível com reprodutores externos + Nenhum transmissão de áudio está disponível para reprodutores externos + Transmissões que ainda não são suportadas pelo baixador não são exibidos + Nenhum vídeo de transmissão está disponível para reprodutores externos + Selecione a qualidade para reprodutores externos Formato desconhecido Qualidade desconhecida Tamanho do intervalo de carregamento da reprodução @@ -730,20 +730,20 @@ Cartão Falha ao copiar para a área de transferência Duplicata adicionada %d vez(es) - As playlists em cinza já contêm este item. + As listas de reprodução em cinza já contêm este item. Ignorar eventos de botão de mídia de hardware Útil, por exemplo, se você estiver usando um fone de ouvido com botões físicos quebrados Remover duplicados Remover duplicados\? - Deseja remover todos os streams duplicados nesta playlist\? - Mostrar os seguintes streams - Mostrar/ocultar streams + Deseja remover todos as transmissões duplicadas nesta lista de reprodução? + Mostrar as transmissões seguintes + Mostrar/ocultar transmissões Parcialmente assistido Em breve Totalmente assistido - Escolha o gesto da mão esquerda da tela do jogador + Escolha o gesto da mão esquerda da tela do reprodutor Ação do gesto esquerdo - Escolha o gesto da mão direita da tela do jogador + Escolha o gesto da mão direita da tela do reprodutor Brilho Volume Nenhum @@ -755,19 +755,19 @@ Selecionar um áudio com descrição para pessoas com dificuldades de visão, se disponível Áudio: %s Faixa de áudio - Seleciona faixa de áudio para players externo + Seleciona faixa de áudio para reprodutor externo Desconhecido Configurações de ExoPlayer - Gerenciar algumas configurações de ExoPlayer. É necessário reiniciar o player para aplicar as mudanças + Gerenciar algumas configurações de ExoPlayer. É necessário reiniciar o reprodutor para aplicar as mudanças %1$s %2$s original dublado descritivo - Esta solução alternativa libera os codificadores de vídeo quando ocorre uma alteração de superfície, em vez de definir a superfície para o codec diretamente. Já usado pelo ExoPlayer em alguns dispositivos com esse problema, essa configuração só tem efeito no Android 6 e superior + Esta solução alternativa libera os codificadores de vídeo quando ocorre uma alteração de superfície, no lugar de definir a superfície para o Codec diretamente. Já usado pelo ExoPlayer em alguns dispositivos com esse problema, essa configuração só tem efeito no Android 6 e superior \n \nAtivar esta opção pode evitar erros de reprodução ao alternar o reprodutor de vídeo atual ou alternar para tela cheia - Uma faixa de áudio já deve estar presente neste stream - Utilizar a função de fallback do decodificador do ExoPlayer + Uma faixa de áudio já deve estar presente nesta transmissão + Utilizar a contingência do decodificador do ExoPlayer Sempre utilizar o configuração de saída de vídeo alternativa do ExoPlayer Habilite essa opção se você tiver problemas de inicialização do decodificador, que retorna codificadores de baixa prioridade se o decodificador primário falhar. Isso pode resultar em pior desempenho de reprodução Mova o seletor da aba principal para a parte inferior @@ -785,8 +785,37 @@ Sobre Álbuns Guias a serem buscadas ao atualizar o feed. Esta opção não tem efeito se um canal for atualizado usando o modo rápido. - Playlists + Listas de reprodução Faixas Canais Ao vivo + Qualidade da imagem + \? + Compartilhar lista URL + Compartilhar com Títulos + %1$s +\n%2$s + Alterna a orientação da tela + Baixa qualidade + Alternar tela cheia + Avatares + Próxima transmissão + Avatares do subcanal + Abrir a fila de reprodução + Não carregar imagens + Alta qualidade + Compartilhar Lista de Reprodução + Avançar + Retroceder + Repete + Compartilhar lista de reprodução com detalhes como nome da lista de reprodução e títulos de vídeo ou como uma lista simples dos URL de vídeos + Qualidade média + Avatares do carregador + - %1$s: %2$s + Escolha a qualidade das imagens ou se deve carregá-las como estão, para reduzir o uso de dados e memória. Alterações limpam a memória e o cache de imagem no disco — %s + Reproduzir + Mais opções + Miniaturas + Duração + Transmissão anterior \ No newline at end of file diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index a44f44200..43eb814e8 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -601,7 +601,7 @@ Acest conținut este disponibil doar pentru utilizatorii care au plătit, ca atare nu poate fi difuzat sau descărcat de NewPipe. Acest videoclip este disponibil doar pentru membrii YouTube Music Premium, ca atare nu poate fi difuzat sau descărcat de NewPipe. Acest conținut este privat, ca atare nu poate fi difuzat sau descărcat de NewPipe. - Aceasta este o piesă SoundCloud Go+, cel puțin în țara ta, deci nu poate fi difuzată sau descărcată de NewPipe. + Aceasta este o piesă SoundCloud Go+, cel puțin în țara dvs., deci nu poate fi difuzată sau descărcată de NewPipe. Acest conținut nu este disponibil în țara dumneavoastră. Afișați detaliile canalului Temă Nocturnă diff --git a/app/src/main/res/values-scn/strings.xml b/app/src/main/res/values-scn/strings.xml new file mode 100644 index 000000000..a6b3daec9 --- /dev/null +++ b/app/src/main/res/values-scn/strings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index 5532001e8..d3739e29e 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -34,12 +34,12 @@ Visa ett alternativ för att spela upp en video med mediacentret Kodi Ljud Standardformat för ljud - Videoformat som föredras + Standardformat för video Tema Ljust Mörkt Svart - Kom ihåg popup inställningar + Kom ihåg popupinställningar Kom ihåg popup-rutans senaste storlek och position Sökförslag Välj förslag att visa i samband med sökning @@ -203,7 +203,7 @@ Inexakt sökning gör det möjligt att söka snabbare med mindre precision. Att hoppa 5, 15 eller 25 sekunder fungerar inte med detta val Ta bort alla cachade webbsidor Metadata cache rensad - Köa nästa ström automatiskt + Köa nästa strömning automatiskt Fortsätt avsluta (icke-upprepande) uppspelningskö genom att lägga till en relaterad ström Standard innehållsland Kanaler @@ -226,14 +226,14 @@ Ta bort hela sökhistoriken\? Sökhistorik borttagen Externa spelare stöder inte dessa typer av länkar - Inga videoströmmar hittades + Inga videoströmningar hittades Inga ljudspår hittades Ingen sådan mapp Ingen sådan fil/innehållskälla Filen finns inte eller behörighet att läsa eller skriva till den saknas Filnamnet får inte vara tomt Ett fel uppstod: %1$s - Inga strömmar tillgängliga för hämtning + Inga strömningar tillgängliga för hämtning Dra för att ändra ordning Skapa Avfärda @@ -614,7 +614,7 @@ Beskrivning Kommentarer Denna video här en åldersgräns. -\nPå grund av nya YouTube-regler med åldersgräns för vissa videor kan NewPipe inte komma åt någon av dess videoströmmar och kan därmed inte spela upp den. +\nPå grund av nya YouTube-regler med åldersgräns för vissa videor kan NewPipe inte komma åt någon av dess videoströmningar och kan därmed inte spela upp den. Visa innehåll som pga sin åldersgräns (ex 18+) kan vara olämpligt för barn Visa beskrivning Öppna med @@ -680,29 +680,29 @@ Aviseringar är avstängda Bli meddelad Du har nu prenumenerat till denna kanalen - Aviseringar om nya strömmar för prenumerationer + Aviseringar om nya strömningar för prenumerationer - %s Ny ström - %s Nya strömmar + %s Ny strömning + strömningar%s Nya strömningar Konfigurera meddelande om aktuell ström som spelas upp - Kör leta efter nya strömmar - Meddela om nya strömmar från prenumerationer + Kör leta efter nya strömningar + Meddela om nya strömningar från prenumerationer Aviseringar - Nya strömmar + Nya strömningar Laddar strömdetaljer… - Aviseringar om nya strömmar + Aviseringar om nya strömningar , Spelaravisering Växla alla Procent Halvton - Inga videoströmmar tillgängliga för externa spelare + Inga videoströmningar tillgängliga för externa spelare Okänd kvalitet - Inga ljudströmmar tillgängliga för externa spelare + Inga ljudströmningar tillgängliga för externa spelare Okänt format - Videoströmmar som ännu inte stöds av nedladdaren visas inte - Inläsningsintervalls storlek + Videoströmningar som ännu inte stöds av nedladdaren visas inte + Inläsningsintervallsstorlek Välj kvalitet för externa spelare Den valda videoströmmen stöds inte av externa spelare Om du har problem med att använda appen, kolla in dessa svar på vanligt ställda frågor! @@ -720,22 +720,22 @@ Dubblett tillagd %d gång(er) Spellistor som är gråmarkerade innehåller redan det här objektet. Användbart om du till exempel använder ett headset med trasiga fysiska knappar - Ignorera hårdvarans media knappar + Ignorera hårdvarans mediaknappar Ta bort dubbletter\? - Visa följande strömmar + Visa följande strömningar Delvis sedd - Vill du ta bort alla duplicerade strömmar i den här spellistan\? + Vill du ta bort alla duplicerade strömningar i den här spellistan\? Ta bort dubbletter - Visa/Dölj strömmar + Visa/Dölj strömningar Fullständigt sedd Kommande Volym Ingen Välj en gest för den vänstra halvan av spelarskärmen Ljusstyrka - Vänster gest åtgärd + Vänstergest åtgärd Välj en gest för den högra halvan av spelarskärmen - Höger gest åtgärd + Högergest åtgärd Ljud: %s Ljudspår Ett ljudspår bör redan finnas i denna ström @@ -759,7 +759,51 @@ dubbad Flytta huvudflik väljaren till botten Huvudflikarnas position - Inga strömmar - Inga live-strömmar + Inga strömningar + Inga live-strömningar Medietunnel har inaktiverats som standard på din enhet eftersom att enhetsmodellen inte stöder funktionen. + Bildkvalité + Videor + Prenumeranter + Vilka filkar visas på kanalsidorna + Dela URL-lista + Kanalflikar + Shorts + Laddar Metadata… + Aktivera skärmorientering + Låg kvalité + Aktivera helskärm + Hämta kanalflikar + Nästa strömning + Öppna spelkö + Ladda inte bilder + Hög kvalité + Om + Dela spellista + Spola frammåt + Album + Spola tillbaka + Återspela + Medelkvalité + Spellistor + Spela + Fler alternativ + Miniatyrbilder + Spår + Längd + Kanaler + Föregående strömning + Live + \? + Dela med Titlar + %1$s +\n%2$s + Visningsbilder + Underkanalens visningsbilder + Flikar att hämta när flödet uppdateras. Det här alternativet har ingen effekt om en kanal uppdateras i snabbt läge. + Uppladdarens visningsbilder + Banderoller + - %1$s: %2$s + Dela spellistan med detaljer så som spellistans namn och video-titlarna eller som en enkel lista med URL till videorna + Välj bildkvalitet och om bilder överhuvudtaget ska laddas för att minska data och minnesanvändningen. Ändringar rensar både i minnet och bildcache på disk – %s \ No newline at end of file diff --git a/app/src/main/res/values-ti/strings.xml b/app/src/main/res/values-ti/strings.xml index dcd5df884..ab3505453 100644 --- a/app/src/main/res/values-ti/strings.xml +++ b/app/src/main/res/values-ti/strings.xml @@ -1,19 +1,65 @@ ሰረዝ - ኣብ ብሮውዘር ክፉት - ውጽኢት ምርኣዩ ን፦%s + ኣብ መርበብ-ሓበሬታ ክፉት + ውጽኢት ምርኣዩ ን፦ %s መጀመርታ ምእንቲ ኽትጅምር ነቲ ዜጕልሕ መረጼን ጠውቆ። ኣብ %1$s እተሓትመ - ዋላ ሓደ ወሓይዝ ዚጻወት ሰብ ኣይተረኽበን። VLC + ወሓይዝ ዚጻወት ኣይተረኽበን። VLC፧ ሐራይ - ምድላው + ቅጥዕታት \"%1$s\" ማለቱ ድዩ፧ ዚተሪየ ጋባራ ክፉቴ ምሲ ፋይል ውሕጅ ኣራግፍ ድለ - ኣካፍሎም + ኣካፍሎ ኣራግፍ ኣካፍሎም ምሲ + መስመር ኣይትጽንበሩ + ኣብ ሓፍ፡ሓፍ ቅዲ ክፉት + ሰዓብካ\'ኪ + ክቕይር ኣይከኣለን ምዝገብ + ድምጺታት ኣብ ገለ ርዝነት የወግድ + ወሓይዝ ዚጻወት ኣይተረኽበን። (ንኽትጻወቶ VLC ከተውራድ ትኽእል)። + ክሕደስ ኣይከኣለን ምዝገባ + ሰዓበ + ናይ ደገ ቪድዮ ተጠቐም መጻወቲ + ምውራድ + ኣይትጽንበሩ + ነቲ ኣብ\'ቲ ምልክታ ዝተርኣየ ናይ ቪድዮ ምስሊ ካብ 16:9 ናብ 1:1 ርሕቐት ኣቀራርባ ቅረጽ + ምስ Kodi ተጻወት + ድምር ምስ + ሓበሬታ ኣርእዩ + መፍለጢ ሕብሪ ልኸ + \"Play with Kodi\" ኣማራጺ + ዝያዳ ድንቀት ኣርኢ + ንተንቃሳቀሴ-ምስሌ ፋይላት ዝኸውን ናይ ምውራድ ማህደር ምረጽ + ተጻዋታይ ወደቀ + ድምጺ + ድምጺ ምውራድ ማህደር ፋይላት ኣብዚ ይኽዘኑ + ዋላ-ሓንቲ + ገለ መሳርሒታት ጥራይ እዮም 2K/4K ተንቃሳቀሴ-ምስሌ ክጻወቱ ዝኽእሉ + ናይ ደገ ድምጺ መጻወቲ ተጠቐም + Android ሕብሪ ናይቲ መተሓሳሰቢ ብመሰረት እቲ ኣብቲ ንእሽቶ ስእሊ ዘሎ ቀንዲ ሕብሪ ከም ዝጥዕሞ ግበር (እዚ ኣብ ኩሉ መሳርሒታት ከምዘይርከብ ኣስተውዕል) + ትሑዝ ፖፕኣፕ ድንቀት + ነፍሲ ወከፍ መፍለጢ ተግባር ኣብ ታሕቲ ብምጥዋቕ ኣርትዖ። ኣብቲ ውህሉል መተሓሳሰቢ ንኽርአ ክሳብ ሰለስተ ካብኣቶም ምረጽ፡ ኣብ የማናይ ሸነኽ ዘሎ ሳጹናት ብምጥቃም + ፖፕኣፕ + ትሑዝ ድንቀት + ዝወረዱ ናይ ተንቃሳቀሴ-ምስሌ ፋይላት ኣብዚ ይኽዘኑ + + ናይ እኽሊ ምስሊ ምስ ናይ 1:1 ርክባት + ቀዳማይ ወሰን ተጠዋቃ + ደገመ + ድምጺ ምውራድ ማህደር + ቦኦክማርከድ ዝርዝር-ጸወታ + ናይ ድምጺ ፋይል ኣራግፍ ምረጽ + ዝጎደለ ኮረ ኣፕፕ ኣውራድ፧ + ነባሪ ቅርጺ ድምጺ + ምዝገባ + Kodi ሚድያ ማእኸል ቪድዮ ንምጽዋት ዝሕግዝ ኣማራጺ + ኣብቲ ውሱን መፍለጢ ንምርኣይ እንተበዝሐ ሰለስተ ተግባራት ክትመርጽ ትኽእል ኢኻ! + ተንቃሳቀሴ-ምስሌ ፋይል ኣራግፍ + ታብ ምረጽ + ድሕረ ባይታ \ No newline at end of file diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index aff2be32b..b1ecacfc3 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -20,7 +20,7 @@ Ses indirme klasörü İndirilen ses dosyaları burada depolanır Ses dosyaları için indirme klasörünü seç - Öntanımlı çözünürlük + Varsayılan çözünürlük Kodi ile oynat Eksik Kore uygulaması yüklensin mi\? \"Kodi ile oynat\" seçeneğini göster @@ -102,7 +102,7 @@ Açılan pencerenin son boyutunu ve konumunu hatırla Bazı çözünürlüklerde sesi kaldırır Arama önerileri - Ararken gösterilecek önerileri seç + Arama yaparken öneriler gösterilsin mi En iyi çözünürlük NewPipe Hakkında Üçüncü Taraf Lisansları @@ -212,11 +212,11 @@ Bu, var olan kurulumunuzu geçersiz kılacaktır. Akış dosyasını indir Bilgi göster - İmlenen Oynatma Listeleri + İmlenen Çalma Listeleri Ekle Yeniden düzenlemek için sürükleyin Oluştur - Reddet + Dışla Yeniden adlandır Son Oynatılan En Çok Oynatılan @@ -279,7 +279,7 @@ Bu sürecin ağa yük olabileceğini unutmayın. \n \nSürdürmek istiyor musunuz\? - Resim önbelleği silindi + Resim önbelleği temizlendi Önbelleğe alınmış üstverileri temizle Önbelleğe alınmış tüm web sayfası verilerini kaldır Üstveri önbelleği temizlendi @@ -623,7 +623,7 @@ \'Depolama Erişimi Çerçevesi\' yalnızca Android 10\'dan başlayarak desteklenmektedir Her indirmede nereye kaydedileceği sorulacak İndirme klasörü belirlenmedi, şimdi öntanımlı indirme klasörünü seçin - Kapat + Kapalı Tablet kipi Konum çubuğu küçük resim ön izlemesi diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index 7f1273c85..f6719c1ed 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -2,53 +2,53 @@ Nhấn vào kính lúp để bắt đầu. Đăng vào %1$s - Không tìm thấy trình phát. Cài đặt VLC\? - Cài vô + Không tìm thấy trình phát trực tuyến. Cài đặt VLC\? + Cài đặt Hủy Mở trong trình duyệt - Mở trong chế độ cửa sổ nổi + Mở trong chế độ bật lên Chia sẻ Tải về Tìm kiếm - Các cài đặt + Thiết đặt Ý bạn là \"%1$s\"\? Chia sẻ với - Sử dụng trình phát video bên ngoài + Sử dụng trình phát băng hình bên ngoài Loại bỏ âm thanh ở một số độ phân giải - Sử dụng trình phát audio bên ngoài + Sử dụng trình phát âm thanh bên ngoài Trình phát nổi - Thư mục video tải về - Video đã tải về được lưu ở đây - Chọn thư mục lưu video tải về - Thư mục tải về audio - Audio đã tải về được lưu ở đây - Chọn vị trí lưu audio tải về + Thư mục băng hình tải về + Băng hình đã tải về được lưu ở đây + Chọn thư mục tải xuống cho các tệp băng hình + Thư mục tải xuống âm thanh + Các tệp âm thanh đã tải xuống được lưu trữ tại đây + Chọn thư mục tải xuống cho các tệp âm thanh Độ phân giải mặc định - Độ phân giải popup mặc định + Độ phân giải cửa sổ bật lên mặc định Hiện độ phân giải cao hơn - Chỉ một số thiết bị hỗ trợ phát video 2K/4K - Phát bằng Kodi - Cài đặt ứng dụng Kore\? - Hiện tùy chọn \"Phát bằng Kodi\" - Hiện tùy chọn phát video qua trung tâm media Kodi + Chỉ một số thiết bị có thể phát băng hình 2K/4K + Phát với Kodi + Cài đặt ứng dụng Kore bị thiếu\? + Hiển thị tùy chọn \"Phát với Kodi\" + Hiển thị tùy chọn phát băng hình qua trung tâm truyền thông Kodi Âm thanh Định dạng âm thanh mặc định - Định dạng video mặc định + Định dạng băng hình mặc định Nền Chủ đề Sáng Tối Đen (Amoled) - Nhớ thuộc tính của popup - Nhớ kích thước và vị trí lần trước của popup + Ghi nhớ thuộc tính cửa sổ bật lên + Ghi nhớ kích thước và vị trí cuối cùng của cửa sổ bật lên Đề xuất tìm kiếm Chọn các đề xuất để hiển thị khi tìm kiếm Tải về - Hiện video \"Tiếp theo\" và \"Tương tự\" + Hiện các cuộn băng \"Tiếp theo\" và \"Tương tự\" URL không hỗ trợ - Hiển thị - Phát ở dưới nền - Phát ở chế độ popup + Vẻ ngoài + Đang phát trong nền + Đang phát trong chế độ bật lên Nội dung Hiển thị nội dung bị giới hạn độ tuổi Trực tiếp @@ -57,7 +57,7 @@ Báo lỗi Tất cả Vô hiệu - Xóa + Dọn dẹp Độ phân giải tốt nhất Lỗi Lỗi kết nối mạng @@ -68,14 +68,14 @@ Ứng dụng / Giao diện người dùng bị lỗi Có vẻ NewPipe đã xảy ra lỗi, lướt xuống kiểm tra xem. Báo lỗi qua email - Có gì đó không đúng lắm. Thật khó chịu. + Rất tiếc, đã xảy ra lỗi rồi. Báo cáo Thông tin: Chuyện gì đã xảy ra: Loại lỗi:\\nYêu cầu:\\nNgôn ngữ của nội dung:\\nVùng miền (quốc gia) của nội dung:\\nNgôn ngữ của ứng dụng:\\nDịch vụ:\\nThời gian GMT:\\nTên gói:\\nPhiên bản:\\nPhiên bản hệ điều hành: Nhận xét của bạn (bằng tiếng Anh): Chi tiết: - Video xem, thời lượng: + Phát băng hình, thời lượng: Hình thu nhỏ của avatar người tải lên Lượt thích Lượt không thích @@ -97,9 +97,9 @@ Chạm để biết chi tiết Đợi chút xíu nha… Đã sao chép vào khay nhớ tạm - Hãy chọn một thư mục tải xuống trong phần cài đặt - Chế độ popup cần quyền này -\n để hoạt động, hãy bật trong phần cài đặt + Hãy chọn một thư mục tải xuống trong phần thiết đặt + Sự cho phép này là cần thiết để +\nmở trong chế độ bật lên reCAPTCHA Yêu cầu reCAPTCHA Giới thiệu về NewPipe @@ -107,54 +107,54 @@ © %1$s bởi %2$s dưới %3$s Thông tin & FAQ Giấy phép - Trình phát video Yiu tu be nhẹ, mã nguồn mở và không quảng cáo cho Android. + Phát trực tuyến nhẹ tự do trên Android. Xem trên GitHub Giấy phép của NewPipe Sự đóng góp của bạn luôn được hoan nghênh – kể cả khi bạn dịch, thay đổi giao diện, dọn code, thêm tính năng hay thay đổi những thứ khác, sự giúp đỡ của bạn vẫn đáng được trân trọng. Bạn càng làm nhiều, ứng dụng này sẽ càng tốt hơn bao giờ hết ! Đọc giấy phép Đóng góp Ngôn ngữ nội dung ưu tiên - Video và âm thanh + Băng hình và âm thanh Lịch sử xem - Lịch sử và bộ nhớ cache + Lịch sử và bộ nhớ đệm Không tìm thấy Đăng ký Đã đăng ký Đã hủy đăng ký kênh Không thể thay đổi tình trạng đăng ký Không thể cập nhật tình trạng đăng ký - Không tìm thấy trình phát luồng nào (bạn có thể cài đặt VLC để phát). + Không tìm thấy trình phát trực tuyến nào (bạn có thể cài đặt VLC để phát nó). Tải tệp luồng về Hiện thông tin Kênh đăng ký - Danh sách phát được đánh dấu - Video mới + Đã đánh dấu danh sách phát + Có gì mới Thêm vào - Sử dụng tìm kiếm nhanh không chính xác - Tua không chính xác cho phép trình phát tua đến các vị trí nhanh hơn với độ chính xác bị giảm. Tua 5, 15 hay 25 giây không dùng được với chế độ này + Dùng tua nhanh ít chính xác + Tua ít chính xác cho phép trình phát giảm độ chính xác để tua tới vị trí nhanh hơn. Tua khoảng 5, 15 hoặc 25 giây không hoạt động với điều này Đã xóa bộ nhớ cache hình ảnh - Xóa siêu dữ liệu đã lưu vào bộ nhớ cache - Xóa tất cả dữ liệu trang web được lưu trong bộ nhớ cache + Lau sạch siêu dữ liệu đã lưu đệm + Loại bỏ mọi dữ liệu trang web đã lưu đệm Đã xóa bộ nhớ cache siêu dữ liệu - Tự động thêm luồng phát tiếp theo vào hàng đợi + Tự động xếp hàng luồng phát tiếp theo Tiếp tục hàng đợi (không lặp lại) bằng cách thêm một luồng phát liên quan Lịch sử tìm kiếm Lưu trữ truy vấn tìm kiếm cục bộ - Theo dõi các video đã xem - Tiếp tục phát - Tiếp tục phát sau khi bị gián đoạn (ví dụ: cuộc gọi điện thoại) - Hiển thị \"Giữ để thêm vào hàng đợi\" - Hiển thị mẹo khi nhấn nút phát trong nền hoặc phát trên popup trong trang \"Chi tiết\" + Theo dõi các cuộn băng đã xem + Tiếp tục đang phát + Tiếp tục phát lại sau khi bị gián đoạn (ví dụ: cuộc gọi) + Hiển thị mẹo \"Giữ để xếp hàng\" + Hiển thị mẹo khi nhấn vào nút nền hoặc nút bật lên trong \"Chi tiết:\" cuốn băng Quốc gia nội dung mặc định - Phát + Trình phát Hành vi Gỡ lỗi Kênh - Playlist + Danh sách phát Bản nhạc Người dùng Hoàn tác - Chơi tất cả + Phát tất cả Luôn luôn Chỉ một lần Tập tin @@ -162,26 +162,26 @@ Thông báo cho trình phát của NewPipe [Không xác định] Chuyển sang nền - Chuyển sang Popup + Chuyển sang Cửa sổ bật lên Chuyển sang Main Nhập cơ sở dữ liệu Xuất cơ sở dữ liệu - Ghi đè lịch sử, kênh đăng ký, playlist hiện tại (và cài đặt, nếu có) của bạn - Xuất lịch sử, danh sách đăng ký, playlist và cài đặt - Xóa lịch sử xem - Xóa lịch sử những video đã xem và vị trí phát + Ghi đè lịch sử, đăng ký, danh sách phát và các thiết đặt (tùy chọn) hiện tại của bạn + Xuất lịch sử, đăng ký, danh sách phát và các thiết đặt + Dọn dẹp lịch sử xem + Xóa lịch sử các luồng đã phát và các vị trí phát lại Xóa toàn bộ lịch sử xem\? Đã xoá lịch sử xem - Xóa lịch sử tìm kiếm + Dọn dẹp lịch sử tìm kiếm Xóa lịch sử tìm kiếm mà bạn đã ghi Xóa toàn bộ lịch sử tìm kiếm\? Đã xóa lịch sử tìm kiếm - Không thể phát video này + Không thể phát luồng này Đã xảy ra lỗi trình phát không thể khôi phục Phục hồi lại trình phát bị lỗi Trình phát ngoài không hỗ trợ các loại liên kết này - Không tìm thấy luồng video nào - Không tìm thấy luồng audio nào + Không tìm thấy luồng băng hình nào + Không tìm thấy luồng âm thanh nào Thư mục không hợp lệ Tệp / nguồn nội dung không hợp lệ Tệp không tồn tại hoặc không có quyền đọc / ghi @@ -198,16 +198,16 @@ %s lượt xem - Không có video nào + Không có cuộn băng nào - %s video + %s cuộn băng Tạo nên Bỏ qua Đổi tên Đã xóa 1 mục. Tải xuống - Các ký tự được cho phép cho tên tệp + Các ký tự được cho phép trong tên tệp Ký tự không hợp lệ được thay thế bằng giá trị này Ký tự thay thế Chỉ chữ cái và chữ số @@ -221,12 +221,12 @@ NewPipe rất coi trọng quyền riêng tư của bạn. Do đó, ứng dụng không thu thập bất kỳ dữ liệu nào mà không có sự đồng ý của bạn. \nChính sách bảo mật của NewPipe giải thích chi tiết dữ liệu nào được gửi và lưu trữ khi bạn gửi báo cáo sự cố. Đọc chính sách bảo mật - NewPipe là phần mềm miễn phí copyleft: Bạn có thể sử dụng, nghiên cứu, chia sẻ và cải thiện nó theo ý của bạn. Nói cụ thể hơn, bạn có thể phân phối lại và/hoặc sửa đổi nó theo các điều khoản trong Giấy phép Công cộng GNU (GPL) được xuất bản bởi Quỹ Phần mềm Tự do (FSF), theo phiên bản 3 hoặc bất kì phiên bản nào sau này của Giấy phép (tùy ý bạn). + NewPipe là phần mềm tự do bản quyền bên trái: Bạn có thể sử dụng, nghiên cứu, chia sẻ và cải tiến nó theo ý muốn. Cụ thể là bạn có thể phân phối lại và/hoặc sửa đổi nó theo các điều khoản của Giấy phép Công cộng GNU do Tổ chức Phần mềm Tự do xuất bản, phiên bản 3 của Giấy phép hoặc (tùy theo lựa chọn của bạn) bất kỳ phiên bản nào mới hơn. Lịch sử Lịch sử Bạn có muốn xóa mục này khỏi lịch sử tìm kiếm không? Lần phát cuối - Hầu hết phát + Được phát nhiều nhất Nội dung trang chính Trang trống Trang chủ @@ -239,43 +239,43 @@ Không có tệp ZIP hợp lệ Cảnh báo: Không thể nhập tất cả các tệp. Thao tác này sẽ ghi đè cài đặt hiện tại của bạn. - Bạn cũng muốn nhập cài đặt? - Đang thịnh hành + Bạn có muốn cũng nhập các thiết đặt không\? + Thịnh hành Mới và đang hot Loại bỏ Chi tiết - Cài đặt âm thanh - Giữ để nối tiếp + Thiết đặt âm thanh + Giữ để xếp hàng Bắt đầu phát từ đây trong nền - Bắt đầu phát trên trình phát popup + Bắt đầu phát trong cửa sổ bật lên Mở ngăn kéo Đóng ngăn Hành động \'mở\' được ưu tiên Hành động mặc định khi mở nội dung — %s - Trình phát video + Trình phát băng hình Trình phát nền - Trình phát popup + Trình phát bật lên Luôn luôn hỏi Đang nhận thông tin… Đang tải nội dung được yêu cầu - Tạo playlist mới - Đổi tên playlist + Danh sách phát mới + Đổi tên Tên Thêm vào danh sách phát Đặt làm hình thu nhỏ của danh sách phát - Đánh dấu playlist này - Xóa dấu trang - Xóa playlist này\? - Đã tạo playlist - Đã thêm vào playlist - Đã thay đổi danh sách của playlist. + Đánh dấu danh sách phát + Loại bỏ đánh dấu + Xóa danh sách phát này\? + Đã tạo danh sách phát + Đã thêm danh sách phát + Hình thu nhỏ của danh sách phát đã thay đổi. Không có phụ đề Phù hợp Lấp đầy Thu phóng Tự động tạo ra Phụ đề - Sửa cỡ chữ, màu chữ và kiểu màu nền phụ đề. Hãy khởi động lại ứng dụng để áp dụng + Thay đổi tỷ lệ văn bản và kiểu nền phụ đề trình phát. Yêu cầu khởi động lại ứng dụng để có hiệu lực Theo dõi rò rỉ bộ nhớ có thể khiến ứng dụng trở nên không phản hồi khi đổ xô đống Báo các lỗi out-of-lifecycle Buộc báo cáo ngoại lệ Rx không thể gửi được bên ngoài vòng đời của mảnh hoặc hoạt động sau khi xử lý @@ -311,7 +311,7 @@ Độ cao Bỏ gắn (có thể gây méo nhưng vui) Tua nhanh trong im lặng - Tiếp theo + Bước Đặt lại Để tuân thủ Quy định bảo vệ dữ liệu chung của châu Âu (GDPR), chúng tôi sẽ thu hút sự chú ý của bạn đến chính sách bảo mật của NewPipe. Vui lòng đọc kỹ. \nBạn phải chấp nhận nó để gửi cho chúng tôi báo cáo lỗi. @@ -320,10 +320,10 @@ Không giới hạn Giới hạn độ phân giải khi sử dụng 3G, 4G Thu nhỏ khi chuyển qua ứng dụng khác - Hành động khi chuyển sang ứng dụng khác từ trình phát chính — %s + Hành động khi chuyển sang ứng dụng khác từ trình phát băng hình chính — %s Không Thu nhỏ xuống trình phát nền - Thu nhỏ vào trình phát popup + Thu nhỏ xuống trình phát bật lên Hủy đăng ký Chọn tab Cập nhật @@ -341,7 +341,7 @@ Top 50 phổ biến Nhập ID SoundCloud hoặc link soundcloud.com/<ID của bạn> Cập nhật - Hiện thông báo khi có bản cập nhật ứng dụng + Hiển thị thông báo để nhắc cập nhật ứng dụng khi có phiên bản mới Chế độ hiển thị danh sách Danh sách Lưới @@ -351,7 +351,7 @@ đã tạm dừng trong hàng đợi đang xử lý - Hàng chờ + Xếp hàng Thao tác bị từ chối bởi hệ thống Tải về không thành công Tạo tên riêng biệt @@ -381,11 +381,11 @@ Không có bình luận nào Không thể tải bình luận Đóng - Tiếp tục phát - Phục hồi vị trí phát lại + Tiếp tục phát lại + Khôi phục vị trí phát lại cuối cùng Vị trí phát trong danh sách - Hiện vị trí phát lại trong danh sách - Xoá dữ liệu + Hiển chỉ báo vị trí phát lại trong danh sách + Dọn dẹp dữ liệu Đã xoá vị trí phát Tệp đã di chuyển hoặc đã xoá Tên file này đã tồn tại @@ -397,17 +397,17 @@ Kết nối hết thời gian Bạn muốn xóa lịch sử tải về hay xóa tất cả những file đã tải về\? Giới hạn hàng chờ tải xuống - Chỉ một tải xuống sẽ chạy + Chỉ một lần tải mỗi lượt Bắt đầu tải xuống Tạm dừng tải xuống Hỏi nơi thư mục để tải xuống Bạn sẽ được hỏi nơi lưu vào mỗi lần tải xuống. \nHãy bật trình chọn thư mục của hệ thống (SAF) nếu bạn muốn tải xuống vào một cái thẻ nhớ Xóa vị trí phát - Xóa toàn bộ vị trí phát - Xác nhận xóa toàn bộ vị trí phát\? + Xóa tất cả vị trí phát + Xóa tất cả vị trí phát\? Nhóm kênh - Chọn thực thể + Chọn một thực thể Thực thể đã tồn tại Không thể xác nhận thực thể Nhập URL thực thể @@ -425,27 +425,27 @@ %d giây - Có, và video đã xem một phần - Video đã xem trước và sau khi được thêm vào playlist sẽ bị xóa. -\nBạn có chắc không\? Video sẽ không thể hồi phục được! - Xóa video đã xem\? - Xóa video đã xem + Có, và cuốn băng đã xem một phần + Những cuốn băng đã xem trước và sau khi thêm vào danh sách phát sẽ bị loại bỏ. +\nBạn có chắc không\? Điều này không thể được hoàn tác! + Loại bỏ các cuốn băng đã xem\? + Xóa đã xem Mặc định hệ thống Ngôn ngữ ứng dụng - \'Khung truy cập bộ nhớ\' cho phép tải xuống thẻ SD bên ngoài + \'Khung truy cập lưu trữ\' cho phép tải xuống một thẻ SD bên ngoài Sử dụng trình chọn thư mục của hệ thống (SAF) Xóa file đã tải về Xóa lịch sử tải về Không thể khôi phục bản tải xuống này Bật tiếng Tắt tiếng - Yêu thích nhất + Được yêu thích nhất Thêm vào gần đây Ngôn ngữ sẽ thay đổi khi ứng dụng khởi động lại Bấm \"Xong\" khi hoàn thành Đã hoàn thành - ∞ video - 100+ video + ∞ cuộn băng + 100+ cuốn băng %s người nghe @@ -458,15 +458,15 @@ Nghệ sĩ Album Bài hát - Các video - Video này bị giới hạn độ tuổi. + Các cuốn băng + Cuốn băng này bị giới hạn độ tuổi. \n -\nBật \"%1$s\" trong cài đặt nếu bạn muốn xem video này. +\nBật \"%1$s\" trong thiết đặt nếu bạn muốn xem cuốn băng này. Bật chế độ hạn chế Youtube Chỉ URL HTTPS được hỗ trợ Chọn thực thể PeerTube ưa thích Thực thể PeerTube - Thời lượng tua video + Thời lượng tua-nhanh tới/-lùi Dòng chữ mô tả thời gian gốc từ các dịch vụ sẽ được hiển thị thay thế Hiện thời gian gốc trên các item Chọn dịch vụ; dịch vụ hiện tại: @@ -476,58 +476,58 @@ NewPipe chưa hỗ trợ loại nội dung này. \n \nCó thể nó sẽ được hỗ trợ bởi một phiên bản mới hơn trong tương lai. - Bạn có thấy feed của mình cập nhật chậm không\? Nếu có thì bạn có thể thử chế độ tăng tốc (bạn có thể bật/tắt chế độ này trong cài đặt hoặc bằng cách nhấn nút bên dưới). + Bạn có nghĩ rằng tải nguồn cấp dữ liệu quá chậm\? Nếu vậy, hãy thử bật tải nhanh (bạn có thể thay đổi nó này trong thiết đặt hoặc bằng cách nhấn nút bên dưới). \n -\nNewPipe hỗ trợ 2 cách cập nhật feed: -\n• Tải thông tin cả kênh cho từng kênh một; chậm nhưng chắc. -\n• Tải từ các nguồn chuyên dụng; nhanh nhưng thường không đầy đủ. +\nNewPipe cung cấp hai chiến lược tải nguồn cấp dữ liệu: +\n• Tìm nạp toàn bộ kênh đăng ký, tuy chậm nhưng đầy đủ. +\n• Sử dụng điểm cuối dịch vụ chuyên dụng, nhanh nhưng thường không hoàn thiện. \n -\nĐiểm khác biệt giữa 2 cách trên là cách nhanh hơn (chế độ tăng tốc) thường có thể thiếu thông tin - như thời lượng hay loại (VD: không thể phân biệt được giữa video thường và livestream) - và thiếu nội dung hơn. +\nSự khác biệt giữa hai loại này là cái nào nhanh thường thiếu một số thông tin, chẳng hạn như thời lượng hoặc loại mục (không thể phân biệt giữa các cuốn băng trực tiếp và bình thường) và nó có thể trả về ít mục hơn. \n -\nYouTube là một trong số các dịch vụ có hỗ trợ cập nhật nhanh, sử dụng RSS. +\nYouTube là một ví dụ về dịch vụ cung cấp phương pháp nhanh này với nguồn cấp RSS. \n -\nTuy nhiên, việc lựa chọn chế độ tùy thuộc vào mong muốn của bạn: tốc độ hay thông tin. - Tải thông tin từ các nguồn chuyên dụng nếu có thể - Bật chế độ tăng tốc - Tắt chế độ tăng tốc - Có thể được với một số dịch vụ, thường sẽ nhanh hơn nhưng có thể bị giới hạn nội dung nhận được hoặc nội dung nhận được không đầy đủ (v.d. thời lượng, trạng thái,..) +\nVì vậy, sự lựa chọn tập trung vào những gì bạn thích: tốc độ hoặc thông tin chính xác. + Tìm nạp từ nguồn cấp dữ liệu chuyên dụng khi có sẵn + Bật chế độ nhanh + Tắt chế độ nhanh + Có sẵn trong một số dịch vụ, nó thường nhanh hơn nhiều nhưng có thể trả về một số lượng mục hạn chế và thông tin thường không đầy đủ (ví dụ: không có thời lượng, loại mục, trạng thái không trực tiếp) Luôn cập nhật - Khoảng thời gian kể từ lần cuối cập nhật thông tin kênh trước khi nó được coi là hết hạn — %s - Ngưỡng thời gian cập nhật thông báo - Thông báo (feed) + Thời gian sau lần cập nhật cuối cùng trước khi đăng ký được coi là lỗi thời — %s + Ngưỡng cập nhật nguồn cấp dữ liệu + Nguồn cấp dữ liệu Tạo mới - Bạn muốn xóa nhóm kênh này\? - Tên nhóm kênh trống + Bạn có muốn xóa nhóm này\? + Tên nhóm trống Đã chọn %d - Chưa chọn kênh nào + Chưa chọn kênh đăng ký nào Chọn kênh đăng ký - Đang xử lý thông báo… - Số kênh không tải được: %d - Đang tải thông báo… - Thông báo cập nhật lần cuối vào: %s - Do giới hạn của ExoPlayer, khoảng thời gian tua đã được đặt lại thành %d giây + Đang xử lý nguồn cấp dữ liệu… + Chưa tải được: %d + Đang tải nguồn cấp dữ liệu… + Nguồn cấp được cập nhật lần cuối: %s + Do các hạn chế của ExoPlayer, đã đặt lại thời lượng tua thành %d giây đang khôi phục - Tự tạo (không tìm thấy người upload) + Được tạo tự động (không tìm thấy người tải lên) Cục bộ Trang chính mặc định Trang danh sách phát - Chỉ hiện các kênh chưa được nhóm + Chỉ hiển thị các đăng ký chưa được nhóm Không bao giờ Chỉ trên Wi-Fi - Tự động phát — %s - Phát hàng đợi (Video) - Không có danh sách nào ở đây - Chọn danh sách + Bắt đầu phát lại tự động — %s + Phát hàng đợi + Chưa đánh dấu danh sách phát nào + Chọn danh sách phát Vui lòng kiểm tra xem vấn đề mà bạn đang gặp đã báo cáo trước đó hay chưa. Nếu bạn tạo quá nhiều báo cáo trùng lặp, bạn sẽ khiến cho chúng tôi tốn thời gian để đọc chúng thay vì sửa lỗi bạn gặp. Báo cáo trên GitHub Sao chép bản báo cáo đã được định dạng Không thể đọc URL này. Mở với app khác\? - Tự động thêm vào hàng đợi + Tự động xếp hàng Hàng đợi của trình phát hiện tại sẽ bị thay thế Việc chuyển từ trình phát này sang trình phát khác có thể sẽ thay thế hàng đợi - Hỏi xác nhận trước khi xóa hàng đợi + Yêu cầu xác nhận trước khi xóa hàng đợi Để trống Đang tải Ngẫu nhiên @@ -539,18 +539,18 @@ Nút hành động thứ ba Nút hành động thứ hai Nút hành động đầu tiên - Chỉnh ảnh thu nhỏ của video trên thanh thông báo từ tỉ lệ 16:9 thành 1:1 (có thể gây méo ảnh) + Cắt bớt hình thu nhỏ cuộn băng hiển thị trong thông báo từ tỷ lệ khung hình 16:9 xuống 1:1 Chỉnh ảnh thu nhỏ thành tỉ lệ 1:1 Đang hiện kết quả cho: %s - Thêm vào danh sách đang phát + Xếp hàng Hiển thị nội dung không phù hợp vì có giới hạn độ tuổi (18+) Hiện ảnh thu nhỏ (thumbnail) trên nền màn hình khóa và trong thông báo Xem hình thu nhỏ Kiểm tra bộ nhớ - Đã thêm vào danh sách đang phát + Đã xếp hàng Xoá Cookie mà NewPipe lưu trữ sau khi bạn hoàn thành nó Cookie reCAPTCHA đã được xóa - Xóa bỏ Cookie của reCAPCHA + Dọn dẹp Cookie của reCAPCHA YouTube cung cấp \"Chế độ hạn chế\" để ẩn nội dung không phụ hợp Yêu cầu Android tùy chỉnh màu của thông báo theo màu chính của ảnh thu nhỏ (lưu ý rằng việc này không khả dụng trên tất cả thiết bị) Tô màu thông báo @@ -559,13 +559,13 @@ Gần đây Đang tính hash Mô tả - Video liên quan + Các mục liên quan Bình luận - Thông báo cho quá trình hash video - Thông báo hash video - Tắt để ẩn các hộp thông tin meta chứa thông tin bổ sung về tác giả/nội dung của stream, hoặc yêu cầu tìm kiếm - Hiện thông tin meta - Tắt để ẩn mô tả video và các thông tin bổ sung + Thông báo cho quá trình băm cuốn băng + Thông báo băm cuộn băng + Tắt để ẩn các hộp siêu thông tin có thông tin bổ sung về người tạo luồng, nội dung luồng hoặc yêu cầu tìm kiếm + Hiển thị siêu thông tin + Tắt để ẩn mô tả cuộn băng và các thông tin bổ sung Hiện mô tả Mở bằng Tệp đang được tải xuống @@ -574,18 +574,18 @@ Tự động (giao diện hệ thống) Radio Nội dung này chỉ dành cho người dùng trả phí, nên NewPipe không thể phát hay tải xuống. - Video này chỉ được dành cho thành viên YouTube Music Premium, nên NewPipe không thể phát hay tải xuống. + Cuốn băng này chỉ được dành cho thành viên YouTube Music Premium, nên NewPipe không thể phát hay tải xuống. Nội dung này được để ở chế độ riêng tư, nên NewPipe không thể phát hay tải xuống. Đây là một track SoundCloud Go+, nên NewPipe không thể phát hay tải xuống được, ít nhất là tại quốc gia của bạn. Nội dung này không có sẵn ở quốc gia của bạn. Làm văng ứng dụng - Video này đã bị giới hạn độ tuổi. -\nVì những quy định mới của YouTube, NewPipe không thể phát được video này, vì không thể tìm thấy nguồn phát video. - Chủ đề ban đêm + Cuốn băng này bị giới hạn độ tuổi. +\nDo chính sách mới của YouTube với các cuốn băng bị giới hạn độ tuổi, NewPipe không thể truy cập bất kỳ luồng băng hình nào của nó và do đó không thể phát nó. + Chủ đề đêm Nổi bật Hiện chi tiết kênh Hoàn thành - Tắt truyền phương tiện qua đường hầm nếu bạn gặp màn hình đen hoặc khựng khi phát video + Tắt tính năng truyền tải phương tiện nếu bạn gặp phải tình trạng màn hình đen hoặc giật hình khi phát lại cuốn băng. Tắt truyền phương tiện qua đường hầm Tắt Bật @@ -608,12 +608,12 @@ Bây giờ bạn có thể chọn văn bản trong mô tả. Lưu ý rằng trang có thể nhấp nháy và các liên kết có thể không nhấn vào được trong khi ở chế độ chọn. %s cung cấp lý do này: Tài khoản đã bị chấm dứt - Chế độ nguồn dữ liệu nhanh không cung cấp thêm thông tin về cái này. - Tài khoản của người này đã bị chấm dứt. -\nNewPipe sẽ không thể tải nguồn dữ liệu này trong tương lai. -\nBạn có muốn huỷ đăng ký kênh này không\? - Không thể tải thông báo cho \'%s\'. - Lỗi khi tải nguồn thông báo + Chế độ nạp nhanh không cung cấp thêm thông tin về điều này. + Tài khoản của tác giả đã bị chấm dứt. +\nNewPipe sẽ không thể tải nguồn cấp dữ liệu này trong tương lai. +\nBạn có muốn hủy đăng ký khỏi kênh này không\? + Không thể tải nguồn cấp dữ liệu cho \'%s\'. + Lỗi tải nguồn cấp dữ liệu \'Storage Access Framework\' chỉ được hỗ trợ từ Android 10 trở đi Bạn sẽ được hỏi nơi bạn muốn lưu mỗi mục tải xuống Chưa có thư mục tải xuống nào được đặt, hãy chọn thư mục tải xuống mặc định ngay @@ -635,11 +635,11 @@ %s lượt tải xuống đã hoàn tất
    Vuốt các mục để xóa chúng - Không bắt đầu video ở trình phát mini, mà chuyển trực tiếp thành chế độ toàn màn hình, nếu tự động xoay bị khóa. Bạn vẫn có thể truy cập trình phát mini bằng cách thoát khỏi toàn màn hình + Không bắt đầu các cuốn băng ở trình phát mini, mà chuyển trực tiếp thành chế độ toàn màn hình, nếu tự động xoay bị khóa. Bạn vẫn có thể truy cập trình phát mini bằng cách thoát khỏi toàn màn hình Khởi động trình phát chính ở toàn màn hình - Đã cho mục tiếp vào hàng đợi - Cho video kế tiếp vào hàng đợi - Đang thực hiện...Có thể mất một lúc + Đã xếp kế tiếp vào hàng + Xếp kế tiếp vào hàng + Đang xử lý... Có thể hơi lâu Thông báo lỗi Thông báo để báo cáo lỗi NewPipe đã gặp sự cố, nhấn để xem và báo cáo @@ -651,27 +651,27 @@ Kiểm tra cập nhật Kiểm tra phiên bản mới theo cách thủ công Đang kiểm tra cập nhật… - Mục thông báo mới - Làm trình phát dừng + Mục nguồn cấp dữ liệu mới + Làm sập trình phát Không tìm thấy ứng dụng quản lý tệp phù hợp nào để thực hiện hành động. \nVui lòng cài đặt ứng dụng quản lý tệp tương thích với Storage Access Framework - Không tìm thấy ứng dụng quản lý tệp phù hợp nào để thực hiện hành động. -\nVui lòng cài đặt ứng dụng quản lý tệp hoặc tắt \'%s\' trong cài đặt tải xuống + Không tìm thấy trình quản lý tệp nào thích hợp cho hành động này. +\nVui lòng cài đặt một trình quản lý tệp hoặc thử tắt \'%s\' trong thiết đặt tải xuống LeakCanary không khả dụng - ExoPlayer mặc định + Mặc định ExoPlayer Bình luận được ghim Thông báo trình phát - Thiết lập thông báo hiện đang phát + Cấu hình thông báo hiện đang phát trực tuyến Thông báo Luồng truyền mới - Thông báo về video mới đối với mục đăng ký + Thông báo về luồng mới của kênh đăng ký %s luồng truyền mới Đang tải chi tiết luồng truyền… Chạy kiểm tra luồng truyền mới - Thông báo video mới - Thông báo về video mới từ kênh bạn đã đăng ký + Thông báo về luồng mới + Thông báo về các luồng mới từ các kênh đăng ký Thời gian kiểm tra Yêu cầu kết nối mạng Bất kỳ loại mạng nào (có thể tính phí) @@ -683,64 +683,114 @@ Phần trăm , Nửa cung - Luồng video mà không được trình tải xuống hỗ trợ sẽ không hiện - Không có video khả dụng cho trình chạy ngoài - Video bạn chọn không hỗ trợ trình chạy bên ngoài - Video này không có âm thanh khả dụng cho trình chạy ngoài + Luồng băng hình mà không được trình tải xuống hỗ trợ sẽ không hiển thị + Không có luồng băng hình nào khả dụng cho trình phát bên ngoài + Luồng phát đã chọn không được trình phát ngoài hỗ trợ + Không có luồng âm thanh nào khả dụng cho máy phát bên ngoài Chọn chất lượng cho trình chạy ngoài Định dạng không xác định (:P) Độ phân giải không xác định - Kích thước khoảng thời gian tải + Kích thước tải thời lượng phát lại Thể loại Câu hỏi thường gặp Xem trên website Nếu bạn gặp vấn đề khi sử dụng ứng dụng , hãy chắc chắn rằng bạn đã tìm kiếm các câu hỏi thường thấy ! Nhập hoặc xuất các kênh bạn đăng ký bằng cách nhấn nút 3 chấm ở góc trên màn hình Không thể sao chép vào khay nhớ tạm - Đã thêm khoảng thời gian %d trùng lặp (s) + Đã thêm trùng lặp %d lần Dạng thẻ Bạn đang dùng phiên bản mới nhất Tùy chọn này chỉ được bật khi chủ đề %s được dùng Nhấn để tải %s Chế độ tăng tốc - Danh sách này bị trùng lặp. + Danh sách phát màu xám thì đã chứa mục này. Hữu ích trong trường hợp phím bấm âm lượng trên tai nghe hoặc thiết bị của bạn bị hỏng Không nhận phím điều khiển âm lượng vật lý Loại bỏ mục trùng lặp Loại bỏ mục trùng lặp\? - Bạn có muốn loại bỏ tất cả các nguồn trùng nhau trong danh sách phát này\? - Hiện/Ẩn nguồn phát - Hiện các nguồn phát sau - Đã xem - Đã xem 1 phần - Bỏ đặt hình thumbnail - Thay đổi kích thước khoảng thời gian tải (tầm khoảng %s). Để ở giá trị thấp hơn có thể sẽ tăng tốc độ tải video hơn ban đầu. Khởi động lại trình phát để áp dụng thay đổi - Bản âm thanh đã có sẳn trong stream này - Sử dụng tính năng giải mã ExoPlayer dự phòng - Giải pháp thay thế này phát hành và khởi tạo lại codec video khi xảy ra thay đổi bề mặt, thay vì đặt trực tiếp bề mặt vào codec. Đã được ExoPlayer sử dụng trên một số thiết bị gặp sự cố, cài đặt này chỉ ảnh hưởng cho thiết bị chạy Android 6 trở lên + Bạn có muốn loại bỏ mọi luồng trùng lặp trong danh sách phát này\? + Hiện/Ẩn luồng phát + Hiển thị các luồng phát sau + Đã xem đầy đủ + Đã xem một phần + Bỏ đặt vĩnh viễn hình thu nhỏ + Thay đổi kích thước khoảng thời gian tải trên nội dung lũy tiến (hiện tại là %s). Giá trị thấp hơn có thể tăng tốc độ tải ban đầu của chúng + Một bản âm thanh đã có sẵn trong luồng này + Sử dụng tính năng bộ giải mã dự phòng của ExoPlayer + Giải pháp thay thế này giải phóng và khởi tạo lại codec băng hình khi xảy ra thay đổi bề mặt, thay vì thiết đặt trực tiếp bề mặt vào codec. Đã được ExoPlayer sử dụng trên một số thiết bị gặp sự cố này, thiết đặt này chỉ ảnh hưởng đến Android 6 trở lên \n -\nBật tùy chọn này có thể ngăn lỗi phát lại khi chuyển đổi trình phát video hiện tại hoặc chuyển sang chế độ toàn màn hình +\nBật tùy chọn này có thể ngăn lỗi phát lại khi chuyển đổi trình phát băng hình hiện tại hoặc chuyển sang chế độ toàn màn hình Bật tùy chọn này nếu bạn gặp sự cố khởi tạo bộ giải mã, vấn đề này sẽ quay trở lại bộ giải mã có mức độ ưu tiên thấp hơn nếu quá trình khởi tạo bộ giải mã chính thất bại. Điều này có thể dẫn đến hiệu suất phát lại kém hơn so với khi sử dụng bộ giải mã chính Luôn dùng biện pháp thay thế cho bề mặt đầu ra video cho ExoPlayer - Nguyên gốc - Phần mô tả - Lồng tiếng - Chọn âm thanh gốc bạn thích + nguyên gốc + mô tả + lồng tiếng + Ưu tiên âm thanh gốc Chọn bản âm thanh gốc kể cả nhiều ngôn ngữ - Âm thanh mô tả bạn thích - Chọn bản âm thanh có phần mô tả cho người kiếm thị nếu có - Chọn cử chỉ vuốt cho phía bên trái nửa màn hình của trình chơi + Ưu tiên âm thanh mô tả + Chọn một bản âm thanh có mô tả cho người khiếm thị nếu có + Chọn cử chỉ vuốt cho nửa bên trái màn hình của trình phát Hành động cho cử chỉ trái - Chọn cử chỉ vuốt cho phía bên phải nửa màn hình của trình chơi + Chọn cử chỉ vuốt cho nửa bên phải màn hình của trình phát Hành động cho cử chỉ phải Độ sáng Âm lượng Không Âm thanh: %s Bản âm thanh - Sắp đến + Sắp tới Không rõ - Chọn bản âm thanh cho trình phát ngoài - Cài đặt Exoplayer - Quản lý một số cài đặt trong Exoplayer. Hãy khởi động lại trình phát để áp dụng thay đổi + Chọn bản âm thanh cho máy phát bên ngoài + Thiết đặt ExoPlayer + Quản lý một số thiết đặt ExoPlayer. Những thay đổi này yêu cầu khởi động lại trình phát để có hiệu lực + Đang tải siêu dữ liệu… + Vị trí tab chính + Tìm nạp các tab kênh + Đường hầm phương tiện đã bị tắt theo mặc định trên thiết bị của bạn vì kiểu thiết bị của bạn được biết là không hỗ trợ tính năng này. + Các tab cần tìm nạp khi cập nhật nguồn cấp dữ liệu. Tùy chọn này không có hiệu lực nếu kênh được cập nhật bằng chế độ nhanh. + Hình đại diện của người tải lên + Di chuyển bộ chọn tab chính xuống dưới cùng + Không có luồng trực tiếp + Ảnh xem trước + Không có luồng + Các cuộn băng + Người đăng ký + Những thẻ nào được hiển thị trên các trang kênh + Thẻ kênh + Chuyển đổi hướng màn hình + Chuyển đổi toàn màn hình + Hình đại diện + %1$s %2$s + Luồng tiếp theo + Hình đại diện kênh phụ + Mở hàng chờ phát + Giới thiệu + Phát lại + Băng rôn + Danh sách phát + Phát + Lựa chọn khác + Thời lượng + Kênh + Luồng trước đó + Chất lượng ảnh + \? + Chia sẻ danh sách URL + Chia sẻ với Tiêu đề + %1$s +\n%2$s + Video ngắn + Chất lượng thấp + Không tải ảnh + Chất lượng cao + Chia sẻ danh sách phát + Tua đi + Album + Tua lại + Chia sẻ danh sách phát với các thông tin chi tiết như tên danh sách phát và tiêu đề video hoặc dưới dạng danh sách URL cuốn băng đơn giản + Chất lượng trung bình + - %1$s: %2$s + Chọn chất lượng hình ảnh và chọn có tải chất lượng ảnh hay không, để giảm mức sử dụng dữ liệu và bộ nhớ. Thay đổi xoá cache ảnh cho cả trong bộ nhớ lẫn ổ cứng - %s + Track + Trực tiếp \ No newline at end of file diff --git a/app/src/main/res/values-zh-rHK/strings.xml b/app/src/main/res/values-zh-rHK/strings.xml index 0cead2277..3afaf86de 100644 --- a/app/src/main/res/values-zh-rHK/strings.xml +++ b/app/src/main/res/values-zh-rHK/strings.xml @@ -20,9 +20,9 @@ 顯示以 Kodi 媒體中心播放影片嘅選項 聲音 預設聲音檔案格式 - 主題 - 黑暗 - 明亮 + 主題色系 + 黑眼睛 + 白頭浪 下載 顯示「接續落」同「咁上下」嘅影片 唔支援呢個網址 @@ -82,7 +82,7 @@ 顯示更高解像度 得某啲機先播到 2K/4K 影片 預設嘅影片檔案格式 - 純黑 + 紅日降 浮面播緊 全部嘢 App/界面閃退 @@ -148,7 +148,7 @@ 顯示喺通知嘅影片縮圖由 16:9 剪成 1:1 長寬比 通知色彩化 等 Android 根據縮圖嘅主色自訂通知嘅顏色 (注意:唔係部部機都用得) - 夜間 + 晚風色系 跳前/跳後嘅快轉長短 閂埋佢去隱藏影片描述同附加資訊 剔低睇過 @@ -498,7 +498,7 @@ 呢部內容限區,喺你所在國家未有提供。 呢首 (至少喺你所在國家而言) 係 SoundCloud Go+ 單曲,因此 NewPipe 未能串流或下載。 呢部內容係私人嘢,因此 NewPipe 未能串流或下載。 - 自動 (跟返部機嘅主題色系) + 明或暗 (跟返部機嘅主題色系) 精選 廣播 你而家可以揀選喺描述入面嘅文字喇。不過要單聲先,喺揀選模式嘅時候,版面可能會有啲眨,同埋啲連結可能會撳唔到。 @@ -671,7 +671,7 @@ 啲圖都要騷 Picasso 三色碼顯示源頭:紅碼係網絡上高落嚟,藍碼係儲存喺磁碟本地,綠碼係潛伏喺記憶體中 服務原本嘅字會騷返喺串流項目上面 影像要推三色碼 - 若果播片嘅時候窒下窒下或者黑畫面,就停用多媒體隧道啦 + 若果播片嘅時候窒下窒下或者黑畫面,就停用多媒體隧道啦。 點樣用 Google 匯出嚟匯入 YouTube 訂閱: \n \n一、去呢個網址:%1$s @@ -701,7 +701,7 @@ 你已經用緊最新版本嘅 NewPipe 撳一下去下載 %s 唔再揀定封面縮圖 - 色系揀做%s 嘅時候至有得揀 + 主題色系揀做%s 嘅時候至有得揀 複製唔到去剪貼簿 一張張 灰咗嘅播放清單,即係已經有呢個項目。 @@ -720,13 +720,13 @@ 左手邊手勢動作 揀選右手邊播放器螢幕嘅手勢 右手邊手勢動作 - 亮度 - 聲音 - - 首選嘅原始聲音 - 首選嘅敘述性聲音 - 如果可以用嘅話,會為視障人士揀敘述性音軌 - 無論語言係咩,都揀選原始音軌 + 調整光暗度 + 調整大細聲 + 乜都唔使做 + 優先揀原聲 + 優先揀旁述 + 揀選為視障人士而設嘅旁述音軌 (如有提供) + 揀選原始音軌,唔理佢講咩話 聲音: %s 音軌 未知 @@ -736,11 +736,61 @@ 用 ExoPlayer 嘅解碼器汰退功能 如果遇到解碼器初始化問題,請啟用呢個選項,如果主解碼器初始化失敗,就會用優先順序較低的解碼器。咁樣可能會導致播放性能比使用主解碼器嗰陣差 幾時都用 Exoplayer嘅浮面影片輸出設定解決方法 - 原始嘅 - 配音嘅 - 敘述性 + 原聲 + 配音 + 旁述 為外面嘅播放器揀選音軌 呢個解決方法係喺發生表面變動嗰陣釋放同埋重新確認視訊編解碼器,而非直接將表面設定做編解碼器。ExoPlayer 已經喺部份有問題嘅裝置上使用了呢個設定,呢個設定僅係對 Android 6 或以上嘅更新版本有效。 \n \n啟用呢個選項可以避免喺切換現有視訊播放程式或切換到全螢幕時出現播放錯誤 + 啲圖嘅畫質 + 影片 + + 訂閱者 + 頻道頁要騷邊啲分頁出嚟 + 齋分享 URL 清單 + 分享埋片名 + %1$s +\n%2$s + 頻道分頁 + 短片 + 載入緊元資料… + 橫豎轉換 + 低畫質 + 主畫面分頁擺位 + 切換全螢幕 + 攞邊啲頻道分頁 + 頭像 + %1$s %2$s + 下一個串流 + 已知您部機個型號唔支援多媒體隧道,因此預設已經停用咗先。 + 子頻道嘅頭像 + 跳去排隊播 + 唔要載入啲圖 + 高畫質 + 簡介 + 分享播放清單 + 跳前 + 專輯 + 跳後 + 重播 + 更新摘要嘅時候要攞邊啲分頁返嚟。若果頻道用快速模式更新,就橫豎都無相干嘞。 + 分享播放清單要詳細包含播放清單個名同埋入面啲片名,定簡單得啲影片嘅 URL + 一般畫質 + 上載者嘅頭像 + 橫額 + 播放清單 + - %1$s:%2$s + 主畫面嘅分頁揀選搬落最底 + 無直播串流 + 揀選啲圖嘅畫質,定索性唔載入啲圖,去慳啲用數據同記憶體。更改會抹走記憶體同磁碟入面嘅影像快取 — %s + 播放 + 其他選項 + 縮圖 + 曲目 + 片長 + 無串流 + 頻道 + 上一個串流 + 直播 \ No newline at end of file diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 761e8e46b..8e613161a 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -1,6 +1,6 @@ - %1$s 發布 + 發布於%1$s 找不到串流播放器。要安裝 VLC 嗎? 安裝 取消 @@ -24,18 +24,18 @@ 顯示「用 Kodi 播放」的選項 預設音訊格式 主題 - 灰暗 - 明亮 + 深色 + 淺色 下載 顯示「下一部」與「相關」的影片 - 不支援此 URL + 不支援此網址 預設內容語言 影片與音訊 外觀 - 背景播放中 + 正在背景播放 網路錯誤 播放影片,持續時間: - 發佈者的個人頭像縮圖 + 發布者的頭像縮圖 喜歡 不喜歡 音訊下載資料夾 @@ -49,17 +49,17 @@ 顯示更高的解析度 僅部份裝置可播放 2K/4K 影片 預設影片格式 - 純黑 + 黑色 記住懸浮視窗屬性 記住上次使用時懸浮視窗的大小和位置 搜尋建議 選擇在搜尋時顯示建議 - 以懸浮視窗播放中 + 正在以懸浮視窗播放 內容 顯示年齡限制內容 下載 下載 - 錯誤回報 + 回報錯誤 全部 已停用 清除 @@ -69,22 +69,22 @@ 無法解析網站 內容無法使用 無法設定下載選單 - 應用程式或界面已停止運作 + 應用程式或介面已崩潰 抱歉,這是不該發生的。 透過電子郵件回報 - 抱歉,發生了一些問題。 + 抱歉,發生問題。 回報 資訊: 發生了什麼事: 發生了什麼:\\n請求:\\n內容語言:\\n內容國家:\\n應用程式語言:\\n服務:\\nGMT 時間:\\n套件:\\n版本:\\n系統版本: - 您的留言(請用英文): + 您的留言(請用英語): 詳細資訊: 影片 音訊 重試 - k + 百萬 - B + 十億 開始 暫停 刪除 @@ -96,7 +96,7 @@ NewPipe 下載中 輕觸以顯示詳細資訊 請稍候… - 已複製至剪貼簿 + 已複製到剪貼簿 稍後請在設定中選擇下載資料夾 使用懸浮視窗模式 \n需要此權限 @@ -111,9 +111,9 @@ 無法更新訂閱 訂閱清單 新鮮事 - 搜尋紀錄 - 在本機儲存搜尋紀錄 - 觀看紀錄 + 搜尋記錄 + 在本機儲存搜尋記錄 + 觀看記錄 記錄觀看過的影片 恢復播放 在干擾結束後繼續播放(例如有來電) @@ -142,18 +142,18 @@ 大部分的特殊字元 關於 NewPipe 第三方授權 - © %1$s 由 %2$s 使用 %3$s 授權條款發佈 + © %1$s 由 %2$s 使用 %3$s 授權條款發布 關於與常見問題 授權條款 Android 上自由且輕巧的串流播放器。 在 GitHub 上檢視 NewPipe 使用的授權條款 - 不管你有什麼點子——翻譯、設計、程式碼整理,或者程式碼撰寫——我們永遠歡迎你來幫忙。完成的越多,NewPipe 也會更好! + 不管你有什麼點子──翻譯、設計、程式碼整理,或者程式碼撰寫──我們永遠歡迎你來幫忙。完成的越多,NewPipe 也會更好! 閱讀授權條款 貢獻 - 歷史紀錄 - 歷史紀錄 - 確定要刪除此項搜尋紀錄嗎? + 歷史記錄 + 歷史記錄 + 確定要刪除此項搜尋記錄嗎? 找不到串流播放器(您可以安裝 VLC 來播放)。 顯示「長按以新增」提示 預設內容國家 @@ -175,7 +175,7 @@ 網站 匯入資料庫 匯出資料庫 - 覆蓋您目前的歷史記錄、訂閱與(可選的)設定 + 覆蓋您目前的歷史記錄、訂閱與設定(選用) 匯出歷史記錄、訂閱內容、播放清單、設定 回饋 如欲了解更多有關 NewPipe 的資訊和新聞,請造訪我們的網站。 @@ -188,7 +188,7 @@ 選擇互動導覽 已匯出 已匯入 - 無有效的 ZIP 檔案 + 無效的 ZIP 檔案 警告:無法匯入所有檔案。 這將覆蓋您目前的設定。 熱門 @@ -240,12 +240,12 @@ 報告週期不足錯誤 強制報告在處理完片段或活動週期外發生的無法傳遞的 Rx 異常 使用粗略但快速的尋找 - 粗略的尋找能讓播放器以降低的精確度更快找到影片的進度位置。尋找 5、15或25秒無法與其一同使用 + 粗略的尋找能讓播放器以降低的精確度更快找到影片的進度位置。尋找 5、15 或 25 秒無法與其一同使用 自動將下一部影片新增至佇列 透過加入相關的串流來繼續結束的(未重複)播放佇列 檔案 無效的資料夾 - 無效的檔案/內容來源 + 無效的檔案或內容來源 檔案名稱不能留空 發生錯誤: %1$s 匯入 @@ -262,11 +262,11 @@ \n \n1. 移至此網址:%1$s \n2. 當被提示時登入帳號 -\n3. 點擊「包含所有資料」,然後「取消選取全部」,然後僅選取「訂閱」並點擊「確定」 -\n4. 點擊「下一步」然後「建立匯出」 -\n5. 在「下載」按鈕出現後點擊它 +\n3. 按一下「包含所有資料」,接著「取消選取全部」,然後僅勾選「訂閱」並按一下「確定」 +\n4. 按一下「下一步」然後「建立匯出」 +\n5. 在「下載」按鈕出現後按一下它 \n6. 點擊下方的「匯入檔案」並選取已下載的 zip 檔案 -\n7. [若 zip 匯入失敗] 擷取 .csv 檔案(通常位於「YouTube 與 YouTube Music/訂閱/訂閱.csv」),點擊下方的「匯入檔案」並選取擷取的 csv 檔案 +\n7. [若 zip 匯入失敗] 擷取 .csv 檔案(通常位於「YouTube 與 YouTube Music/訂閱/訂閱.csv」),按一下下方的「匯入檔案」並選取擷取的 csv 檔案 yourID, soundcloud.com/yourid 請記住,此操作可造成昂貴網路花費。 \n @@ -277,16 +277,16 @@ \n2. 移至此網址: %1$s \n3. 當被提示時登入帳號 \n4. 複製您被重新導向到的個人設定檔網址。 - 已抹除圖片快取 - 抹除已快取的中介資料 + 已清除圖片快取 + 清除已快取的後設資料 移除所有已快取的網頁資料 - 已抹除中介資料快取 + 已清除後設資料快取 播放速度控制 節奏 音高 解除掛鉤(可能導致失真) 偏好的「開啟」動作 - 開啟內容時的預設動作 — %s + 開啟內容時的預設動作 ─ %s 沒有可供下載的串流 字幕 調整播放器字幕文字大小與背景樣式。必須重新啟動應用程式才會生效 @@ -295,10 +295,10 @@ 刪除所有觀看歷史記錄? 觀看歷史已刪除 清除搜尋歷史 - 刪除搜尋關鍵字的歷史 + 刪除搜尋關鍵字的記錄 刪除所有搜尋歷史記錄? - 搜尋歷史已刪除 - 已刪除 1 個項目。 + 搜尋記錄已刪除 + 已刪除一個項目。 NewPipe 是一個 Copyleft 的自由軟體:您可以隨意使用、研究、分享並改進它。在遵守由自由軟體基金會所發佈的 GNU 通用公共授權條款的狀況下,您可以自由地再散佈及/或修改它;授權條款預設使用第三版,但您也可以選擇更新的版本。 您是否要同時匯入設定? NewPipe 的隱私政策 @@ -312,7 +312,7 @@ 沒有限制 使用行動網路時限制解析度 切換 app 時最小化 - 從主影片播放器切換到其他 app 時要執行的動作 — %s + 從主影片播放器切換到其他 app 時要執行的動作 ─ %s 最小化為背景播放器 最小化為彈出式播放器 @@ -392,7 +392,7 @@ NewPipe 在處理檔案時被關閉 裝置上沒有剩餘的空間 進度遺失,因為檔案已被刪除 - 您想要清除您的下載歷史紀錄,還是刪除所有已下載的檔案? + 您想要清除您的下載歷史記錄,還是刪除所有已下載的檔案? 限制下載佇列 一次執行一個下載 開始下載 @@ -424,9 +424,9 @@ 選取您最愛的 PeerTube 站臺 在 %s 上找到您喜愛的站臺 新增站臺 - 輸入站臺 URL + 輸入站臺網址 無法驗證站臺 - 僅支援 HTTPS URL + 僅支援 HTTPS 網址 站臺已存在 本機 最近新增 @@ -435,7 +435,7 @@ 正在恢復 無法恢復此下載 選擇一個站臺 - 清除下載歷史紀錄 + 清除下載歷史記錄 刪除已下載的檔案 給予顯示在其他應用程式上層的權限 應用程式語言 @@ -473,7 +473,7 @@ Feed Feed 更新閾值 - 上次更新後,訂閱被視為過時的時間 — %s + 上次更新後,訂閱被視為過時的時間 ─ %s 總是更新 在可用時從專用 feed 擷取 其在某些服務中可用,且通常較快速,但可能只會回傳有限的項目,而且資訊通常不完整(例如:沒有持續時間、項目類型、沒有即時狀態) @@ -516,17 +516,17 @@ 尚無播放清單書籤 播放清單頁面 選取播放清單 - 請檢查是否已有與您的應用程式當機相關的討論議題。當建立重複的工單時,您就是在耗費我們本來可以用來修復臭蟲的時間。 + 請檢查是否已有與您的應用程式崩潰相關的討論議題。當建立重複的客服單時,您就是在耗費我們本來可以用來修復錯誤的時間。 在 GitHub 上回報 複製格式化過的報告 目前顯示 %s 的結果 從不 僅在 Wi-Fi 上 - 自動開始播放 — %s + 自動開始播放 ─ %s 播放佇列 - 無法識別 URL。要用其他應用程式開啟嗎? + 無法識別此網址。要用其他應用程式開啟嗎? 自動佇列 - 作用中播放器的佇列可能會被取代 + 啟動中播放器的佇列可能會被取代 從一個播放器切換到另一個可能會取代您的佇列 清除佇列前要求確認 @@ -534,7 +534,7 @@ 隨機播放 循環播放 您可以選取最多三個動作來顯示在簡潔通知中! - 透過點擊下方的每一個通知來編輯它。使用右側的勾選框,最多可以選取三個在簡潔通知中顯示 + 透過輕觸下方的通知來編輯它。使用右側的勾選框,最多可以選取三個在簡潔通知中顯示 第五動作按鈕 第四動作按鈕 第三動作按鈕 @@ -549,7 +549,7 @@ reCAPTCHA cookies 已被清除 清除 reCAPTCHA cookies YouTube 有提供「嚴格篩選模式」,可以隱藏潛在的成人內容 - 顯示可能不適於兒童的內容(因為其有年齡限制,如18歲以上等) + 顯示可能不適於兒童的內容,因為其有年齡限制(如 18 歲以上等) 讓 Android 根據縮圖中的主要色彩來自訂通知的顏色(請注意,此功能不是在所有裝置上都能正常運作) 彩色通知 於鎖定畫面背景與通知使用縮圖 @@ -581,9 +581,9 @@ 解決 下載已經開始 您可以在下方選取您最愛的夜間佈景主題 - 選取您最愛的夜間佈景主題 — %s + 選取您最愛的夜間佈景主題 ─ %s 自動(裝置佈景主題) - 夜間佈景主題 + 夜間布景主題 顯示頻道詳細資訊 如果您遇到黑畫面或影片播放停頓的現象,請停用媒體隧道。 停用媒體隧道 @@ -623,7 +623,7 @@ 高品質(較大) 拖動列縮圖預覽 被創作者加心號 - 標記為已看過 + 標記為已觀看 在圖片頂部顯示畢卡索彩色絲帶,指示其來源:紅色代表網路、藍色代表磁碟、綠色代表記憶體 顯示圖片指示器 遠端搜尋建議 @@ -656,7 +656,7 @@ 找不到適合此動作的檔案管理程式。 \n請安裝檔案管理程式或在下載設定嘗試停用「%s」 NewPipe 遇到錯誤,點擊以回報 - 發生錯誤,請檢視通知 + 發生錯誤,請查看通知 釘選的留言 LeakCanary 無法使用 ExoPlayer 預設值 @@ -669,7 +669,7 @@ 新串流通知 設定目前播放串流通知 需要網路連線 - 從磁碟抹除所有已下載的檔案? + 從磁碟清除所有已下載的檔案? 取得通知 新串流 關於訂閱的新串流通知 @@ -754,7 +754,7 @@ 頻道頁面上顯示哪些分頁 頻道分頁 短片 - 正在載入詮釋資料…… + 正在載入後設資料…… 擷取頻道分頁 關於 專輯 diff --git a/fastlane/metadata/android/de/changelogs/63.txt b/fastlane/metadata/android/de/changelogs/63.txt index 1fdd53b55..3ccc56bc0 100644 --- a/fastlane/metadata/android/de/changelogs/63.txt +++ b/fastlane/metadata/android/de/changelogs/63.txt @@ -5,4 +5,4 @@ - Alles über DSGVO hinzugefügt #1420 ### Repariert -- Downloader: Absturz beim Laden unvollendeter Downloads aus .giga-Dateien behoben #1407 +- Downloader: Absturz beim Laden unvollendeter Downloads von .giga-Dateien behoben #1407 diff --git a/fastlane/metadata/android/de/changelogs/65.txt b/fastlane/metadata/android/de/changelogs/65.txt index 8190e9ae9..3405af363 100644 --- a/fastlane/metadata/android/de/changelogs/65.txt +++ b/fastlane/metadata/android/de/changelogs/65.txt @@ -1,10 +1,10 @@ Verbesserungen --Menü Animation deaktiviert #1486 +-Menüanimation deaktiviert #1486 -Löschen von Downloads rückgängig machen #1472 --Option zum Downloaden im Austausch Menu #1498 --hinzufügen der Teilen Funktion im Menü #1454 --Minimieren der Wiedergabe beim beenden #1354 +-Option zum Downloaden im Teilen-Menü #1498 +-hinzufügen der Teilen-Funktion im Menü #1454 +-Minimieren der Wiedergabe beim Beenden #1354 -Datenbank Versions Aktualisierung und Datenbestand Wiederherstellung #1510 -ExoPlayer 2.8.2 aktualisiert #1392 --Überarbeitung der Wiedergabegeschwindigkeitskolntrolle um Änderungen besser zu unterstützen --hinzufügen der Möglichkeit Stille zu überspringen(Hilfreich bei Audiobücher und einigen Musik Arten) unterstützt dadurch eine nahtlose Wiedergabe (nicht so toll bei Liedern in denen es auch Stille Passagen gibt) +-Überarbeitung der Wiedergabegeschwindigkeitskontrolle um Änderungen besser zu unterstützen +-hinzufügen der Möglichkeit Stille zu überspringen(Hilfreich bei Audiobücher und einigen Musikarten) unterstützt dadurch eine nahtlose Wiedergabe (Nicht so toll bei Liedern, in denen es auch stille Passagen gibt.) diff --git a/fastlane/metadata/android/de/changelogs/968.txt b/fastlane/metadata/android/de/changelogs/968.txt index a619dc5c2..eaaf0637c 100644 --- a/fastlane/metadata/android/de/changelogs/968.txt +++ b/fastlane/metadata/android/de/changelogs/968.txt @@ -1,7 +1,7 @@ -Option "Kanaldetails" wurde zum Langdruckmenü hinzugefügt. -Funktion zum Umbenennen des Playlist-Namens von der Playlist-Oberfläche zugefügt. +Option „Kanaldetails“ dem Langdruck-Menü hinzugefügt. +Funktion zum Umbenennen des Namens der Wiedergabeliste der Oberfläche hinzugefügt. Benutzer kann nun pausieren, während ein Video gepuffert wird. -Weiße Thema wurde aufpoliert. +Weißes Design wurde aufpoliert. Überlappende Schriftarten bei Verwendung einer größeren Schriftgröße behoben. -Kein Video auf Formuler- und Zephier-Geräten behoben. +Videoanzeige auf Formuler- und Zephier-Geräten behoben. Verschiedene Abstürze behoben. diff --git a/fastlane/metadata/android/de/changelogs/970.txt b/fastlane/metadata/android/de/changelogs/970.txt index 53f80fed1..cf0ae0e0b 100644 --- a/fastlane/metadata/android/de/changelogs/970.txt +++ b/fastlane/metadata/android/de/changelogs/970.txt @@ -5,7 +5,7 @@ Neu: Behoben: • Rotationsabsturz auf der Videodetailseite -• „Mit Kodi spielen“-Button im Player fordert immer auf, Kore zu installieren +• „Mit Kodi spielen“-Schaltfläche 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 diff --git a/fastlane/metadata/android/de/changelogs/993.txt b/fastlane/metadata/android/de/changelogs/993.txt index 54b04faa7..23f4db0b0 100644 --- a/fastlane/metadata/android/de/changelogs/993.txt +++ b/fastlane/metadata/android/de/changelogs/993.txt @@ -1,12 +1,12 @@ Neu -• Warnung bei Erstellung von Duplikaten in Wiedergabelisten und neue Schaltfläche um Duplikate zu entfernen -• Möglichkeit, Hardware Tasten zu ignorieren +• Warnung beim Erstellen von Duplikaten in Wiedergabelisten und neue Schaltfläche um diese zu entfernen +• Möglichkeit, Hardwaretasten zu ignorieren • Möglichkeit, teilweise gesehene Videos im Feed auszublenden Verbessert -• Mehr Rasterspalten auf großen Displays +• Mehr Gitterspalten auf großen Displays • Fortschrittsbalken sind jetzt konsistent mit Einstellungen Behoben -• Das Öffnen von Browser-URLs, Downloads und externen Videoplayern auf Android 11+ -• Fullscreen-Bedingung benötigte zweimaliges Drücken auf MIUI +• Das Öffnen von Browser-URLs, Downloads und externen Videoplayern unter Android 11+ +• Vollbildmodus-Bedienung benötigte zweimaliges Tippen unter MIUI diff --git a/fastlane/metadata/android/de/changelogs/995.txt b/fastlane/metadata/android/de/changelogs/995.txt new file mode 100644 index 000000000..284d1c192 --- /dev/null +++ b/fastlane/metadata/android/de/changelogs/995.txt @@ -0,0 +1,14 @@ +Neu +• Unterstützung von Kanaltabs +• Bildqualität auswählbar +• URLs zu allen Bildern erhalten + +Verbessert +• Zugänglichkeit der Player-Oberflächen +• Option zum Hinzufügen von Wiedergabelisten- und Videonamen beim Teilen von Inhalten +• Interne Verbesserungen und Aktualisierungen der Abhängigkeiten + +Behoben +• Auswahl der falschen Sprachen in der Sprachauswahl +• Der Audio-Fokus des Players respektierte die Stummschaltung nicht +• Das Hinzufügen von Elementen zu Wiedergabelisten in bestimmten Fällen diff --git a/fastlane/metadata/android/eo/changelogs/63.txt b/fastlane/metadata/android/eo/changelogs/63.txt new file mode 100644 index 000000000..c6e1e9ad5 --- /dev/null +++ b/fastlane/metadata/android/eo/changelogs/63.txt @@ -0,0 +1,8 @@ +### Plibonigojn +- Importi/eksporti konfiguraĵojn #1333 +- Malpliigi superdesegnaĵon (rendimentan plibonigon) #1371 +- Malgrandajn kodajn plibonigojn #1375 +- Aldoni ĉion pri GDPR #1420 + +### Fiksitaj +- Elŝutilo: Fiksi kraŝon kiam ŝarĝi malfinitajn elŝutaĵojn el .giga-j dosieroj #1407 diff --git a/fastlane/metadata/android/eo/full_description.txt b/fastlane/metadata/android/eo/full_description.txt new file mode 100644 index 000000000..74418f2ab --- /dev/null +++ b/fastlane/metadata/android/eo/full_description.txt @@ -0,0 +1 @@ +NewPipe uzas nek frambildotekojn de *Google*, nek la aplikprograman interfacon de YouTube. Ĝi nur sintakse analizas la retejon por akiri la necesaj datumoj. Tial ĉi tio aplikaĵo estas uzebla per disponaĵoj sen instalita *Google Services*. Oni ne bezonas konton de YouTube por uzi NewPipe, kaj ĝi estas libera programaro. diff --git a/fastlane/metadata/android/pt-BR/changelogs/954.txt b/fastlane/metadata/android/pt-BR/changelogs/954.txt index 449fde5dc..cd131c162 100644 --- a/fastlane/metadata/android/pt-BR/changelogs/954.txt +++ b/fastlane/metadata/android/pt-BR/changelogs/954.txt @@ -1,7 +1,7 @@ -fluxo de trabalho do novo aplicativo: reproduza vídeos na página de detalhes, deslize para baixo para minimizar o player -• Notificações MediaStyle: ações personalizáveis em notificações, melhorias de desempenho -• redimensionamento básico ao usar NewPipe como app de desktop -• mostrar diálogo com opções abertas em caso de URL não suportado -• Melhorada a experiência de sugestão de pesquisa -• Qualidade de vídeo padrão aumentada para 720p60 (player do app) e 480p (pop-up) -• correções de bugs +• Novo recurso: veja vídeos na página de detalhes, deslize para baixo para minimizar o vídeo +• Notificações MediaStyle: ações personalizáveis em notificações, melhorias de desempenho +• redimensionamento básico ao usar NewPipe como aplicativo de computador +• diálogo com opções abertas se URL não for suportado +• Melhor experiência de sugestão de pesquisa quando não pode ser buscada +• Maior qualidade do vídeo padrão para 720p60 no reprodutor interno e 480p no Pop-up +• correções de falhas e mais (?) diff --git a/fastlane/metadata/android/pt-BR/changelogs/994.txt b/fastlane/metadata/android/pt-BR/changelogs/994.txt new file mode 100644 index 000000000..d8e986051 --- /dev/null +++ b/fastlane/metadata/android/pt-BR/changelogs/994.txt @@ -0,0 +1,15 @@ +Novo +• Suporte a múltiplas faixas de áudio e idiomas +• Definição de gestos para volume e brilho em qualquer lado da tela +• Suporte para exibir abas principais na parte inferior da tela + +Melhorias +• [Bandcamp] Lida com faixas sob acesso pago + +Corrigido +• [YouTube] erros HTTP 403 para transmissões +• Tela preta ao alternar ao reprodutor a partir da visualização da lista de reprodução +• Vazamento de memória no reprodutor +• [PeerTube] Avatares do carregador e do subcanal foram trocados + +e mais diff --git a/fastlane/metadata/android/pt-BR/changelogs/995.txt b/fastlane/metadata/android/pt-BR/changelogs/995.txt new file mode 100644 index 000000000..943b842b0 --- /dev/null +++ b/fastlane/metadata/android/pt-BR/changelogs/995.txt @@ -0,0 +1,14 @@ +Novidades +• Suporta abas de canal +• Seleção da qualidade da imagem +• Obtém os URL para todas as imagens + +Melhorias +• Acessibilidade das interfaces do reprodutor +• Pode adicionar nome da lista de reprodução e de vídeo para compartilhamento do conteúdo +• Melhorias internas (?) e atualizações de dependências + +Corrigido +• Seleção de idiomas errados ao selecionar +• O foco do áudio do reprodutor não respeitava o mudo +• Adicionar itens para listas de reprodução não funcionava em casos específicos diff --git a/fastlane/metadata/android/pt/changelogs/995.txt b/fastlane/metadata/android/pt/changelogs/995.txt new file mode 100644 index 000000000..ebe4e742f --- /dev/null +++ b/fastlane/metadata/android/pt/changelogs/995.txt @@ -0,0 +1,14 @@ +Novo +- Separadores de canais de suporte +- Selecionar a qualidade da imagem +- Obter URLs para todas as imagens + +Melhorado +- Acessibilidade das interfaces do leitor +- Opção para adicionar o nome da lista de reprodução e o nome do vídeo ao conteúdo de partilha da lista de reprodução +- Melhorias internas e atualizações de dependências + +Corrigido +- Seleção de idiomas errados no seletor de idiomas +- O foco do áudio do leitor não estava a respeitar o silêncio +- A adição de itens a listas de reprodução não funcionava em casos específicos diff --git a/fastlane/metadata/android/ru/changelogs/994.txt b/fastlane/metadata/android/ru/changelogs/994.txt new file mode 100644 index 000000000..bf11a4f4b --- /dev/null +++ b/fastlane/metadata/android/ru/changelogs/994.txt @@ -0,0 +1,13 @@ +Нововведения +• Поддержка нескольких аудиодорожек/языков +• Использование жестов настройки громкости и яркости на любой части экрана +• Поддержка отображения основных вкладок в нижней части экрана + +Улучшения +• [Bandcamp] Управление платными композициями + +Исправления +• [YouTube] Ошибки 403 HTTP при просмотре живых трансляций +• Чёрный плеер при переключении на основной плеер из режима просмотра плэйлистов +• Утечка памяти в службе плеера +• [PeerTube] Загрузчик и изображения профиля дополнительных каналов изменены местами diff --git a/fastlane/metadata/android/ru/changelogs/995.txt b/fastlane/metadata/android/ru/changelogs/995.txt new file mode 100644 index 000000000..dcefd106a --- /dev/null +++ b/fastlane/metadata/android/ru/changelogs/995.txt @@ -0,0 +1,14 @@ +Из нового +• Поддержка вкладок каналов +• Выбор качества изображения +• Получение URL всех изображений + +Улучшения +• Доступность интерфейсов проигрывателей +• Добавлена возможность добавлять название подборки и название видеораспространяемого содержимого подборки. +• Внутренние усовершенствования и обновление зависимостей + +Исправления +• Выбор неправильных языков в переключателе языков +• Фокусировка звука проигрывателя не учитывала выключение звука +• Добавление элементов в подборки не работало в определённых случаях diff --git a/fastlane/metadata/android/sv/changelogs/954.txt b/fastlane/metadata/android/sv/changelogs/954.txt new file mode 100644 index 000000000..4ba3dc350 --- /dev/null +++ b/fastlane/metadata/android/sv/changelogs/954.txt @@ -0,0 +1,9 @@ +• nytt arbetsflöde för applikationen: spela upp videor på detalj-sidan, dra nedåt för att minimera spelaren +• MediaStyle-aviseringar: anpassningsbara åtgärder i aviseringar, prestanda-förbättringar +• grundläggande storleksändring när NewPipe används som en skrivbordsapp + +• visa ett dialogfönster med öppna alternativ i händelse av en URL-toast som inte stöds +• Förbättra sökförslagsupplevelsen när avlägsna sökningar inte kan hämtas +• Ökad standardvideokvalitet till 720p60 (spelare i appen) och 480p (popup-spelare) + +• tonvis med buggfixar och mer diff --git a/fastlane/metadata/android/tr/changelogs/68.txt b/fastlane/metadata/android/tr/changelogs/68.txt index b2507d484..069a0a22e 100644 --- a/fastlane/metadata/android/tr/changelogs/68.txt +++ b/fastlane/metadata/android/tr/changelogs/68.txt @@ -1,31 +1,31 @@ # v0.14.1 değişiklikleri -### Sabit -- Sabit video url # 1659 şifresini çözmek için başarısız oldu -- Sabit açıklama bağlantısı iyi ayıklanmıyor # 1657 +### Düzeltmeler +- Video url'sinin şifresinin çözülememesi düzeltildi #1659 +- Sabit açıklama bağlantısı iyi açılamıyor #1657 # v0.14.0 değişiklikleri -### Yeni -- Yeni Çekmece tasarımı # 1461 -- Yeni özelleştirilebilir ön sayfa # 1461 +### Yenilikler +- Yeni Çekmece tasarımı #1461 +- Yeni özelleştirilebilir ön sayfa #1461 -### Geliştirmeler -- Yeniden işlenmiş Hareket kontrolleri # 1604 -- Pop-up oynatıcıyı kapatmanın yeni yolu # 1597 +### İyileştirmeler +- Yenilenmiş Hareket kontrolleri #1604 +- Açılır oynatıcıyı kapatmanın yeni yolu #1597 -### Sabit -- Abonelik sayısı mevcut olmadığında bir hata düzeltildi. # 1649'u kapatır. -- Bu durumlarda "Abone sayısı mevcut değil" i göster -- Bir YouTube çalma listesi boş olduğunda npe'yi düzeltin -- Soundcloud'daki kiosklar için hızlı düzeltme -- Refactor ve hata düzeltme # 1623 -- Döngüsel arama sonucunu düzelt # 1562 -- Statik olarak yerleştirilmemiş Arama çubuğunu düzeltin -- Fix YT Premium video doğru engellenmiyor -- Bazen yüklenmeyen videoları düzeltin (ÇİZGİ ayrıştırma nedeniyle) -- Video açıklamasındaki bağlantıları düzeltin -- Birisi harici sd karta indirmeye çalıştığında uyarıyı göster -- gösterilen hiçbir şey düzeltilmedi istisna tetikleyicileri raporu -- android 8.1 için arka plan oynatıcısında gösterilmeyen küçük resim [buraya bakın] (https://github.com/TeamNewPipe/NewPipe/issues/943 ) -- Yayın alıcısının kaydını düzeltin. # 1641'i kapatır. +### Düzeltmeler +- Abonelik sayısı mevcut olmadığında hatayı düzeldi. Kapatılır #1649. + - Bu durumlarda "Abone sayısı mevcut değil" ifadesini göster +- Bir YouTube oynatma listesi boş olduğunda NPE düzeltme +- SoundCloud'daki kiosklar için hızlı düzeltme +- Yeniden düzenleme ve hata düzeltme #1623 + - Döngüsel arama sonucunu düzeltildi#1562 + - Arama çubuğu statik olarak düzenlenmemiş düzeltildi + -YT Premium videoları doğru şekilde engellenmiyor düzeltildi + - Videoların bazen yüklenmemesi düzeltildi (DASH ayrıştırma nedeniyle) + - Video açıklamasındaki bağlantıları düzeltildi + - Birisi harici sd karta indirmeye çalıştığında uyarı göster + - Gösterilen hiçbir istisna tetikleyici bildirmesi düzeltildi + - android 8.1 için arka plan oynatıcıda küçük resim gösterilmiyor [buradan ulaşabilirsiniz](https://github.com/TeamNewPipe/NewPipe/issues/943) +- Yayın alıcısının kaydı düzeltildi. Kapatılır #1641. diff --git a/fastlane/metadata/android/tr/changelogs/69.txt b/fastlane/metadata/android/tr/changelogs/69.txt new file mode 100644 index 000000000..d927ed9c4 --- /dev/null +++ b/fastlane/metadata/android/tr/changelogs/69.txt @@ -0,0 +1,19 @@ +### Yenilikler +- Aboneliklerde uzun dokunarak silme ve paylaşma işlemleri eklendi #1516 +- Tablet kullanıcı arayüzü ve kılavuz liste düzeni eklendi #1617 + +### İyileştirmeler +- En son kullanılan en-boy oranını kaydetme ve tekrar yükleme eklendi #1748 +- İndirmeler etkinliğinde tam video isimleriyle lineer düzen etkinleştirildi #1771 +- Abonelikleri doğrudan abonelikler sekmesi içinden silme ve paylaşma eklendi #1516 +- Kuyrukta oynatma zaten sona ermişse video oynatmayı tetikleyen sıra eklendi #1783 +- Ses ve parlaklık jestleri için ayrı ayarlar eklendi #1644 +- Yerelleştirme desteği eklendi #1792 + +### Düzeltmeler +- Finlandiya'da kullanılabilmesi için nokta biçemi için zaman ayrıştırma düzeltildi +- Abonelik sayısı düzeltildi +- API 28+ cihazlar için öncelikli hizmet izni eklendi #1830 + +### Bilinen Hatalar +- Oynatma durumu Android P üzerinde kaydedilemiyor diff --git a/fastlane/metadata/android/tr/changelogs/70.txt b/fastlane/metadata/android/tr/changelogs/70.txt new file mode 100644 index 000000000..930b73eeb --- /dev/null +++ b/fastlane/metadata/android/tr/changelogs/70.txt @@ -0,0 +1,25 @@ +DİKKAT: Bu sürüm muhtemelen bir öncekinde olduğu gibi bir hata festivalidir. Ancak 17. sürümden bu yana tam kapanma nedeniyle bozuk bir sürüm, hiç sürüm olmamasından daha iyidir. Değil mi? ¯\_(ツ)_/¯ + +### İyileştirmeler +* indirilen dosyalar artık tek bir tıklama ile açılabilir #1879 +* Android 4.1 - 4.3 için desteği bırakın #1884 +* eski oynatıcıyı kaldır #1884 +* akışları sağa kaydırarak mevcut oynatma kuyruğundan kaldırın #1915 +* Yeni bir akış manuel olarak sıralandığında otomatik sıralanan akışı kaldır #1878 +* İndirmeler için postprocessing ve eksik özellikleri uygulama #1759 by @kapodamy +* İşlem sonrası altyapı +* Uygun hata işleme "altyapısı" (indirici için) +* Çoklu indirme yerine kuyruk +* Serileştirilmiş bekleyen indirmeleri (`.giga` dosyaları) uygulama verilerine taşı +* Maksimum indirme yeniden denemesini uygulayın +* Uygun çok iş parçacıklı indirme duraklatması +* Mobil ağa geçildiğinde indirmeleri durdur (asla çalışmaz, bkz. 2. nokta) +* İplik sayısını sonraki indirmeler için saklayın +* Bir çok tutarsızlık düzeltildi + +### Sabit +* Varsayılan çözünürlük en iyi ve sınırlı mobil veri çözünürlüğü olarak ayarlandığında oluşan çökme düzeltildi #1835 +* pop-up oynatıcı çökmesi düzeltildi #1874 +* Arka plan oynatıcısını açmaya çalışırken NPE #1901 +* Otomatik kuyruklama etkinleştirildiğinde yeni akışların eklenmesi için düzeltme #1878 +* deşifre sorunu düzeltildi diff --git a/fastlane/metadata/android/tr/changelogs/71.txt b/fastlane/metadata/android/tr/changelogs/71.txt new file mode 100644 index 000000000..8786821a6 --- /dev/null +++ b/fastlane/metadata/android/tr/changelogs/71.txt @@ -0,0 +1,10 @@ +### İyileştirmeler +* GitHub derlemesi için uygulama güncelleme bildirimi ekleyin (#1608 yazan @krtkush) +* İndiricide çeşitli iyileştirmeler (@kapodamy tarafından #1944): +* eksik beyaz simgeleri ekleyin ve simge renklerini değiştirmek için sert çizgili yol kullanın +* yineleyicinin başlatılıp başlatılmadığını kontrol edin (#2031'i düzeltir) +* Yeni muxer'da " işlem-sonrası başarısız" hatası ile yeniden indirme denemelerine izin verin +* Senkronize olmayan video ve ses akışlarını düzelten yeni MPEG-4 muxer (#2039) + +### Sabit +* YouTube canlı yayınları kısa bir süre sonra oynatılmayı durduruyor (#1996 by @yausername) diff --git a/fastlane/metadata/android/tr/changelogs/730.txt b/fastlane/metadata/android/tr/changelogs/730.txt new file mode 100644 index 000000000..cb6e64592 --- /dev/null +++ b/fastlane/metadata/android/tr/changelogs/730.txt @@ -0,0 +1,2 @@ +# Sabit +- Şifre çözme işlevi hatasını tekrar düzeltin. diff --git a/fastlane/metadata/android/tr/changelogs/740.txt b/fastlane/metadata/android/tr/changelogs/740.txt new file mode 100644 index 000000000..14f47d14d --- /dev/null +++ b/fastlane/metadata/android/tr/changelogs/740.txt @@ -0,0 +1,22 @@ +Sure, I can provide a Turkish translation for your list: + +**Geliştirmeler** +- Yorumlardaki bağlantıları tıklanabilir yap, metin boyutunu artır +- Zaman damgası bağlantılarına tıklanınca konumu ayarla +- Son seçilen duruma göre tercih edilen sekme göster +- Çalma listesi penceresinde 'Arka Plan' üzerine uzun tıklayarak sıraya ekle +- URL olmayan paylaşılan metni ara +- Ana video oynatıcısına 'şu anki zamanda paylaş' düğmesi ekle +- Video sırası bittiğinde ana oynatıcıya kapat düğmesi ekle +- Video listesi öğeleri için uzun tıklama menüsüne 'Arka Planda Doğrudan Oynat' ekle +- Play/Enqueue komutları için İngilizce çevirileri iyileştir +- Küçük performans iyileştirmeleri +- Kullanılmayan dosyaları kaldır +- ExoPlayer'ı 2.9.6 sürümüne güncelle +- Invidious bağlantılarına destek ekle + +**Düzeltmeler** +- Yorumlar ve ilgili akışlar devre dışı bırakıldığında kaydırma sorununu düzelt +- CheckForNewAppVersionTask'in gereksiz yürütülmesini düzelt +- Geçersiz URL'leri olan abonelikleri yok say ve başlığı boş olanları sakla +- Geçersiz YouTube URL'lerini düzelt: İmza etiket adı her zaman "signature" olmadığından akışların yüklenmesini engelle diff --git a/fastlane/metadata/android/tr/changelogs/750.txt b/fastlane/metadata/android/tr/changelogs/750.txt new file mode 100644 index 000000000..8e3a2f37f --- /dev/null +++ b/fastlane/metadata/android/tr/changelogs/750.txt @@ -0,0 +1,21 @@ +Yeni +Oynatma devam ediyor #2288 +- Akışlara en son kaldığınız yerden devam edin +İndirici Geliştirmeleri #2149 +- İndirmeleri harici SD kartlarda depolamak için Depolama Erişim Çerçevesini kullanın +- Yeni mp4 muxer +- İsteğe bağlı olarak indirme işlemine başlamadan önce indirme dizinini değiştirme +- Ölçülü ağlara saygı gösterin + +Geliştirilmiş +- Gema dizeleri kaldırıldı #2295 +- Etkinlik yaşam döngüsü sırasında (otomatik) rotasyon değişikliklerini işleme #2444 +- Uzun basma menülerini tutarlı hale getirin #2368 + +Sabit +- Seçili altyazı parça adının gösterilmemesi düzeltildi #2394 +- Uygulama güncellemesi kontrolü başarısız olduğunda çökme (GitHub sürümü) #2423 +- İndirmelerin %99,9'da takılması düzeltildi #2440 +- Oynatma kuyruğu meta verilerini güncelleme #2453 +- [SoundCloud] Çalma listeleri yüklenirken oluşan çökme düzeltildi TeamNewPipe/NewPipeExtractor#170 +- [YouTube] Sabit süre ayrıştırılamıyor TeamNewPipe/NewPipeExtractor#177 diff --git a/fastlane/metadata/android/tr/changelogs/760.txt b/fastlane/metadata/android/tr/changelogs/760.txt new file mode 100644 index 000000000..f6ca13ce6 --- /dev/null +++ b/fastlane/metadata/android/tr/changelogs/760.txt @@ -0,0 +1,40 @@ +0.17.1'deki Değişiklikler + +Yeni +- Tayca yerelleştirme + +Geliştirilmiş +- Çalma listeleri için uzun basma menülerine burada oynatmaya başla eylemini tekrar ekleyin #2518 +- SAF / eski dosya seçici için anahtar ekleyin #2521 + +Sabit +- Uygulama değiştirirken indirilenler görünümünde kaybolan düğmeleri düzeltme #2487 +- İzleme geçmişi devre dışı olmasına rağmen sabit oynatma konumu kaydedilir +- Liste görünümlerinde oynatma konumunun neden olduğu düşük performansı düzeltme #2517 +- [Extractor] ReCaptchaActivity #2527'yi düzeltin, TeamNewPipe/NewPipeExtractor#186 +- [Extractor] [YouTube] Çalma listeleri sonuçlarda olduğunda sıradan arama hatasını düzeltin TeamNewPipe/NewPipeExtractor#185 + +0.17.0'daki Değişiklikler + +Yeni +Oynatma devam ediyor #2288 +- Akışlara en son kaldığınız yerden devam edin +İndirici Geliştirmeleri #2149 +- İndirmeleri harici SD kartlarda depolamak için Depolama Erişim Çerçevesini kullanın +- Yeni mp4 muxer +- İsteğe bağlı olarak indirme işlemine başlamadan önce indirme dizinini değiştirme +- Ölçülü ağlara saygı gösterin + + +Geliştirilmiş +- Gema dizeleri kaldırıldı #2295 +- Etkinlik yaşam döngüsü sırasında (otomatik) rotasyon değişikliklerini işleme #2444 +- Uzun basma menülerini tutarlı hale getirin #2368 + +Sabit +- Seçili altyazı parça adının gösterilmemesi düzeltildi #2394 +- Uygulama güncellemesi kontrolü başarısız olduğunda çökme (GitHub sürümü) #2423 +- İndirmelerin %99,9'da takılması düzeltildi #2440 +- Oynatma kuyruğu meta verilerini güncelleme #2453 +- [SoundCloud] Çalma listeleri yüklenirken oluşan çökme düzeltildi TeamNewPipe/NewPipeExtractor#170 +- [YouTube] Sabit süre ayrıştırılamıyor TeamNewPipe/NewPipeExtractor#177 diff --git a/fastlane/metadata/android/tr/changelogs/770.txt b/fastlane/metadata/android/tr/changelogs/770.txt new file mode 100644 index 000000000..0fbf281de --- /dev/null +++ b/fastlane/metadata/android/tr/changelogs/770.txt @@ -0,0 +1,3 @@ +0.17.2'deki Değişiklikler +Düzeltme +- Düzeltme video mevcut değildi diff --git a/fastlane/metadata/android/tr/changelogs/780.txt b/fastlane/metadata/android/tr/changelogs/780.txt new file mode 100644 index 000000000..68b98d7b4 --- /dev/null +++ b/fastlane/metadata/android/tr/changelogs/780.txt @@ -0,0 +1,12 @@ +0.17.3'teki Değişiklikler + +Geliştirilmiş +- Oynatma durumlarını temizleme seçeneği eklendi #2550 +- Dosya seçicide gizli dizinleri gösterme #2591 +- NewPipe ile açılacak `invidio.us` örneklerinden URL'leri destekleyin #2488 +- music.youtube.com` URL`leri için destek ekleyin TeamNewPipe/NewPipeExtractor#194 + +Sabit +- [YouTube] 'java.lang.IllegalArgumentException #192 düzeltildi +- [YouTube] Canlı yayınların çalışmaması düzeltildi TeamNewPipe/NewPipeExtractor#195 +- Android pie'da akış indirirken yaşanan performans sorunu düzeltildi #2592 diff --git a/fastlane/metadata/android/tr/changelogs/790.txt b/fastlane/metadata/android/tr/changelogs/790.txt new file mode 100644 index 000000000..5ff443779 --- /dev/null +++ b/fastlane/metadata/android/tr/changelogs/790.txt @@ -0,0 +1,14 @@ +Geliştirilmiş +- Görme engelli kişilerin erişilebilirliğini iyileştirmek için daha fazla başlık ekleyin #2655 +- İndirme klasörü ayarının dilini daha tutarlı ve daha az belirsiz hale getirin #2637 + +Sabit +- Bloktaki son baytın indirilip indirilmediğini kontrol edin #2646 +- Video ayrıntı parçasındaki kaydırma düzeltildi #2672 +- Çift arama temizleme kutusu animasyonlarını teke indir #2695 +- [SoundCloud] Client_id çıkarma işlemini düzeltin #2745 + +Geliştirme +- NewPipeExtractor'dan miras alınan eksik bağımlılıkları NewPipe'a ekleyin #2535 +- AndroidX'e geçiş #2685 +- ExoPlayer 2.10.6 #2697, #2736 için güncelleme diff --git a/fastlane/metadata/android/tr/full_description.txt b/fastlane/metadata/android/tr/full_description.txt index 11daef85b..9422ff2ba 100644 --- a/fastlane/metadata/android/tr/full_description.txt +++ b/fastlane/metadata/android/tr/full_description.txt @@ -1,2 +1,2 @@ -NewPipe herhangi bir Google çerçeve kütüphanesi veya YouTube API'ı kullanmaz. Sadece, ihtiyaç duyduğu bilgiyi edinmek için web sitesini ayrıştırır. +NewPipe herhangi bir Google frameworkü veya YouTube API'si kullanmaz. Sadece, ihtiyaç duyduğu bilgiyi edinmek için web sitesini ayrıştırır. Bu nedenle Google hizmetlerinin kurulmadığı aygıtlarda kullanılabilir. Ayrıca, NewPipe'ı kullanırken YouTube hesabına ihtiyacınız yok, ve bu özgür ve açık kaynaklı bir yazılımdır. diff --git a/fastlane/metadata/android/vi/changelogs/65.txt b/fastlane/metadata/android/vi/changelogs/65.txt new file mode 100644 index 000000000..3bffa51b0 --- /dev/null +++ b/fastlane/metadata/android/vi/changelogs/65.txt @@ -0,0 +1,9 @@ +##Cải thiện: + +- Tắt hoạt ảnh icon burgermenu #1486 +- Cho phép hoàn tắc nội dung đã tải xuống #1472 +- Tùy chọn tải xuống ở menu chia sẻ #1498 +- Đã thêm tùy chọn chia sẻ vào menu nhẫn giữ #1454 +- Thu nhỏ bộ phát phương tiện chính khi thoát #1354 +- Sửa lỗi Cập nhật thư viện và cơ sở dữ liệu dự phòng #1510 +- Cập nhật trình phát ExoPlayer 2.8.2 #1392 diff --git a/fastlane/metadata/android/vi/changelogs/987.txt b/fastlane/metadata/android/vi/changelogs/987.txt new file mode 100644 index 000000000..776bf53f7 --- /dev/null +++ b/fastlane/metadata/android/vi/changelogs/987.txt @@ -0,0 +1,12 @@ +Mới +• Hỗ trợ các phương thức phân phối khác ngoài HTTP lũy tiến: thời gian tải nhanh hơn, sửa lỗi cho PeerTube và SoundCloud, phát lại các luồng trực tiếp YouTube đã kết thúc gần đây +• Thêm nút để thêm danh sách phát từ xa vào danh sách phát cục bộ +• Xem trước hình ảnh trong bảng chia sẻ Android 10+ + +Cải thiện +• Cải thiện hộp thoại thông số phát lại +• Di chuyển các nút nhập / xuất đăng ký sang menu ba chấm + +Cố định +• Khắc phục sự cố xóa video đã xem đầy đủ khỏi danh sách phát +• Sửa chủ đề thực đơn chia sẻ và mục "thêm vào danh sách phát" diff --git a/fastlane/metadata/android/vi/changelogs/988.txt b/fastlane/metadata/android/vi/changelogs/988.txt new file mode 100644 index 000000000..545f3c7b4 --- /dev/null +++ b/fastlane/metadata/android/vi/changelogs/988.txt @@ -0,0 +1,2 @@ +[YouTube] Sửa lỗi “Không thể nhận bất kỳ luồng nào” khi cố gắng phát bất kỳ video nào +[YouTube] Khắc phục thông báo hiển thị “Nội dung sau không có sẵn trên ứng dụng này.” thay vì video được yêu cầu diff --git a/fastlane/metadata/android/vi/changelogs/989.txt b/fastlane/metadata/android/vi/changelogs/989.txt new file mode 100644 index 000000000..542db61c7 --- /dev/null +++ b/fastlane/metadata/android/vi/changelogs/989.txt @@ -0,0 +1,3 @@ +• [YouTube] Sửa lỗi tải vô hạn khi cố gắng phát bất kỳ video nào +• [YouTube] Sửa lỗi điều tiết trên một số video +• Nâng cấp thư viện jsoup lên 1.15.3, bao gồm bản sửa lỗi bảo mật diff --git a/fastlane/metadata/android/vi/changelogs/990.txt b/fastlane/metadata/android/vi/changelogs/990.txt new file mode 100644 index 000000000..c867f31dd --- /dev/null +++ b/fastlane/metadata/android/vi/changelogs/990.txt @@ -0,0 +1,15 @@ +Hiện tại hỗ trợ phiên bản tối thiểu là Android 5 Lollipop! + +Mới +• Tải xuống từ menu nhấn và giữ +• Ẩn các video trong tương lai trong nguồn cấp dữ liệu +• Chia sẻ danh sách phát địa phương + +Cải thiện +• Tái cấu trúc mã trình phát.. +• Cải thiện chế độ chia tỷ lệ của hình thu nhỏ +• Trình giữ chỗ hình ảnh theo kiểu vector hóa + +Khắc phục +• Khắc phục nhiều vấn đề khác nhau với thông báo trình phát: thông tin phương tiện lỗi thời/bị thiếu, hình thu nhỏ bị méo +• Sửa toàn màn hình bằng 1/4 màn hình diff --git a/fastlane/metadata/android/vi/changelogs/991.txt b/fastlane/metadata/android/vi/changelogs/991.txt new file mode 100644 index 000000000..8ffaf1551 --- /dev/null +++ b/fastlane/metadata/android/vi/changelogs/991.txt @@ -0,0 +1,13 @@ +Mới +• Thêm nút "Mở trong trình duyệt" trong bảng lỗi +• Thêm tùy chọn hiển thị nhóm kênh dạng danh sách +• [YouTube] Nhấp và giữ vào các phân đoạn phát trực tuyến để chia sẻ URL dấu thời gian +• Thêm nút xếp hàng phát vào trình phát mini + +Cải thiện +• Thêm bản địa hóa tiếng Iceland và cập nhật nhiều bản dịch khác +• Nhiều cải tiến nội bộ + +Sửa chữa +• Khắc phục nhiều sự cố +• [YouTube] Khắc phục sự cố tải kênh, nguồn cấp dữ liệu không chuyên dụng và giải pháp khắc phục sự cố phát lại ở một số quốc gia diff --git a/fastlane/metadata/android/vi/changelogs/994.txt b/fastlane/metadata/android/vi/changelogs/994.txt new file mode 100644 index 000000000..e73fcb20a --- /dev/null +++ b/fastlane/metadata/android/vi/changelogs/994.txt @@ -0,0 +1,15 @@ +Mới +• Hỗ trợ nhiều bản âm thanh/ngôn ngữ +• Cho phép cài đặt cử chỉ âm lượng và độ sáng ở bất kỳ phía nào của màn hình +• Hỗ trợ hiển thị các tab chính ở cuối màn hình + +Cải thiện +• [Bandcamp] Xử lý các dấu vết đằng sau bức tường phí + +Đã sửa +• [YouTube] Lỗi HTTP 403 cho luồng +• Trình phát màu đen khi chuyển sang trình phát chính từ chế độ xem danh sách phát +• Rò rỉ bộ nhớ dịch vụ trình phát +• [PeerTube] Hình đại diện của người tải lên và kênh con đã bị hoán đổi + +và hơn thế nữa diff --git a/fastlane/metadata/android/vi/changelogs/995.txt b/fastlane/metadata/android/vi/changelogs/995.txt new file mode 100644 index 000000000..69b616883 --- /dev/null +++ b/fastlane/metadata/android/vi/changelogs/995.txt @@ -0,0 +1,14 @@ +Mới +• Hỗ trợ tab kênh +• Chọn chất lượng hình ảnh +• Nhận URL cho tất cả hình ảnh + +Cải thiện +• Khả năng truy cập của giao diện trình phát +• Tùy chọn thêm tên danh sách phát và tên video vào nội dung chia sẻ danh sách phát +• Cải tiến nội bộ và cập nhật phụ thuộc + +Đã sửa +• Lựa chọn ngôn ngữ sai trong bộ chọn ngôn ngữ +• Tiêu điểm âm thanh của trình phát không bị tắt tiếng +• Thêm mục vào danh sách phát không hoạt động trong các trường hợp cụ thể diff --git a/fastlane/metadata/android/zh_Hant_HK/changelogs/994.txt b/fastlane/metadata/android/zh_Hant_HK/changelogs/994.txt new file mode 100644 index 000000000..dcc635e90 --- /dev/null +++ b/fastlane/metadata/android/zh_Hant_HK/changelogs/994.txt @@ -0,0 +1,15 @@ +新嘢 +• 支援多重音軌/語言 +• 螢幕嘅音量同光暗手勢設定有得分左右 +• 主畫面嘅分頁揀選有得搬落最低 + +進步 +• [Bandcamp] 處理收費閘之下嘅曲目 + +修正 +• [YouTube] 串流出現 403 HTTP 錯誤 +• 播放清單版面轉去主版面播放器時播放器冇嘢睇 +• 播放器服務記憶體洩漏 +• [PeerTube] 上載者同子頻道頭像調轉咗 + +其餘不贅 diff --git a/fastlane/metadata/android/zh_Hant_HK/changelogs/995.txt b/fastlane/metadata/android/zh_Hant_HK/changelogs/995.txt new file mode 100644 index 000000000..ddd775f08 --- /dev/null +++ b/fastlane/metadata/android/zh_Hant_HK/changelogs/995.txt @@ -0,0 +1,14 @@ +新嘢 +• 支援頻道分頁 +• 啲圖有得揀畫質 +• 啲圖全部都有得攞返個 URL + +進步 +• 播放器介面暢易達 +• 分享播放清單有得加埋播放清單個名同入面啲片名 +• 內部提昇以及依賴元件更新 + +修正 +• 揀選版面語言揀錯文 +• 播放器聲音焦點無視噤聲 +• 加入項目去播放清單有時唔得 From 35c1dfd145d26cd408dc87c0e36ba8433fdfdbe8 Mon Sep 17 00:00:00 2001 From: Stypox Date: Sun, 10 Dec 2023 15:05:29 +0100 Subject: [PATCH 161/172] Update changelog for NewPipe 0.26.0 (995) --- fastlane/metadata/android/en-US/changelogs/995.txt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/fastlane/metadata/android/en-US/changelogs/995.txt b/fastlane/metadata/android/en-US/changelogs/995.txt index fe47aae1e..78e0770f7 100644 --- a/fastlane/metadata/android/en-US/changelogs/995.txt +++ b/fastlane/metadata/android/en-US/changelogs/995.txt @@ -5,10 +5,12 @@ New Improved • Accessibility of player interfaces -• Option to option to add playlist name and video name to playlist sharing content -• Internal improvements and dependencies updates +• Better audio selection for video-only downloads +• Option to include playlist and video names to shared playlist content Fixed +• [YouTube] Fix getting like count +• Fix player not responding popups and crashes • Selection of wrong languages in language picker • Player audio focus was not respecting mute -• Adding items to playlists not working in specific cases +• Playlist item addition occasionally not working \ No newline at end of file From 0d8d3479e12238ab31cd1130b6cf0c99b8f057d1 Mon Sep 17 00:00:00 2001 From: TobiGr Date: Thu, 5 Oct 2023 14:52:27 +0200 Subject: [PATCH 162/172] NewPipe 0.26.0 (995) --- app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 7b69b5b72..f1ec6ed51 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -20,8 +20,8 @@ android { resValue "string", "app_name", "NewPipe" minSdk 21 targetSdk 33 - versionCode 994 - versionName "0.25.2" + versionCode 995 + versionName "0.26.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" From e6965622bd55fc5a9f656a7193c8061116f5364e Mon Sep 17 00:00:00 2001 From: TobiGr Date: Sat, 7 Oct 2023 14:34:44 +0200 Subject: [PATCH 163/172] Fix crash with disabled thumbnails when trying to play a stream --- .../java/org/schabi/newpipe/player/mediaitem/MediaItemTag.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/schabi/newpipe/player/mediaitem/MediaItemTag.java b/app/src/main/java/org/schabi/newpipe/player/mediaitem/MediaItemTag.java index 1119fb903..346bb92fa 100644 --- a/app/src/main/java/org/schabi/newpipe/player/mediaitem/MediaItemTag.java +++ b/app/src/main/java/org/schabi/newpipe/player/mediaitem/MediaItemTag.java @@ -81,8 +81,9 @@ public interface MediaItemTag { @NonNull default MediaItem asMediaItem() { + final String thumbnailUrl = getThumbnailUrl(); final MediaMetadata mediaMetadata = new MediaMetadata.Builder() - .setArtworkUri(Uri.parse(getThumbnailUrl())) + .setArtworkUri(thumbnailUrl == null ? null : Uri.parse(thumbnailUrl)) .setArtist(getUploaderName()) .setDescription(getTitle()) .setDisplayTitle(getTitle()) From e39ac885de7ec5bc530d920ef021b2a785e95fc5 Mon Sep 17 00:00:00 2001 From: TobiGr Date: Thu, 19 Oct 2023 11:38:39 +0200 Subject: [PATCH 164/172] Update new version check to match new API structure See TeamNewPipe/web-api#17 --- .../main/java/org/schabi/newpipe/NewVersionWorker.kt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/NewVersionWorker.kt b/app/src/main/java/org/schabi/newpipe/NewVersionWorker.kt index c46dd6348..39d8e90dc 100644 --- a/app/src/main/java/org/schabi/newpipe/NewVersionWorker.kt +++ b/app/src/main/java/org/schabi/newpipe/NewVersionWorker.kt @@ -120,13 +120,13 @@ class NewVersionWorker( // Parse the json from the response. try { - val githubStableObject = JsonParser.`object`() + val newpipeVersionInfo = JsonParser.`object`() .from(response.responseBody()).getObject("flavors") - .getObject("github").getObject("stable") + .getObject("newpipe") - val versionName = githubStableObject.getString("version") - val versionCode = githubStableObject.getInt("version_code") - val apkLocationUrl = githubStableObject.getString("apk") + val versionName = newpipeVersionInfo.getString("version") + val versionCode = newpipeVersionInfo.getInt("version_code") + val apkLocationUrl = newpipeVersionInfo.getString("apk") compareAppVersionAndShowNotification(versionName, apkLocationUrl, versionCode) } catch (e: JsonParserException) { // Most likely something is wrong in data received from NEWPIPE_API_URL. From 8d59812827a3993fcdd3d322100e7f053bcca96b Mon Sep 17 00:00:00 2001 From: Stypox Date: Thu, 16 Nov 2023 22:46:43 +0100 Subject: [PATCH 165/172] Fix channel avatar not loading correctly sometimes The fix just involves removing some really outdated code (6 years ago) added in https://github.com/TeamNewPipe/NewPipe/commit/33e29be7db2e4a6fcd23e411081c871bf3c4b5c3#diff-38bd2cf1b92659b499c08e1cf6ac9ef384c7e13381b906f2f98c57cbb758756dR778 (blame: https://github.com/TeamNewPipe/NewPipe/blame/9318bb530619898c1e1f3f8a8c866f3d2e35ab0c/app/src/main/java/org/schabi/newpipe/detail/VideoItemDetailActivity.java#L778). What that code did was setting the 'buddy' image to the uploader avatar as a placeholder, and then setting the actual image if it existed and after it had loaded. That code remained there up until now, but now it doesn't make sense anymore, since Picasso already takes care of setting placeholders. The problem is, starting from #10066 the actual uploader image is set before (not after) those lines of code, making them do the wrong thing, i.e. always overwrite the currently set image. But then why did the channel avatar image work normally sometimes? My guess is that since Picasso loads images in the background, when opening a video from scratch setting the placeholder still happened before Picasso finished loading the image. However when the image is already cached it's loaded much faster and therefore setting the placeholder happens after, effectively hiding the loaded image. --- .../newpipe/fragments/detail/VideoDetailFragment.java | 6 ------ 1 file changed, 6 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java index a25d0fae4..7db5e0251 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java @@ -24,7 +24,6 @@ import android.content.pm.ActivityInfo; import android.database.ContentObserver; import android.graphics.Color; import android.graphics.Rect; -import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Build; import android.os.Bundle; @@ -1482,11 +1481,6 @@ public final class VideoDetailFragment displayUploaderAsSubChannel(info); } - final Drawable buddyDrawable = - AppCompatResources.getDrawable(activity, R.drawable.placeholder_person); - binding.detailSubChannelThumbnailView.setImageDrawable(buddyDrawable); - binding.detailUploaderThumbnailView.setImageDrawable(buddyDrawable); - if (info.getViewCount() >= 0) { if (info.getStreamType().equals(StreamType.AUDIO_LIVE_STREAM)) { binding.detailViewCountView.setText(Localization.listeningCount(activity, From e876647af56433bf6021637b08ea2bb19c9b1cac Mon Sep 17 00:00:00 2001 From: Stypox Date: Sun, 10 Dec 2023 15:58:45 +0100 Subject: [PATCH 166/172] Update NewPipeExtractor to v0.23.0 --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index f1ec6ed51..ef1d1fe87 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -197,7 +197,7 @@ dependencies { // name and the commit hash with the commit hash of the (pushed) commit you want to test // This works thanks to JitPack: https://jitpack.io/ implementation 'com.github.TeamNewPipe:nanojson:1d9e1aea9049fc9f85e68b43ba39fe7be1c1f751' - implementation 'com.github.TeamNewPipe:NewPipeExtractor:289db1178ab66694c23893e6a487d4708343c47b' + implementation 'com.github.TeamNewPipe:NewPipeExtractor:v0.23.0' implementation 'com.github.TeamNewPipe:NoNonsense-FilePicker:5.0.0' /** Checkstyle **/ From b871b5d2dde0bfa87a0e8e970ebbe1602bb0fe3f Mon Sep 17 00:00:00 2001 From: Stypox Date: Sun, 10 Dec 2023 16:06:07 +0100 Subject: [PATCH 167/172] Fix crashes due to wrong root fragment manager --- .../java/org/schabi/newpipe/BaseFragment.java | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/BaseFragment.java b/app/src/main/java/org/schabi/newpipe/BaseFragment.java index 5dde2a747..7a06771dd 100644 --- a/app/src/main/java/org/schabi/newpipe/BaseFragment.java +++ b/app/src/main/java/org/schabi/newpipe/BaseFragment.java @@ -120,9 +120,20 @@ public abstract class BaseFragment extends Fragment { } } + /** + * Finds the root fragment by looping through all of the parent fragments. The root fragment + * is supposed to be {@link org.schabi.newpipe.fragments.MainFragment}, and is the fragment that + * handles keeping the backstack of opened fragments in NewPipe, and also the player bottom + * sheet. This function therefore returns the fragment manager of said fragment. + * + * @return the fragment manager of the root fragment, i.e. + * {@link org.schabi.newpipe.fragments.MainFragment} + */ protected FragmentManager getFM() { - return getParentFragment() == null - ? getFragmentManager() - : getParentFragment().getFragmentManager(); + Fragment current = this; + while (current.getParentFragment() != null) { + current = current.getParentFragment(); + } + return current.getFragmentManager(); } } From 80f33daeeb246ee548dc707d3798ae382d137079 Mon Sep 17 00:00:00 2001 From: Stypox Date: Wed, 20 Dec 2023 20:22:45 +0100 Subject: [PATCH 168/172] Fix OutOfMemory when fetching feed Reduced memory footprint of FeedUpdateInfo objects. Those objects might stay around for a while and accumulate (up to BUFFER_COUNT_BEFORE_INSERT = 20 at the moment), so in order not to fill up the memory it's better to keep as little data as possible. Previously ChannelInfo data was stored, causing ReadyChannelTabLinkHandler objects to be also stored uselessly (and those channel tabs contain prefetched JSON data which used ~700KB of memory). --- .../feed/notifications/NotificationHelper.kt | 8 ++--- .../local/feed/service/FeedLoadManager.kt | 4 +-- .../local/feed/service/FeedUpdateInfo.kt | 31 +++++++++++++++---- .../local/subscription/SubscriptionManager.kt | 23 ++++++-------- 4 files changed, 40 insertions(+), 26 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/local/feed/notifications/NotificationHelper.kt b/app/src/main/java/org/schabi/newpipe/local/feed/notifications/NotificationHelper.kt index 9f7553e1f..8ea89368d 100644 --- a/app/src/main/java/org/schabi/newpipe/local/feed/notifications/NotificationHelper.kt +++ b/app/src/main/java/org/schabi/newpipe/local/feed/notifications/NotificationHelper.kt @@ -58,7 +58,7 @@ class NotificationHelper(val context: Context) { .setAutoCancel(true) .setCategory(NotificationCompat.CATEGORY_SOCIAL) .setGroupSummary(true) - .setGroup(data.originalInfo.url) + .setGroup(data.url) .setGroupAlertBehavior(NotificationCompat.GROUP_ALERT_SUMMARY) // Build a summary notification for Android versions < 7.0 @@ -73,7 +73,7 @@ class NotificationHelper(val context: Context) { context, data.pseudoId, NavigationHelper - .getChannelIntent(context, data.originalInfo.serviceId, data.originalInfo.url) + .getChannelIntent(context, data.serviceId, data.url) .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK), 0, false @@ -88,7 +88,7 @@ class NotificationHelper(val context: Context) { // Show individual stream notifications, set channel icon only if there is actually // one - showStreamNotifications(newStreams, data.originalInfo.serviceId, bitmap) + showStreamNotifications(newStreams, data.serviceId, bitmap) // Show summary notification manager.notify(data.pseudoId, summaryBuilder.build()) @@ -97,7 +97,7 @@ class NotificationHelper(val context: Context) { override fun onBitmapFailed(e: Exception, errorDrawable: Drawable) { // Show individual stream notifications - showStreamNotifications(newStreams, data.originalInfo.serviceId, null) + showStreamNotifications(newStreams, data.serviceId, null) // Show summary notification manager.notify(data.pseudoId, summaryBuilder.build()) iconLoadingTargets.remove(this) // allow it to be garbage-collected diff --git a/app/src/main/java/org/schabi/newpipe/local/feed/service/FeedLoadManager.kt b/app/src/main/java/org/schabi/newpipe/local/feed/service/FeedLoadManager.kt index b86c856fc..0b6a8068c 100644 --- a/app/src/main/java/org/schabi/newpipe/local/feed/service/FeedLoadManager.kt +++ b/app/src/main/java/org/schabi/newpipe/local/feed/service/FeedLoadManager.kt @@ -277,14 +277,14 @@ class FeedLoadManager(private val context: Context) { notification.value!!.newStreams = filterNewStreams(info.streams) feedDatabaseManager.upsertAll(info.uid, info.streams) - subscriptionManager.updateFromInfo(info.uid, info.originalInfo) + subscriptionManager.updateFromInfo(info) if (info.errors.isNotEmpty()) { feedResultsHolder.addErrors( info.errors.map { FeedLoadService.RequestException( info.uid, - "${info.originalInfo.serviceId}:${info.originalInfo.url}", + "${info.serviceId}:${info.url}", it ) } diff --git a/app/src/main/java/org/schabi/newpipe/local/feed/service/FeedUpdateInfo.kt b/app/src/main/java/org/schabi/newpipe/local/feed/service/FeedUpdateInfo.kt index 12fbe8d41..84cd8ed59 100644 --- a/app/src/main/java/org/schabi/newpipe/local/feed/service/FeedUpdateInfo.kt +++ b/app/src/main/java/org/schabi/newpipe/local/feed/service/FeedUpdateInfo.kt @@ -3,29 +3,48 @@ package org.schabi.newpipe.local.feed.service import org.schabi.newpipe.database.subscription.NotificationMode import org.schabi.newpipe.database.subscription.SubscriptionEntity import org.schabi.newpipe.extractor.Info +import org.schabi.newpipe.extractor.channel.ChannelInfo import org.schabi.newpipe.extractor.stream.StreamInfoItem +import org.schabi.newpipe.util.image.ImageStrategy +/** + * Instances of this class might stay around in memory for some time while fetching the feed, + * because of [FeedLoadManager.BUFFER_COUNT_BEFORE_INSERT]. Therefore this class should contain + * as little data as possible to avoid out of memory errors. In particular, avoid storing whole + * [ChannelInfo] objects, as they might contain raw JSON info in ready channel tabs link handlers. + */ data class FeedUpdateInfo( val uid: Long, @NotificationMode val notificationMode: Int, val name: String, val avatarUrl: String, - val originalInfo: Info, + val url: String, + val serviceId: Int, + // description and subscriberCount are null if the constructor info is from the fast feed method + val description: String?, + val subscriberCount: Long?, val streams: List, val errors: List, ) { constructor( subscription: SubscriptionEntity, - originalInfo: Info, + info: Info, streams: List, errors: List, ) : this( uid = subscription.uid, notificationMode = subscription.notificationMode, - name = subscription.name, - avatarUrl = subscription.avatarUrl, - originalInfo = originalInfo, + name = info.name, + avatarUrl = (info as? ChannelInfo)?.avatars?.let { + // if the newly fetched info is not from fast feed, then it contains updated avatars + ImageStrategy.imageListToDbUrl(it) + } ?: subscription.avatarUrl, + url = info.url, + serviceId = info.serviceId, + // there is no description and subscriberCount in the fast feed + description = (info as? ChannelInfo)?.description, + subscriberCount = (info as? ChannelInfo)?.subscriberCount, streams = streams, errors = errors, ) @@ -34,7 +53,7 @@ data class FeedUpdateInfo( * Integer id, can be used as notification id, etc. */ val pseudoId: Int - get() = originalInfo.url.hashCode() + get() = url.hashCode() lateinit var newStreams: List } diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionManager.kt b/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionManager.kt index bd42bbe41..488d8b3d2 100644 --- a/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionManager.kt +++ b/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionManager.kt @@ -12,12 +12,11 @@ import org.schabi.newpipe.database.stream.model.StreamEntity import org.schabi.newpipe.database.subscription.NotificationMode import org.schabi.newpipe.database.subscription.SubscriptionDAO import org.schabi.newpipe.database.subscription.SubscriptionEntity -import org.schabi.newpipe.extractor.Info import org.schabi.newpipe.extractor.channel.ChannelInfo import org.schabi.newpipe.extractor.channel.tabs.ChannelTabInfo -import org.schabi.newpipe.extractor.feed.FeedInfo import org.schabi.newpipe.extractor.stream.StreamInfoItem import org.schabi.newpipe.local.feed.FeedDatabaseManager +import org.schabi.newpipe.local.feed.service.FeedUpdateInfo import org.schabi.newpipe.util.ExtractorHelper import org.schabi.newpipe.util.image.ImageStrategy @@ -97,19 +96,15 @@ class SubscriptionManager(context: Context) { } } - fun updateFromInfo(subscriptionId: Long, info: Info) { - val subscriptionEntity = subscriptionTable.getSubscription(subscriptionId) + fun updateFromInfo(info: FeedUpdateInfo) { + val subscriptionEntity = subscriptionTable.getSubscription(info.uid) - if (info is FeedInfo) { - subscriptionEntity.name = info.name - } else if (info is ChannelInfo) { - subscriptionEntity.setData( - info.name, - ImageStrategy.imageListToDbUrl(info.avatars), - info.description, - info.subscriberCount - ) - } + subscriptionEntity.name = info.name + subscriptionEntity.avatarUrl = info.avatarUrl + + // these two fields are null if the feed info was fetched using the fast feed method + info.description?.let { subscriptionEntity.description = it } + info.subscriberCount?.let { subscriptionEntity.subscriberCount = it } subscriptionTable.update(subscriptionEntity) } From c0f8d145f83b852ebd4fa7e407da26754e379936 Mon Sep 17 00:00:00 2001 From: Stypox Date: Wed, 20 Dec 2023 22:46:24 +0100 Subject: [PATCH 169/172] Fix lag with many channels on main page Disable loading all tabs at once, since there can be many of them, and use default strategy of only keeping in memory the two tabs adjacent to the current tab. --- app/src/main/java/org/schabi/newpipe/fragments/MainFragment.java | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/main/java/org/schabi/newpipe/fragments/MainFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/MainFragment.java index 96b13922b..d50f0b0d8 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/MainFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/MainFragment.java @@ -194,7 +194,6 @@ public class MainFragment extends BaseFragment implements TabLayout.OnTabSelecte } binding.pager.setAdapter(null); - binding.pager.setOffscreenPageLimit(tabsList.size()); binding.pager.setAdapter(pagerAdapter); updateTabsIconAndDescription(); From 495c9850b486c79a6b5cbd272554c0718d2b285e Mon Sep 17 00:00:00 2001 From: Stypox Date: Wed, 20 Dec 2023 23:57:43 +0100 Subject: [PATCH 170/172] Fix transaction too large for channel tab fragments --- .../list/channel/ChannelTabFragment.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelTabFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelTabFragment.java index 8712ab4d9..76849d94d 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelTabFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelTabFragment.java @@ -1,6 +1,7 @@ package org.schabi.newpipe.fragments.list.channel; import android.os.Bundle; +import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -14,7 +15,9 @@ import org.schabi.newpipe.error.UserAction; import org.schabi.newpipe.extractor.InfoItem; import org.schabi.newpipe.extractor.ListExtractor; import org.schabi.newpipe.extractor.channel.tabs.ChannelTabInfo; +import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler; +import org.schabi.newpipe.extractor.linkhandler.ReadyChannelTabListLinkHandler; import org.schabi.newpipe.extractor.stream.StreamInfoItem; import org.schabi.newpipe.fragments.list.BaseListInfoFragment; import org.schabi.newpipe.fragments.list.playlist.PlaylistControlViewHolder; @@ -114,6 +117,27 @@ public class ChannelTabFragment extends BaseListInfoFragment Date: Thu, 21 Dec 2023 22:28:09 +0100 Subject: [PATCH 171/172] Update NewPipeExtractor to v0.23.1 --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index ef1d1fe87..993363e32 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -197,7 +197,7 @@ dependencies { // name and the commit hash with the commit hash of the (pushed) commit you want to test // This works thanks to JitPack: https://jitpack.io/ implementation 'com.github.TeamNewPipe:nanojson:1d9e1aea9049fc9f85e68b43ba39fe7be1c1f751' - implementation 'com.github.TeamNewPipe:NewPipeExtractor:v0.23.0' + implementation 'com.github.TeamNewPipe:NewPipeExtractor:v0.23.1' implementation 'com.github.TeamNewPipe:NoNonsense-FilePicker:5.0.0' /** Checkstyle **/ From 9aff49bd880cf9d0d9c04b192fc752c573298dc4 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Thu, 21 Dec 2023 22:36:13 +0100 Subject: [PATCH 172/172] Translated using Weblate (Portuguese (Portugal)) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 100.0% (725 of 725 strings) Translated using Weblate (Danish) Currently translated at 88.2% (640 of 725 strings) Translated using Weblate (Serbian) Currently translated at 17.1% (13 of 76 strings) Translated using Weblate (Indonesian) Currently translated at 100.0% (76 of 76 strings) Translated using Weblate (Ukrainian) Currently translated at 100.0% (76 of 76 strings) Translated using Weblate (Filipino) Currently translated at 32.1% (233 of 725 strings) Translated using Weblate (Indonesian) Currently translated at 100.0% (725 of 725 strings) Translated using Weblate (Romanian) Currently translated at 99.4% (721 of 725 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (76 of 76 strings) Translated using Weblate (Indonesian) Currently translated at 97.3% (74 of 76 strings) Translated using Weblate (Arabic (Libya)) Currently translated at 100.0% (725 of 725 strings) Translated using Weblate (French) Currently translated at 100.0% (725 of 725 strings) Translated using Weblate (Arabic) Currently translated at 100.0% (76 of 76 strings) Translated using Weblate (Italian) Currently translated at 100.0% (76 of 76 strings) Translated using Weblate (Polish) Currently translated at 61.8% (47 of 76 strings) Translated using Weblate (Hindi) Currently translated at 100.0% (76 of 76 strings) Translated using Weblate (Punjabi) Currently translated at 100.0% (76 of 76 strings) Translated using Weblate (Czech) Currently translated at 100.0% (76 of 76 strings) Translated using Weblate (Portuguese (Brazil)) Currently translated at 28.9% (22 of 76 strings) Translated using Weblate (German) Currently translated at 81.5% (62 of 76 strings) Merge branch 'origin/dev' into Weblate. Translated using Weblate (Bengali) Currently translated at 78.7% (571 of 725 strings) Translated using Weblate (Basque) Currently translated at 95.0% (689 of 725 strings) Translated using Weblate (Turkish) Currently translated at 43.4% (33 of 76 strings) Translated using Weblate (Lithuanian) Currently translated at 92.9% (674 of 725 strings) Translated using Weblate (Portuguese (Brazil)) Currently translated at 30.2% (23 of 76 strings) Translated using Weblate (Swedish) Currently translated at 100.0% (725 of 725 strings) Translated using Weblate (Swedish) Currently translated at 100.0% (725 of 725 strings) Translated using Weblate (Portuguese (Brazil)) Currently translated at 99.8% (724 of 725 strings) Translated using Weblate (Interlingua) Currently translated at 32.0% (232 of 725 strings) Translated using Weblate (Norwegian Bokmål) Currently translated at 94.6% (686 of 725 strings) Translated using Weblate (Norwegian Bokmål) Currently translated at 94.6% (686 of 725 strings) Translated using Weblate (Romanian) Currently translated at 89.3% (648 of 725 strings) Translated using Weblate (German) Currently translated at 81.5% (62 of 76 strings) Translated using Weblate (German) Currently translated at 100.0% (725 of 725 strings) Translated using Weblate (Filipino) Currently translated at 32.1% (233 of 725 strings) Translated using Weblate (Filipino) Currently translated at 32.1% (233 of 725 strings) Translated using Weblate (Vietnamese) Currently translated at 100.0% (725 of 725 strings) Translated using Weblate (Swedish) Currently translated at 72.3% (55 of 76 strings) Translated using Weblate (Esperanto) Currently translated at 3.9% (3 of 76 strings) Translated using Weblate (Swedish) Currently translated at 99.7% (723 of 725 strings) Translated using Weblate (Esperanto) Currently translated at 71.0% (515 of 725 strings) Translated using Weblate (Esperanto) Currently translated at 2.6% (2 of 76 strings) Translated using Weblate (Tigrinya) Currently translated at 8.4% (61 of 725 strings) Translated using Weblate (Vietnamese) Currently translated at 43.4% (33 of 76 strings) Translated using Weblate (German) Currently translated at 81.5% (62 of 76 strings) Translated using Weblate (Finnish) Currently translated at 98.3% (713 of 725 strings) Translated using Weblate (Vietnamese) Currently translated at 100.0% (725 of 725 strings) Translated using Weblate (Esperanto) Currently translated at 70.0% (508 of 725 strings) Added translation using Weblate (English (Old)) Added translation using Weblate (Aymara) Added translation using Weblate (English (Middle)) Added translation using Weblate (Arabic (Najdi)) Added translation using Weblate (German (Low)) Added translation using Weblate (Sicilian) Added translation using Weblate (Kashmiri) Added translation using Weblate (Burmese) Translated using Weblate (Tigrinya) Currently translated at 3.5% (26 of 725 strings) Translated using Weblate (Georgian) Currently translated at 91.1% (661 of 725 strings) Translated using Weblate (French) Currently translated at 98.8% (717 of 725 strings) Translated using Weblate (Vietnamese) Currently translated at 42.1% (32 of 76 strings) Translated using Weblate (Vietnamese) Currently translated at 100.0% (725 of 725 strings) Translated using Weblate (Interlingua) Currently translated at 31.3% (227 of 725 strings) Translated using Weblate (Vietnamese) Currently translated at 35.5% (27 of 76 strings) Translated using Weblate (Esperanto) Currently translated at 69.2% (502 of 725 strings) Translated using Weblate (Esperanto) Currently translated at 69.2% (502 of 725 strings) Translated using Weblate (German) Currently translated at 81.5% (62 of 76 strings) Translated using Weblate (Punjabi) Currently translated at 100.0% (725 of 725 strings) Translated using Weblate (Bulgarian) Currently translated at 63.8% (463 of 725 strings) Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (725 of 725 strings) Translated using Weblate (Esperanto) Currently translated at 66.3% (481 of 725 strings) Translated using Weblate (French) Currently translated at 98.6% (715 of 725 strings) Translated using Weblate (Vietnamese) Currently translated at 100.0% (725 of 725 strings) Translated using Weblate (Turkish) Currently translated at 31.5% (24 of 76 strings) Translated using Weblate (Vietnamese) Currently translated at 97.3% (706 of 725 strings) Translated using Weblate (Swedish) Currently translated at 98.4% (714 of 725 strings) Translated using Weblate (Turkish) Currently translated at 100.0% (725 of 725 strings) Translated using Weblate (Turkish) Currently translated at 100.0% (725 of 725 strings) Translated using Weblate (Portuguese) Currently translated at 100.0% (76 of 76 strings) Translated using Weblate (Russian) Currently translated at 100.0% (76 of 76 strings) Translated using Weblate (Vietnamese) Currently translated at 94.6% (686 of 725 strings) Translated using Weblate (Portuguese) Currently translated at 100.0% (76 of 76 strings) Translated using Weblate (Chinese (Traditional, Hong Kong)) Currently translated at 21.0% (16 of 76 strings) Translated using Weblate (Chinese (Traditional, Hong Kong)) Currently translated at 100.0% (725 of 725 strings) Translated using Weblate (French) Currently translated at 98.2% (712 of 725 strings) Deleted translation using Weblate (English (Middle)) Co-authored-by: /dev/urandom Co-authored-by: A Co-authored-by: Agnieszka C Co-authored-by: Aitor Salaberria Co-authored-by: Alexthegib Co-authored-by: Allan Nordhøy Co-authored-by: Ans Virlis Co-authored-by: AudricV Co-authored-by: ButterflyOfFire Co-authored-by: Cem TÜRKER Co-authored-by: Danr Co-authored-by: David Svane Co-authored-by: Edward Co-authored-by: Erik Matson Co-authored-by: Fjuro Co-authored-by: Giorgi Taba K'obakhidze Co-authored-by: Hosted Weblate Co-authored-by: Ihfandi Co-authored-by: Ihor Hordiichuk Co-authored-by: Jener Gomes Co-authored-by: Kristoffer Grundström Co-authored-by: LiftedStarfish Co-authored-by: NEXI Co-authored-by: Napstaguy04 Co-authored-by: Nista <42772160+Nista11@users.noreply.github.com> Co-authored-by: P.O Co-authored-by: PiryusQ Co-authored-by: Ray Co-authored-by: Rex_sa Co-authored-by: ShareASmile Co-authored-by: Software In Interlingua Co-authored-by: Stypox Co-authored-by: TXRdev Archive Co-authored-by: Tmpod Co-authored-by: TobiGr Co-authored-by: Translator Co-authored-by: VfBFan Co-authored-by: Weblate Co-authored-by: bittin1ddc447d824349b2 Co-authored-by: ferarilalon Co-authored-by: fsbat0 Co-authored-by: gallegonovato Co-authored-by: ngocanhtve Co-authored-by: notlin4 Co-authored-by: searinminecraft <114207889+searinminecraft@users.noreply.github.com> Co-authored-by: sum1tookshoe Co-authored-by: trunars Co-authored-by: İbrahim Dinç Co-authored-by: Макар Разин Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/ar/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/cs/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/de/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/eo/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/es/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/hi/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/id/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/it/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/pa/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/pl/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/pt/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/pt_BR/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/ru/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/sr/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/sv/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/tr/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/uk/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/vi/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/zh_Hant_HK/ Translation: NewPipe/Metadata --- app/src/main/res/values-ar-rLY/strings.xml | 4 +- app/src/main/res/values-da/strings.xml | 5 +- app/src/main/res/values-fil/strings.xml | 2 +- app/src/main/res/values-fr/strings.xml | 14 ++-- app/src/main/res/values-in/strings.xml | 8 +- app/src/main/res/values-pt-rPT/strings.xml | 4 +- app/src/main/res/values-ro/strings.xml | 80 ++++++++++++++++++- .../metadata/android/ar/changelogs/995.txt | 12 +-- .../metadata/android/cs/changelogs/995.txt | 8 +- .../metadata/android/de/changelogs/995.txt | 10 ++- .../metadata/android/es/changelogs/995.txt | 22 ++--- .../metadata/android/hi/changelogs/995.txt | 10 ++- .../metadata/android/id/changelogs/991.txt | 13 +++ .../metadata/android/id/changelogs/993.txt | 12 +++ .../metadata/android/id/changelogs/994.txt | 15 ++++ .../metadata/android/id/changelogs/995.txt | 16 ++++ .../metadata/android/it/changelogs/995.txt | 8 +- .../metadata/android/pa/changelogs/995.txt | 8 +- .../metadata/android/pl/changelogs/995.txt | 16 ++-- .../metadata/android/pt-BR/changelogs/64.txt | 10 +-- .../metadata/android/sr/changelogs/995.txt | 14 ++-- .../metadata/android/uk/changelogs/995.txt | 12 +-- 22 files changed, 229 insertions(+), 74 deletions(-) create mode 100644 fastlane/metadata/android/id/changelogs/991.txt create mode 100644 fastlane/metadata/android/id/changelogs/993.txt create mode 100644 fastlane/metadata/android/id/changelogs/994.txt create mode 100644 fastlane/metadata/android/id/changelogs/995.txt diff --git a/app/src/main/res/values-ar-rLY/strings.xml b/app/src/main/res/values-ar-rLY/strings.xml index aa7f3e53a..aca74e743 100644 --- a/app/src/main/res/values-ar-rLY/strings.xml +++ b/app/src/main/res/values-ar-rLY/strings.xml @@ -5,13 +5,13 @@ الإعدادات بحث تنزيل ملف البث - تحميل + تنزيل إعادة النشر فتح في نافدة منبثقة افتح في المتصفح إلغاء تثبيت - لم يتم العثور على مشغل بث (يمكنك تثبيت VLC لتشغيله). + لم يتم العثور على مشغل بث (يمكنك تثبيت VLC لتشغيلها). لم يتم العثور على مشغل بث. يرجى تثبيت VLC؟ تم النشر في %1$s اضغط على عدسة المكبرة للبدء. diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml index 601a0c603..afde293a6 100644 --- a/app/src/main/res/values-da/strings.xml +++ b/app/src/main/res/values-da/strings.xml @@ -718,4 +718,7 @@ Playlists der er grået ud, indeholder allerede dette objekt. Inaktiver permanent thumbnail Fejlede at kopiere til udklipsholderen - + Brug det originale lydspor uanset sprog + Foretræk lydbeskrivelser + Foretræk original lyd + \ No newline at end of file diff --git a/app/src/main/res/values-fil/strings.xml b/app/src/main/res/values-fil/strings.xml index c798a7aa8..00ce78257 100644 --- a/app/src/main/res/values-fil/strings.xml +++ b/app/src/main/res/values-fil/strings.xml @@ -47,7 +47,7 @@ Ipakita ang \"I-play gamit Kodi\" Pangalawang action button Pangatlong action button - Pinapayagan ng di-saktong seek ang player na mag-seek sa mga posisyon nang mabilis ngunit na may pinababang kasaktuhan. Di ito gagana sa pag-seek nang 5, 15, o 25 segundo. + Pinapayagan ng di-saktong seek ang player na mag-seek sa mga posisyon nang mabilis ngunit na may pinababang kasaktuhan. Di ito gagana sa pag-seek nang 5, 15, o 25 segundo Piliin ang mga mungkahing ipapakita habang naghahanap Patayin para itago ang paglalarawan ng video at karagdagang impormasyon I-edit ang bawat action sa abiso sa baba sa pamamagitan ng pagpindot sa mga ito. Pumili ng hanggang tatlong ipapakita sa siksik na abiso gamit ang mga checkbox sa kanan diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index bad5cd7b9..738f9f58f 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -547,7 +547,7 @@ Jamais Uniquement en Wi-Fi Démarrer la lecture automatiquement — %s - Liste de lecture + File de lecture Impossible de reconnaitre l’URL fournie. Voulez-vous l’ouvrir avec une autre application \? Ajout auto. à la file La file de lecture du lecteur actif sera remplacée @@ -814,11 +814,11 @@ Partager avec les noms Avatars de sous-chaîne Ouvrir la file de lecture - En avant + Avancer Rembobiner - Relancer - Partager la liste de lecture avec des détails tel que son nom et le nom de ses vidéos ou simplement la liste des URL des vidéos - Mise en ligne des avatars - Sélectionnez la qualités des images et si les images doivent être chargées, pour réduire l\'utilisation de la mémoire et de données. Les modifications vide à la fois le cache des images en mémoire et sur le disque — %s - Lancer + Rejouer + Partager la liste de lecture avec des détails tel que son nom et le titre de ses vidéos ou simplement la liste des URLs des vidéos + Avatars du téléverseur + Sélectionnez la qualité des images et si les images doivent être chargées, pour réduire l\'utilisation de la mémoire et de données. Les modifications vident à la fois le cache des images en mémoire et sur le disque — %s + Lire \ No newline at end of file diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index 9da696627..2dc9ecdea 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -1,7 +1,7 @@ - Ketuk kaca pembesar untuk segera memulai. - Dipublikasikan pada tanggal %1$s + Sentuh kaca pembesar untuk memulai. + Dipublikasikan pada %1$s Pasang Batal Buka di browser @@ -74,7 +74,7 @@ Mohon tunggu… Disalin ke papan klip Silakan pilih folder unduhan di pengaturan - Pemutar stream tidak ditemukan. Pasang VLC\? + Pemutar stream tidak ada. Pasang VLC? App/UI rusak Apa:\\nPermintaan:\\nBahasa Konten:\\nNegara Konten:\\nBahasa Apl:\\nLayanan:\\nWaktu GMT:\\nPaket:\\nVersi:\\nVersi OS: Thread @@ -237,7 +237,7 @@ Isi Perbesar Otomatis dibuat - Pemutar stream tidak ditemukan (Anda bisa memasang VLC untuk memutarnya). + Pemutar stream tidak ada (pasang VLC untuk memutarnya). Unduh berkas stream Tidak bisa mengubah langganan Tampilkan info diff --git a/app/src/main/res/values-pt-rPT/strings.xml b/app/src/main/res/values-pt-rPT/strings.xml index fa88d003c..335c989ed 100644 --- a/app/src/main/res/values-pt-rPT/strings.xml +++ b/app/src/main/res/values-pt-rPT/strings.xml @@ -44,8 +44,8 @@ Histórico de visualizações %s visualização - %s subscritores - %s subscritores + %s visualizações + %s visualizações Deseja limpar o histórico de descargas ou remover todos os ficheiros descarregados\? Histórico e cache diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index 43eb814e8..42e23c3a4 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -482,7 +482,7 @@ Serverul nu acceptă descărcări cu mai multe fire, încercați din nou cu @string/msg_threads = 1 Serverul nu trimite date Nu se poate conecta la server - Nu s-a putut găsi server-ul + Nu s-a putut găsi serverul Nu s-a putut stabili o conexiune sigură Folderul de destinație nu poate fi creat Fișierul nu poate fi creat @@ -662,7 +662,7 @@ Miniatură de previzualizare în bara de derulare Afișați panglici colorate de Picasso deasupra imaginilor, indicând sursa acestora: roșu pentru rețea, albastru pentru disc și verde pentru memorie Afișați indicatorii de imagine - Dezactivați tunelarea media dacă întâmpinați un ecran negru sau blocaje la redarea video + Dezactivați tunelarea media dacă întâmpinați un ecran negru sau blocaje la redarea video. Procesarea.. Poate dura un moment Verifică dacă există actualizări Verifică manual dacă există versiuni noi @@ -741,4 +741,80 @@ Vizionat complet Vizionat parțial Urmează + Calitatea imaginii + original + Videouri + \? + Abonați + Necunoscut + Ce file sunt afișate pe paginile canalelor + descriptiv + Distribuiți lista URL + Distribuiți cu titluri + %1$s +\n%2$s + Filele canalului + Volum + Utilizați funcționalitatea de rezervă a decodorului din ExoPlayer + Niciunul + Se încarcă metadata… + Schimbați orientarea ecranului + Gestionați unele setări pentru ExoPlayer. Aceste schimbări necesită un restart la player ca să aibă efect + Calitate scăzută + Poziția filelor principale + Schimbați pe ecran complet + Preluați filele canalului + Avatare + Activați această opțiune dacă aveți probleme cu inițializarea decodorului care trece înapoi la decodoare cu prioritate mai scăzută dacă inițializarea decodoarelor principale eșuează. Asta poate duce la performanță de redare mai slabă decât atunci când se utilizează decodoarele principale. + Acțiunea gestului din dreapta + %1$s %2$s + Utilizați întotdeauna configurarația suprafeței de ieșire video din ExoPlayer ca soluție alternativă + Transmisia viitoare + Tunelizarea media a fost dezactivată în mod implicit pe dispozitivul dumneavoastră deoarece se cunoaște despre acest model de dispozitiv că nu o suportă. + Avatarele subcanalelor + Această soluție alternativă eliberează și reinstanțează codecurile video când se întamplă o schimbare a suprafeței, în loc de a seta suprafața pentru codec direct. Deja +\n folosită de ExoPlayer pe unele dispozitive cu această problemă, această setare are efect doar pe Android 6 sau mai mare +\n +\nActivarea acestei opțiuni poate preveni erorile de redare când se schimbă playerul video curent sau se trece pe ecran complet + O coloană sonoră ar trebui să fie deja prezentă în această transmisie + Deschideți coada de redare + Selectați coloana sonoră originală indiferent de limbă + Nu încărcați imagini + Calitate înaltă + Despre + Distribuiți playlistul + Avansați + Selectați coloana sonoră pentru playeri externi + Albume + Derulați + Reluați + dublat + File ce vor fi preluate când se actualizează fluxul. Această opțiune nu are niciun efect dacă un canal este actualizat folosind modul rapid. + Selectați o coloană sonoră cu descrieri pentru persoane cu deficiențe vizuale, dacă este disponibilă + Acțiunea gestului din stânga + Distribuiți playlistul cu detalii precum numele playlistului și titlurile videourilor sau ca o simplă listă de URL-uri a videourilor + Calitate medie + Preferați audioul descriptiv + Modificați dimensiunea intervalului de încărcare pentru conținuturi progresive (în prezent %s). O valoare mai mică poate accelera încărcarea lor inițială + Preferați audioul original + Audio: %s + Bannere + Playlisturi + Alegeți un gest pentru jumătatea dreaptă din ecranul playerului + - %1$s: %2$s + Mutați fila principală în partea de jos + Coloană sonoră + Fără transmisii în direct + Alegeți calitatea imaginilor și dacă să se încarce sau nu imaginile, pentru a reduce utilizarea datelor și memoriei. Schimbările șterg cache-ul atât din memoria internă cât și din disc --%s + Redați + Mai multe opțiuni + Miniaturi + Setări pentru ExoPlayer + Luminozitate + Durată + Fără transmisii + Canale + Transmisia anterioară + Alegeți un gest pentru jumătatea stângă din ecranul playerului + În direct \ No newline at end of file diff --git a/fastlane/metadata/android/ar/changelogs/995.txt b/fastlane/metadata/android/ar/changelogs/995.txt index 82acc602b..3995ca6eb 100644 --- a/fastlane/metadata/android/ar/changelogs/995.txt +++ b/fastlane/metadata/android/ar/changelogs/995.txt @@ -1,14 +1,16 @@ جديد • دعم علامات التبويب القناة -• حدد جودة الصورة -• الحصول على عناوين URL لجميع الصور +• تحديد جودة الصورة +• الحصول على العناوين لجميع الصور تحسين • إمكانية الوصول إلى واجهات المشغل -• خيار إضافة اسم قائمة التشغيل واسم الفيديو إلى محتوى مشاركة قائمة التشغيل -• التحسينات الداخلية وتحديثات التبعيات +• اختيار أفضل للصوت لتنزيلات الفيديو فقط +• خيار لتضمين قائمة التشغيل وأسماء الفيديو لمحتوى قائمة التشغيل المشتركة مُثَبَّت +• [يوتيوب] إصلاح جلب عدد الإعجابات +• إصلاح عدم استجابة المشغل للنوافذ المنبثقة والأعطال • اختيار لغات خاطئة في منتقي اللغة • تركيز صوت المشغل لم يكن يحترم كتم الصوت -• إضافة عناصر إلى قوائم التشغيل لا تعمل في حالات معينة +• إضافة عنصر قائمة التشغيل لا يعمل في بعض الأحيان diff --git a/fastlane/metadata/android/cs/changelogs/995.txt b/fastlane/metadata/android/cs/changelogs/995.txt index 325cef51e..222437b3a 100644 --- a/fastlane/metadata/android/cs/changelogs/995.txt +++ b/fastlane/metadata/android/cs/changelogs/995.txt @@ -5,10 +5,12 @@ Nové Vylepšeno • Přístupnost rozhraní přehrávače -• Možnost přidat název playlistu a název videa do sdíleného obsahu playlistu -• Interní vylepšení a aktualizace závislostí +• Lepší výběr zvuku pro stahování videa +• Možnost přidat název playlistů a videí do obsahu sdíleného playlistu Opraveno +• [YouTube] Opraveno získání počtů líbí se +• Opraveny popupy neodpovídání přehrávače a pády • Výběr nesprávných jazyků ve výběru jazyka • Zaměření zvuku přehrávače nerespektovalo ztlumení -• Přidávání položek do playlistů v určitých případech nefungovalo +• Přidávání položek do playlistů někdy nefungovalo diff --git a/fastlane/metadata/android/de/changelogs/995.txt b/fastlane/metadata/android/de/changelogs/995.txt index 284d1c192..9c9ed1147 100644 --- a/fastlane/metadata/android/de/changelogs/995.txt +++ b/fastlane/metadata/android/de/changelogs/995.txt @@ -5,10 +5,12 @@ Neu Verbessert • Zugänglichkeit der Player-Oberflächen -• Option zum Hinzufügen von Wiedergabelisten- und Videonamen beim Teilen von Inhalten -• Interne Verbesserungen und Aktualisierungen der Abhängigkeiten +• Bessere Audioauswahl bei reinen Video-Downloads +• Option zur Aufnahme von Wiedergabelisten-/Videonamen in geteilten Wiedergabelisteninhalten Behoben +• [YouTube] Erhalten der Like-Anzahl +• Nicht reagierende Popups und Abstürze des Players • Auswahl der falschen Sprachen in der Sprachauswahl -• Der Audio-Fokus des Players respektierte die Stummschaltung nicht -• Das Hinzufügen von Elementen zu Wiedergabelisten in bestimmten Fällen +• Audio-Fokus des Players respektiert keine Stummschaltung +… diff --git a/fastlane/metadata/android/es/changelogs/995.txt b/fastlane/metadata/android/es/changelogs/995.txt index 5c13533fa..93aab836e 100644 --- a/fastlane/metadata/android/es/changelogs/995.txt +++ b/fastlane/metadata/android/es/changelogs/995.txt @@ -1,14 +1,16 @@ Nuevo -• Pestañas del canal -• Calidad de la imagen -• URLs a todas las imágenes +• Pestañas de canal +• Calidad de imagen +• URLs de las imágenes -Mejorado +Mejora de • Accesibilidad de las interfaces de los reproductores -• Opción para añadir el nombre de la lista de reproducción y el nombre del vídeo a la lista de reproducción compartida -• Mejoras internas y actualizaciones de dependencias +• Mejor selección de audio para descargas de vídeo +• Incluir nombres de listas de reproducción y vídeos en listas compartidas -Fijo -• Idiomas incorrectos en el selector de idiomas -• El audio del reproductor no se silenciaba -• Agregar elementos a listas de reproducción que no funcionan en casos específicos +Corregido +• [YouTube] Corrección del recuento "Me gusta" +• Ventanas emergentes y bloqueos +• Idiomas incorrectos en selector de idiomas +• Audio del reproductor no respetaba silencio +• La lista de reproducción no funcionaba ocasionalmente diff --git a/fastlane/metadata/android/hi/changelogs/995.txt b/fastlane/metadata/android/hi/changelogs/995.txt index ecba503d9..63ed335a4 100644 --- a/fastlane/metadata/android/hi/changelogs/995.txt +++ b/fastlane/metadata/android/hi/changelogs/995.txt @@ -5,10 +5,12 @@ सुधार किए • प्लेयर इंटरफ़ेस की पहुंच -• प्लेलिस्ट साझाकरण सामग्री में प्लेलिस्ट का नाम और वीडियो का नाम जोड़ने का विकल्प -• आंतरिक सुधार और निर्भरता अद्यतन +• केवल-वीडियो डाउनलोड के लिए बेहतर ऑडियो चयन +• साझा प्लेलिस्ट सामग्री में प्लेलिस्ट और वीडियो नाम शामिल करने का विकल्प ठीक किए -• भाषा चयनकर्ता में गलत भाषाओं का चयन +• [यूट्यूब] लाइक पाने की संख्या ठीक करें +• पॉपअप और क्रैश पर प्रतिक्रिया नहीं देने वाले प्लेयर को ठीक करें +• भाषा चयनकर्ता में गलत भाषाओं का चयन ठीक करें • प्लेयर ऑडियो फोकस म्यूट का सम्मान नहीं कर रहा था -• प्लेलिस्ट में आइटम जोड़ना विशिष्ट मामलों में काम नहीं कर रहा था +• प्लेलिस्ट में आइटम जोड़ना कभी-कभी काम नहीं कर रहा था diff --git a/fastlane/metadata/android/id/changelogs/991.txt b/fastlane/metadata/android/id/changelogs/991.txt new file mode 100644 index 000000000..a803d5a14 --- /dev/null +++ b/fastlane/metadata/android/id/changelogs/991.txt @@ -0,0 +1,13 @@ +Baru +• Tambahkan tombol "Buka di browser" di panel kesalahan +• Tambahkan opsi untuk menampilkan grup saluran sebagai daftar +• [YouTube] Klik-lama pada segmen streaming untuk membagikan URL stempel waktu +• Tambahkan tombol antrian putar ke pemutar mini + +Disempurnakan +• Tambahkan lokalisasi Islandia dan perbarui banyak terjemahan lainnya +• Banyak perbaikan internal + +Diperbaiki +• Memperbaiki beberapa kerusakan +• [YouTube] Memperbaiki pemuatan saluran, feed non-khusus, dan mengatasi masalah pemutaran di beberapa negara diff --git a/fastlane/metadata/android/id/changelogs/993.txt b/fastlane/metadata/android/id/changelogs/993.txt new file mode 100644 index 000000000..2a4c8f2d6 --- /dev/null +++ b/fastlane/metadata/android/id/changelogs/993.txt @@ -0,0 +1,12 @@ +Baru +• Tambahkan peringatan saat menambahkan duplikat daftar putar dan tombol tambahkan untuk menghapusnya +• Izinkan pengabaian tombol perangkat keras +• Izinkan menyembunyikan video yang ditonton sebagian di feed + +Ditingkatkan +• Gunakan lebih banyak kolom grid di layar besar +• Membuat indikator kemajuan konsisten dengan pengaturan + +Tetap +• Memperbaiki URL pembuka browser, unduhan, dan pemutar eksternal di Android 11+ +• Memperbaiki interaksi dengan layar penuh yang memerlukan dua ketukan pada MIUI diff --git a/fastlane/metadata/android/id/changelogs/994.txt b/fastlane/metadata/android/id/changelogs/994.txt new file mode 100644 index 000000000..fc75016b1 --- /dev/null +++ b/fastlane/metadata/android/id/changelogs/994.txt @@ -0,0 +1,15 @@ +Baru +• Mendukung beberapa track audio/bahasa +• Izinkan mengatur gestur volume dan kecerahan di sisi mana pun pada layar +• Dukungan untuk menampilkan tab utama di bagian bawah layar + +Disempurnakan +• [Bandcamp] Menangani track berbayar + +Diperbaiki +• [YouTube] Kesalahan HTTP 403 untuk streaming +• Pemutar berwarna hitam saat beralih ke pemutar utama dari tampilan daftar putar +• Kebocoran memori layanan pemutar +• [PeerTube] Avatar pengunggah dan subsaluran ditukar + +dan banyak lagi diff --git a/fastlane/metadata/android/id/changelogs/995.txt b/fastlane/metadata/android/id/changelogs/995.txt new file mode 100644 index 000000000..277b2468a --- /dev/null +++ b/fastlane/metadata/android/id/changelogs/995.txt @@ -0,0 +1,16 @@ +Baru +• Mendukung tab saluran +• Pilih kualitas gambar +• Dapatkan URL ke semua gambar + +Ditingkatkan +• Aksesibilitas antarmuka pemain +• Pilihan audio yang lebih baik untuk download video saja +• Pilihan untuk memasukkan nama playlist dan video ke konten playlist bersama + +Tetap +• [YouTube] Perbaiki penghitungan jumlah suka +• Memperbaiki pemain yang tidak merespons popup dan crash +• Pemilihan bahasa yang salah di pemilih bahasa +• Fokus audio pemutar tidak menerapkan mode senyap +• Penambahan item playlist terkadang tidak berfungsi diff --git a/fastlane/metadata/android/it/changelogs/995.txt b/fastlane/metadata/android/it/changelogs/995.txt index 8da9a7ee7..efed82f4e 100644 --- a/fastlane/metadata/android/it/changelogs/995.txt +++ b/fastlane/metadata/android/it/changelogs/995.txt @@ -5,10 +5,12 @@ Novità Migliorato • Accessibilità delle interfacce del player -• Opzione per aggiungere il nome della playlist e il nome video al contenuto di condivisione della playlist -• Miglioramenti interni e aggiornamenti delle dipendenze +• Miglior scelta dell'audio per i download video-only +• Condivisione playlist con più opzioni Corretto +• [YouTube] Sistemati i mi piace +• Talvolta il player non rispondeva o crashava • Selezione di lingue errate nel selettore • Il focus audio del player non rispettava il muto -• Aggiungere elementi a playlist non funzionava in casi specifici +• Talvolta aggiungere elementi a playlist non funzionava diff --git a/fastlane/metadata/android/pa/changelogs/995.txt b/fastlane/metadata/android/pa/changelogs/995.txt index dc9c576c9..0da0a4261 100644 --- a/fastlane/metadata/android/pa/changelogs/995.txt +++ b/fastlane/metadata/android/pa/changelogs/995.txt @@ -5,10 +5,12 @@ ਸੁਧਾਰ • ਪਲੇਅਰ ਇੰਟਰਫੇਸ ਦੀ ਪਹੁੰਚਯੋਗਤਾ -• ਪਲੇਲਿਸਟ ਸ਼ੇਅਰਿੰਗ ਸਮੱਗਰੀ ਵਿੱਚ ਪਲੇਲਿਸਟ ਨਾਮ ਅਤੇ ਵੀਡੀਓ ਨਾਮ ਜੋੜਨ ਲਈ ਵਿਕਲਪ -• ਅੰਦਰੂਨੀ ਸੁਧਾਰ ਅਤੇ ਨਿਰਭਰਤਾ ਅੱਪਡੇਟ +• ਸਿਰਫ਼-ਵੀਡੀਓ ਡਾਊਨਲੋਡਾਂ ਲਈ ਬਿਹਤਰ ਆਡੀਓ ਚੋਣ +• ਸਾਂਝੀ ਕੀਤੀ ਪਲੇਲਿਸਟ ਸਮੱਗਰੀ ਵਿੱਚ ਪਲੇਲਿਸਟ ਅਤੇ ਵੀਡੀਓ ਨਾਮ ਸ਼ਾਮਲ ਕਰਨ ਦਾ ਵਿਕਲਪ ਠੀਕ ਕੀਤੇ +• [ਯੂਟਿਊਬ] ਲਾਈਕ ਗਿਣਤੀ ਨੂੰ ਠੀਕ ਕਰੋ +• ਪਲੇਅਰ ਰਿਸਪੌੰਡ ਨਹੀਂ ਕਰ ਰਿਹਾ ਦੇ ਸੁਨੇਹੇ ਦੇਣ ਵਾਲੇ ਪੌਪਅੱਪ ਅਤੇ ਕਰੈਸ਼ਾਂ ਨੂੰ ਠੀਕ ਕਰੋ • ਭਾਸ਼ਾ ਚੋਣਕਾਰ ਵਿੱਚ ਗਲਤ ਭਾਸ਼ਾਵਾਂ ਦੀ ਚੋਣ • ਪਲੇਅਰ ਆਡੀਓ ਫੋਕਸ ਮਿਊਟ ਦਾ ਆਦਰ ਨਹੀਂ ਕਰ ਰਿਹਾ ਸੀ -• ਖਾਸ ਮਾਮਲਿਆਂ ਵਿੱਚ ਪਲੇਲਿਸਟਾਂ ਵਿੱਚ ਆਈਟਮਾਂ ਨੂੰ ਜੋੜਨਾ ਕੰਮ ਨਹੀਂ ਕਰ ਰਿਹਾ ਸੀ +• ਪਲੇਲਿਸਟਾਂ ਵਿੱਚ ਆਈਟਮਾਂ ਨੂੰ ਜੋੜਨਾ ਕਦੇ-ਕਦਾਈਂ ਕੰਮ ਨਹੀਂ ਕਰ ਰਿਹਾ ਸੀ diff --git a/fastlane/metadata/android/pl/changelogs/995.txt b/fastlane/metadata/android/pl/changelogs/995.txt index ffbcbf374..3a227a3ea 100644 --- a/fastlane/metadata/android/pl/changelogs/995.txt +++ b/fastlane/metadata/android/pl/changelogs/995.txt @@ -1,14 +1,16 @@ Nowe • Obsługa kart kanałów -• Wybieranie jakości obrazów +• Wybór jakości obrazów • Uzyskiwanie adresów URL do wszystkich obrazów Ulepszone -• Dostępność interfejsów odtwarzacza -• Opcja dodania nazwy playlisty i tytułów wideo do udostępnianej zawartości playlisty -• Wewnętrzne ulepszenia i aktualizacje zależności +• Dostępność UI odtwarzacza +• Lepszy wybór dźwięku dla pobierania tylko wideo +• Opcja uwzględ. nazw playlist i wideo do udostęp. zawartości playlisty Naprawione -• Wybór błędnych języków w selektorze języków -• Skupienie na dźwięku odtwarzacza nie uwzględniało wyciszenia -• Dodawanie pozycji do playlist nie działało w określonych przypadkach +• [YouTube] Liczba polubień +• Zawieszone wysk. okienka i awarie odtwarzacza +• Błędne wybory w selektorze języków +• Skupienie na dźwięku odtwarzacza nie uwzględ. wyciszenia +• Czasami niedziałające dodawanie pozycji do playlisty diff --git a/fastlane/metadata/android/pt-BR/changelogs/64.txt b/fastlane/metadata/android/pt-BR/changelogs/64.txt index 74205f9ba..4497e3965 100644 --- a/fastlane/metadata/android/pt-BR/changelogs/64.txt +++ b/fastlane/metadata/android/pt-BR/changelogs/64.txt @@ -1,8 +1,8 @@ ### Melhorias -- Adicionada a capacidade de limitar a qualidade do vídeo ao usar dados móveis. # 1339 -- Lembra-se do brilho da sessão # 1442 -- Melhora o desempenho de download em CPUs mais fracas # 1431 -- Adiciona suporte (funcionando) à sessão de mídia # 1433 +- Adiciona o recurso de limitar a qualidade do vídeo ao usar dados móveis. #1339 +- Mantém o brilho da sessão #1442 +- Melhora o desempenho para baixar em CPU mais fracas #1431 +- Adiciona suporte (funcionando) à sessão de mídia #1433 ### Correção -- Corrige falha ao iniciar downloads (correção agora disponível em versões de lançamento) # 1441 +- Corrige falha ao iniciar Downloads (correção agora disponível em versões de lançamento) # 1441 diff --git a/fastlane/metadata/android/sr/changelogs/995.txt b/fastlane/metadata/android/sr/changelogs/995.txt index fd8da6381..0604eb088 100644 --- a/fastlane/metadata/android/sr/changelogs/995.txt +++ b/fastlane/metadata/android/sr/changelogs/995.txt @@ -4,11 +4,13 @@ • Набавите URL адресе за све слике Побољшано -• Приступачност интерфејса плејера -• Опција за опцију додавања назива плејлисте и назива видео снимка у садржај листе за дељење -• Интерна побољшања и ажурирања зависности +• Прист. интерф. плејера +• Бољи избор звука за преузимања само видео снимака +• Опција за укљ. назива плејлисте и видео сним. у дељ. сад. плејл. Поправљено -• Избор погрешних језика у бирачу језика -• Аудио фокус плејера није поштовао искључен звук -• Додавање ставки на плејлисте не функционише у одређеним случајевима +• [YouTube] Попр. доб. лајкова +• Попр. проб. када плејер не реаг. на иск. проз. и отказује +• Изб. погр. јез. у бир. јез. +• Аудио фокус плејера није пошт. утиш. звук +• Додавање пред. на плејлисте повр. не функционише diff --git a/fastlane/metadata/android/uk/changelogs/995.txt b/fastlane/metadata/android/uk/changelogs/995.txt index 1cd40224a..3e40c900a 100644 --- a/fastlane/metadata/android/uk/changelogs/995.txt +++ b/fastlane/metadata/android/uk/changelogs/995.txt @@ -1,14 +1,16 @@ Нове • Підтримка вкладок каналів -• Вибір якості зображення +• Вибір якості зображень • Отримання URL всіх зображень Поліпшено -• Доступність інтерфейсів програвачів -• Додано можливість додавати назву добірки й назву відео поширюваного вмісту добірки -• Внутрішні вдосконалення й оновлення залежностей +• Доступність інтерфейсу +• Кращий вибір аудіо для завантаження відео +• Опція додавати назву добірки й відео поширюваного вмісту добірки Виправлено +• [YouTube] лічильник вподобайок +• Нереагування спливних вікон і збої в роботі програвача • Вибір неправильних мов у перемикачі мов • Фокусування звуку програвача не враховувало вимкнення звуку -• Додавання елементів у добірки не працювало у певних випадках +• Додавання елементів добірок інколи не працювало