From e333197ed5dfcb67b33029a0cbbc82e5afd2b344 Mon Sep 17 00:00:00 2001 From: Isira Seneviratne Date: Sat, 27 Aug 2022 08:06:58 +0530 Subject: [PATCH 01/23] Use OnClickListener and OnLongClickListener lambdas in the player UIs. --- .../newpipe/player/ui/MainPlayerUi.java | 47 ++--- .../newpipe/player/ui/VideoPlayerUi.java | 174 +++++++----------- 2 files changed, 89 insertions(+), 132 deletions(-) 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 248104738..6226900f6 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 @@ -154,6 +154,16 @@ public final class MainPlayerUi extends VideoPlayerUi implements View.OnLayoutCh protected void initListeners() { super.initListeners(); + binding.screenRotationButton.setOnClickListener(makeOnClickListener(() -> { + // Only if it's not a vertical video or vertical video but in landscape with locked + // orientation a screen orientation can be changed automatically + if (!isVerticalVideo || (isLandscape() && globalScreenOrientationLocked(context))) { + player.getFragmentListener() + .ifPresent(PlayerServiceEventListener::onScreenRotationButtonClicked); + } else { + toggleFullscreen(); + } + })); binding.queueButton.setOnClickListener(v -> onQueueClicked()); binding.segmentsButton.setOnClickListener(v -> onSegmentsClicked()); @@ -173,6 +183,14 @@ public final class MainPlayerUi extends VideoPlayerUi implements View.OnLayoutCh settingsContentObserver); binding.getRoot().addOnLayoutChangeListener(this); + + binding.moreOptionsButton.setOnLongClickListener(v -> { + player.getFragmentListener() + .ifPresent(PlayerServiceEventListener::onMoreOptionsLongClicked); + hideControls(0, 0); + hideSystemUIIfNeeded(); + return true; + }); } @Override @@ -846,23 +864,6 @@ public final class MainPlayerUi extends VideoPlayerUi implements View.OnLayoutCh //////////////////////////////////////////////////////////////////////////*/ //region Click listeners - @Override - public void onClick(final View v) { - if (v.getId() == binding.screenRotationButton.getId()) { - // Only if it's not a vertical video or vertical video but in landscape with locked - // orientation a screen orientation can be changed automatically - if (!isVerticalVideo || (isLandscape() && globalScreenOrientationLocked(context))) { - player.getFragmentListener().ifPresent( - PlayerServiceEventListener::onScreenRotationButtonClicked); - } else { - toggleFullscreen(); - } - } - - // call it later since it calls manageControlsAfterOnClick at the end - super.onClick(v); - } - @Override protected void onPlaybackSpeedClicked() { final AppCompatActivity activity = getParentActivity().orElse(null); @@ -875,18 +876,6 @@ public final class MainPlayerUi extends VideoPlayerUi implements View.OnLayoutCh .show(activity.getSupportFragmentManager(), null); } - @Override - public boolean onLongClick(final View v) { - if (v.getId() == binding.moreOptionsButton.getId() && isFullscreen) { - player.getFragmentListener().ifPresent( - PlayerServiceEventListener::onMoreOptionsLongClicked); - hideControls(0, 0); - hideSystemUIIfNeeded(); - return true; - } - return super.onLongClick(v); - } - @Override public boolean onKeyDown(final int keyCode) { if (keyCode == KeyEvent.KEYCODE_SPACE && isFullscreen) { 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 1709755f2..64a6ba376 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 @@ -83,11 +83,11 @@ import org.schabi.newpipe.util.external_communication.ShareUtils; import org.schabi.newpipe.views.player.PlayerFastSeekOverlay; import java.util.List; +import java.util.Objects; import java.util.Optional; import java.util.stream.Collectors; -public abstract class VideoPlayerUi extends PlayerUi - implements SeekBar.OnSeekBarChangeListener, View.OnClickListener, View.OnLongClickListener, +public abstract class VideoPlayerUi extends PlayerUi implements SeekBar.OnSeekBarChangeListener, PopupMenu.OnMenuItemClickListener, PopupMenu.OnDismissListener { private static final String TAG = VideoPlayerUi.class.getSimpleName(); @@ -131,9 +131,11 @@ public abstract class VideoPlayerUi extends PlayerUi private GestureDetector gestureDetector; private BasePlayerGestureListener playerGestureListener; - @Nullable private View.OnLayoutChangeListener onLayoutChangeListener = null; + @Nullable + private View.OnLayoutChangeListener onLayoutChangeListener = null; - @NonNull private final SeekbarPreviewThumbnailHolder seekbarPreviewThumbnailHolder = + @NonNull + private final SeekbarPreviewThumbnailHolder seekbarPreviewThumbnailHolder = new SeekbarPreviewThumbnailHolder(); @@ -186,13 +188,13 @@ public abstract class VideoPlayerUi extends PlayerUi abstract BasePlayerGestureListener buildGestureListener(); protected void initListeners() { - binding.qualityTextView.setOnClickListener(this); - binding.playbackSpeed.setOnClickListener(this); + binding.qualityTextView.setOnClickListener(makeOnClickListener(this::onQualityClicked)); + binding.playbackSpeed.setOnClickListener(makeOnClickListener(this::onPlaybackSpeedClicked)); binding.playbackSeekBar.setOnSeekBarChangeListener(this); - binding.captionTextView.setOnClickListener(this); - binding.resizeTextView.setOnClickListener(this); - binding.playbackLiveSync.setOnClickListener(this); + binding.captionTextView.setOnClickListener(makeOnClickListener(this::onCaptionClicked)); + binding.resizeTextView.setOnClickListener(makeOnClickListener(this::onResizeClicked)); + binding.playbackLiveSync.setOnClickListener(makeOnClickListener(player::seekToDefault)); playerGestureListener = buildGestureListener(); gestureDetector = new GestureDetector(context, playerGestureListener); @@ -201,20 +203,36 @@ public abstract class VideoPlayerUi extends PlayerUi binding.repeatButton.setOnClickListener(v -> onRepeatClicked()); binding.shuffleButton.setOnClickListener(v -> onShuffleClicked()); - binding.playPauseButton.setOnClickListener(this); - binding.playPreviousButton.setOnClickListener(this); - binding.playNextButton.setOnClickListener(this); + binding.playPauseButton.setOnClickListener(makeOnClickListener(player::playPause)); + binding.playPreviousButton.setOnClickListener(makeOnClickListener(player::playPrevious)); + binding.playNextButton.setOnClickListener(makeOnClickListener(player::playNext)); - binding.moreOptionsButton.setOnClickListener(this); - binding.moreOptionsButton.setOnLongClickListener(this); - binding.share.setOnClickListener(this); - binding.share.setOnLongClickListener(this); - binding.fullScreenButton.setOnClickListener(this); - binding.screenRotationButton.setOnClickListener(this); - binding.playWithKodi.setOnClickListener(this); - binding.openInBrowser.setOnClickListener(this); - binding.playerCloseButton.setOnClickListener(this); - binding.switchMute.setOnClickListener(this); + binding.moreOptionsButton.setOnClickListener( + makeOnClickListener(this::onMoreOptionsClicked)); + binding.share.setOnClickListener(makeOnClickListener(() -> { + final PlayQueueItem currentItem = player.getCurrentItem(); + if (currentItem != null) { + ShareUtils.shareText(context, currentItem.getTitle(), + player.getVideoUrlAtCurrentTime(), currentItem.getThumbnailUrl()); + } + })); + binding.share.setOnLongClickListener(v -> { + ShareUtils.copyToClipboard(context, player.getVideoUrlAtCurrentTime()); + return true; + }); + binding.fullScreenButton.setOnClickListener(makeOnClickListener(() -> { + player.setRecovery(); + NavigationHelper.playOnMainPlayer(context, + Objects.requireNonNull(player.getPlayQueue()), true); + })); + binding.playWithKodi.setOnClickListener(makeOnClickListener(this::onPlayWithKodiClicked)); + binding.openInBrowser.setOnClickListener(makeOnClickListener(this::onOpenInBrowserClicked)); + binding.playerCloseButton.setOnClickListener(makeOnClickListener(() -> + // set package to this app's package to prevent the intent from being seen outside + context.sendBroadcast(new Intent(VideoDetailFragment.ACTION_HIDE_MAIN_PLAYER) + .setPackage(App.PACKAGE_NAME)) + )); + binding.switchMute.setOnClickListener(makeOnClickListener(player::toggleMute)); ViewCompat.setOnApplyWindowInsetsListener(binding.itemsListPanel, (view, windowInsets) -> { final Insets cutout = windowInsets.getInsets(WindowInsetsCompat.Type.displayCutout()); @@ -228,11 +246,8 @@ public abstract class VideoPlayerUi extends PlayerUi // player_overlays and fast_seek_overlay too. Without it they will be off-centered. onLayoutChangeListener = (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> { - binding.playerOverlays.setPadding( - v.getPaddingLeft(), - v.getPaddingTop(), - v.getPaddingRight(), - v.getPaddingBottom()); + binding.playerOverlays.setPadding(v.getPaddingLeft(), v.getPaddingTop(), + v.getPaddingRight(), v.getPaddingBottom()); // If we added padding to the fast seek overlay, too, it would not go under the // system ui. Instead we apply negative margins equal to the window insets of @@ -1324,86 +1339,39 @@ public abstract class VideoPlayerUi extends PlayerUi //////////////////////////////////////////////////////////////////////////*/ //region Click listeners - @Override - public void onClick(final View v) { - if (DEBUG) { - Log.d(TAG, "onClick() called with: v = [" + v + "]"); - } - if (v.getId() == binding.resizeTextView.getId()) { - onResizeClicked(); - } else if (v.getId() == binding.captionTextView.getId()) { - onCaptionClicked(); - } else if (v.getId() == binding.playbackLiveSync.getId()) { - player.seekToDefault(); - } else if (v.getId() == binding.playPauseButton.getId()) { - player.playPause(); - } else if (v.getId() == binding.playPreviousButton.getId()) { - player.playPrevious(); - } else if (v.getId() == binding.playNextButton.getId()) { - player.playNext(); - } else if (v.getId() == binding.moreOptionsButton.getId()) { - onMoreOptionsClicked(); - } else if (v.getId() == binding.share.getId()) { - final PlayQueueItem currentItem = player.getCurrentItem(); - if (currentItem != null) { - ShareUtils.shareText(context, currentItem.getTitle(), - player.getVideoUrlAtCurrentTime(), currentItem.getThumbnailUrl()); - } - } else if (v.getId() == binding.playWithKodi.getId()) { - onPlayWithKodiClicked(); - } else if (v.getId() == binding.openInBrowser.getId()) { - onOpenInBrowserClicked(); - } else if (v.getId() == binding.fullScreenButton.getId()) { - player.setRecovery(); - NavigationHelper.playOnMainPlayer(context, player.getPlayQueue(), true); - return; - } else if (v.getId() == binding.switchMute.getId()) { - player.toggleMute(); - } else if (v.getId() == binding.playerCloseButton.getId()) { - // set package to this app's package to prevent the intent from being seen outside - context.sendBroadcast(new Intent(VideoDetailFragment.ACTION_HIDE_MAIN_PLAYER) - .setPackage(App.PACKAGE_NAME)); - } else if (v.getId() == binding.playbackSpeed.getId()) { - onPlaybackSpeedClicked(); - } else if (v.getId() == binding.qualityTextView.getId()) { - onQualityClicked(); - } - - manageControlsAfterOnClick(v); - } - /** - * Manages the controls after a click occurred on the player UI. - * @param v – The view that was clicked + * Create on-click listener which manages the player controls after the view on-click action. + * + * @param runnable The action to be executed. + * @return The view click listener. */ - public void manageControlsAfterOnClick(@NonNull final View v) { - if (player.getCurrentState() == STATE_COMPLETED) { - return; - } + protected View.OnClickListener makeOnClickListener(@NonNull final Runnable runnable) { + return v -> { + if (DEBUG) { + Log.d(TAG, "onClick() called with: v = [" + v + "]"); + } - controlsVisibilityHandler.removeCallbacksAndMessages(null); - showHideShadow(true, DEFAULT_CONTROLS_DURATION); - animate(binding.playbackControlRoot, true, DEFAULT_CONTROLS_DURATION, - AnimationType.ALPHA, 0, () -> { - if (player.getCurrentState() == STATE_PLAYING && !isSomePopupMenuVisible) { - if (v.getId() == binding.playPauseButton.getId() - // Hide controls in fullscreen immediately - || (v.getId() == binding.screenRotationButton.getId() - && isFullscreen())) { - hideControls(0, 0); - } else { - hideControls(DEFAULT_CONTROLS_DURATION, DEFAULT_CONTROLS_HIDE_TIME); + runnable.run(); + + // Manages the player controls after handling the view click. + if (player.getCurrentState() == STATE_COMPLETED) { + return; + } + controlsVisibilityHandler.removeCallbacksAndMessages(null); + showHideShadow(true, DEFAULT_CONTROLS_DURATION); + animate(binding.playbackControlRoot, true, DEFAULT_CONTROLS_DURATION, + AnimationType.ALPHA, 0, () -> { + if (player.getCurrentState() == STATE_PLAYING && !isSomePopupMenuVisible) { + if (v == binding.playPauseButton + // Hide controls in fullscreen immediately + || (v == binding.screenRotationButton && isFullscreen())) { + hideControls(0, 0); + } else { + hideControls(DEFAULT_CONTROLS_DURATION, DEFAULT_CONTROLS_HIDE_TIME); + } } - } - }); - } - - @Override - public boolean onLongClick(final View v) { - if (v.getId() == binding.share.getId()) { - ShareUtils.copyToClipboard(context, player.getVideoUrlAtCurrentTime()); - } - return true; + }); + }; } public boolean onKeyDown(final int keyCode) { From e4f97465a41a103c7f2cbb9f4f3269e90b5d3105 Mon Sep 17 00:00:00 2001 From: Isira Seneviratne Date: Sun, 21 Aug 2022 06:38:33 +0530 Subject: [PATCH 02/23] Use lambdas for VideoDetailFragment listeners. --- .../fragments/detail/VideoDetailFragment.java | 366 ++++++++---------- 1 file changed, 152 insertions(+), 214 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 bf84c7325..68cb9948b 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 @@ -10,6 +10,8 @@ import static org.schabi.newpipe.player.helper.PlayerHelper.isClearingQueueConfi import static org.schabi.newpipe.player.playqueue.PlayQueueItem.RECOVERY_UNSET; import static org.schabi.newpipe.util.ExtractorHelper.showMetaInfoInTextView; import static org.schabi.newpipe.util.ListHelper.getUrlAndNonTorrentStreams; +import static org.schabi.newpipe.util.NavigationHelper.openPlayQueue; +import static org.schabi.newpipe.util.NavigationHelper.playWithKore; import android.animation.ValueAnimator; import android.app.Activity; @@ -119,6 +121,7 @@ import java.util.List; import java.util.Objects; import java.util.Optional; import java.util.concurrent.TimeUnit; +import java.util.function.Consumer; import icepick.State; import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; @@ -129,9 +132,6 @@ import io.reactivex.rxjava3.schedulers.Schedulers; public final class VideoDetailFragment extends BaseStateFragment implements BackPressable, - SharedPreferences.OnSharedPreferenceChangeListener, - View.OnClickListener, - View.OnLongClickListener, PlayerServiceExtendedEventListener, OnKeyDownListener { public static final String KEY_SWITCHING_PLAYERS = "switching_players"; @@ -167,6 +167,20 @@ public final class VideoDetailFragment private boolean tabSettingsChanged = false; private int lastAppBarVerticalOffset = Integer.MAX_VALUE; // prevents useless updates + private final SharedPreferences.OnSharedPreferenceChangeListener preferenceChangeListener = + (sharedPreferences, key) -> { + if (key.equals(getString(R.string.show_comments_key))) { + showComments = sharedPreferences.getBoolean(key, true); + tabSettingsChanged = true; + } else if (key.equals(getString(R.string.show_next_video_key))) { + showRelatedItems = sharedPreferences.getBoolean(key, true); + tabSettingsChanged = true; + } else if (key.equals(getString(R.string.show_description_key))) { + showDescription = sharedPreferences.getBoolean(key, true); + tabSettingsChanged = true; + } + }; + @State protected int serviceId = Constants.NO_SERVICE_ID; @State @@ -290,7 +304,7 @@ public final class VideoDetailFragment showDescription = prefs.getBoolean(getString(R.string.show_description_key), true); selectedTabTag = prefs.getString( getString(R.string.stream_info_selected_tab_key), COMMENTS_TAB_TAG); - prefs.registerOnSharedPreferenceChangeListener(this); + prefs.registerOnSharedPreferenceChangeListener(preferenceChangeListener); setupBroadcastReceiver(); @@ -375,7 +389,7 @@ public final class VideoDetailFragment } PreferenceManager.getDefaultSharedPreferences(activity) - .unregisterOnSharedPreferenceChangeListener(this); + .unregisterOnSharedPreferenceChangeListener(preferenceChangeListener); activity.unregisterReceiver(broadcastReceiver); activity.getContentResolver().unregisterContentObserver(settingsContentObserver); @@ -421,130 +435,129 @@ public final class VideoDetailFragment } } - @Override - public void onSharedPreferenceChanged(final SharedPreferences sharedPreferences, - final String key) { - if (key.equals(getString(R.string.show_comments_key))) { - showComments = sharedPreferences.getBoolean(key, true); - tabSettingsChanged = true; - } else if (key.equals(getString(R.string.show_next_video_key))) { - showRelatedItems = sharedPreferences.getBoolean(key, true); - tabSettingsChanged = true; - } else if (key.equals(getString(R.string.show_description_key))) { - showDescription = sharedPreferences.getBoolean(key, true); - tabSettingsChanged = true; - } - } - /*////////////////////////////////////////////////////////////////////////// // OnClick //////////////////////////////////////////////////////////////////////////*/ - @Override - public void onClick(final View v) { - switch (v.getId()) { - case R.id.detail_controls_background: - openBackgroundPlayer(false); - break; - case R.id.detail_controls_popup: - openPopupPlayer(false); - break; - case R.id.detail_controls_playlist_append: - if (getFM() != null && currentInfo != null) { - disposables.add( - PlaylistDialog.createCorrespondingDialog( - getContext(), - List.of(new StreamEntity(currentInfo)), - dialog -> dialog.show(getFM(), TAG) - ) - ); - } - break; - case R.id.detail_controls_download: - if (PermissionHelper.checkStoragePermissions(activity, - PermissionHelper.DOWNLOAD_DIALOG_REQUEST_CODE)) { - this.openDownloadDialog(); - } - break; - case R.id.detail_controls_share: - if (currentInfo != null) { - ShareUtils.shareText(requireContext(), currentInfo.getName(), - currentInfo.getUrl(), currentInfo.getThumbnailUrl()); - } - break; - case R.id.detail_controls_open_in_browser: - if (currentInfo != null) { - ShareUtils.openUrlInBrowser(requireContext(), currentInfo.getUrl()); - } - break; - case R.id.detail_controls_play_with_kodi: - if (currentInfo != null) { - try { - NavigationHelper.playWithKore( - requireContext(), Uri.parse(currentInfo.getUrl())); - } catch (final Exception e) { - if (DEBUG) { - Log.i(TAG, "Failed to start kore", e); - } - KoreUtils.showInstallKoreDialog(requireContext()); - } - } - break; - case R.id.detail_uploader_root_layout: - if (isEmpty(currentInfo.getSubChannelUrl())) { - if (!isEmpty(currentInfo.getUploaderUrl())) { - openChannel(currentInfo.getUploaderUrl(), currentInfo.getUploaderName()); - } - - if (DEBUG) { - Log.i(TAG, "Can't open sub-channel because we got no channel URL"); - } - } else { - openChannel(currentInfo.getSubChannelUrl(), - currentInfo.getSubChannelName()); - } - break; - case R.id.detail_thumbnail_root_layout: - // make sure not to open any player if there is nothing currently loaded! - // FIXME removing this `if` causes the player service to start correctly, then stop, - // then restart badly without calling `startForeground()`, causing a crash when - // later closing the detail fragment - if (currentInfo != null) { - autoPlayEnabled = true; // forcefully start playing - // FIXME Workaround #7427 - if (isPlayerAvailable()) { - player.setRecovery(); - } - openVideoPlayerAutoFullscreen(); - } - break; - case R.id.detail_title_root_layout: - toggleTitleAndSecondaryControls(); - break; - case R.id.overlay_thumbnail: - case R.id.overlay_metadata_layout: - case R.id.overlay_buttons_layout: - bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED); - break; - case R.id.overlay_play_queue_button: - NavigationHelper.openPlayQueue(getContext()); - break; - case R.id.overlay_play_pause_button: - if (playerIsNotStopped()) { - player.playPause(); - player.UIs().get(VideoPlayerUi.class).ifPresent(ui -> ui.hideControls(0, 0)); - showSystemUi(); - } else { - autoPlayEnabled = true; // forcefully start playing - openVideoPlayer(false); + private void setOnClickListeners() { + binding.detailTitleRootLayout.setOnClickListener(v -> toggleTitleAndSecondaryControls()); + binding.detailUploaderRootLayout.setOnClickListener(makeOnClickListener(info -> { + if (isEmpty(info.getSubChannelUrl())) { + if (!isEmpty(info.getUploaderUrl())) { + openChannel(info.getUploaderUrl(), info.getUploaderName()); } - setOverlayPlayPauseImage(isPlayerAvailable() && player.isPlaying()); - break; - case R.id.overlay_close_button: - bottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN); - break; + if (DEBUG) { + Log.i(TAG, "Can't open sub-channel because we got no channel URL"); + } + } else { + openChannel(info.getSubChannelUrl(), info.getSubChannelName()); + } + })); + binding.detailThumbnailRootLayout.setOnClickListener(v -> { + autoPlayEnabled = true; // forcefully start playing + // FIXME Workaround #7427 + if (isPlayerAvailable()) { + player.setRecovery(); + } + openVideoPlayerAutoFullscreen(); + }); + + binding.detailControlsBackground.setOnClickListener(v -> openBackgroundPlayer(false)); + binding.detailControlsPopup.setOnClickListener(v -> openPopupPlayer(false)); + binding.detailControlsPlaylistAppend.setOnClickListener(makeOnClickListener(info -> + disposables.add(PlaylistDialog.createCorrespondingDialog(requireContext(), + List.of(new StreamEntity(info)), + dialog -> dialog.show(getParentFragmentManager(), TAG))))); + binding.detailControlsDownload.setOnClickListener(v -> { + if (PermissionHelper.checkStoragePermissions(activity, + PermissionHelper.DOWNLOAD_DIALOG_REQUEST_CODE)) { + openDownloadDialog(); + } + }); + binding.detailControlsShare.setOnClickListener(makeOnClickListener(info -> + ShareUtils.shareText(requireContext(), info.getName(), info.getUrl(), + info.getThumbnailUrl()))); + binding.detailControlsOpenInBrowser.setOnClickListener(makeOnClickListener(info -> + ShareUtils.openUrlInBrowser(requireContext(), info.getUrl()))); + binding.detailControlsPlayWithKodi.setOnClickListener(makeOnClickListener(info -> { + try { + playWithKore(requireContext(), Uri.parse(info.getUrl())); + } catch (final Exception e) { + if (DEBUG) { + Log.i(TAG, "Failed to start kore", e); + } + KoreUtils.showInstallKoreDialog(requireContext()); + } + })); + if (DEBUG) { + binding.detailControlsCrashThePlayer.setOnClickListener(v -> + VideoDetailPlayerCrasher.onCrashThePlayer(requireContext(), player)); } + + final View.OnClickListener overlayListener = v -> bottomSheetBehavior + .setState(BottomSheetBehavior.STATE_EXPANDED); + binding.overlayThumbnail.setOnClickListener(overlayListener); + binding.overlayMetadataLayout.setOnClickListener(overlayListener); + binding.overlayButtonsLayout.setOnClickListener(overlayListener); + binding.overlayCloseButton.setOnClickListener(v -> bottomSheetBehavior + .setState(BottomSheetBehavior.STATE_HIDDEN)); + binding.overlayPlayQueueButton.setOnClickListener(v -> openPlayQueue(requireContext())); + binding.overlayPlayPauseButton.setOnClickListener(v -> { + if (playerIsNotStopped()) { + player.playPause(); + player.UIs().get(VideoPlayerUi.class).ifPresent(ui -> ui.hideControls(0, 0)); + showSystemUi(); + } else { + autoPlayEnabled = true; // forcefully start playing + openVideoPlayer(false); + } + + setOverlayPlayPauseImage(isPlayerAvailable() && player.isPlaying()); + }); + } + + private View.OnClickListener makeOnClickListener(final Consumer consumer) { + return v -> { + if (currentInfo != null) { + consumer.accept(currentInfo); + } + }; + } + + private void setOnLongClickListeners() { + binding.detailTitleRootLayout.setOnLongClickListener(makeOnLongClickListener(info -> + ShareUtils.copyToClipboard(requireContext(), + binding.detailVideoTitleView.getText().toString()))); + binding.detailUploaderRootLayout.setOnLongClickListener(makeOnLongClickListener(info -> { + if (isEmpty(info.getSubChannelUrl())) { + Log.w(TAG, "Can't open parent channel because we got no parent channel URL"); + } else { + openChannel(info.getUploaderUrl(), info.getUploaderName()); + } + })); + + binding.detailControlsBackground.setOnLongClickListener(makeOnLongClickListener(info -> + openBackgroundPlayer(true))); + binding.detailControlsPopup.setOnLongClickListener(makeOnLongClickListener(info -> + openPopupPlayer(true))); + binding.detailControlsDownload.setOnLongClickListener(makeOnLongClickListener(info -> + NavigationHelper.openDownloads(activity))); + + final View.OnLongClickListener overlayListener = makeOnLongClickListener(info -> + openChannel(info.getUploaderUrl(), info.getUploaderName())); + binding.overlayThumbnail.setOnLongClickListener(overlayListener); + binding.overlayMetadataLayout.setOnLongClickListener(overlayListener); + } + + private View.OnLongClickListener makeOnLongClickListener(final Consumer consumer) { + return v -> { + if (isLoading.get() || currentInfo == null) { + return false; + } + consumer.accept(currentInfo); + return true; + }; } private void openChannel(final String subChannelUrl, final String subChannelName) { @@ -556,43 +569,6 @@ public final class VideoDetailFragment } } - @Override - public boolean onLongClick(final View v) { - if (isLoading.get() || currentInfo == null) { - return false; - } - - switch (v.getId()) { - case R.id.detail_controls_background: - openBackgroundPlayer(true); - break; - case R.id.detail_controls_popup: - openPopupPlayer(true); - break; - case R.id.detail_controls_download: - NavigationHelper.openDownloads(activity); - break; - case R.id.overlay_thumbnail: - case R.id.overlay_metadata_layout: - openChannel(currentInfo.getUploaderUrl(), currentInfo.getUploaderName()); - break; - case R.id.detail_uploader_root_layout: - if (isEmpty(currentInfo.getSubChannelUrl())) { - Log.w(TAG, - "Can't open parent channel because we got no parent channel URL"); - } else { - openChannel(currentInfo.getUploaderUrl(), currentInfo.getUploaderName()); - } - break; - case R.id.detail_title_root_layout: - ShareUtils.copyToClipboard(requireContext(), - binding.detailVideoTitleView.getText().toString()); - break; - } - - return true; - } - private void toggleTitleAndSecondaryControls() { if (binding.detailSecondaryControlPanel.getVisibility() == View.GONE) { binding.detailVideoTitleView.setMaxLines(10); @@ -613,11 +589,6 @@ public final class VideoDetailFragment // Init //////////////////////////////////////////////////////////////////////////*/ - @Override - public void onViewCreated(@NonNull final View rootView, final Bundle savedInstanceState) { - super.onViewCreated(rootView, savedInstanceState); - } - @Override // called from onViewCreated in {@link BaseFragment#onViewCreated} protected void initViews(final View rootView, final Bundle savedInstanceState) { super.initViews(rootView, savedInstanceState); @@ -658,41 +629,25 @@ public final class VideoDetailFragment protected void initListeners() { super.initListeners(); - binding.detailTitleRootLayout.setOnClickListener(this); - binding.detailTitleRootLayout.setOnLongClickListener(this); - binding.detailUploaderRootLayout.setOnClickListener(this); - binding.detailUploaderRootLayout.setOnLongClickListener(this); - binding.detailThumbnailRootLayout.setOnClickListener(this); + setOnClickListeners(); + setOnLongClickListeners(); - binding.detailControlsBackground.setOnClickListener(this); - binding.detailControlsBackground.setOnLongClickListener(this); - binding.detailControlsPopup.setOnClickListener(this); - binding.detailControlsPopup.setOnLongClickListener(this); - binding.detailControlsPlaylistAppend.setOnClickListener(this); - binding.detailControlsDownload.setOnClickListener(this); - binding.detailControlsDownload.setOnLongClickListener(this); - binding.detailControlsShare.setOnClickListener(this); - binding.detailControlsOpenInBrowser.setOnClickListener(this); - binding.detailControlsPlayWithKodi.setOnClickListener(this); - if (DEBUG) { - binding.detailControlsCrashThePlayer.setOnClickListener( - v -> VideoDetailPlayerCrasher.onCrashThePlayer( - this.getContext(), - this.player) - ); - } + final View.OnTouchListener controlsTouchListener = (view, motionEvent) -> { + if (!PreferenceManager.getDefaultSharedPreferences(activity) + .getBoolean(getString(R.string.show_hold_to_append_key), true)) { + return false; + } - binding.overlayThumbnail.setOnClickListener(this); - binding.overlayThumbnail.setOnLongClickListener(this); - binding.overlayMetadataLayout.setOnClickListener(this); - binding.overlayMetadataLayout.setOnLongClickListener(this); - binding.overlayButtonsLayout.setOnClickListener(this); - binding.overlayPlayQueueButton.setOnClickListener(this); - binding.overlayCloseButton.setOnClickListener(this); - binding.overlayPlayPauseButton.setOnClickListener(this); - - binding.detailControlsBackground.setOnTouchListener(getOnControlsTouchListener()); - binding.detailControlsPopup.setOnTouchListener(getOnControlsTouchListener()); + if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) { + animate(binding.touchAppendDetail, true, 250, AnimationType.ALPHA, + 0, () -> + animate(binding.touchAppendDetail, false, 1500, + AnimationType.ALPHA, 1000)); + } + return false; + }; + binding.detailControlsBackground.setOnTouchListener(controlsTouchListener); + binding.detailControlsPopup.setOnTouchListener(controlsTouchListener); binding.appBarLayout.addOnOffsetChangedListener((layout, verticalOffset) -> { // prevent useless updates to tab layout visibility if nothing changed @@ -711,23 +666,6 @@ public final class VideoDetailFragment } } - private View.OnTouchListener getOnControlsTouchListener() { - return (view, motionEvent) -> { - if (!PreferenceManager.getDefaultSharedPreferences(activity) - .getBoolean(getString(R.string.show_hold_to_append_key), true)) { - return false; - } - - if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) { - animate(binding.touchAppendDetail, true, 250, AnimationType.ALPHA, - 0, () -> - animate(binding.touchAppendDetail, false, 1500, - AnimationType.ALPHA, 1000)); - } - return false; - }; - } - private void initThumbnailViews(@NonNull final StreamInfo info) { PicassoHelper.loadDetailsThumbnail(info.getThumbnailUrl()).tag(PICASSO_VIDEO_DETAILS_TAG) .into(binding.detailThumbnailImageView, new Callback() { From 048b0972de545f1ceb5e3b89a36f1a8b05a4db83 Mon Sep 17 00:00:00 2001 From: Stypox Date: Sat, 5 Nov 2022 23:44:35 +0100 Subject: [PATCH 03/23] Set compileSdk and targetSdk to 33 (Android 13) android:exported in now required in the manifest on all activities/services/receivers/providers. It was set to true for those that need to interact with outside apps or the OS, while others have exported=false. This also required updating LeakCanary to the latest version as the older version being used was not using android:exported in AndroidManifest.xml. --- app/build.gradle | 6 +- app/src/main/AndroidManifest.xml | 67 ++++++++++++------- .../gesture/PopupPlayerGestureListener.kt | 6 +- 3 files changed, 50 insertions(+), 29 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 206c830e7..2dfbeb55f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -8,14 +8,14 @@ plugins { } android { - compileSdk 32 + compileSdk 33 namespace 'org.schabi.newpipe' defaultConfig { applicationId "org.schabi.newpipe" resValue "string", "app_name", "NewPipe" minSdk 21 - targetSdk 29 + targetSdk 33 versionCode 991 versionName "0.24.1" @@ -107,7 +107,7 @@ ext { groupieVersion = '2.10.1' markwonVersion = '4.6.2' - leakCanaryVersion = '2.5' + leakCanaryVersion = '2.9.1' stethoVersion = '1.6.0' mockitoVersion = '4.0.0' assertJVersion = '3.23.1' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index be14274aa..7a0eacdf6 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -24,11 +24,12 @@ android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:logo="@mipmap/ic_launcher" - android:theme="@style/OpeningTheme" android:resizeableActivity="true" + android:theme="@style/OpeningTheme" tools:ignore="AllowBackup"> @@ -39,7 +40,9 @@ - + @@ -47,7 +50,7 @@ @@ -56,15 +59,18 @@ @@ -73,6 +79,7 @@ @@ -85,13 +92,18 @@ - + + @@ -99,6 +111,7 @@ @@ -109,6 +122,7 @@ @@ -354,30 +369,30 @@ - - - + + + - - + + - - - + + + - - - + + + - - + + - - - + + + @@ -386,11 +401,17 @@ android:exported="false" /> - + - + - + 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 666ea6a46..a540c0ab0 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 @@ -160,15 +160,15 @@ class PopupPlayerGestureListener( } } - override fun onLongPress(e: MotionEvent?) { + override fun onLongPress(e: MotionEvent) { playerUi.updateScreenSize() playerUi.checkPopupPositionBounds() playerUi.changePopupSize(playerUi.screenWidth) } override fun onFling( - e1: MotionEvent?, - e2: MotionEvent?, + e1: MotionEvent, + e2: MotionEvent, velocityX: Float, velocityY: Float ): Boolean { From 8db90ba449f4ca178518ca1e1504c9c58ec98d13 Mon Sep 17 00:00:00 2001 From: Isira Seneviratne Date: Mon, 22 Aug 2022 09:25:08 +0530 Subject: [PATCH 04/23] Use SparseArrayCompat for thumbnails. --- .../fragments/list/search/SearchFragment.java | 14 +-- .../SeekbarPreviewThumbnailHolder.java | 97 +++++++------------ .../giga/service/DownloadManagerService.java | 31 +++--- 3 files changed, 57 insertions(+), 85 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 5175e0096..26a283229 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 @@ -33,6 +33,7 @@ import androidx.annotation.Nullable; import androidx.appcompat.app.ActionBar; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.widget.TooltipCompat; +import androidx.collection.SparseArrayCompat; import androidx.core.text.HtmlCompat; import androidx.preference.PreferenceManager; import androidx.recyclerview.widget.ItemTouchHelper; @@ -70,9 +71,7 @@ import org.schabi.newpipe.util.ServiceHelper; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.Queue; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; @@ -141,7 +140,7 @@ public class SearchFragment extends BaseListFragment menuItemToFilterName = null; + private final SparseArrayCompat menuItemToFilterName = new SparseArrayCompat<>(); private StreamingService service; private Page nextPage; private boolean showLocalSuggestions = true; @@ -426,8 +425,6 @@ public class SearchFragment extends BaseListFragment(); - int itemId = 0; boolean isFirstItem = true; final Context c = getContext(); @@ -468,11 +465,8 @@ public class SearchFragment extends BaseListFragment cf = new ArrayList<>(1); - cf.add(menuItemToFilterName.get(item.getItemId())); - changeContentFilter(item, cf); - } + final var filter = Collections.singletonList(menuItemToFilterName.get(item.getItemId())); + changeContentFilter(item, filter); return true; } 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 08c6366c8..50ffa2f2a 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 @@ -1,6 +1,7 @@ package org.schabi.newpipe.player.seekbarpreview; import static org.schabi.newpipe.player.seekbarpreview.SeekbarPreviewThumbnailHelper.SeekbarPreviewThumbnailType; +import static org.schabi.newpipe.player.seekbarpreview.SeekbarPreviewThumbnailHelper.getSeekbarPreviewThumbnailType; import android.content.Context; import android.graphics.Bitmap; @@ -8,6 +9,7 @@ import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.collection.SparseArrayCompat; import com.google.common.base.Stopwatch; @@ -15,12 +17,9 @@ import org.schabi.newpipe.extractor.stream.Frameset; import org.schabi.newpipe.util.PicassoHelper; import java.util.Comparator; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.Optional; import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.function.Supplier; @@ -34,18 +33,15 @@ public class SeekbarPreviewThumbnailHolder { // Key = Position of the picture in milliseconds // Supplier = Supplies the bitmap for that position - private final Map> seekbarPreviewData = new ConcurrentHashMap<>(); + private final SparseArrayCompat> seekbarPreviewData = + new SparseArrayCompat<>(); // This ensures that if the reset is still undergoing // and another reset starts, only the last reset is processed private UUID currentUpdateRequestIdentifier = UUID.randomUUID(); - public synchronized void resetFrom( - @NonNull final Context context, - final List framesets) { - - final int seekbarPreviewType = - SeekbarPreviewThumbnailHelper.getSeekbarPreviewThumbnailType(context); + public void resetFrom(@NonNull final Context context, final List framesets) { + final int seekbarPreviewType = getSeekbarPreviewThumbnailType(context); final UUID updateRequestIdentifier = UUID.randomUUID(); this.currentUpdateRequestIdentifier = updateRequestIdentifier; @@ -63,13 +59,12 @@ public class SeekbarPreviewThumbnailHolder { executorService.shutdown(); } - private void resetFromAsync( - final int seekbarPreviewType, - final List framesets, - final UUID updateRequestIdentifier) { - + private void resetFromAsync(final int seekbarPreviewType, final List framesets, + final UUID updateRequestIdentifier) { Log.d(TAG, "Clearing seekbarPreviewData"); - seekbarPreviewData.clear(); + synchronized (seekbarPreviewData) { + seekbarPreviewData.clear(); + } if (seekbarPreviewType == SeekbarPreviewThumbnailType.NONE) { Log.d(TAG, "Not processing seekbarPreviewData due to settings"); @@ -94,10 +89,8 @@ public class SeekbarPreviewThumbnailHolder { generateDataFrom(frameset, updateRequestIdentifier); } - private Frameset getFrameSetForType( - final List framesets, - final int seekbarPreviewType) { - + private Frameset getFrameSetForType(final List framesets, + final int seekbarPreviewType) { if (seekbarPreviewType == SeekbarPreviewThumbnailType.HIGH_QUALITY) { Log.d(TAG, "Strategy for seekbarPreviewData: high quality"); return framesets.stream() @@ -111,17 +104,14 @@ public class SeekbarPreviewThumbnailHolder { } } - private void generateDataFrom( - final Frameset frameset, - final UUID updateRequestIdentifier) { - + private void generateDataFrom(final Frameset frameset, final UUID updateRequestIdentifier) { Log.d(TAG, "Starting generation of seekbarPreviewData"); final Stopwatch sw = Log.isLoggable(TAG, Log.DEBUG) ? Stopwatch.createStarted() : null; int currentPosMs = 0; int pos = 1; - final int frameCountPerUrl = frameset.getFramesPerPageX() * frameset.getFramesPerPageY(); + final int urlFrameCount = frameset.getFramesPerPageX() * frameset.getFramesPerPageY(); // Process each url in the frameset for (final String url : frameset.getUrls()) { @@ -130,11 +120,11 @@ public class SeekbarPreviewThumbnailHolder { // The data is not added directly to "seekbarPreviewData" due to // concurrency and checks for "updateRequestIdentifier" - final Map> generatedDataForUrl = new HashMap<>(); + final var generatedDataForUrl = new SparseArrayCompat>(urlFrameCount); // The bitmap consists of several images, which we process here // foreach frame in the returned bitmap - for (int i = 0; i < frameCountPerUrl; i++) { + for (int i = 0; i < urlFrameCount; i++) { // Frames outside the video length are skipped if (pos > frameset.getTotalCount()) { break; @@ -161,7 +151,9 @@ public class SeekbarPreviewThumbnailHolder { // Check if we are still the latest request // If not abort method execution if (isRequestIdentifierCurrent(updateRequestIdentifier)) { - seekbarPreviewData.putAll(generatedDataForUrl); + synchronized (seekbarPreviewData) { + seekbarPreviewData.putAll(generatedDataForUrl); + } } else { Log.d(TAG, "Aborted of generation of seekbarPreviewData"); break; @@ -169,7 +161,7 @@ public class SeekbarPreviewThumbnailHolder { } if (sw != null) { - Log.d(TAG, "Generation of seekbarPreviewData took " + sw.stop().toString()); + Log.d(TAG, "Generation of seekbarPreviewData took " + sw.stop()); } } @@ -189,17 +181,14 @@ public class SeekbarPreviewThumbnailHolder { final Bitmap bitmap = PicassoHelper.loadSeekbarThumbnailPreview(url).get(); if (sw != null) { - Log.d(TAG, - "Download of bitmap for seekbarPreview from '" + url - + "' took " + sw.stop().toString()); + Log.d(TAG, "Download of bitmap for seekbarPreview from '" + url + "' took " + + sw.stop()); } return bitmap; } catch (final Exception ex) { - Log.w(TAG, - "Failed to get bitmap for seekbarPreview from url='" + url - + "' in time", - ex); + Log.w(TAG, "Failed to get bitmap for seekbarPreview from url='" + url + + "' in time", ex); return null; } } @@ -208,32 +197,20 @@ public class SeekbarPreviewThumbnailHolder { return this.currentUpdateRequestIdentifier.equals(requestIdentifier); } - public Optional getBitmapAt(final int positionInMs) { - // Check if the BitmapData is empty - if (seekbarPreviewData.isEmpty()) { - return Optional.empty(); + // Get the frame supplier closest to the requested position + Supplier closestFrame = () -> null; + synchronized (seekbarPreviewData) { + int min = Integer.MAX_VALUE; + for (int i = 0; i < seekbarPreviewData.size(); i++) { + final int pos = Math.abs(seekbarPreviewData.keyAt(i) - positionInMs); + if (pos < min) { + closestFrame = seekbarPreviewData.valueAt(i); + min = pos; + } + } } - // Get the closest frame to the requested position - final int closestIndexPosition = - seekbarPreviewData.keySet().stream() - .min(Comparator.comparingInt(i -> Math.abs(i - positionInMs))) - .orElse(-1); - - // this should never happen, because - // it indicates that "seekbarPreviewData" is empty which was already checked - if (closestIndexPosition == -1) { - return Optional.empty(); - } - - try { - // Get the bitmap for the position (executes the supplier) - return Optional.ofNullable(seekbarPreviewData.get(closestIndexPosition).get()); - } catch (final Exception ex) { - // If there is an error, log it and return Optional.empty - Log.w(TAG, "Unable to get seekbar preview", ex); - return Optional.empty(); - } + return Optional.ofNullable(closestFrame.get()); } } diff --git a/app/src/main/java/us/shandian/giga/service/DownloadManagerService.java b/app/src/main/java/us/shandian/giga/service/DownloadManagerService.java index 25ec87f80..dc56ee205 100755 --- a/app/src/main/java/us/shandian/giga/service/DownloadManagerService.java +++ b/app/src/main/java/us/shandian/giga/service/DownloadManagerService.java @@ -1,5 +1,8 @@ package us.shandian.giga.service; +import static org.schabi.newpipe.BuildConfig.APPLICATION_ID; +import static org.schabi.newpipe.BuildConfig.DEBUG; + import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; @@ -22,12 +25,12 @@ import android.os.IBinder; import android.os.Message; import android.os.Parcelable; import android.util.Log; -import android.util.SparseArray; import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.StringRes; +import androidx.collection.SparseArrayCompat; import androidx.core.app.NotificationCompat; import androidx.core.app.NotificationCompat.Builder; import androidx.core.app.ServiceCompat; @@ -37,24 +40,21 @@ import androidx.preference.PreferenceManager; import org.schabi.newpipe.R; import org.schabi.newpipe.download.DownloadActivity; import org.schabi.newpipe.player.helper.LockManager; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; - -import us.shandian.giga.get.DownloadMission; -import us.shandian.giga.get.MissionRecoveryInfo; import org.schabi.newpipe.streams.io.StoredDirectoryHelper; import org.schabi.newpipe.streams.io.StoredFileHelper; import org.schabi.newpipe.util.Localization; import org.schabi.newpipe.util.PendingIntentCompat; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import us.shandian.giga.get.DownloadMission; +import us.shandian.giga.get.MissionRecoveryInfo; import us.shandian.giga.postprocessing.Postprocessing; import us.shandian.giga.service.DownloadManager.NetworkState; -import static org.schabi.newpipe.BuildConfig.APPLICATION_ID; -import static org.schabi.newpipe.BuildConfig.DEBUG; - public class DownloadManagerService extends Service { private static final String TAG = "DownloadManagerService"; @@ -95,7 +95,7 @@ public class DownloadManagerService extends Service { private Builder downloadDoneNotification = null; private StringBuilder downloadDoneList = null; - private final ArrayList mEchoObservers = new ArrayList<>(1); + private final List mEchoObservers = new ArrayList<>(1); private ConnectivityManager mConnectivityManager; private ConnectivityManager.NetworkCallback mNetworkStateListenerL = null; @@ -108,7 +108,8 @@ public class DownloadManagerService extends Service { private int downloadFailedNotificationID = DOWNLOADS_NOTIFICATION_ID + 1; private Builder downloadFailedNotification = null; - private final SparseArray mFailedDownloads = new SparseArray<>(5); + private final SparseArrayCompat mFailedDownloads = + new SparseArrayCompat<>(5); private Bitmap icLauncher; private Bitmap icDownloadDone; @@ -277,7 +278,7 @@ public class DownloadManagerService extends Service { } if (msg.what != MESSAGE_ERROR) - mFailedDownloads.delete(mFailedDownloads.indexOfValue(mission)); + mFailedDownloads.remove(mFailedDownloads.indexOfValue(mission)); for (Callback observer : mEchoObservers) observer.handleMessage(msg); @@ -461,7 +462,7 @@ public class DownloadManagerService extends Service { } public void notifyFailedDownload(DownloadMission mission) { - if (!mDownloadNotificationEnable || mFailedDownloads.indexOfValue(mission) >= 0) return; + if (!mDownloadNotificationEnable || mFailedDownloads.containsValue(mission)) return; int id = downloadFailedNotificationID++; mFailedDownloads.put(id, mission); From d6617007d4ec48f900bf37b4e9797330f5cdb38e Mon Sep 17 00:00:00 2001 From: Isira Seneviratne Date: Tue, 22 Nov 2022 18:31:58 +0530 Subject: [PATCH 05/23] Use SparseArrayCompat instead of SparseArray in StreamItemAdapter. Make additional small improvements as well. --- .../newpipe/util/StreamItemAdapterTest.kt | 18 ++---- .../newpipe/download/DownloadDialog.java | 12 ++-- .../newpipe/util/StreamItemAdapter.java | 57 +++++++------------ 3 files changed, 31 insertions(+), 56 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 016feb576..0fe251c16 100644 --- a/app/src/androidTest/java/org/schabi/newpipe/util/StreamItemAdapterTest.kt +++ b/app/src/androidTest/java/org/schabi/newpipe/util/StreamItemAdapterTest.kt @@ -1,12 +1,12 @@ package org.schabi.newpipe.util import android.content.Context -import android.util.SparseArray import android.view.View import android.view.View.GONE import android.view.View.INVISIBLE import android.view.View.VISIBLE import android.widget.Spinner +import androidx.collection.SparseArrayCompat import androidx.test.core.app.ApplicationProvider import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.MediumTest @@ -39,9 +39,7 @@ class StreamItemAdapterTest { @Test fun videoStreams_noSecondaryStream() { val adapter = StreamItemAdapter( - context, - getVideoStreams(true, true, true, true), - null + getVideoStreams(true, true, true, true) ) spinner.adapter = adapter @@ -54,7 +52,6 @@ class StreamItemAdapterTest { @Test fun videoStreams_hasSecondaryStream() { val adapter = StreamItemAdapter( - context, getVideoStreams(false, true, false, true), getAudioStreams(false, true, false, true) ) @@ -69,7 +66,6 @@ class StreamItemAdapterTest { @Test fun videoStreams_Mixed() { val adapter = StreamItemAdapter( - context, getVideoStreams(true, true, true, true, true, false, true, true), getAudioStreams(false, true, false, false, false, true, true, true) ) @@ -88,7 +84,6 @@ class StreamItemAdapterTest { @Test fun subtitleStreams_noIcon() { val adapter = StreamItemAdapter( - context, StreamItemAdapter.StreamSizeWrapper( (0 until 5).map { SubtitlesStream.Builder() @@ -99,8 +94,7 @@ class StreamItemAdapterTest { .build() }, context - ), - null + ) ) spinner.adapter = adapter for (i in 0 until spinner.count) { @@ -111,7 +105,6 @@ class StreamItemAdapterTest { @Test fun audioStreams_noIcon() { val adapter = StreamItemAdapter( - context, StreamItemAdapter.StreamSizeWrapper( (0 until 5).map { AudioStream.Builder() @@ -122,8 +115,7 @@ class StreamItemAdapterTest { .build() }, context - ), - null + ) ) spinner.adapter = adapter for (i in 0 until spinner.count) { @@ -200,7 +192,7 @@ class StreamItemAdapterTest { * Helper function that builds a secondary stream list. */ private fun getSecondaryStreamsFromList(streams: List) = - SparseArray?>(streams.size).apply { + SparseArrayCompat?>(streams.size).apply { streams.forEachIndexed { index, stream -> val secondaryStreamHelper: SecondaryStreamHelper? = stream?.let { SecondaryStreamHelper( 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 2975fe43a..3f3384b8e 100644 --- a/app/src/main/java/org/schabi/newpipe/download/DownloadDialog.java +++ b/app/src/main/java/org/schabi/newpipe/download/DownloadDialog.java @@ -17,7 +17,6 @@ import android.os.Bundle; import android.os.Environment; import android.os.IBinder; import android.util.Log; -import android.util.SparseArray; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -36,6 +35,7 @@ import androidx.annotation.StringRes; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.view.menu.ActionMenuItemView; import androidx.appcompat.widget.Toolbar; +import androidx.collection.SparseArrayCompat; import androidx.documentfile.provider.DocumentFile; import androidx.fragment.app.DialogFragment; import androidx.preference.PreferenceManager; @@ -211,8 +211,7 @@ public class DownloadDialog extends DialogFragment setStyle(STYLE_NO_TITLE, ThemeHelper.getDialogTheme(context)); Icepick.restoreInstanceState(this, savedInstanceState); - final SparseArray> secondaryStreams = - new SparseArray<>(4); + final var secondaryStreams = new SparseArrayCompat>(4); final List videoStreams = wrappedVideoStreams.getStreamsList(); for (int i = 0; i < videoStreams.size(); i++) { @@ -236,10 +235,9 @@ public class DownloadDialog extends DialogFragment } } - this.videoStreamsAdapter = new StreamItemAdapter<>(context, wrappedVideoStreams, - secondaryStreams); - this.audioStreamsAdapter = new StreamItemAdapter<>(context, wrappedAudioStreams); - this.subtitleStreamsAdapter = new StreamItemAdapter<>(context, wrappedSubtitleStreams); + this.videoStreamsAdapter = new StreamItemAdapter<>(wrappedVideoStreams, secondaryStreams); + this.audioStreamsAdapter = new StreamItemAdapter<>(wrappedAudioStreams); + this.subtitleStreamsAdapter = new StreamItemAdapter<>(wrappedSubtitleStreams); final Intent intent = new Intent(context, DownloadManagerService.class); context.startService(intent); 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 4b5e675c9..74de45720 100644 --- a/app/src/main/java/org/schabi/newpipe/util/StreamItemAdapter.java +++ b/app/src/main/java/org/schabi/newpipe/util/StreamItemAdapter.java @@ -1,7 +1,6 @@ package org.schabi.newpipe.util; import android.content.Context; -import android.util.SparseArray; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -11,6 +10,8 @@ import android.widget.Spinner; import android.widget.TextView; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.collection.SparseArrayCompat; import org.schabi.newpipe.DownloaderImpl; import org.schabi.newpipe.R; @@ -39,10 +40,10 @@ import us.shandian.giga.util.Utility; * @param the secondary stream type's class extending {@link Stream} */ public class StreamItemAdapter extends BaseAdapter { - private final Context context; - + @NonNull private final StreamSizeWrapper streamsWrapper; - private final SparseArray> secondaryStreams; + @NonNull + private final SparseArrayCompat> secondaryStreams; /** * Indicates that at least one of the primary streams is an instance of {@link VideoStream}, @@ -51,9 +52,10 @@ public class StreamItemAdapter extends BaseA */ private final boolean hasAnyVideoOnlyStreamWithNoSecondaryStream; - public StreamItemAdapter(final Context context, final StreamSizeWrapper streamsWrapper, - final SparseArray> secondaryStreams) { - this.context = context; + public StreamItemAdapter( + @NonNull final StreamSizeWrapper streamsWrapper, + @NonNull final SparseArrayCompat> secondaryStreams + ) { this.streamsWrapper = streamsWrapper; this.secondaryStreams = secondaryStreams; @@ -61,15 +63,15 @@ public class StreamItemAdapter extends BaseA checkHasAnyVideoOnlyStreamWithNoSecondaryStream(); } - public StreamItemAdapter(final Context context, final StreamSizeWrapper streamsWrapper) { - this(context, streamsWrapper, null); + public StreamItemAdapter(final StreamSizeWrapper streamsWrapper) { + this(streamsWrapper, new SparseArrayCompat<>(0)); } public List getAll() { return streamsWrapper.getStreamsList(); } - public SparseArray> getAllSecondary() { + public SparseArrayCompat> getAllSecondary() { return secondaryStreams; } @@ -106,6 +108,7 @@ public class StreamItemAdapter extends BaseA final View view, final ViewGroup parent, final boolean isDropdownItem) { + final var context = parent.getContext(); View convertView = view; if (convertView == null) { convertView = LayoutInflater.from(context).inflate( @@ -129,7 +132,7 @@ public class StreamItemAdapter extends BaseA if (hasAnyVideoOnlyStreamWithNoSecondaryStream) { if (videoStream.isVideoOnly()) { - woSoundIconVisibility = hasSecondaryStream(position) + woSoundIconVisibility = secondaryStreams.get(position) != null // It has a secondary stream associated with it, so check if it's a // dropdown view so it doesn't look out of place (missing margin) // compared to those that don't. @@ -163,8 +166,7 @@ public class StreamItemAdapter extends BaseA } if (streamsWrapper.getSizeInBytes(position) > 0) { - final SecondaryStreamHelper secondary = secondaryStreams == null ? null - : secondaryStreams.get(position); + final var secondary = secondaryStreams.get(position); if (secondary != null) { final long size = secondary.getSizeInBytes() + streamsWrapper.getSizeInBytes(position); @@ -196,14 +198,6 @@ public class StreamItemAdapter extends BaseA return convertView; } - /** - * @param position which primary stream to check. - * @return whether the primary stream at position has a secondary stream associated with it. - */ - private boolean hasSecondaryStream(final int position) { - return secondaryStreams != null && secondaryStreams.get(position) != null; - } - /** * @return if there are any video-only streams with no secondary stream associated with them. * @see #hasAnyVideoOnlyStreamWithNoSecondaryStream @@ -213,7 +207,7 @@ public class StreamItemAdapter extends BaseA final T stream = streamsWrapper.getStreamsList().get(i); if (stream instanceof VideoStream) { final boolean videoOnly = ((VideoStream) stream).isVideoOnly(); - if (videoOnly && !hasSecondaryStream(i)) { + if (videoOnly && secondaryStreams.get(i) == null) { return true; } } @@ -228,16 +222,15 @@ 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); + private static final StreamSizeWrapper EMPTY = + new StreamSizeWrapper<>(Collections.emptyList(), null); private final List streamsList; private final long[] streamSizes; private final String unknownSize; - public StreamSizeWrapper(final List sL, final Context context) { - this.streamsList = sL != null - ? sL - : Collections.emptyList(); + public StreamSizeWrapper(@NonNull final List streamList, + @Nullable final Context context) { + this.streamsList = streamList; this.streamSizes = new long[streamsList.size()]; this.unknownSize = context == null ? "--.-" : context.getString(R.string.unknown_content); @@ -297,10 +290,6 @@ public class StreamItemAdapter extends BaseA return formatSize(getSizeInBytes(streamIndex)); } - public String getFormattedSize(final T stream) { - return formatSize(getSizeInBytes(stream)); - } - private String formatSize(final long size) { if (size > -1) { return Utility.formatBytes(size); @@ -308,10 +297,6 @@ public class StreamItemAdapter extends BaseA return unknownSize; } - public void setSize(final int streamIndex, final long sizeInBytes) { - streamSizes[streamIndex] = sizeInBytes; - } - public void setSize(final T stream, final long sizeInBytes) { streamSizes[streamsList.indexOf(stream)] = sizeInBytes; } From e5af1c93aeadda204862e4643b7d10037c02d90a Mon Sep 17 00:00:00 2001 From: Jared Fantaye Date: Sat, 26 Nov 2022 15:35:13 +0100 Subject: [PATCH 06/23] Seeking no longer pauses the played video --- .../main/java/org/schabi/newpipe/player/ui/VideoPlayerUi.java | 3 --- 1 file changed, 3 deletions(-) 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 1709755f2..9fb4552b2 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 @@ -602,9 +602,6 @@ public abstract class VideoPlayerUi extends PlayerUi } player.saveWasPlaying(); - if (player.isPlaying()) { - player.getExoPlayer().pause(); - } showControls(0); animate(binding.currentDisplaySeek, true, DEFAULT_CONTROLS_DURATION, From f07886fc5e5ef6068f70f2e1083a7ed8a269e96a Mon Sep 17 00:00:00 2001 From: Stypox Date: Mon, 28 Nov 2022 18:23:47 +0100 Subject: [PATCH 07/23] Add notifications permission --- app/src/main/AndroidManifest.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 7a0eacdf6..7aa1a2939 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -9,6 +9,7 @@ + Date: Mon, 28 Nov 2022 18:49:11 +0100 Subject: [PATCH 08/23] Request permission to send notifications --- .../java/org/schabi/newpipe/MainActivity.java | 12 +++++++++--- .../schabi/newpipe/util/PermissionHelper.java | 16 ++++++++++++++-- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/MainActivity.java b/app/src/main/java/org/schabi/newpipe/MainActivity.java index d4b2305c7..a703b9e80 100644 --- a/app/src/main/java/org/schabi/newpipe/MainActivity.java +++ b/app/src/main/java/org/schabi/newpipe/MainActivity.java @@ -157,9 +157,12 @@ public class MainActivity extends AppCompatActivity { } openMiniPlayerUponPlayerStarted(); - // Schedule worker for checking for new streams and creating corresponding notifications - // if this is enabled by the user. - NotificationWorker.initialize(this); + if (PermissionHelper.checkPostNotificationsPermission(this, + PermissionHelper.POST_NOTIFICATIONS_REQUEST_CODE)) { + // Schedule worker for checking for new streams and creating corresponding notifications + // if this is enabled by the user. + NotificationWorker.initialize(this); + } } @Override @@ -599,6 +602,9 @@ public class MainActivity extends AppCompatActivity { ((VideoDetailFragment) fragment).openDownloadDialog(); } break; + case PermissionHelper.POST_NOTIFICATIONS_REQUEST_CODE: + NotificationWorker.initialize(this); + break; } } diff --git a/app/src/main/java/org/schabi/newpipe/util/PermissionHelper.java b/app/src/main/java/org/schabi/newpipe/util/PermissionHelper.java index f3151ec8b..f47494770 100644 --- a/app/src/main/java/org/schabi/newpipe/util/PermissionHelper.java +++ b/app/src/main/java/org/schabi/newpipe/util/PermissionHelper.java @@ -21,6 +21,7 @@ import org.schabi.newpipe.R; import org.schabi.newpipe.settings.NewPipeSettings; public final class PermissionHelper { + public static final int POST_NOTIFICATIONS_REQUEST_CODE = 779; public static final int DOWNLOAD_DIALOG_REQUEST_CODE = 778; public static final int DOWNLOADS_REQUEST_CODE = 777; @@ -71,8 +72,7 @@ public final class PermissionHelper { // No explanation needed, we can request the permission. ActivityCompat.requestPermissions(activity, - new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, - requestCode); + new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, requestCode); // PERMISSION_WRITE_STORAGE is an // app-defined int constant. The callback method gets the @@ -83,6 +83,18 @@ public final class PermissionHelper { return true; } + public static boolean checkPostNotificationsPermission(final Activity activity, + final int requestCode) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU + && ContextCompat.checkSelfPermission(activity, + Manifest.permission.POST_NOTIFICATIONS) + != PackageManager.PERMISSION_GRANTED) { + ActivityCompat.requestPermissions(activity, + new String[] {Manifest.permission.POST_NOTIFICATIONS}, requestCode); + return false; + } + return true; + } /** * In order to be able to draw over other apps, From a2f2d562f6a2d4e9382e5b212c1232db6df195cd Mon Sep 17 00:00:00 2001 From: Jared Fantaye Date: Thu, 1 Dec 2022 13:01:58 +0100 Subject: [PATCH 09/23] Disabling night theme selection if auto theme is not used --- .../settings/AppearanceSettingsFragment.java | 14 ++++++-------- app/src/main/res/values/strings.xml | 1 + 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/settings/AppearanceSettingsFragment.java b/app/src/main/java/org/schabi/newpipe/settings/AppearanceSettingsFragment.java index 550d64d06..72ce0f201 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/AppearanceSettingsFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/AppearanceSettingsFragment.java @@ -44,7 +44,12 @@ public class AppearanceSettingsFragment extends BasePreferenceFragment { return false; }); } else { - removePreference(nightThemeKey); + // disable the night theme selection + final Preference preference = findPreference(nightThemeKey); + if (preference != null) { + preference.setEnabled(false); + preference.setSummary(getString(R.string.night_theme_available)); + } } } @@ -61,13 +66,6 @@ public class AppearanceSettingsFragment extends BasePreferenceFragment { return super.onPreferenceTreeClick(preference); } - private void removePreference(final String preferenceKey) { - final Preference preference = findPreference(preferenceKey); - if (preference != null) { - getPreferenceScreen().removePreference(preference); - } - } - private void applyThemeChange(final String beginningThemeKey, final String themeKey, final Object newValue) { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 3fa37155a..68f5f67a4 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -714,6 +714,7 @@ Automatic (device theme) Select your favorite night theme — %s You can select your favorite night theme below + This option is only available if Automatic (Device Theme) is selected for Theme Download has started You can now select text inside the description. Note that the page may flicker and links may not be clickable while in selection mode. Enable selecting text in the description From 074a8ff46a4011e12d1c1394c424590b44a3bced Mon Sep 17 00:00:00 2001 From: TacoTheDank Date: Fri, 2 Dec 2022 13:52:30 -0500 Subject: [PATCH 10/23] Update Desugaring to 1.1.8 --- app/build.gradle | 4 ++-- build.gradle | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 206c830e7..b5b6ba0bd 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -179,7 +179,7 @@ sonarqube { dependencies { /** Desugaring **/ - coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.6' + coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.8' /** NewPipe libraries **/ // You can use a local version by uncommenting a few lines in settings.gradle @@ -259,7 +259,7 @@ dependencies { implementation "io.noties.markwon:linkify:${markwonVersion}" // Crash reporting - implementation "ch.acra:acra-core:5.9.3" + implementation "ch.acra:acra-core:5.9.7" // Properly restarting implementation 'com.jakewharton:process-phoenix:2.1.2' diff --git a/build.gradle b/build.gradle index a0c1fdf27..d2f1dc4c5 100644 --- a/build.gradle +++ b/build.gradle @@ -7,7 +7,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:7.3.0' + classpath 'com.android.tools.build:gradle:7.3.1' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // NOTE: Do not place your application dependencies here; they belong From 0923594e51b4300faade4bce79e49793377be3b1 Mon Sep 17 00:00:00 2001 From: Jared Fantaye Date: Sun, 4 Dec 2022 20:35:06 +0100 Subject: [PATCH 11/23] Added option to download items in the queue --- .../java/org/schabi/newpipe/QueueItemMenuUtil.java | 12 ++++++++++++ app/src/main/res/menu/menu_play_queue_item.xml | 3 +++ 2 files changed, 15 insertions(+) diff --git a/app/src/main/java/org/schabi/newpipe/QueueItemMenuUtil.java b/app/src/main/java/org/schabi/newpipe/QueueItemMenuUtil.java index 7c646d0e4..66c19f86d 100644 --- a/app/src/main/java/org/schabi/newpipe/QueueItemMenuUtil.java +++ b/app/src/main/java/org/schabi/newpipe/QueueItemMenuUtil.java @@ -1,5 +1,6 @@ package org.schabi.newpipe; +import static org.schabi.newpipe.util.SparseItemUtil.fetchStreamInfoAndSaveToDatabase; import static org.schabi.newpipe.util.external_communication.ShareUtils.shareText; import android.content.Context; @@ -7,9 +8,11 @@ import android.view.ContextThemeWrapper; import android.view.View; import android.widget.PopupMenu; +import androidx.appcompat.app.AppCompatActivity; import androidx.fragment.app.FragmentManager; import org.schabi.newpipe.database.stream.model.StreamEntity; +import org.schabi.newpipe.download.DownloadDialog; import org.schabi.newpipe.local.dialog.PlaylistDialog; import org.schabi.newpipe.player.playqueue.PlayQueue; import org.schabi.newpipe.player.playqueue.PlayQueueItem; @@ -75,6 +78,15 @@ public final class QueueItemMenuUtil { shareText(context, item.getTitle(), item.getUrl(), item.getThumbnailUrl()); return true; + case R.id.menu_item_download: + fetchStreamInfoAndSaveToDatabase(context, item.getServiceId(), + item.getUrl(), info -> { + final DownloadDialog downloadDialog = new DownloadDialog(context, + info); + downloadDialog.show(((AppCompatActivity) context) + .getSupportFragmentManager(), "downloadDialog"); + }); + return true; } return false; }); diff --git a/app/src/main/res/menu/menu_play_queue_item.xml b/app/src/main/res/menu/menu_play_queue_item.xml index b23f8008f..00c63e1e0 100644 --- a/app/src/main/res/menu/menu_play_queue_item.xml +++ b/app/src/main/res/menu/menu_play_queue_item.xml @@ -16,4 +16,7 @@ + \ No newline at end of file From 5fc85fa2e01ef95cffd59571a2c500d661354653 Mon Sep 17 00:00:00 2001 From: Jared Fantaye Date: Mon, 5 Dec 2022 21:21:46 +0100 Subject: [PATCH 12/23] Implemented suggestions --- .../schabi/newpipe/settings/AppearanceSettingsFragment.java | 3 ++- app/src/main/res/values/strings.xml | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/settings/AppearanceSettingsFragment.java b/app/src/main/java/org/schabi/newpipe/settings/AppearanceSettingsFragment.java index 72ce0f201..ef0e8670c 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/AppearanceSettingsFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/AppearanceSettingsFragment.java @@ -48,7 +48,8 @@ public class AppearanceSettingsFragment extends BasePreferenceFragment { final Preference preference = findPreference(nightThemeKey); if (preference != null) { preference.setEnabled(false); - preference.setSummary(getString(R.string.night_theme_available)); + preference.setSummary(getString(R.string.night_theme_available, + getString(R.string.auto_device_theme_title))); } } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 68f5f67a4..d4172ff36 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -714,7 +714,7 @@ Automatic (device theme) Select your favorite night theme — %s You can select your favorite night theme below - This option is only available if Automatic (Device Theme) is selected for Theme + This option is only available if %s is selected for Theme Download has started You can now select text inside the description. Note that the page may flicker and links may not be clickable while in selection mode. Enable selecting text in the description From 7c5b4510af6b4f634e1bb1a053a29c12a5045a3e Mon Sep 17 00:00:00 2001 From: Isira Seneviratne Date: Sat, 26 Nov 2022 10:57:27 +0530 Subject: [PATCH 13/23] Update RxJava to 3.1.5. --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 72a03e063..582f61618 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -265,7 +265,7 @@ dependencies { implementation 'com.jakewharton:process-phoenix:2.1.2' // Reactive extensions for Java VM - implementation "io.reactivex.rxjava3:rxjava:3.0.13" + implementation "io.reactivex.rxjava3:rxjava:3.1.5" implementation "io.reactivex.rxjava3:rxandroid:3.0.0" // RxJava binding APIs for Android UI widgets implementation "com.jakewharton.rxbinding4:rxbinding:4.0.0" From c537776826dd0c11a4361cf937f73713882e14ab Mon Sep 17 00:00:00 2001 From: pratyaksh1610 Date: Fri, 9 Dec 2022 14:09:40 +0530 Subject: [PATCH 14/23] Fixes #9518 - Crash fix on clicking on add to playlist. - Added toast when clicked on share button for better UI. --- .../list/playlist/PlaylistFragment.java | 27 ++++++++++++------- app/src/main/res/values/strings.xml | 1 + 2 files changed, 19 insertions(+), 9 deletions(-) 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 e3caeb522..899534793 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 @@ -13,6 +13,7 @@ import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; +import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -233,21 +234,29 @@ public class PlaylistFragment extends BaseListInfoFragment dialog.show(getFM(), TAG) - )); + if (currentInfo != null) { + disposables.add(PlaylistDialog.createCorrespondingDialog( + getContext(), + getPlayQueue() + .getStreams() + .stream() + .map(StreamEntity::new) + .collect(Collectors.toList()), + dialog -> dialog.show(getFM(), TAG) + )); + } else { + Toast.makeText(getContext(), getString(R.string.playlist_loading_message), + Toast.LENGTH_SHORT).show(); + } break; default: return super.onOptionsItemSelected(item); diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 76b828746..d72fd4217 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -241,6 +241,7 @@ Restore defaults Do you want to restore defaults? Give permission to display over other apps + Playlist loading… NewPipe encountered an error, tap to report An error occurred, see the notification From 12796920a361c63831a8c2644df5a76ec9f50d90 Mon Sep 17 00:00:00 2001 From: Jared Fantaye Date: Sat, 10 Dec 2022 21:56:04 +0100 Subject: [PATCH 15/23] Removed the wasPlaying variable --- .../main/java/org/schabi/newpipe/player/Player.java | 8 -------- .../java/org/schabi/newpipe/player/PlayerService.java | 2 -- .../org/schabi/newpipe/player/ui/VideoPlayerUi.java | 11 +++-------- 3 files changed, 3 insertions(+), 18 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 99d36f66e..95520ba1e 100644 --- a/app/src/main/java/org/schabi/newpipe/player/Player.java +++ b/app/src/main/java/org/schabi/newpipe/player/Player.java @@ -216,7 +216,6 @@ public final class Player implements PlaybackListener, Listener { // minimized to background but will resume automatically to the original player type private boolean isAudioOnly = false; private boolean isPrepared = false; - private boolean wasPlaying = false; /*////////////////////////////////////////////////////////////////////////// // UIs, listeners and disposables @@ -918,13 +917,6 @@ public final class Player implements PlaybackListener, Listener { error -> Log.e(TAG, "Progress update failure: ", error)); } - public void saveWasPlaying() { - this.wasPlaying = getPlayWhenReady(); - } - - public boolean wasPlaying() { - return wasPlaying; - } //endregion 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 33b024e3d..d81301205 100644 --- a/app/src/main/java/org/schabi/newpipe/player/PlayerService.java +++ b/app/src/main/java/org/schabi/newpipe/player/PlayerService.java @@ -86,8 +86,6 @@ public final class PlayerService extends Service { } if (!player.exoPlayerIsNull()) { - player.saveWasPlaying(); - // 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 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 9fb4552b2..afdfbd81d 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 @@ -601,8 +601,6 @@ public abstract class VideoPlayerUi extends PlayerUi player.changeState(STATE_PAUSED_SEEK); } - player.saveWasPlaying(); - showControls(0); animate(binding.currentDisplaySeek, true, DEFAULT_CONTROLS_DURATION, AnimationType.SCALE_AND_ALPHA); @@ -617,7 +615,7 @@ public abstract class VideoPlayerUi extends PlayerUi } player.seekTo(seekBar.getProgress()); - if (player.wasPlaying() || player.getExoPlayer().getDuration() == seekBar.getProgress()) { + if (player.getExoPlayer().getDuration() == seekBar.getProgress()) { player.getExoPlayer().play(); } @@ -631,9 +629,8 @@ public abstract class VideoPlayerUi extends PlayerUi if (!player.isProgressLoopRunning()) { player.startProgressLoop(); } - if (player.wasPlaying()) { - showControlsThenHide(); - } + + showControlsThenHide(); } //endregion @@ -1168,8 +1165,6 @@ public abstract class VideoPlayerUi extends PlayerUi binding.qualityTextView.setText(MediaFormat.getNameById(videoStream.getFormatId()) + " " + videoStream.getResolution()); } - - player.saveWasPlaying(); } /** From d255d3e3764170d05955ae8c48642799d673b90c Mon Sep 17 00:00:00 2001 From: pratyaksh1610 Date: Sat, 17 Dec 2022 17:41:57 +0530 Subject: [PATCH 16/23] added icon for play all --- app/src/main/res/layout/playlist_control.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/res/layout/playlist_control.xml b/app/src/main/res/layout/playlist_control.xml index 5a8856128..685082013 100644 --- a/app/src/main/res/layout/playlist_control.xml +++ b/app/src/main/res/layout/playlist_control.xml @@ -48,6 +48,8 @@ Date: Sun, 25 Dec 2022 21:22:19 +0100 Subject: [PATCH 17/23] Translated using Weblate (French) Currently translated at 93.0% (67 of 72 strings) Translated using Weblate (Ukrainian) Currently translated at 100.0% (72 of 72 strings) Translated using Weblate (Ukrainian) Currently translated at 100.0% (648 of 648 strings) Translated using Weblate (French) Currently translated at 91.6% (66 of 72 strings) Translated using Weblate (Urdu) Currently translated at 66.9% (434 of 648 strings) Translated using Weblate (Hungarian) Currently translated at 100.0% (648 of 648 strings) Translated using Weblate (Portuguese (Portugal)) Currently translated at 100.0% (648 of 648 strings) Translated using Weblate (Punjabi) Currently translated at 100.0% (648 of 648 strings) Translated using Weblate (Azerbaijani) Currently translated at 100.0% (648 of 648 strings) Translated using Weblate (Hindi) Currently translated at 100.0% (648 of 648 strings) Translated using Weblate (Romanian) Currently translated at 100.0% (648 of 648 strings) Translated using Weblate (Italian) Currently translated at 100.0% (72 of 72 strings) Translated using Weblate (Telugu) Currently translated at 6.9% (5 of 72 strings) Translated using Weblate (Telugu) Currently translated at 66.9% (434 of 648 strings) Translated using Weblate (Russian) Currently translated at 100.0% (648 of 648 strings) Translated using Weblate (Dutch) Currently translated at 100.0% (648 of 648 strings) Translated using Weblate (Tamil) Currently translated at 54.0% (350 of 648 strings) Translated using Weblate (Chinese (Traditional, Hong Kong)) Currently translated at 100.0% (648 of 648 strings) Co-authored-by: Ahmad Raza Co-authored-by: Dan Co-authored-by: Florian Co-authored-by: Hosted Weblate Co-authored-by: Igor Nedoboy Co-authored-by: Igor Sorocean Co-authored-by: K.B.Dharun Krishna Co-authored-by: Kiss Attila Co-authored-by: Nidi Co-authored-by: Ray Co-authored-by: ShareASmile Co-authored-by: Terry Louwers Co-authored-by: Translator Co-authored-by: pjammo Co-authored-by: ssantos Co-authored-by: subba raidu Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/fr/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/it/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/te/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/uk/ Translation: NewPipe/Metadata --- app/src/main/res/values-az/strings.xml | 80 +++++++++---------- app/src/main/res/values-hi/strings.xml | 60 +++++++------- app/src/main/res/values-hu/strings.xml | 26 +++--- app/src/main/res/values-nl/strings.xml | 5 ++ app/src/main/res/values-pa/strings.xml | 30 +++---- app/src/main/res/values-pt-rPT/strings.xml | 9 ++- app/src/main/res/values-ro/strings.xml | 4 + app/src/main/res/values-ru/strings.xml | 2 +- app/src/main/res/values-ta/strings.xml | 1 + app/src/main/res/values-te/strings.xml | 22 +++++ app/src/main/res/values-uk/strings.xml | 4 +- app/src/main/res/values-ur/strings.xml | 10 +++ app/src/main/res/values-zh-rHK/strings.xml | 4 + .../metadata/android/fr/changelogs/740.txt | 23 ++++++ .../metadata/android/fr/changelogs/991.txt | 13 +++ .../metadata/android/it/changelogs/740.txt | 2 +- .../metadata/android/te/changelogs/65.txt | 26 ++++++ .../metadata/android/uk/changelogs/951.txt | 2 +- 18 files changed, 220 insertions(+), 103 deletions(-) create mode 100644 fastlane/metadata/android/fr/changelogs/740.txt create mode 100644 fastlane/metadata/android/fr/changelogs/991.txt create mode 100644 fastlane/metadata/android/te/changelogs/65.txt diff --git a/app/src/main/res/values-az/strings.xml b/app/src/main/res/values-az/strings.xml index a4491688f..22f3ba5e5 100644 --- a/app/src/main/res/values-az/strings.xml +++ b/app/src/main/res/values-az/strings.xml @@ -5,7 +5,7 @@ Yayım oynadıcı tapılmadı. \"VLC\" yüklənilsin\? Yayım oynadıcı tapılmadı (Oynatmaq üçün VLC\'ni quraşdıra bilərsiniz). Yüklə - İmtina + Ləğv et Brauzerdə aç Paylaş Endir @@ -17,7 +17,7 @@ Xarici video oynadıcı istifadə et Bəzi qətnamələrdə səsi silir Xarici səs oynadıcı istifadə et - Abunə Olun + Abunə Ol Abunə olundu Kanal abunəliyi ləğv edildi Məlumat göstər @@ -30,7 +30,7 @@ Video faylları üçün endirmə qovluğunu seç Səs endirmə qovluğu Endirilmiş səs faylları burada saxlanılır - Səs faylları üçün endirmə qovluğunu seç + Səs faylları üçün endirmə qovluğu seç Defolt keyfiyyət Daha böyük keyfiyyət seçimləri göstər \"Kodi\" ilə Oynat @@ -40,13 +40,13 @@ Səs Defolt səs formatı Defolt video formatı - Mövzu + Tema İşıqlı Qaranlıq Qara Abunəlikdən çıxın Ani pəncərə rejimində aç - Avtomatik oynatma + Avtomatik oynat Endir Fasilələrdən sonra (məsələn, telefon zəngləri) oynatmağa davam etdir Oynatmanı davam etdir @@ -54,24 +54,24 @@ Məlumat təmizlə Siyahılarda oynatma mövqelərini göstər Siyahılardakı mövqelər - Son oynatma mövqeyinə qaytar + Son oynatma mövqeyini qaytar Oynatmanı davam etdir Baxış tarixçəsi Axtarış sorğularını yerli olaraq saxla Axtarış tarixçəsi Axtarış edərkən göstəriləcək təklifləri seç Axtarış təklifləri - Oynadıcının parlaqlığını nizamlamaq üçün jestlərdən istifadə et - Parlaqlığı jestlə nizamlama - Oynadıcının səsini nizamlamaq üçün jestlərdən istifadə et - Səsi jestlə nizamla - Avto-növbələmə - Növbəti Yayımı Avto-növbələmə + Oynadıcının parlaqlığını nizamlamaq üçün jestləri istifadə et + Parlaqlığı jestlə nizamlamaq + Oynadıcı səsini nizamlamaq üçün jestləri istifadə et + Səsi jestlə idarə etmək + Avto-növbələ + Növbəti Yayımı Avto-növbələ Üst məlumat keşi silindi Keşlənmiş bütün veb-səhifə məlumatlarını sil Keşlənmiş üst məlumatı təmizlə Şəkil keşi silindi - Şərhləri gizlətmək üçün söndür + Şərhləri gizlətmək üçün bağla Şərhləri göstər Aktiv oynadıcının növbəsi dəyişdiriləcək Bir oynadıcıdan digərinə keçid növbənizi dəyişdirə bilər @@ -94,7 +94,7 @@ Ani Pəncərə Paneli Seç Abunəliyi yeniləmək alınmadı - Abunəliyi dəyişdirmək alınmadı + Abunəliyi dəyişmək alınmadı Nəticələr göstərilir: %s Kanallar %s tərəfindən @@ -102,8 +102,8 @@ Yaş həddi səbəbiylə (məsələn, 18+) uşaqlar üçün uyğun olmayan məzmunu göstər Yaş məhdudiyyətli məzmunu göstər Məzmun - Ani pəncərədə oynadılır - Arxa fonda oynadılır + Ani pəncərə rejimində oynadılır + Fonda oynadılır Yeniləmələr Sazlama Görünüş @@ -115,7 +115,7 @@ Defolt məzmun ölkəsi URL\'i tanımaq olmadı. Başqa tətbiqlə açılsın\? Dəstəklənməyən URL\'i - \"Növbəyə əlavə etmək üçün basılı saxla\" ipucusun göstər + \"Növbələmək üçün basılı saxla\" tövsiyəsin göstər \"Növbəti\" və \"Bənzər\" videoları göstər Tarixçəni, abunəlikləri, pleylistləri və tənzimləmələri ixrac edin Cari tarixçənizi, abunəliklərinizi, pleylistlərinizi və (könüllü) tənzimləmələrinizi etibarsız edir @@ -179,7 +179,7 @@ Xəta Axtarış tarixçəsi silindi Bütün axtarış tarixçəsi silinsin\? - Axtarışdakı açar sözlərin tarixçəsini silir + Açar sözləri axtarışının tarixçəsini silir Axtarış tarixçəsini silin Oynatma mövqeləri silindi Bütün oynatma mövqeləri silinsin\? @@ -208,7 +208,7 @@ Mobil internet istifadə edərkən görüntü keyfiyyətini məhdudlaşdır Limitsiz 1 element silindi. - Server əlavə edin + Nümunə əlavə et Sevimli \"PeerTube\" nümunələrinizi seçin Endirilmiş faylları silin Endirmə tarixçənizi təmizləmək və ya endirilmiş bütün faylları silmək istəyirsiniz\? @@ -217,7 +217,7 @@ Endirmələri dayandır Haraya endiriləcəyini soruş Sizdən hər endirmənin harada saxlanılacağı soruşulacaq. -\nXarici SD karta yükləmək istəyirsinizsə, sistem qovluğu seçicisini (SAF) aktiv edin +\nXarici SD karta endirmək istəyirsinizsə, sistem qovluğu seçicisini (SAF) aktiv edin \'Yaddaş Giriş Çərçivəsi \' xarici SD karta endirməyə imkan verir Sistem defoltu Tətbiq dili @@ -262,7 +262,7 @@ Xarici yaddaş əlçatan deyil Oynadılmış yayımlar tarixçəsini və oynatma mövqelərini silir Üst məlumatı göstər - Video açıqlamasını və əlavə məlumatı gizlətmək üçün söndürün + Video açıqlamasını və əlavə məlumatı gizlətmək üçün bağla Açıqlamanı göstər Bildirişi rəngləndir Belə qovluq yoxdur @@ -270,10 +270,10 @@ Xarici oynadıcılar bu cür linkləri dəstəkləmir Yerli axtarış təklifləri Video - Əlaqədar yayımlar + Əlaqəli elementlər Baxılmış kimi işarələ ilə aç - Gecə Mövzusu + 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ı @@ -292,7 +292,7 @@ Digər tətbiqlərin üzərində göstərməyə icazə ver İlkin tənzimləmələri qaytarmaq istəyirsiniz\? Miniatürlərin yüklənməsini, dataya qənaət etmək və yaddaşdan istifadəni azaltmaq üçün söndürün. Dəyişikliklər həm yaddaşdaxili, həm də diskdə olan təsvir keşini təmizləyir - Növbətini sıraya salın + Növbətini növbələ Yenidən Cəhd Et Cari oynatma yayımı bildirişini konfiqurasiya et Bildirişlər @@ -302,7 +302,7 @@ Fayl adı boş ola bilməz Yadda saxlanmış tabları oxumaq mümkün olmadı, buna görə defolt tablardan istifadə edin NewPipe xəta ilə qarşılaşdı, bildirmək üçün toxun - Bağışlayın, belə olmamalı idi. + Bağışlayın, o baş verməməli idi. Bu xətanı e-poçt vasitəsilə bildirin GitHub\'da Hesabat Ver Zəhmət olmasa, xətanızı müzakirə edən məsələnin mövcud olub-olmadığını yoxlayın. Dublikat biletləri yaradarkən, bizdən faktiki səhvi düzəltməyə sərf edəcəyimiz vaxt alırsınız. @@ -324,7 +324,7 @@ Video yoxdur Şərhlər qeyri-aktivdir Başlat - Dayandır + Fasilə Təsdiqləmə İmtina Xəta @@ -386,7 +386,7 @@ Avtomatik yaradıldı Altyazılar LeakCanary yoxdur - Yaddaş sızmasının monitorinqi yığın boşaltma zamanı tətbiqin cavab verməməsinə səbəb ola bilər + Yaddaş sızma monitorinqi yığın boşaltma zamanı tətbiqin cavab verməməsinə səbəb ola bilər Yaddaş sızmalarını göstər Utilizasiyadan sonra fraqment və ya fəaliyyətin yaşam dövründən kənarda çatdırıla bilməyən Rx istisnaları barədə hesabat verməyə məcbur et Xidmətlərdən alınmış orijinal mətnlər yayım elementlərində görünəcək @@ -430,8 +430,8 @@ Ən Yeni Bu məzmun ölkənizdə mövcud deyil. Bu məzmun yalnız ödəniş etmiş istifadəçilər üçün əlçatandır, ona görə də NewPipe tərəfindən yayımlana və ya endirilə bilməz. - Avtomatik (cihaz mövzusu) - Sevimli gecə mövzunuzu seçin — %s + Avtomatik (cihaz teması) + Sevimli gecə temanızı seçin — %s Sabitlənmiş şərh Bildirişlər deaktiv edilib Bildiriş al @@ -464,7 +464,7 @@ Sizdən hər endirmənin harada saxlanılacağı soruşulacaq \"Yaddaş Giriş Çərçivəsi\"yalnız Android 10\'dan başlayaraq dəstəklənir Kanalın avatar miniatürü - Sevdiyiniz gecə mövzusunu aşağıda seçə bilərsiniz + Sevdiyiniz gecə temasını aşağıda seçə bilərsiniz Android\'in bildiriş rəngini miniatürdəki əsas rəngə uyğun fərdiləşdirməsini təmin et (qeyd edək ki, bu, bütün cihazlarda mövcud deyil) GitHub\'da Bax İanə Et @@ -498,10 +498,10 @@ Miniatürü 1:1 görünüş nisbətinə kəs Yükləmə intervalının həcmini dəyişdir (hazırda %s). Daha aşağı dəyər ilkin video yükləməni sürətləndirə bilər. Dəyişikliklər oynadıcının yenidən başladılmasını tələb edir Yayım yaradıcısı, məzmunu və ya axtarış sorğusu haqqında əlavə məlumat olan üst məlumat qutularını gizlətmək üçün söndürün - Əlaqədar yayımı əlavə etməklə (təkrarlanmayan) sonlanacaq oynatma sırasını davam etdir + Əlaqəli yayımı əlavə etməklə (təkrarlanmayan) sonlanacaq oynatma növbəsini davam etdir Kənar axtarış təklifləri - Server artıq mövcuddur - Videoları mini oynadıcıda başlatma, avtomatik fırlatma kilidlidirsə, birbaşa tam ekran rejiminə keçid. Siz hələ də tam ekran rejimindən çıxmaqla mini pleyerə daxil ola bilərsiniz + Nümunə artıq mövcuddur + Videoları mini oynadıcıda başlatma, avtomatik fırlatma kilidlidirsə, birbaşa tam ekran rejiminə keçid. Siz hələ də tam ekrandan çıxmaqla mini oynadıcıya daxil ola bilərsiniz 100+ video ∞ video Şərhlər yoxdur @@ -548,7 +548,7 @@ Yarımton Endirmə tamamlandı - %s endirmələr tamamlandı + %s endirmə tamamlandı Defolt ExoPlayer Mövcud olduqda xüsusi axından al @@ -605,11 +605,11 @@ Nə:\\nTələb:\\nMəzmun Dili:\\nMəzmun Ölkəsi:\\nTətbiq Dili:\\nXidmət:\\nGMT Saatı:\\nPaket:\\nVersiya:\\nƏS versiyası: Bağışlayın, nəsə xəta baş verdi. Formatlanmış hesabatı kopyala - Server URL\'sini daxil edin - Serveri doğrulamaq mümkün olmadı + Nümunə URL\'sini daxil et + Nümunəni doğrulamaq mümkün olmadı %s-də bəyəndiyiniz nümunələri tapın Video \"Təfsilatlar:\"səhifəsində fon və ya ani pəncərə düyməsini basarkən ipucu göstər - Oynadıcı altyazı miqyasını və arxa fon üslublarını dəyişdirin. Effektiv olması üçün tətbiqin yenidən başladılması tələb olunur + Oynadıcı altyazı mətn miqyasını və arxa fon üslublarını dəyişdirin. Effektiv olması üçün tətbiqi yenidən başlatmaq tələb olunur Xəta baş verdi: %1$s Fayl mövcud deyil, yaxud oxumaq və ya yazmaq icazəsi yoxdur Veb saytı təhlil etmək alınmadı @@ -654,7 +654,7 @@ Video URL\'i imzasının şifrəsi qırılmadı Endirmək üçün heç bir yayım yoxdur Xəta baş verdi, bildirişə baxın - Şərhiniz (İngilis dilində): + Şərhiniz (İngiliscə): Video oynat, müddət: Zəhmət olmasa, daha sonra tənzimləmələrdə endirmə qovluğunu təyin et NewPipe Endirilir @@ -704,8 +704,8 @@ \nZəhmət olmasa ,Yaddaş Giriş Çərçivəsinə uyğun fayl menecerini quraşdırın Bu video yalnız YouTube Music Premium üzvləri üçün əlçatandır, ona görə də NewPipe tərəfindən yayımlamaq və ya endirmək mümkün deyil. İndi açıqlamadakı mətni seçə bilərsiniz. Nəzərə alın ki, seçim rejimində səhifə titrəyə və keçidlər kliklənməyə bilər. - Bildirişdə göstərilən video miniatürünü 16:9-dan 1:1 nisbətinə qədər kəs - Aşağıdakı bildiriş fəaliyyətini hər birinin üzərinə toxunaraq redaktə edin. Sağdakı təsdiq qutularından istifadə edərək yığcam bildirişdə göstərilməsi üçün onlardan üçə qədərini seç + Bildirişdə göstərilən video miniatürünü 16:9-dan 1:1 görünüş nisbətinə qədər kəs + Aşağıdakı bildiriş fəaliyyətini hər birinin üzərinə toxunaraq redaktə edin. Sağdakı təsdiq qutularından istifadə edərək yığcam bildirişdə göstərilməsi üçün onların üçə qədərini seç Belə fayl/məzmun mənbəyi yoxdur Seçilmiş yayım xarici oynadıcılar tərəfindən dəstəklənmir Yükləyici tərəfindən hələ dəstəklənməyən yayımlar göstərilmir diff --git a/app/src/main/res/values-hi/strings.xml b/app/src/main/res/values-hi/strings.xml index df6d3f3d3..b4f9fadc0 100644 --- a/app/src/main/res/values-hi/strings.xml +++ b/app/src/main/res/values-hi/strings.xml @@ -18,7 +18,7 @@ ध्वनि रौशनी काला - देखे हुए विडियोज का इतिहास + देखे हुए वीडियोज़ का इतिहास डाउनलोड करे वीडियो और ऑडियो इतिहास और कैश @@ -29,7 +29,7 @@ तृतीय-पक्ष लाइसेंस ऐप के बारे में और सामान्य प्रश्न लाइसेंस - GitHub में देखें + गिटहब में देखें न्यूपाइप का लाइसेंस लाइसेंस पढ़ें योगदान करें @@ -41,12 +41,12 @@ रद्द करें क्या आप का मतलब \"%1$s\" था\? के साथ शेयर करे - कोई दूसरा विडियो चालक प्रयोग करें - कुछ विडियो गुणवत्ता स्तर पर ध्वनि हट सकती है + कोई दूसरा वीडियो चालक प्रयोग करें + कुछ वीडियो गुणवत्ता स्तर पर ध्वनि हट सकती है कोई दूसरा ध्वनि चालक उपयोग करें सब्सक्रिप्शन बदली नहीं जा सकी सब्सक्रिप्शन अपडेट नहीं किया जा सका - देखे की क्या नया है + देखें कि क्या नया है वीडियो डाउनलोड का फ़ोल्डर डाउनलोड की गई वीडियो फ़ाइलें यहां संग्रहीत हैं वीडियो फ़ाइलों के लिए डाउनलोड फ़ोल्डर चुनें @@ -56,33 +56,33 @@ प्रथम स्थापित गुणवत्ता स्तर पॉपअप का प्रथम स्थापित गुणवत्ता स्तर उच्च गुणवत्ता स्तर दिखाएं - केवल कुछ ही यंत्र 2K/4K मे विडियो चला सकते हैं + केवल कुछ ही यंत्र 2K/4K मे वीडियो चला सकते हैं Kodi मे चलाए Kore ऐप नहीं मिली, इसे स्थापित करें\? \"Kodi मे चलाएं\" वाला विकल्प दिखाएँ - Kodi मीडिया सेंटर से विडियो चलने के लिए विकल्प प्रदर्शित करें + कोडी मीडिया सेंटर से वीडियो चलने के लिए विकल्प प्रदर्शित करें प्रथम स्थापित ध्वनि फॉर्मेट - प्रथम स्थापित विडियो फॉर्मेट + प्रथम स्थापित वीडियो फॉर्मेट ऐप थीम गहरा - विडियो पॉपअप का आकर और उसकी स्थति को याद रखे - विडियो पॉपअप की अंतिम स्थिति और आकर को याद रखे + वीडियो पॉपअप का आकार और उसकी स्थिति को याद रखें + वीडियो पॉपअप की अंतिम स्थिति और आकार को याद रखें खोज में सुझाव खोज के दौरान दिखाये जाने वाले सुझाव चुने खोज का इतिहास खोज के डेटा को सिर्फ डिवाइस मेमोरी में रखे - देखे गए विडियोज की सूची रखे + देखे गए वीडियोज़ की सूची रखें प्लेबैक फिर से शुरू करें - रूकावटे खत्म होने के बाद विडियो प्ले करे (जैसे - फ़ोन कॉल) + रुकावटें खत्म होने के बाद वीडियो प्ले करें (जैसे - फ़ोन कॉल) \'अगला\' और \'समान\' वीडियो दिखाए \"कतार में जोड़ने के लिए स्पर्श बनाये रखें\" दिखाएं - जब बैकग्राउंड और पॉपअप बटन विडियो के विवरण पन्ने में दबाई जाए तो सलाह दिखाएं + जब बैकग्राउंड और पॉपअप बटन वीडियो के विवरण पन्ने में दबाई जाए तो सलाह दिखाएं असमर्थित URL डिफ़ॉल्ट विषय की भाषा प्लेयर चाल चलन दिखावट - विडियो पॉपअप के अंदाज में चल रहा + वीडियो पॉपअप के अंदाज में चल रहा विषयवस्तु आयु प्रतिबंधित सामग्री दिखाएं लाइव @@ -92,23 +92,23 @@ सारे बंद करे साफ़ - बेहतर विडियो की क्वालिटी - वापस जाए + बेहतर वीडियो की क्वालिटी + वापस जाएँ सारे प्ले करे NewPipe की सूचनापत्र - न्यूपाइप के बैकग्राउंड में चल रहे विडियो और पॉपअप विडियो के लिए सूचनापत्र + न्यूपाइप के बैकग्राउंड में चल रहे वीडियो और पॉपअप वीडियो के लिए सूचनापत्र [नहीं जानते] त्रुटी नेटवर्क में त्रुटी सारे thumbnail(फोटो जो फ़ोन की मेमोरी में है ) भरे नहीं जा सकते - विडियो के URL signature को decrypt नहीं कर सकते + वीडियो के URL हस्ताक्षर को डीऑबफस्केट नहीं कर सकते इस website का निरंक्षण नहीं कर सकते विषय वस्तु उपलब्ध नहीं है डाउनलोड मेनू को स्थापित नहीं कर सकते APP/UI टूट गया - इस विडियो को चलाने में असफल हुए - कभी ठीक न होने वाले विडियो प्लेयर की त्रुटी आ रही है - विडियो प्लेयर त्रुटी से ठीक हो रहा है + इस वीडियो को चलाने में असफल हुए + कभी ठीक न होने वाले वीडियो प्लेयर की त्रुटी आ रही है + वीडियो प्लेयर त्रुटी से ठीक हो रहा है खेद है की, ऐसा होना नहीं चाहिए था. त्रुटी की रिपोर्ट को ईमेल से भेजे माफ़ करे , कुछ त्रुटियाँ हो रही है @@ -124,7 +124,7 @@ नापसंद कोई परिणाम नहीं मिला यहां के खालीपन को दूर करने के लिए कुछ सर्च करें या किसी चैनल को सब्सक्राइब करें - विडियो + वीडियो ऑडियो फिर से कोशिश करे हज़ार @@ -146,7 +146,7 @@ शुरू रोकें मिटाएँ - checksum + चेकसम ठीक है फाइल का नाम मेसेज के thread @@ -187,10 +187,10 @@ स्ट्रीमिंग करने के लिए कोई चालक उपलब्ध नहीं है (आप इसे चलाने के लिए VLC चालक स्थापित कर सकते हैं)। स्ट्रीम फाइल डाउनलोड करें जानकारी दिखाएं - बुकमार्क किये गए प्लेलिस्टस + बुकमार्क की गई प्लेलिस्टें में शामिल करें डिफ़ॉल्ट देश का विषय - हमेशा के लिए + हमेशा सिर्फ एक बार के लिए बैकग्राउंड में स्विच करें पॉपअप मोड में जाएं @@ -208,7 +208,7 @@ नाम बदलें दान करें न्यूपाइप स्वयंसेवकों द्वारा विकसित किया जाता है जो आपको अच्छा अनुभव देने के लिए अपना खाली समय व्यतीत करते हैं। स्वयंसेवको को मदद भेजे, ताकि वह न्यूपाइप को और अच्छा बना सके। - वापस दे + वापस दें वेबसाइट अधिक जानकारी और खबरों के लिए न्यूपाइप की वेबसाइट पर जाएं। पिछला चलाया गया @@ -281,7 +281,7 @@ \nन्यूपाइप की गोपनीयता नीति विस्तार से समज़ाती है कि कोनसा डेटा भेजा या संग्रह किया जाता है जब आप क्रेश विवरण भेजते है। गोपनीयता नीति पढ़े क्या आप सेटिंग्स भी आयात करना चाहते है? - पसंदीदा \'खोलने\' कि प्रक्रिया + पसंदीदा \'खोलने\' की प्रक्रिया सामग्री खोलते समय डिफ़ॉल्ट कारवाही — %s अनुशीर्षक प्लेयर अनुशीर्षक के शब्दों का परिमाण और पृष्ठभूमि शैलियों को बदले। लागू करने के लिए ऐप को पुनः प्रारम्भ करना जरूरी है @@ -321,7 +321,7 @@ ऐप बदलते समय उसे मिनिमाइज करे मुख्य वीडियो चालक से दूसरी ऐप पर जाने पर — %s कोई नही - पृष्ठभूमि प्लेयर में बदले + बैकग्राउंड प्लेयर में बदले पॉप अप प्लेयर में बदले न्यूपाइप एक काॅपीलेफ़्ट फ़्री साॅफ़्टवेर है: इसे आप अपनी इच्छा के अनुसार इस्तेमाल, जाँच, बाँट तथा और बेहतर बना सकते है। खास तौर पर आप इसे फ़्री साॅफ़्टवेर फ़ाउंडेशन के द्वारा जारी जीएनयू जनरल पब्लिक लाइसेंस के तीसरे या उसके बाद आने वाले कोई भी वर्णन के शर्तों के मुताबिक फिर से बाँट या बदल सकते हैं। अनसब्सक्राईब करें @@ -690,7 +690,7 @@ आइटम्स का असल अपलोड समय दिखाएं सेवाओं से मूल पाठ स्ट्रीम आइटम में दिखाई देंगे प्लेलिस्ट में जोड़े गए पहले और बाद में देखे गए वीडियो हटा दिए जाएंगे। -\nक्या आपको यकीन है\? इसे असंपादित नहीं किया जा सकेगा! +\nक्या यक़ीनन आप ऐसा चाह्ते हैं\? इसे असंपादित नहीं किया जा सकेगा! %d मिनट %d मिनट @@ -712,7 +712,7 @@ निर्माता द्वारा दिया दिल टैबलेट मोड आपने इस चैनल को अब सब्सक्राइब किया है - बाहरी प्लेयरस के लिए कोई विडियो स्ट्रीम उपलब्ध नहीं है + बाहरी प्लेयरस के लिए कोई वीडियो स्ट्रीम उपलब्ध नहीं है बाहरी प्लेयरस के लिए कोई ऑडियो स्ट्रीम उपलब्ध नहीं है कुछ सेवाओं में उपलब्ध, यह आमतौर पर बहुत तेज होता है लेकिन सीमित मात्रा में आइटम और अक्सर अधूरी जानकारी (जैसे कोई अवधि नहीं, आइटम प्रकार, कोई लाइव स्थिति नहीं) लौटा सकता है इस क्रिया के लिए कोई उपयुक्त फ़ाइल प्रबंधक नहीं मिला। diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml index 6db9216a7..8a518bda6 100644 --- a/app/src/main/res/values-hu/strings.xml +++ b/app/src/main/res/values-hu/strings.xml @@ -135,9 +135,9 @@ Közvetítési fájl letöltése 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. + 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. + 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 @@ -266,7 +266,7 @@ Nagyítás Automatikusan létrehozott Feliratok - Feliratok méretének és hátterének stílusbeli módosítása. A módosítások életbe lépésehez az alkalmazás újraindítása szükséges. + Feliratok méretének és hátterének stílusbeli módosítása. A módosítások életbe lépésehez az alkalmazás újraindítása szükséges Importálás Importálás a következőből Exportálás a következőbe @@ -491,7 +491,7 @@ Frissítési értesítés megjelenítése, amikor egy új verzió érhető el Frissítések Az Android igazítsa az értesítés színét a bélyegkép meghatározó színéhez (nem minden eszközön érhető el) - Legfeljebb három művelet jeleníthető meg a kompakt értesítésben. + Legfeljebb három művelet jeleníthető meg a kompakt értesítésben! Koppintással szerkesztheti az egyes értesítéseken megjelenő műveleteket. Válasszon ki legfeljebb hármat a jobb oldali jelölőnégyzetekkel, amelyek a kompakt értesítéseken is megjelennek. Ötödik műveletgomb Negyedik műveletgomb @@ -568,13 +568,13 @@ Helyi keresési javaslatok Távoli keresési javaslatok A fő lejátszó teljes képernyős indítása - A videókat ne a kis lejátszóban indítsa el, hanem kapcsolja be a teljes képernyős módot, ha az automatikus forgatás zárolva van. Továbbra is elérheti a kis lejátszót, ha kilép a teljes képernyőből. + A videókat ne a kis lejátszóban indítsa el, hanem kapcsolja be a teljes képernyős módot, ha az automatikus forgatás zárolva van. Továbbra is elérheti a kis lejátszót, ha kilép a teljes képernyőből Szolgáltatás be/ki, jelenleg kiválasztott: A megjegyzések ki vannak kapcsolva Húzza oldalra az elemeket az eltávolításukhoz A következő sorba állítása A következő sorba állítva - Feldolgozás… Ez eltarthat egy ideig. + Feldolgozás… Ez eltarthat egy ideig Az eltávolítás utáni, fragment vagy activity életcikluson kívüli, nem kézbesíthető Rx kivételek jelentésének kényszerítése Eredeti „ennyi ideje” megjelenítése az elemeken Tiltsa le a médiacsatornázást, ha fekete képernyőt vagy akadozást tapasztal videólejátszáskor @@ -617,7 +617,7 @@ Nem listázott Ki Nem található megfelelő fájlkezelő ehhez a művelethez. -\nTelepítsen egy fájlkezelőt, vagy próbálja meg letiltani a következőt a letöltési beállításokban: „%s”. +\nTelepítsen egy fájlkezelőt, vagy próbálja meg letiltani a következőt a letöltési beállításokban: „%s” Letöltés befejezve %s letöltés befejezve @@ -656,7 +656,7 @@ Frissítések keresése… Készítette: %s Nem található megfelelő fájlkezelő ehhez a művelethez. -\nTelepítsen egy olyan fájlkezelőt, amely kompatibilis a Storage Access Frameworkkel. +\nTelepítsen egy olyan fájlkezelőt, amely kompatibilis a Storage Access Frameworkkel Szöveg kijelölésének engedélyezése a leírásban Kategória Címkék @@ -664,7 +664,7 @@ Gyors mód letiltása Igen, és távolítsa el a részben megnézett videókat is A videók, melyeket már megnézett miután a lejátszási listához adta őket, el lesznek távolítva. -\nBiztos benne\? Ez nem vonható vissza. +\nBiztos benne\? Ez nem vonható vissza! A szolgáltatásokból származó eredeti szövegek láthatók lesznek a közvetítési elemeken Lejátszó összeomlasztása Képjelölők megjelenítése @@ -682,7 +682,7 @@ Rögzített megjegyzés LeakCanary nem elérhető Lejátszó értesítés - Módosítsa a betöltési intervallum méretét (jelenleg %s). Az alacsonyabb érték felgyorsíthatja a videó kezdeti betöltését. A változtatásokhoz a lejátszó újraindítása szükséges. + Módosítsa a betöltési intervallum méretét (jelenleg %s). Az alacsonyabb érték felgyorsíthatja a videó kezdeti betöltését. A változtatásokhoz a lejátszó újraindítása szükséges Az aktuális lejátszás konfigurálása értesítés Értesítések Új élő közvetítések @@ -720,6 +720,10 @@ Gyakran ismételt kérdések Megtekintés a weboldalon Rendezés - Ha problémája van az alkalmazás használatával, akkor nézze meg az ezekre a gyakori kérdésekre adott válaszokat. + Ha problémája van az alkalmazás használatával, akkor nézze meg az ezekre a gyakori kérdésekre adott válaszokat! Megnézett elemek elrejtése + Gyors mód + Feliratkozások importálása vagy exportálása a 3 pontos menüből + Ön a Newpipe legfrissebb verzióját futtatja + Nyomjon a %s letöltéséhez \ 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 f0e510bfd..2390f8e69 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -721,4 +721,9 @@ Veelgestelde vragen Als u problemen ondervindt bij het gebruik van de app, bekijk dan deze antwoorden op veelgestelde vragen! Bekijk op de website + Sorteer + Snelle modus + Importeer of exporteer abonnementen vanuit het 3-punten menu + U heeft de laatste versie van NewPipe + Klik om %s te downloaden \ 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 7be904b99..08c7e47c9 100644 --- a/app/src/main/res/values-pa/strings.xml +++ b/app/src/main/res/values-pa/strings.xml @@ -16,7 +16,7 @@ ਕੀ ਤੁਹਾਡਾ ਮਤਲਬ ਸੀ \"%1$s\"\? ਇਸ ਨਾਲ਼ ਸਾਂਝਾ ਕਰੋ ਬਾਹਰੀ ਵੀਡੀਓ ਪਲੇਅਰ ਵਰਤੋ - ਕੁਝ ਰੈਜ਼ੋਲੂਸ਼ਨਾਂ \'ਤੇ ਆਵਾਜ਼ ਨੂੰ ਹਟਾ ਦਿੰਦਾ ਹੈ + ਕੁਝ ਰੈਜ਼ੋਲਿਊਸ਼ਨਾਂ \'ਤੇ ਆਵਾਜ਼ ਨੂੰ ਹਟਾ ਦਿੰਦਾ ਹੈ ਬਾਹਰੀ ਆਡੀਓ ਪਲੇਅਰ ਵਰਤੋ ਸਬਸਕ੍ਰਾਈਬ ਕਰੋ ਸਬਸਕ੍ਰਾਈਬ ਹੈ @@ -36,9 +36,9 @@ ਆਡੀਓ ਲਈ ਡਾਊਨਲੋਡ ਫ਼ੋਲਡਰ ਡਾਊਨਲੋਡ ਕੀਤੀਆਂ ਆਡੀਓ ਇੱਥੇ ਜਮ੍ਹਾਂ ਹੁੰਦੀਆਂ ਹਨ ਆਡੀਓ ਫ਼ਾਈਲਾਂ ਲਈ ਡਾਊਨਲੋਡ ਫ਼ੋਲਡਰ ਚੁਣੋ - ਡਿਫ਼ਾਲਟ ਰੈਜ਼ੋਲੂਸ਼ਨ - ਪੌਪ-ਅਪ ਲਈ ਡਿਫ਼ਾਲਟ ਰੈਜ਼ੋਲੂਸ਼ਨ - ਵੱਡੀਆਂ ਰੈਜ਼ੋਲੂਸ਼ਨਾਂ ਦਿਖਾਓ + ਡਿਫ਼ਾਲਟ ਰੈਜ਼ੋਲਿਊਸ਼ਨ + ਪੌਪ-ਅਪ ਲਈ ਡਿਫ਼ਾਲਟ ਰੈਜ਼ੋਲਿਊਸ਼ਨ + ਵੱਡੀਆਂ ਰੈਜ਼ੋਲਿਊਸ਼ਨਜ਼ ਦਿਖਾਓ ਸਿਰਫ਼ ਕੁਝ ਹੀ ਡਿਵਾਈਸ 2K/4K ਵੀਡੀਓ ਨੂੰ ਚਲਾ ਸਕਦੇ ਹਨ Kodi ਵਿੱਚ ਚਲਾਓ Kodi ਐਪ ਇੰਸਟਾਲ ਨਹੀਂ ਹੈ\? @@ -53,13 +53,13 @@ ਕਾਲ੍ਹਾ ਪੌਪ-ਅਪ ਦਾ ਆਕਾਰ ਅਤੇ ਸਥਿਤੀ ਯਾਦ ਰੱਖੋ ਪੌਪ-ਅਪ ਦਾ ਆਖਰੀ ਅਕਾਰ ਅਤੇ ਸਥਿਤੀ ਯਾਦ ਰੱਖੋ - ਤੇਜ਼ ਪਰ inexact seek ਵਰਤੋ - Inexact seek ਵੀਡੀਓ ਨੂੰ ਤੇਜ਼ ਪਰ ਅਣ-ਸਟੀਕ ਢੰਗ ਨਾਲ ਅੱਗੇ-ਪਿੱਛੇ ਲਿਜਾਂਦਾ ਹੈ । ਇਸ ਨਾਲ ਅੱਗੇ-ਪਿੱਛੇ 5,15 ਜਾਂ 25 ਸਕਿੰਟ ਜਾਣਾ ਕੰਮ ਨਹੀਂ ਕਰੇਗਾ + ਤੇਜ਼ ਪਰ ਅਸਪੱਸ਼ਟ ਸੀਕ ਵਰਤੋ + ਅਸਪੱਸ਼ਟ ਸੀਕ ਵੀਡੀਓ ਨੂੰ ਤੇਜ਼ ਪਰ ਅਣ-ਸਟੀਕ ਢੰਗ ਨਾਲ ਅੱਗੇ-ਪਿੱਛੇ ਲਿਜਾਂਦਾ ਹੈ । ਇਸ ਨਾਲ ਅੱਗੇ-ਪਿੱਛੇ 5,15 ਜਾਂ 25 ਸਕਿੰਟ ਜਾਣਾ ਕੰਮ ਨਹੀਂ ਕਰੇਗਾ ਥੰਮਨੇਲ ਲੋਡ ਕਰੋ ਥੰਮਨੇਲ ਲੋਡ, ਡਾਟਾ ਦੀ ਬੱਚਤ ਅਤੇ ਮੈਮੋਰੀ ਦੀ ਵਰਤੋਂ ਨੂੰ ਰੋਕਣ ਲਈ ਇਸਨੂੰ ਬੰਦ ਕਰੋ। ਇਸ ਵਿਚ ਤਬਦੀਲੀ ਕਰਨ ਨਾਲ ਇਨ-ਮੈਮੋਰੀ ਅਤੇ ਆਨ-ਡਿਸਕ ਚਿੱਤਰ cache ਦੋਵੇਂ ਮਿਟ ਜਾਣਗੇ ਚਿੱਤਰ cache ਮਿਟਾ ਦਿੱਤੀ ਗਈ ਹੈ - Cached ਮੈਟਾ-ਡਾਟਾ ਮਿਟਾਓ - ਸਾਰੇ cached ਵੈੱਬ-ਪੇਜਾਂ ਦਾ ਡਾਟਾ ਮਿਟਾਓ + ਕੈਸ਼ ਕੀਤਾ ਮੈਟਾ-ਡਾਟਾ ਮਿਟਾਓ + ਸਾਰੇ ਕੈਸ਼ ਕੀਤੇ ਵੈੱਬ-ਪੇਜਾਂ ਦਾ ਡਾਟਾ ਮਿਟਾਓ ਮੈਟਾ-ਡਾਟਾ cache ਮਿਟਾ ਦਿੱਤੀ ਗਈ ਹੈ ਅਗਲੀ ਸਟ੍ਰੀਮ ਨੂੰ ਆਟੋ-ਕਤਾਰਬੱਧ ਕਰੋ ਇੱਕ ਮੁੱਕਣ ਵਾਲੀ ਪਰ ਨਾ-ਦੁਹਰਾਉਣ ਵਾਲੀ ਕਤਾਰ ਨੂੰ, ਸੰਬੰਧਤ ਸਟ੍ਰੀਮ ਜੋੜਦਿਆਂ, ਚਲਾਉਂਦੇ ਜਾਓ @@ -94,7 +94,7 @@ ਸਾਰੇ ਬੰਦ ਕੀਤਾ ਮਿਟਾਓ - ਵਧੀਆ ਰੈਜ਼ੋਲੂਸ਼ਨ + ਵਧੀਆ ਰੈਜ਼ੋਲਿਊਸ਼ਨ ਵਾਪਿਸ ਸਾਰੇ ਚਲਾਓ ਹਮੇਸ਼ਾ @@ -110,7 +110,7 @@ ਡਾਟਾਬੇਸ ਨਿਰਯਾਤ ਕਰੋ ਤੁਹਾਡੇ ਮੌਜੂਦਾ ਇਤਿਹਾਸ, ਸਬਸਕ੍ਰਿਪਸ਼ਨਜ਼, ਪਲੇਸੂਚੀ ਅਤੇ (ਆਪਨਸ਼ਨਲੀ) ਸੈਟਿੰਗਾਂ ਨੂੰ ਨਵਿਆਂ ਨਾਲ਼ ਬਦਲ ਦਿੰਦਾ ਹੈ ਇਤਿਹਾਸ, ਸੁਬਸਕ੍ਰਿਪਸ਼ਨਜ਼, ਪਲੇ-ਸੂਚੀ ਅਤੇ ਸੈਟਿੰਗਾਂ ਦਰਾਮਦ ਕਰੋ - ਦੇਖੇ ਗਏ ਵੀਡੀਓਜ਼ ਦੀ ਸੂਚੀ ਮਿਟਾਓ + ਵੇਖੇ ਗਏ ਵੀਡੀਓਜ਼ ਦੀ ਸੂਚੀ ਮਿਟਾਓ ਚਲਾਏ ਗਏ ਵੀਡੀਓਜ਼ ਦੇ ਇਤਿਹਾਸ ਅਤੇ ਪਲੇ-ਸਥਿਤੀਆਂ ਨੂੰ ਮਿਟਾਉਂਦਾ ਹੈ ਕੀ ਵੇਖੇ ਗਏ ਵੀਡੀਓਜ਼ ਦਾ ਇਤਿਹਾਸ ਮਿਟਾ ਦਿੱਤਾ ਜਾਵੇ\? ਖੋਜ ਸੂਚੀ ਦਾ ਇਤਿਹਾਸ ਮਿਟਾਓ @@ -318,7 +318,7 @@ ਸਵੀਕਾਰ ਕਰੋ ਅਸਵੀਕਾਰ ਕੋਈ ਸੀਮਾ ਨਹੀਂ - ਮੋਬਾਈਲ ਡਾਟਾ ਦੀ ਵਰਤੋਂ ਕਰਦੇ ਸਮੇਂ ਰੈਜ਼ੋਲੂਸ਼ਨ ਨੂੰ ਸੀਮਿਤ ਕਰੋ + ਮੋਬਾਈਲ ਡਾਟਾ ਦੀ ਵਰਤੋਂ ਕਰਦੇ ਸਮੇਂ ਰੈਜ਼ੋਲਿਊਸ਼ਨ ਨੂੰ ਸੀਮਿਤ ਕਰੋ ਐਪ ਸਵਿੱਚ ਕਰਨ ਤੇ ਮਿਨੀਮਾਈਜ਼ ਕਰੋ ਮੁੱਖ ਵੀਡੀਓ ਪਲੇਅਰ ਤੋਂ ਦੂਜੇ ਐਪ \'ਤੇ ਜਾਣ ਵੇਲ਼ੇ ਕਾਰਵਾਈ — %s ਕੋਈ ਨਹੀਂ @@ -327,7 +327,7 @@ ਚੁੱਪ ਦੌਰਾਨ ਤੇਜ਼ੀ ਨਾਲ ਅੱਗੇ ਕਰੋ ਕਦਮ ਰੀਸੈੱਟ - ਚੈਨਲਾਂ + ਚੈਨਲ ਪਲੇ ਸੂਚੀਆਂ ਟਰੈਕਸ ਯੂਜ਼ਰਸ @@ -575,11 +575,11 @@ ਸਾਰੀਆਂ ਪਲੇ-ਸਥਿਤੀਆਂ ਮਿਟਾਉਣੀਆਂ ਹਨ\? ਸਾਰੀਆਂ ਪਲੇ-ਸਥਿਤੀਆਂ ਮਿਟਾਉਂਦਾ ਹੈ ਪਲੇ-ਸਥਿਤੀਆਂ ਮਿਟਾਓ - ਵੀਡੀਉ ਹੈਸ਼ ਇਤਲਾਹ + ਵੀਡੀਓ ਹੈਸ਼ ਇਤਲਾਹ ਐਲਬਮਾਂ ਕਲਾਕਾਰ ਗੀਤ - ਵਿਡੀਉ + ਵੀਡੀਓ ਇਹ ਵੀਡੀਓ ਉਮਰ-ਪਾਬੰਦੀਸ਼ੁਦਾ ਹੈ। \n \nਜੇ ਤੁਸੀਂ ਇਸਨੂੰ ਵੇਖਣਾ ਚਾਹੁੰਦੇ ਹੋ ਤਾਂ ਸੈਟਿੰਗਾਂ ਵਿੱਚੋਂ \"%1$s\" ਚਾਲੂ ਕਰੋ। @@ -598,7 +598,7 @@ ਆਪ-ਮੁਖ਼ਤਾਰ ਕਤਾਰ ਕਰੋ ਸਟ੍ਰੀਮ ਦੇ ਕਰਤਾ, ਸਮੱਗਰੀ ਜਾਂ ਖੋਜ ਬੇਨਤੀ ਵਾਲੇ ਵਾਧੂ ਜਾਣਕਾਰੀ ਬਕਸਿਆਂ ਵਾਲ਼ੀ ਮੈਟਾ ਜਾਣਕਾਰੀ ਲੁਕਾਉਣ ਲਈ ਇਸਨੂੰ ਬੰਦ ਕਰ ਦਿਓ ਮੈਟਾ ਜਾਣਕਾਰੀ ਦਿਖਾਓ - ਵੀਡੀਉ ਵੇਰਵਾ ਅਤੇ ਵਾਧੂ ਜਾਣਕਾਰੀ ਲੁਕਾਉਣ ਲਈ ਇਸਨੂੰ ਬੰਦ ਕਰੋ + ਵੀਡੀਓ ਵੇਰਵਾ ਅਤੇ ਵਾਧੂ ਜਾਣਕਾਰੀ ਲੁਕਾਉਣ ਲਈ ਇਸਨੂੰ ਬੰਦ ਕਰੋ ਵੇਰਵਾ ਦਿਖਾਓ ਸਰਗਰਮ ਪਲੇਅਰ ਕਤਾਰ ਬਦਲ ਜਾਵੇਗੀ ਪਲੇਅਰ ਬਦਲਣ ਨਾਲ ਤੁਹਾਡੀ ਕਤਾਰ ਬਦਲ ਸਕਦੀ ਹੈ diff --git a/app/src/main/res/values-pt-rPT/strings.xml b/app/src/main/res/values-pt-rPT/strings.xml index 25a3f6e70..0a2205eee 100644 --- a/app/src/main/res/values-pt-rPT/strings.xml +++ b/app/src/main/res/values-pt-rPT/strings.xml @@ -493,7 +493,7 @@ Conteúdo indisponível Subscrito Cache de imagens limpa - Acerca + Sobre e FAQ Contagem de subscrições indisponível Ação padrão ao abrir o conteúdo — %s Repor @@ -716,9 +716,14 @@ Selecione a qualidade para reprodutores externos Tamanho do intervalo de carregamento da reprodução Mostrar artigos futuros - Ocultar artigos vistos + Ocultar itens reproduzidos Ocultar artigos futuros Perguntas frequentes Se tem problemas a usar a app, veja estas respostas para perguntas frequentes! Ver no sítio web + Modo rápido + Importar ou exportar subscrições do menu de 3 pontos + Já está a executar a versão mais recente do NewPipe + Toque para descarregar %s + Ordenação \ 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 a8d49d46d..636c617b2 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -735,4 +735,8 @@ Dacă întâmpinați probleme cu utilizarea aplicației, nu uitați să consultați aceste răspunsuri la întrebări frecvente! Întrebări puse frecvent Sortează + Modul rapid + Importați sau exportați abonamente din meniul cu 3 puncte + Rulați cea mai recentă versiune NewPipe + Atingeți pentru a descărca %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 e611059e1..159b27a2a 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -716,7 +716,7 @@ Закреплённый комментарий LeakCanary недоступна Стандартное значение ExoPlayer - Изменить размер предварительной загрузки (сейчас %s). Меньшее значение может ускорить загрузку видео. При изменении требуется перезапуск плеера + Изменить интервал загрузки (сейчас %s). Меньшее значение может ускорить запуск видео. Нужен перезапуск плеера Загрузка сведений о трансляции… Проверить наличие новых трансляций Удалить все загруженные файлы\? diff --git a/app/src/main/res/values-ta/strings.xml b/app/src/main/res/values-ta/strings.xml index 7aec8a4e9..3b8bff427 100644 --- a/app/src/main/res/values-ta/strings.xml +++ b/app/src/main/res/values-ta/strings.xml @@ -373,4 +373,5 @@ சந்தாவுக்கான புதிய ஸ்ட்ரீம்கள் பற்றிய அறிவிப்புகள் இந்த வீடியோ வயது வரம்புக்குட்பட்டது. \nவயது வரம்புக்குட்பட்ட வீடியோக்கள் கொண்ட புதிய YouTube கொள்கைகள் காரணமாக, NewPipe ஆல் அதன் எந்த வீடியோ ஸ்ட்ரீம்களையும் அணுக முடியாது, இதனால் அதை இயக்க முடியவில்லை. + வேகமான பயன்முறை \ No newline at end of file diff --git a/app/src/main/res/values-te/strings.xml b/app/src/main/res/values-te/strings.xml index bc310bf2a..ac34a316e 100644 --- a/app/src/main/res/values-te/strings.xml +++ b/app/src/main/res/values-te/strings.xml @@ -449,4 +449,26 @@ అడుగు నిశ్శబ్ద సమయంలో వేగంగా ముందుకు వెళ్లుము ప్లేబ్యాక్ స్పీడ్ నియంత్రణలు + ఏమిలేదు + మీరు బ్లాక్ స్క్రీన్ లేదా చలనచిత్రం ప్లేబ్యాక్‌లో అంతరాయాన్ని అనుభవిస్తే మీడియా టన్నెలింగ్‌ను నిలిపివేయండి + చిత్రాల మూలాన్ని సూచించే విధంగా వాటి పైభాగంలో పికాసో రంగు రిబ్బన్‌లను చూపండి: నెట్‌వర్క్ కోసం ఎరుపు, డిస్క్ కోసం నీలం మరియు మెమరీ కోసం ఆకుపచ్చ + లోపం స్నాక్‌బార్‌ని చూపండి + మీరు NewPipe యొక్క తాజా సంస్కరణను అమలు చేస్తున్నారు + NewPipe నవీకరణ అందుబాటులో ఉంది! + పూర్తయింది + వేలాడుతున్న + సర్వీస్‌ల నుండి ఒరిజినల్ టెక్స్ట్‌లు స్ట్రీమ్ ఐటెమ్‌లలో కనిపిస్తాయి + \"ప్లేయర్ పతనం\" చూపించు + ప్లేయర్‌ని ఉపయోగిస్తున్నప్పుడు పతనం ఎంపికను చూపుము + యాప్‌ను పతనం చేయండి + తక్కువ నాణ్యత (చిన్నది) + చూపించవద్దు + మీడియా టన్నెలింగ్‌ని నిలిపివేయండి + చిత్ర సూచికలను చూపు + కొత్త స్ట్రీమ్‌ల కోసం తనిఖీని అమలు చేయండి + ఎర్రర్ నోటిఫికేషన్‌ను సృష్టించండి + దిగుమతి + ఆగిపోయింది + క్రమం + %sని డౌన్‌లోడ్ చేయడానికి నొక్కండి \ 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 a2b392324..9c4ec3957 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -321,7 +321,7 @@ Імпортувати разом з налаштуваннями\? Політика приватності NewPipe Проєкт NewPipe дуже серйозно ставиться до вашої приватності. Тому застосунок не збирає ніяких даних без вашої згоди. -\nПолітика приватності докладно NewPipe пояснює, які дані надсилаються і зберігаються у звіті про збій програми. +\nПолітика приватності докладно NewPipe пояснює, які дані надсилаються і зберігаються у звіті про збій. Читати політику приватності З метою дотримання Загального регламенту про захист даних ЄС (General Data Protection Regulation, GDPR) ми звертаємо вашу увагу на політику приватності NewPipe. Будь ласка, прочитайте уважно. \nВи маєте прийняти її, аби надіслати нам звіт про помилку. @@ -578,7 +578,7 @@ Повʼязані елементи Коментарі Налаштувати повідомлення про відтворюваний наразі потік - Не розпізнано URL. Відкрити через іншу програму\? + Не розпізнано URL. Відкрити через інший застосунок\? Автоматична черга Показувати метадані Показувати описи diff --git a/app/src/main/res/values-ur/strings.xml b/app/src/main/res/values-ur/strings.xml index 0a105c5a8..686644fd9 100644 --- a/app/src/main/res/values-ur/strings.xml +++ b/app/src/main/res/values-ur/strings.xml @@ -498,4 +498,14 @@ کے ساتھ کھولیں ویڈیو پلیئر کو کریش کریں دیکھے ہوئے کو نشان لگائیں + مقامی تلاش کی سفارشات + اطلاعات + مین پلیئر کو مکمل سکرین سے شروع کریں + غلطی کی دستاویزات کی اطلاع + غلطی کی حبر کی اطلاعات + جب ٹھیک ہو جائے تو \"Done\" دبائیں + حل کریں + زیادہ تر پوچھے گئے سوالات + اگر آپ کو یہ ایپ استعمال کرنے میں دشواری آ رہی ہو تو ان عام سوالات کے جوابات کو ضرور دیکھیں! + ویب سائٹ پر دیکھیں \ 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 8dd8684b5..ab902d373 100644 --- a/app/src/main/res/values-zh-rHK/strings.xml +++ b/app/src/main/res/values-zh-rHK/strings.xml @@ -709,4 +709,8 @@ 排序 常見問題 若然您用呢個 app 有疑問,然而「亦有些難啟齒」,不妨睇下常見問題集,話唔定會發現「有場舞還未發表」! + 快速模式 + 右上角嘅選單有得匯入或匯出訂閱 + 您已經用緊最新版本嘅 NewPipe + 撳一下去下載 %s \ No newline at end of file diff --git a/fastlane/metadata/android/fr/changelogs/740.txt b/fastlane/metadata/android/fr/changelogs/740.txt new file mode 100644 index 000000000..da4bdc2f8 --- /dev/null +++ b/fastlane/metadata/android/fr/changelogs/740.txt @@ -0,0 +1,23 @@ +

Améliorations

+
    +
  • Rendre les liens dans les commentaires cliquables, augmenter la taille du texte
  • +
  • Rechercher en cliquant sur les liens d'horodatage dans les commentaires
  • +
  • Afficher l'onglet préféré en fonction de l'état récemment sélectionné
  • +
  • Ajouter la liste de lecture à la file d'attente lors d'un clic long sur 'Arrière-plan' dans la fenêtre de la liste de lecture
  • +
  • Rechercher le texte partagé lorsqu'il ne s'agit pas d'une URL
  • +
  • Ajouter "partager à l'heure actuelle" bouton au lecteur vidéo principal lecteur vidéo principal
  • +
  • Ajouter un bouton de fermeture du lecteur principal lorsque la file d'attente vidéo est terminée
  • +
  • Ajouter "jouer directement en arrière-plan" au menu longpress pour les éléments de la liste vidéo
  • +
  • Améliorer les traductions en anglais des commandes Play/Enqueue
  • +
  • Petites améliorations des performances
  • +
  • Supprimer les fichiers inutilisés
  • +
  • Mise à jour ExoPlayer à 2.9.6
  • +
  • Ajouter le support pour les liens Invidious
  • +
+

Corrections

+
    +
  • Défilement avec les commentaires et les flux associés désactivés
  • +
  • CheckForNewAppVersionTask qui est exécuté alors qu'il ne devrait pas l'être'
  • +
  • Importation des abonnements YouTube : ignorer ceux dont l’URL est invalide et conserver ceux dont le titre est vide
  • +
  • URL YouTube invalide : le nom de la balise signature n'est pas toujours "signature", ce qui empêche le chargement des flux.
  • +
diff --git a/fastlane/metadata/android/fr/changelogs/991.txt b/fastlane/metadata/android/fr/changelogs/991.txt new file mode 100644 index 000000000..59a34f25e --- /dev/null +++ b/fastlane/metadata/android/fr/changelogs/991.txt @@ -0,0 +1,13 @@ +Nouveautés +• Ajout du bouton « Ouvrir dans un navigateur » dans le paneau d'erreur +• Ajout de la possibilité d'afficher les groupes de chaîne en liste +• [YouTube] Appuis long sur le segment d'un flux pour partager l'URL avec l'horodatage +• Ajout d'un bouton sur le lecteur reduit + +Améliorations +• Ajout de la traduction en islandais et mise à jour de d'autre langues +• De nombreuses améliorations internes + +Corrections +• Correction de plantages +• [YouTube] Correction du chargement des chaînes diff --git a/fastlane/metadata/android/it/changelogs/740.txt b/fastlane/metadata/android/it/changelogs/740.txt index 785280b90..297ff9a3c 100644 --- a/fastlane/metadata/android/it/changelogs/740.txt +++ b/fastlane/metadata/android/it/changelogs/740.txt @@ -1,4 +1,4 @@ -
  • Miglioramenti

    +

    Miglioramenti

    • rendi cliccabili i link nei commenti, aumenta la dimensione del testo
    • cerca facendo clic sui collegamenti timestamp nei commenti
    • diff --git a/fastlane/metadata/android/te/changelogs/65.txt b/fastlane/metadata/android/te/changelogs/65.txt new file mode 100644 index 000000000..34d16b0eb --- /dev/null +++ b/fastlane/metadata/android/te/changelogs/65.txt @@ -0,0 +1,26 @@ +### మెరుగుదలలు + +- బర్గర్‌మెను ఐకాన్ యానిమేషన్ #1486ని నిలిపివేయండి +- డౌన్‌లోడ్‌ల తొలగింపును రద్దు చేయండి #1472 +- షేర్ మెను #1498లో డౌన్‌లోడ్ ఎంపిక +- లాంగ్ ట్యాప్ మెనూ #1454కి షేర్ ఆప్షన్ జోడించబడింది +- నిష్క్రమణ #1354లో ప్రధాన ప్లేయర్‌ని తగ్గించండి +- లైబ్రరీ వెర్షన్ అప్‌డేట్ మరియు డేటాబేస్ బ్యాకప్ ఫిక్స్ #1510 +- ExoPlayer 2.8.2 నవీకరణ #1392 + - వేగవంతమైన స్పీడ్ మార్పు కోసం వివిధ దశల పరిమాణాలకు మద్దతు ఇవ్వడానికి ప్లేబ్యాక్ స్పీడ్ కంట్రోల్ డైలాగ్‌ని మళ్లీ రూపొందించారు. + - ప్లేబ్యాక్ స్పీడ్ కంట్రోల్‌లో నిశ్శబ్దం సమయంలో ఫాస్ట్-ఫార్వర్డ్ చేయడానికి టోగుల్ జోడించబడింది. ఇది ఆడియోబుక్‌లు మరియు నిర్దిష్ట సంగీత శైలులకు సహాయకరంగా ఉండాలి మరియు నిజమైన అతుకులు లేని అనుభవాన్ని అందించగలదు (మరియు అనేక నిశ్శబ్దాలతో పాటను విచ్ఛిన్నం చేయవచ్చు =\\). + - మాన్యువల్‌గా కాకుండా ప్లేయర్‌లో అంతర్గతంగా మీడియాతో పాటు మెటాడేటాను పాస్ చేయడానికి రీఫ్యాక్టర్డ్ మీడియా సోర్స్ రిజల్యూషన్. ఇప్పుడు మేము మెటాడేటా యొక్క ఒకే మూలాన్ని కలిగి ఉన్నాము మరియు ప్లేబ్యాక్ ప్రారంభమైనప్పుడు నేరుగా అందుబాటులో ఉంటుంది. + - ప్లేజాబితా భాగాన్ని తెరిచినప్పుడు కొత్త మెటాడేటా అందుబాటులో ఉన్నప్పుడు స్థిర రిమోట్ ప్లేజాబితా మెటాడేటా నవీకరించబడదు. + - వివిధ UI పరిష్కారాలు: #1383, బ్యాక్‌గ్రౌండ్ ప్లేయర్ నోటిఫికేషన్ నియంత్రణలు ఇప్పుడు ఎల్లప్పుడూ తెల్లగా ఉంటాయి, ఫ్లింగ్ ద్వారా పాప్‌అప్ ప్లేయర్‌ని షట్‌డౌన్ చేయడం సులభం +- మల్టీసర్వీస్ కోసం రీఫ్యాక్టర్డ్ ఆర్కిటెక్చర్‌తో కొత్త ఎక్స్‌ట్రాక్టర్‌ని ఉపయోగించండి + +### పరిష్కారాలు + +- #1440 బ్రోకెన్ వీడియో ఇన్ఫో లేఅవుట్ #1491ని పరిష్కరించండి +- చరిత్ర పరిష్కారాన్ని వీక్షించండి #1497 + - #1495, యూజర్ ప్లేజాబితాను యాక్సెస్ చేసిన వెంటనే మెటాడేటా (థంబ్‌నెయిల్, టైటిల్ మరియు వీడియో కౌంట్) అప్‌డేట్ చేయడం ద్వారా. + - #1475, వినియోగదారు వివరాలు ఫ్రాగ్‌మెంట్‌పై బాహ్య ప్లేయర్‌లో వీడియోను ప్రారంభించినప్పుడు డేటాబేస్‌లో వీక్షణను నమోదు చేయడం ద్వారా. +- పాప్అప్ మోడ్ విషయంలో స్క్రీన్ సమయం ముగియడాన్ని పరిష్కరించండి. #1463 (స్థిర #640) +- ప్రధాన వీడియో ప్లేయర్ ఫిక్స్ #1509 + - [#1412] ప్లేయర్ యాక్టివిటీ బ్యాక్‌గ్రౌండ్‌లో ఉన్నప్పుడు కొత్త ఉద్దేశం వచ్చినప్పుడు ప్లేయర్ NPEకి కారణమయ్యే ఫిక్స్డ్ రిపీట్ మోడ్. + - పాప్‌అప్‌కి ప్లేయర్‌ని కనిష్టీకరించడం అనేది పాప్‌అప్ అనుమతి ఇవ్వనప్పుడు ప్లేయర్‌ను నాశనం చేయదు. diff --git a/fastlane/metadata/android/uk/changelogs/951.txt b/fastlane/metadata/android/uk/changelogs/951.txt index 1cd68b0b8..37ebfd318 100644 --- a/fastlane/metadata/android/uk/changelogs/951.txt +++ b/fastlane/metadata/android/uk/changelogs/951.txt @@ -5,7 +5,7 @@ •Швид.перемот.вперед/назад у фоні/вікні програв.черги •Показ порад пошуку: мали на увазі й показ результ. для Покр. -•Вил.запис метадан.програми в зміш.файли +•Вил.запис метадан.застосунку в зміш.файли •Не вилуч.невдалі потоки з черги •Оновл.колір пан.стану відповідно до коль.пан.засобів Випр. From c13b858f0246bc7b8ca9dcfd922ed5f5bf0a5758 Mon Sep 17 00:00:00 2001 From: TobiGr Date: Fri, 23 Dec 2022 00:51:25 +0100 Subject: [PATCH 18/23] Add Nynorsk (nn) to the language chooser --- app/src/main/res/values/settings_keys.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/res/values/settings_keys.xml b/app/src/main/res/values/settings_keys.xml index 9244f05c4..17ed547a0 100644 --- a/app/src/main/res/values/settings_keys.xml +++ b/app/src/main/res/values/settings_keys.xml @@ -441,6 +441,7 @@ hu nl no + nn uz pl pt-PT @@ -519,6 +520,7 @@ Magyar Nederlands Norsk + Nynorsk O‘zbek Polski Português From 413a1b504a1fe423c83f654428a5b68cb8230bf6 Mon Sep 17 00:00:00 2001 From: Stypox Date: Sat, 31 Dec 2022 17:47:57 +0100 Subject: [PATCH 19/23] Refactor constrolsTouchListener code --- .../fragments/detail/VideoDetailFragment.java | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 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 784b24619..2aa0e6ad2 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 @@ -14,6 +14,7 @@ import static org.schabi.newpipe.util.NavigationHelper.openPlayQueue; import static org.schabi.newpipe.util.NavigationHelper.playWithKore; import android.animation.ValueAnimator; +import android.annotation.SuppressLint; import android.app.Activity; import android.content.BroadcastReceiver; import android.content.Context; @@ -617,6 +618,7 @@ public final class VideoDetailFragment } @Override + @SuppressLint("ClickableViewAccessibility") protected void initListeners() { super.initListeners(); @@ -624,16 +626,12 @@ public final class VideoDetailFragment setOnLongClickListeners(); final View.OnTouchListener controlsTouchListener = (view, motionEvent) -> { - if (!PreferenceManager.getDefaultSharedPreferences(activity) + if (motionEvent.getAction() == MotionEvent.ACTION_DOWN + && PreferenceManager.getDefaultSharedPreferences(activity) .getBoolean(getString(R.string.show_hold_to_append_key), true)) { - return false; - } - if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) { - animate(binding.touchAppendDetail, true, 250, AnimationType.ALPHA, - 0, () -> - animate(binding.touchAppendDetail, false, 1500, - AnimationType.ALPHA, 1000)); + animate(binding.touchAppendDetail, true, 250, AnimationType.ALPHA, 0, () -> + animate(binding.touchAppendDetail, false, 1500, AnimationType.ALPHA, 1000)); } return false; }; From 97978033dddac988a724c59fb83b574eead438fb Mon Sep 17 00:00:00 2001 From: Stypox Date: Sat, 31 Dec 2022 17:49:10 +0100 Subject: [PATCH 20/23] Activate on click listeners only when not loading For consistency with long click listeners, in VideoDetailFragment --- .../schabi/newpipe/fragments/detail/VideoDetailFragment.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 2aa0e6ad2..2fb62413f 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 @@ -523,7 +523,7 @@ public final class VideoDetailFragment private View.OnClickListener makeOnClickListener(final Consumer consumer) { return v -> { - if (currentInfo != null) { + if (!isLoading.get() && currentInfo != null) { consumer.accept(currentInfo); } }; From b3bfec9505ac956883dd62cc5db410568ef1bb1b Mon Sep 17 00:00:00 2001 From: Stypox Date: Sat, 31 Dec 2022 19:31:24 +0100 Subject: [PATCH 21/23] Use correct fragment manager for download dialog Tapping download on the long-press menu of queue items when the queue is shown inside the player would crash otherwise --- .../main/java/org/schabi/newpipe/QueueItemMenuUtil.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/QueueItemMenuUtil.java b/app/src/main/java/org/schabi/newpipe/QueueItemMenuUtil.java index 66c19f86d..3255489b0 100644 --- a/app/src/main/java/org/schabi/newpipe/QueueItemMenuUtil.java +++ b/app/src/main/java/org/schabi/newpipe/QueueItemMenuUtil.java @@ -8,7 +8,6 @@ import android.view.ContextThemeWrapper; import android.view.View; import android.widget.PopupMenu; -import androidx.appcompat.app.AppCompatActivity; import androidx.fragment.app.FragmentManager; import org.schabi.newpipe.database.stream.model.StreamEntity; @@ -79,12 +78,11 @@ public final class QueueItemMenuUtil { item.getThumbnailUrl()); return true; case R.id.menu_item_download: - fetchStreamInfoAndSaveToDatabase(context, item.getServiceId(), - item.getUrl(), info -> { + fetchStreamInfoAndSaveToDatabase(context, item.getServiceId(), item.getUrl(), + info -> { final DownloadDialog downloadDialog = new DownloadDialog(context, info); - downloadDialog.show(((AppCompatActivity) context) - .getSupportFragmentManager(), "downloadDialog"); + downloadDialog.show(fragmentManager, "downloadDialog"); }); return true; } From d21fac658b018cf3f06f8ace07ffae67a82a480e Mon Sep 17 00:00:00 2001 From: Stypox Date: Sat, 31 Dec 2022 23:30:12 +0100 Subject: [PATCH 22/23] Remove playlist details toasts --- .../fragments/list/playlist/PlaylistFragment.java | 13 ++----------- app/src/main/res/values/strings.xml | 1 - 2 files changed, 2 insertions(+), 12 deletions(-) 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 899534793..a3150a773 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 @@ -13,7 +13,6 @@ import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; -import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -231,13 +230,8 @@ public class PlaylistFragment extends BaseListInfoFragment dialog.show(getFM(), TAG) )); - } else { - Toast.makeText(getContext(), getString(R.string.playlist_loading_message), - Toast.LENGTH_SHORT).show(); } break; default: diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index d72fd4217..76b828746 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -241,7 +241,6 @@ Restore defaults Do you want to restore defaults? Give permission to display over other apps - Playlist loading… NewPipe encountered an error, tap to report An error occurred, see the notification From 56800c24b937416d7c22d71db09b2a81df650c28 Mon Sep 17 00:00:00 2001 From: Stypox Date: Sun, 1 Jan 2023 12:46:56 +0100 Subject: [PATCH 23/23] Update rxandroid from 3.0.0 to 3.0.2 --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 582f61618..c577b3426 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -266,7 +266,7 @@ dependencies { // Reactive extensions for Java VM implementation "io.reactivex.rxjava3:rxjava:3.1.5" - implementation "io.reactivex.rxjava3:rxandroid:3.0.0" + implementation "io.reactivex.rxjava3:rxandroid:3.0.2" // RxJava binding APIs for Android UI widgets implementation "com.jakewharton.rxbinding4:rxbinding:4.0.0"