From 79060f0bfe56009f5c7c059feeeaf8435e0faba4 Mon Sep 17 00:00:00 2001 From: TacoTheDank Date: Wed, 2 Feb 2022 13:12:29 -0500 Subject: [PATCH 01/19] Update ACRA library --- app/build.gradle | 2 +- app/src/main/java/org/schabi/newpipe/App.java | 18 +++--------------- 2 files changed, 4 insertions(+), 16 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 4cebcb7f5..7d6123d6f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -260,7 +260,7 @@ dependencies { implementation "com.nononsenseapps:filepicker:4.2.1" // Crash reporting - implementation "ch.acra:acra-core:5.7.0" + implementation "ch.acra:acra-core:5.8.4" // Properly restarting implementation 'com.jakewharton:process-phoenix:2.1.2' diff --git a/app/src/main/java/org/schabi/newpipe/App.java b/app/src/main/java/org/schabi/newpipe/App.java index 6c02b6f57..54e0af8c6 100644 --- a/app/src/main/java/org/schabi/newpipe/App.java +++ b/app/src/main/java/org/schabi/newpipe/App.java @@ -13,13 +13,8 @@ import androidx.preference.PreferenceManager; import com.jakewharton.processphoenix.ProcessPhoenix; import org.acra.ACRA; -import org.acra.config.ACRAConfigurationException; -import org.acra.config.CoreConfiguration; import org.acra.config.CoreConfigurationBuilder; -import org.schabi.newpipe.error.ErrorInfo; -import org.schabi.newpipe.error.ErrorUtil; import org.schabi.newpipe.error.ReCaptchaActivity; -import org.schabi.newpipe.error.UserAction; import org.schabi.newpipe.extractor.NewPipe; import org.schabi.newpipe.extractor.downloader.Downloader; import org.schabi.newpipe.ktx.ExceptionUtils; @@ -210,16 +205,9 @@ public class App extends MultiDexApplication { return; } - try { - final CoreConfiguration acraConfig = new CoreConfigurationBuilder(this) - .setBuildConfigClass(BuildConfig.class) - .build(); - ACRA.init(this, acraConfig); - } catch (final ACRAConfigurationException exception) { - exception.printStackTrace(); - ErrorUtil.openActivity(this, new ErrorInfo(exception, - UserAction.SOMETHING_ELSE, "Could not initialize ACRA crash report")); - } + final CoreConfigurationBuilder acraConfig = new CoreConfigurationBuilder(this) + .withBuildConfigClass(BuildConfig.class); + ACRA.init(this, acraConfig); } private void initNotificationChannels() { From c08a4e851bc927347c26e4be8a3093fce26cd8b5 Mon Sep 17 00:00:00 2001 From: litetex <40789489+litetex@users.noreply.github.com> Date: Tue, 15 Feb 2022 20:09:21 +0100 Subject: [PATCH 02/19] Improved image-minimizer * Don't minimize images that are too wide -> they will get stretched otherwise * Don't try to modify the issue/comment when nothing changed * Fixed typo --- .github/workflows/image-minimizer.js | 29 +++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/.github/workflows/image-minimizer.js b/.github/workflows/image-minimizer.js index 8d10a1e77..273c6d328 100644 --- a/.github/workflows/image-minimizer.js +++ b/.github/workflows/image-minimizer.js @@ -4,7 +4,12 @@ module.exports = async ({github, context}) => { const IGNORE_KEY = ''; const IGNORE_ALT_NAME_END = 'ignoreImageMinify'; + // Targeted maximum height const IMG_MAX_HEIGHT_PX = 600; + // maximum width of GitHub issues/comments + const IMG_MAX_WIDTH_PX = 800; + // all images that have a lower aspect ration (-> have a smaller width) than this will be minimized + const MIN_ASPECT_RATION = IMG_MAX_WIDTH_PX / IMG_MAX_HEIGHT_PX // Get the body of the image let initialBody = null; @@ -38,6 +43,8 @@ module.exports = async ({github, context}) => { // Require the probe lib for getting the image dimensions const probe = require('probe-image-size'); + + var wasMatchModified = false; // Try to find and replace the images with minimized ones let newBody = await replaceAsync(initialBody, REGEX_IMAGE_LOOKUP, async (match, g1, g2) => { @@ -48,7 +55,7 @@ module.exports = async ({github, context}) => { return match; } - let shouldModifiy = false; + let shouldModify = false; try { console.log(`Probing ${g2}`); let probeResult = await probe(g2); @@ -58,15 +65,26 @@ module.exports = async ({github, context}) => { if (probeResult.hUnits != 'px') { throw `Unexpected probeResult.hUnits (expected px but got ${probeResult.hUnits})`; } + if (probeResult.height <= 0) { + throw `Unexpected probeResult.height (height is invalid: ${probeResult.height})`; + } + if (probeResult.wUnits != 'px') { + throw `Unexpected probeResult.wUnits (expected px but got ${probeResult.wUnits})`; + } + if (probeResult.width <= 0) { + throw `Unexpected probeResult.width (width is invalid: ${probeResult.width})`; + } + console.log(`Probing resulted in ${probeResult.width}x${probeResult.height}px`); - shouldModifiy = probeResult.height > IMG_MAX_HEIGHT_PX; + shouldModify = probeResult.height > IMG_MAX_HEIGHT_PX && (probeResult.width / probeResult.height) < MIN_ASPECT_RATION; } catch(e) { console.log('Probing failed:', e); // Immediately abort return match; } - if (shouldModifiy) { + if (shouldModify) { + wasMatchModified = true; console.log(`Modifying match '${match}'`); return `${g1}`; } @@ -74,6 +92,11 @@ module.exports = async ({github, context}) => { console.log(`Match '${match}' is ok/will not be modified`); return match; }); + + if (!wasMatchModified) { + console.log('Nothing was modified. Skipping update'); + return; + } // Update the corresponding element if (context.eventName == 'issue_comment') { From 7225199debff83ba2dd2839372a928ebe8070dbf Mon Sep 17 00:00:00 2001 From: litetex <40789489+litetex@users.noreply.github.com> Date: Wed, 16 Feb 2022 20:31:15 +0100 Subject: [PATCH 03/19] Fixed typo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It was late when I typed this 😆 --- .github/workflows/image-minimizer.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/image-minimizer.js b/.github/workflows/image-minimizer.js index 273c6d328..80cc5294c 100644 --- a/.github/workflows/image-minimizer.js +++ b/.github/workflows/image-minimizer.js @@ -8,8 +8,8 @@ module.exports = async ({github, context}) => { const IMG_MAX_HEIGHT_PX = 600; // maximum width of GitHub issues/comments const IMG_MAX_WIDTH_PX = 800; - // all images that have a lower aspect ration (-> have a smaller width) than this will be minimized - const MIN_ASPECT_RATION = IMG_MAX_WIDTH_PX / IMG_MAX_HEIGHT_PX + // all images that have a lower aspect ratio (-> have a smaller width) than this will be minimized + const MIN_ASPECT_RATIO = IMG_MAX_WIDTH_PX / IMG_MAX_HEIGHT_PX // Get the body of the image let initialBody = null; @@ -76,7 +76,7 @@ module.exports = async ({github, context}) => { } console.log(`Probing resulted in ${probeResult.width}x${probeResult.height}px`); - shouldModify = probeResult.height > IMG_MAX_HEIGHT_PX && (probeResult.width / probeResult.height) < MIN_ASPECT_RATION; + shouldModify = probeResult.height > IMG_MAX_HEIGHT_PX && (probeResult.width / probeResult.height) < MIN_ASPECT_RATIO; } catch(e) { console.log('Probing failed:', e); // Immediately abort From fb362022f732ed81fcc60725b094bb6cf80707aa Mon Sep 17 00:00:00 2001 From: litetex <40789489+litetex@users.noreply.github.com> Date: Sat, 15 Jan 2022 17:05:40 +0100 Subject: [PATCH 04/19] Load enough initial data into BaseListFragment --- .../fragments/list/BaseListFragment.java | 63 ++++++++++++++++++- .../fragments/list/BaseListInfoFragment.java | 19 ++++-- .../fragments/list/search/SearchFragment.java | 14 ++++- 3 files changed, 85 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListFragment.java index 3c2e65bb7..d0a07ffc4 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListFragment.java @@ -271,7 +271,7 @@ public abstract class BaseListFragment extends BaseStateFragment @Override protected void initListeners() { super.initListeners(); - infoListAdapter.setOnStreamSelectedListener(new OnClickGesture() { + infoListAdapter.setOnStreamSelectedListener(new OnClickGesture<>() { @Override public void selected(final StreamInfoItem selectedItem) { onStreamSelected(selectedItem); @@ -418,7 +418,66 @@ public abstract class BaseListFragment extends BaseStateFragment // Load and handle //////////////////////////////////////////////////////////////////////////*/ - protected abstract void loadMoreItems(); + /** + * If more items are loadable and the itemList is not scrollable -> load more data. + *
+ * Should be called once the initial items inside {@link #startLoading(boolean)} + * has been loaded and added to the {@link #itemsList}. + *
+ * Otherwise the loading indicator is always shown but no data can be loaded + * because the view is not scrollable; see also #1974. + */ + protected void ifMoreItemsLoadableLoadUntilScrollable() { + ifMoreItemsLoadableLoadUntilScrollable(0); + } + + /** + * If more items are loadable and the itemList is not scrollable -> load more data. + * + * @param recursiveCallCount Amount of recursive calls that occurred + * @see #ifMoreItemsLoadableLoadUntilScrollable() + */ + protected void ifMoreItemsLoadableLoadUntilScrollable(final int recursiveCallCount) { + // Try to prevent malfunction / stackoverflow + if (recursiveCallCount > 100) { + Log.w(TAG, "loadEnoughInitialData - Too many recursive calls - Aborting"); + return; + } + if (!hasMoreItems()) { + if (DEBUG) { + Log.d(TAG, "loadEnoughInitialData - OK: No more items to load"); + } + return; + } + if (itemsList.canScrollVertically(1) + || itemsList.canScrollVertically(-1)) { + if (DEBUG) { + Log.d(TAG, "loadEnoughInitial - OK: itemList is scrollable"); + } + return; + } + if (DEBUG) { + Log.d(TAG, "loadEnoughInitialData - View is not scrollable " + + "but it could load more items -> Loading more"); + } + loadMoreItems(() -> + ifMoreItemsLoadableLoadUntilScrollable(recursiveCallCount + 1)); + } + + /** + * Loads more items. + * @param initialDataLoadCallback + * Callback used in {@link #ifMoreItemsLoadableLoadUntilScrollable()}. + *
+ * Execute it once the data was loaded and added to the {@link #itemsList}. + *
+ * Might be null. + */ + protected abstract void loadMoreItems(@Nullable Runnable initialDataLoadCallback); + + protected void loadMoreItems() { + loadMoreItems(null); + } protected abstract boolean hasMoreItems(); diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListInfoFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListInfoFragment.java index e98dc9fda..87f031c12 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListInfoFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListInfoFragment.java @@ -6,6 +6,7 @@ import android.util.Log; import android.view.View; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import org.schabi.newpipe.error.ErrorInfo; import org.schabi.newpipe.error.UserAction; @@ -65,7 +66,7 @@ public abstract class BaseListInfoFragment super.onResume(); // Check if it was loading when the fragment was stopped/paused, if (wasLoading.getAndSet(false)) { - if (hasMoreItems() && infoListAdapter.getItemsList().size() > 0) { + if (hasMoreItems() && !infoListAdapter.getItemsList().isEmpty()) { loadMoreItems(); } else { doInitialLoadLogic(); @@ -105,6 +106,7 @@ public abstract class BaseListInfoFragment // Load and handle //////////////////////////////////////////////////////////////////////////*/ + @Override protected void doInitialLoadLogic() { if (DEBUG) { Log.d(TAG, "doInitialLoadLogic() called"); @@ -144,6 +146,7 @@ public abstract class BaseListInfoFragment currentInfo = result; currentNextPage = result.getNextPage(); handleResult(result); + ifMoreItemsLoadableLoadUntilScrollable(); }, throwable -> showError(new ErrorInfo(throwable, errorUserAction, "Start loading: " + url, serviceId))); @@ -158,7 +161,8 @@ public abstract class BaseListInfoFragment */ protected abstract Single loadMoreItemsLogic(); - protected void loadMoreItems() { + @Override + protected void loadMoreItems(@Nullable final Runnable initialDataLoadCallback) { isLoading.set(true); if (currentWorker != null) { @@ -171,9 +175,12 @@ public abstract class BaseListInfoFragment .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .doFinally(this::allowDownwardFocusScroll) - .subscribe((@NonNull ListExtractor.InfoItemsPage InfoItemsPage) -> { + .subscribe(infoItemsPage -> { isLoading.set(false); - handleNextItems(InfoItemsPage); + handleNextItems(infoItemsPage); + if (initialDataLoadCallback != null) { + initialDataLoadCallback.run(); + } }, (@NonNull Throwable throwable) -> dynamicallyShowErrorPanelOrSnackbar(new ErrorInfo(throwable, errorUserAction, "Loading more items: " + url, serviceId))); @@ -223,7 +230,7 @@ public abstract class BaseListInfoFragment setTitle(name); if (infoListAdapter.getItemsList().isEmpty()) { - if (result.getRelatedItems().size() > 0) { + if (!result.getRelatedItems().isEmpty()) { infoListAdapter.addInfoItemList(result.getRelatedItems()); showListFooter(hasMoreItems()); } else { @@ -240,7 +247,7 @@ public abstract class BaseListInfoFragment final List errors = new ArrayList<>(result.getErrors()); // handling ContentNotSupportedException not to show the error but an appropriate string // so that crashes won't be sent uselessly and the user will understand what happened - errors.removeIf(throwable -> throwable instanceof ContentNotSupportedException); + errors.removeIf(ContentNotSupportedException.class::isInstance); if (!errors.isEmpty()) { dynamicallyShowErrorPanelOrSnackbar(new ErrorInfo(result.getErrors(), 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 055c27733..35bb2c349 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 @@ -868,12 +868,15 @@ public class SearchFragment extends BaseListFragment isLoading.set(false)) - .subscribe(this::handleResult, this::onItemError); + .subscribe(result -> { + handleResult(result); + ifMoreItemsLoadableLoadUntilScrollable(); + }, this::onItemError); } @Override - protected void loadMoreItems() { + protected void loadMoreItems(@Nullable final Runnable initialDataLoadCallback) { if (!Page.isValid(nextPage)) { return; } @@ -891,7 +894,12 @@ public class SearchFragment extends BaseListFragment isLoading.set(false)) - .subscribe(this::handleNextItems, this::onItemError); + .subscribe(itemsPage -> { + handleNextItems(itemsPage); + if (initialDataLoadCallback != null) { + initialDataLoadCallback.run(); + } + }, this::onItemError); } @Override From 2c51a7970d0bf3174a25b0c4cde03a4878e7cefa Mon Sep 17 00:00:00 2001 From: litetex <40789489+litetex@users.noreply.github.com> Date: Sat, 15 Jan 2022 17:28:03 +0100 Subject: [PATCH 05/19] Improved InfoListAdapter * Removed unused code * Cleaned it up * Made code more readable --- .../newpipe/info_list/InfoListAdapter.java | 70 ++++--------------- 1 file changed, 12 insertions(+), 58 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/info_list/InfoListAdapter.java b/app/src/main/java/org/schabi/newpipe/info_list/InfoListAdapter.java index 56bc63384..410a65449 100644 --- a/app/src/main/java/org/schabi/newpipe/info_list/InfoListAdapter.java +++ b/app/src/main/java/org/schabi/newpipe/info_list/InfoListAdapter.java @@ -145,43 +145,6 @@ public class InfoListAdapter extends RecyclerView.Adapter data) { - infoItemList.clear(); - infoItemList.addAll(data); - notifyDataSetChanged(); - } - - public void addInfoItem(@Nullable final InfoItem data) { - if (data == null) { - return; - } - if (DEBUG) { - Log.d(TAG, "addInfoItem() before > infoItemList.size() = " - + infoItemList.size() + ", thread = " + Thread.currentThread()); - } - - final int positionInserted = sizeConsideringHeaderOffset(); - infoItemList.add(data); - - if (DEBUG) { - Log.d(TAG, "addInfoItem() after > position = " + positionInserted + ", " - + "infoItemList.size() = " + infoItemList.size() + ", " - + "header = " + header + ", footer = " + footer + ", " - + "showFooter = " + showFooter); - } - notifyItemInserted(positionInserted); - - if (footer != null && showFooter) { - final int footerNow = sizeConsideringHeaderOffset(); - notifyItemMoved(positionInserted, footerNow); - - if (DEBUG) { - Log.d(TAG, "addInfoItem() footer from " + positionInserted - + " to " + footerNow); - } - } - } - public void clearStreamItemList() { if (infoItemList.isEmpty()) { return; @@ -226,7 +189,7 @@ public class InfoListAdapter extends RecyclerView.Adapter getItemsList() { + public List getItemsList() { return infoItemList; } @@ -335,29 +298,23 @@ public class InfoListAdapter extends RecyclerView.Adapter payloads) { - if (!payloads.isEmpty() && holder instanceof InfoItemHolder) { - for (final Object payload : payloads) { - if (payload instanceof StreamStateEntity) { - ((InfoItemHolder) holder).updateState(infoItemList - .get(header == null ? position : position - 1), recordManager); - } else if (payload instanceof Boolean) { - ((InfoItemHolder) holder).updateState(infoItemList - .get(header == null ? position : position - 1), recordManager); - } - } - } else { + if (payloads.isEmpty() || !(holder instanceof InfoItemHolder)) { onBindViewHolder(holder, position); + return; + } + + for (final Object payload : payloads) { + if (payload instanceof StreamStateEntity || payload instanceof Boolean) { + ((InfoItemHolder) holder).updateState(infoItemList + .get(header == null ? position : position - 1), recordManager); + } } } @@ -372,11 +329,8 @@ public class InfoListAdapter extends RecyclerView.Adapter Date: Sat, 15 Jan 2022 17:40:08 +0100 Subject: [PATCH 06/19] Removed InfoListAdapter from checkstyle-suppressions because if you modify something in the code the suppressions-file no longer matches --- .../java/org/schabi/newpipe/info_list/InfoListAdapter.java | 2 ++ checkstyle-suppressions.xml | 4 ---- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/info_list/InfoListAdapter.java b/app/src/main/java/org/schabi/newpipe/info_list/InfoListAdapter.java index 410a65449..57e6fa380 100644 --- a/app/src/main/java/org/schabi/newpipe/info_list/InfoListAdapter.java +++ b/app/src/main/java/org/schabi/newpipe/info_list/InfoListAdapter.java @@ -212,6 +212,7 @@ public class InfoListAdapter extends RecyclerView.Adapter - - From 91c67b085bd6a5553b44a08a296e2c2f72f761c8 Mon Sep 17 00:00:00 2001 From: litetex <40789489+litetex@users.noreply.github.com> Date: Sat, 15 Jan 2022 23:55:19 +0100 Subject: [PATCH 07/19] Code improvements Removed - partial - stupid code. --- .../fragments/list/BaseListFragment.java | 5 ---- .../list/channel/ChannelFragment.java | 23 ++++++++----------- .../list/playlist/PlaylistFragment.java | 2 +- .../list/videos/RelatedItemsFragment.java | 14 +++-------- 4 files changed, 13 insertions(+), 31 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListFragment.java index d0a07ffc4..741729d5b 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListFragment.java @@ -79,11 +79,6 @@ public abstract class BaseListFragment extends BaseStateFragment } } - @Override - public void onDetach() { - super.onDetach(); - } - @Override public void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java index 37954478d..66eb64b82 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java @@ -183,13 +183,6 @@ public class ChannelFragment extends BaseListInfoFragment } } - private void openRssFeed() { - final ChannelInfo info = currentInfo; - if (info != null) { - ShareUtils.openUrlInBrowser(requireContext(), info.getFeedUrl(), false); - } - } - @Override public boolean onOptionsItemSelected(final MenuItem item) { switch (item.getItemId()) { @@ -197,7 +190,10 @@ public class ChannelFragment extends BaseListInfoFragment NavigationHelper.openSettings(requireContext()); break; case R.id.menu_item_rss: - openRssFeed(); + if (currentInfo != null) { + ShareUtils.openUrlInBrowser( + requireContext(), currentInfo.getFeedUrl(), false); + } break; case R.id.menu_item_openInBrowser: if (currentInfo != null) { @@ -516,12 +512,11 @@ public class ChannelFragment extends BaseListInfoFragment } private PlayQueue getPlayQueue(final int index) { - final List streamItems = new ArrayList<>(); - for (final InfoItem i : infoListAdapter.getItemsList()) { - if (i instanceof StreamInfoItem) { - streamItems.add((StreamInfoItem) i); - } - } + final List streamItems = infoListAdapter.getItemsList().stream() + .filter(StreamInfoItem.class::isInstance) + .map(StreamInfoItem.class::cast) + .collect(Collectors.toList()); + return new ChannelPlayQueue(currentInfo.getServiceId(), currentInfo.getUrl(), currentInfo.getNextPage(), streamItems, index); } 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 640d08064..89ee3980e 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 @@ -413,7 +413,7 @@ public class PlaylistFragment extends BaseListInfoFragment { } private Subscriber> getPlaylistBookmarkSubscriber() { - return new Subscriber>() { + return new Subscriber<>() { @Override public void onSubscribe(final Subscription s) { if (bookmarkReactor != null) { diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/videos/RelatedItemsFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/videos/RelatedItemsFragment.java index 6532417c0..285024484 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/videos/RelatedItemsFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/videos/RelatedItemsFragment.java @@ -26,12 +26,11 @@ import org.schabi.newpipe.util.RelatedItemInfo; import java.io.Serializable; import io.reactivex.rxjava3.core.Single; -import io.reactivex.rxjava3.disposables.CompositeDisposable; public class RelatedItemsFragment extends BaseListInfoFragment implements SharedPreferences.OnSharedPreferenceChangeListener { private static final String INFO_KEY = "related_info_key"; - private final CompositeDisposable disposables = new CompositeDisposable(); + private RelatedItemInfo relatedItemInfo; /*////////////////////////////////////////////////////////////////////////// @@ -54,11 +53,6 @@ public class RelatedItemsFragment extends BaseListInfoFragment // LifeCycle //////////////////////////////////////////////////////////////////////////*/ - @Override - public void onAttach(@NonNull final Context context) { - super.onAttach(context); - } - @Override public View onCreateView(@NonNull final LayoutInflater inflater, @Nullable final ViewGroup container, @@ -67,9 +61,6 @@ public class RelatedItemsFragment extends BaseListInfoFragment } @Override - public void onDestroy() { - super.onDestroy(); - disposables.clear(); } @Override @@ -128,7 +119,6 @@ public class RelatedItemsFragment extends BaseListInfoFragment } ViewUtils.slideUp(requireView(), 120, 96, 0.06f); - disposables.clear(); } /*////////////////////////////////////////////////////////////////////////// @@ -137,11 +127,13 @@ public class RelatedItemsFragment extends BaseListInfoFragment @Override public void setTitle(final String title) { + // Nothing to do - override parent } @Override public void onCreateOptionsMenu(@NonNull final Menu menu, @NonNull final MenuInflater inflater) { + // Nothing to do - override parent } private void setInitialData(final StreamInfo info) { From d3cd3d62b4ab542888669492f6da025cc2db2cfd Mon Sep 17 00:00:00 2001 From: litetex <40789489+litetex@users.noreply.github.com> Date: Sun, 16 Jan 2022 17:08:13 +0100 Subject: [PATCH 08/19] Tried to repair #4475 and #3368 * Always recreate the footer so that it's not possible to attach the same instance twice * Removed support for creating a custom footer as it's never used * Supply the header with an supplier * This might not fix the problem completely as we currently can only create the header once inside Channel, Playlist and RelatedItems-Fragment - allowing creation of multiple headers might be done in the future if the issues still arise * Other minor fixes --- .../fragments/list/BaseListFragment.java | 18 ++---- .../list/channel/ChannelFragment.java | 19 +++---- .../list/playlist/PlaylistFragment.java | 20 +++---- .../list/videos/RelatedItemsFragment.java | 42 +++++++------- .../newpipe/info_list/InfoListAdapter.java | 57 +++++++++++-------- 5 files changed, 78 insertions(+), 78 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListFragment.java index 741729d5b..d1685c5af 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListFragment.java @@ -17,10 +17,8 @@ import androidx.appcompat.app.ActionBar; import androidx.preference.PreferenceManager; import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.RecyclerView; -import androidx.viewbinding.ViewBinding; import org.schabi.newpipe.R; -import org.schabi.newpipe.databinding.PignateFooterBinding; import org.schabi.newpipe.error.ErrorUtil; import org.schabi.newpipe.extractor.InfoItem; import org.schabi.newpipe.extractor.channel.ChannelInfoItem; @@ -44,6 +42,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Queue; +import java.util.function.Supplier; import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty; import static org.schabi.newpipe.ktx.ViewUtils.animate; @@ -215,14 +214,10 @@ public abstract class BaseListFragment extends BaseStateFragment //////////////////////////////////////////////////////////////////////////*/ @Nullable - protected ViewBinding getListHeader() { + protected Supplier getListHeaderSupplier() { return null; } - protected ViewBinding getListFooter() { - return PignateFooterBinding.inflate(activity.getLayoutInflater(), itemsList, false); - } - protected RecyclerView.LayoutManager getListLayoutManager() { return new SuperScrollLayoutManager(activity); } @@ -247,11 +242,10 @@ public abstract class BaseListFragment extends BaseStateFragment itemsList.setLayoutManager(useGrid ? getGridLayoutManager() : getListLayoutManager()); infoListAdapter.setUseGridVariant(useGrid); - infoListAdapter.setFooter(getListFooter().getRoot()); - final ViewBinding listHeader = getListHeader(); - if (listHeader != null) { - infoListAdapter.setHeader(listHeader.getRoot()); + final Supplier listHeaderSupplier = getListHeaderSupplier(); + if (listHeaderSupplier != null) { + infoListAdapter.setHeaderSupplier(listHeaderSupplier); } itemsList.setAdapter(infoListAdapter); @@ -447,7 +441,7 @@ public abstract class BaseListFragment extends BaseStateFragment if (itemsList.canScrollVertically(1) || itemsList.canScrollVertically(-1)) { if (DEBUG) { - Log.d(TAG, "loadEnoughInitial - OK: itemList is scrollable"); + Log.d(TAG, "loadEnoughInitialData - OK: itemList is scrollable"); } return; } diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java index 66eb64b82..918facc4e 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java @@ -1,5 +1,9 @@ package org.schabi.newpipe.fragments.list.channel; +import static org.schabi.newpipe.ktx.TextViewUtils.animateTextColor; +import static org.schabi.newpipe.ktx.ViewUtils.animate; +import static org.schabi.newpipe.ktx.ViewUtils.animateBackgroundColor; + import android.content.Context; import android.os.Bundle; import android.text.TextUtils; @@ -17,7 +21,6 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.ActionBar; import androidx.core.content.ContextCompat; -import androidx.viewbinding.ViewBinding; import com.jakewharton.rxbinding4.view.RxView; @@ -29,7 +32,6 @@ import org.schabi.newpipe.databinding.PlaylistControlBinding; import org.schabi.newpipe.error.ErrorInfo; import org.schabi.newpipe.error.ErrorUtil; import org.schabi.newpipe.error.UserAction; -import org.schabi.newpipe.extractor.InfoItem; import org.schabi.newpipe.extractor.ListExtractor; import org.schabi.newpipe.extractor.channel.ChannelInfo; import org.schabi.newpipe.extractor.exceptions.ContentNotSupportedException; @@ -43,13 +45,14 @@ import org.schabi.newpipe.player.playqueue.PlayQueue; import org.schabi.newpipe.util.ExtractorHelper; import org.schabi.newpipe.util.Localization; import org.schabi.newpipe.util.NavigationHelper; -import org.schabi.newpipe.util.external_communication.ShareUtils; import org.schabi.newpipe.util.PicassoHelper; import org.schabi.newpipe.util.ThemeHelper; +import org.schabi.newpipe.util.external_communication.ShareUtils; -import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; +import java.util.function.Supplier; +import java.util.stream.Collectors; import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; import io.reactivex.rxjava3.core.Observable; @@ -61,10 +64,6 @@ import io.reactivex.rxjava3.functions.Consumer; import io.reactivex.rxjava3.functions.Function; import io.reactivex.rxjava3.schedulers.Schedulers; -import static org.schabi.newpipe.ktx.TextViewUtils.animateTextColor; -import static org.schabi.newpipe.ktx.ViewUtils.animate; -import static org.schabi.newpipe.ktx.ViewUtils.animateBackgroundColor; - public class ChannelFragment extends BaseListInfoFragment implements View.OnClickListener { @@ -145,12 +144,12 @@ public class ChannelFragment extends BaseListInfoFragment //////////////////////////////////////////////////////////////////////////*/ @Override - protected ViewBinding getListHeader() { + protected Supplier getListHeaderSupplier() { headerBinding = ChannelHeaderBinding .inflate(activity.getLayoutInflater(), itemsList, false); playlistControlBinding = headerBinding.playlistControl; - return headerBinding; + return headerBinding::getRoot; } @Override 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 89ee3980e..84dcb4fd9 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 @@ -1,5 +1,9 @@ package org.schabi.newpipe.fragments.list.playlist; +import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty; +import static org.schabi.newpipe.ktx.ViewUtils.animate; +import static org.schabi.newpipe.ktx.ViewUtils.animateHideRecyclerViewAllowingScrolling; + import android.app.Activity; import android.content.Context; import android.os.Bundle; @@ -15,7 +19,6 @@ import android.view.ViewGroup; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.content.res.AppCompatResources; -import androidx.viewbinding.ViewBinding; import org.reactivestreams.Subscriber; import org.reactivestreams.Subscription; @@ -42,17 +45,18 @@ import org.schabi.newpipe.player.helper.PlayerHolder; import org.schabi.newpipe.player.playqueue.PlayQueue; import org.schabi.newpipe.player.playqueue.PlaylistPlayQueue; import org.schabi.newpipe.util.ExtractorHelper; -import org.schabi.newpipe.util.PicassoHelper; -import org.schabi.newpipe.util.external_communication.KoreUtils; import org.schabi.newpipe.util.Localization; import org.schabi.newpipe.util.NavigationHelper; -import org.schabi.newpipe.util.external_communication.ShareUtils; +import org.schabi.newpipe.util.PicassoHelper; import org.schabi.newpipe.util.StreamDialogEntry; +import org.schabi.newpipe.util.external_communication.KoreUtils; +import org.schabi.newpipe.util.external_communication.ShareUtils; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Supplier; import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; import io.reactivex.rxjava3.core.Flowable; @@ -60,10 +64,6 @@ import io.reactivex.rxjava3.core.Single; import io.reactivex.rxjava3.disposables.CompositeDisposable; import io.reactivex.rxjava3.disposables.Disposable; -import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty; -import static org.schabi.newpipe.ktx.ViewUtils.animate; -import static org.schabi.newpipe.ktx.ViewUtils.animateHideRecyclerViewAllowingScrolling; - public class PlaylistFragment extends BaseListInfoFragment { private static final String PICASSO_PLAYLIST_TAG = "PICASSO_PLAYLIST_TAG"; @@ -120,12 +120,12 @@ public class PlaylistFragment extends BaseListInfoFragment { //////////////////////////////////////////////////////////////////////////*/ @Override - protected ViewBinding getListHeader() { + protected Supplier getListHeaderSupplier() { headerBinding = PlaylistHeaderBinding .inflate(activity.getLayoutInflater(), itemsList, false); playlistControlBinding = headerBinding.playlistControl; - return headerBinding; + return headerBinding::getRoot; } @Override diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/videos/RelatedItemsFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/videos/RelatedItemsFragment.java index 285024484..7ba6aa2ab 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/videos/RelatedItemsFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/videos/RelatedItemsFragment.java @@ -1,6 +1,5 @@ package org.schabi.newpipe.fragments.list.videos; -import android.content.Context; import android.content.SharedPreferences; import android.os.Bundle; import android.view.LayoutInflater; @@ -12,7 +11,6 @@ import android.view.ViewGroup; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.preference.PreferenceManager; -import androidx.viewbinding.ViewBinding; import org.schabi.newpipe.R; import org.schabi.newpipe.databinding.RelatedItemsHeaderBinding; @@ -24,6 +22,7 @@ import org.schabi.newpipe.ktx.ViewUtils; import org.schabi.newpipe.util.RelatedItemInfo; import java.io.Serializable; +import java.util.function.Supplier; import io.reactivex.rxjava3.core.Single; @@ -60,9 +59,6 @@ public class RelatedItemsFragment extends BaseListInfoFragment return inflater.inflate(R.layout.fragment_related_items, container, false); } - @Override - } - @Override public void onDestroyView() { headerBinding = null; @@ -70,22 +66,23 @@ public class RelatedItemsFragment extends BaseListInfoFragment } @Override - protected ViewBinding getListHeader() { - if (relatedItemInfo != null && relatedItemInfo.getRelatedItems() != null) { - headerBinding = RelatedItemsHeaderBinding - .inflate(activity.getLayoutInflater(), itemsList, false); - - final SharedPreferences pref = PreferenceManager - .getDefaultSharedPreferences(requireContext()); - final boolean autoplay = pref.getBoolean(getString(R.string.auto_queue_key), false); - headerBinding.autoplaySwitch.setChecked(autoplay); - headerBinding.autoplaySwitch.setOnCheckedChangeListener((compoundButton, b) -> - PreferenceManager.getDefaultSharedPreferences(requireContext()).edit() - .putBoolean(getString(R.string.auto_queue_key), b).apply()); - return headerBinding; - } else { + protected Supplier getListHeaderSupplier() { + if (relatedItemInfo == null || relatedItemInfo.getRelatedItems() == null) { return null; } + + headerBinding = RelatedItemsHeaderBinding + .inflate(activity.getLayoutInflater(), itemsList, false); + + final SharedPreferences pref = PreferenceManager + .getDefaultSharedPreferences(requireContext()); + final boolean autoplay = pref.getBoolean(getString(R.string.auto_queue_key), false); + headerBinding.autoplaySwitch.setChecked(autoplay); + headerBinding.autoplaySwitch.setOnCheckedChangeListener((compoundButton, b) -> + PreferenceManager.getDefaultSharedPreferences(requireContext()).edit() + .putBoolean(getString(R.string.auto_queue_key), b).apply()); + + return headerBinding::getRoot; } @Override @@ -161,11 +158,10 @@ public class RelatedItemsFragment extends BaseListInfoFragment @Override public void onSharedPreferenceChanged(final SharedPreferences sharedPreferences, final String s) { - final SharedPreferences pref = - PreferenceManager.getDefaultSharedPreferences(requireContext()); - final boolean autoplay = pref.getBoolean(getString(R.string.auto_queue_key), false); if (headerBinding != null) { - headerBinding.autoplaySwitch.setChecked(autoplay); + headerBinding.autoplaySwitch.setChecked( + sharedPreferences.getBoolean( + getString(R.string.auto_queue_key), false)); } } diff --git a/app/src/main/java/org/schabi/newpipe/info_list/InfoListAdapter.java b/app/src/main/java/org/schabi/newpipe/info_list/InfoListAdapter.java index 57e6fa380..839125fd1 100644 --- a/app/src/main/java/org/schabi/newpipe/info_list/InfoListAdapter.java +++ b/app/src/main/java/org/schabi/newpipe/info_list/InfoListAdapter.java @@ -2,6 +2,7 @@ package org.schabi.newpipe.info_list; import android.content.Context; import android.util.Log; +import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -11,6 +12,7 @@ import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.RecyclerView; import org.schabi.newpipe.database.stream.model.StreamStateEntity; +import org.schabi.newpipe.databinding.PignateFooterBinding; import org.schabi.newpipe.extractor.InfoItem; import org.schabi.newpipe.extractor.channel.ChannelInfoItem; import org.schabi.newpipe.extractor.comments.CommentsInfoItem; @@ -34,6 +36,7 @@ import org.schabi.newpipe.util.OnClickGesture; import java.util.ArrayList; import java.util.List; +import java.util.function.Supplier; /* * Created by Christian Schabesberger on 01.08.16. @@ -74,6 +77,7 @@ public class InfoListAdapter extends RecyclerView.Adapter infoItemList; private final HistoryRecordManager recordManager; @@ -81,11 +85,12 @@ public class InfoListAdapter extends RecyclerView.Adapter headerSupplier = null; public InfoListAdapter(final Context context) { - this.recordManager = new HistoryRecordManager(context); + layoutInflater = LayoutInflater.from(context); + recordManager = new HistoryRecordManager(context); infoItemBuilder = new InfoItemBuilder(context); infoItemList = new ArrayList<>(); } @@ -129,12 +134,12 @@ public class InfoListAdapter extends RecyclerView.Adapter offsetStart = " + offsetStart + ", " + "infoItemList.size() = " + infoItemList.size() + ", " - + "header = " + header + ", footer = " + footer + ", " + + "header = " + hasHeader() + ", " + "showFooter = " + showFooter); } notifyItemRangeInserted(offsetStart, data.size()); - if (footer != null && showFooter) { + if (showFooter) { final int footerNow = sizeConsideringHeaderOffset(); notifyItemMoved(offsetStart, footerNow); @@ -153,16 +158,16 @@ public class InfoListAdapter extends RecyclerView.Adapter headerSupplier) { + final boolean changed = headerSupplier != this.headerSupplier; + this.headerSupplier = headerSupplier; if (changed) { notifyDataSetChanged(); } } - public void setFooter(final View view) { - this.footer = view; + protected boolean hasHeader() { + return this.headerSupplier != null; } public void showFooter(final boolean show) { @@ -182,7 +187,7 @@ public class InfoListAdapter extends RecyclerView.Adapter Date: Sun, 16 Jan 2022 19:05:51 +0100 Subject: [PATCH 09/19] Reverted to loading behavior of #7638 and improved it The previous/reverted behavior caused unwanted data transmission: * Removed loading via handleResults/loadMoreItems-callback because the RecyclerView is apparently not immediately updated in the UI when the data is set which causes one load of data to much. --- .../fragments/list/BaseListFragment.java | 127 +++++++++--------- .../fragments/list/BaseListInfoFragment.java | 7 +- .../fragments/list/search/SearchFragment.java | 14 +- 3 files changed, 68 insertions(+), 80 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListFragment.java index d1685c5af..279d6d563 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListFragment.java @@ -312,14 +312,74 @@ public abstract class BaseListFragment extends BaseStateFragment }); itemsList.clearOnScrollListeners(); - itemsList.addOnScrollListener(new OnScrollBelowItemsListener() { + + /* + * Add initial scroll listener - which tries to load more items when not enough + * are in the view (not scrollable) and more are available. + * + * Note: This method only works because "This callback will also be called if visible + * item range changes after a layout calculation. In that case, dx and dy will be 0." + * - which might be unexpected because no actual scrolling occurs... + * + * This listener will be replaced by DefaultItemListOnScrolledDownListener when + * * the view was actually scrolled + * * the view is scrollable + * * No more items can be loaded + */ + itemsList.addOnScrollListener(new DefaultItemListOnScrolledDownListener() { @Override - public void onScrolledDown(final RecyclerView recyclerView) { - onScrollToBottom(); + public void onScrolled(final RecyclerView recyclerView, final int dx, final int dy) { + super.onScrolled(recyclerView, dx, dy); + + if (dy != 0) { + log("Vertical scroll occurred"); + + useNormalScrollListener(); + return; + } + if (isLoading.get()) { + log("Still loading data -> Skipping"); + return; + } + if (!hasMoreItems()) { + log("No more items to load"); + + useNormalScrollListener(); + return; + } + if (itemsList.canScrollVertically(1) + || itemsList.canScrollVertically(-1)) { + log("View is scrollable"); + + useNormalScrollListener(); + return; + } + + log("Loading more data"); + loadMoreItems(); + } + + private void useNormalScrollListener() { + log("Unregistering and using normal listener"); + itemsList.removeOnScrollListener(this); + itemsList.addOnScrollListener(new DefaultItemListOnScrolledDownListener()); + } + + private void log(final String msg) { + if (DEBUG) { + Log.d(TAG, "itemListInitScrollListener - " + msg); + } } }); } + class DefaultItemListOnScrolledDownListener extends OnScrollBelowItemsListener { + @Override + public void onScrolledDown(final RecyclerView recyclerView) { + onScrollToBottom(); + } + } + private void onStreamSelected(final StreamInfoItem selectedItem) { onItemSelected(selectedItem); NavigationHelper.openVideoDetailFragment(requireContext(), getFM(), @@ -407,66 +467,7 @@ public abstract class BaseListFragment extends BaseStateFragment // Load and handle //////////////////////////////////////////////////////////////////////////*/ - /** - * If more items are loadable and the itemList is not scrollable -> load more data. - *
- * Should be called once the initial items inside {@link #startLoading(boolean)} - * has been loaded and added to the {@link #itemsList}. - *
- * Otherwise the loading indicator is always shown but no data can be loaded - * because the view is not scrollable; see also #1974. - */ - protected void ifMoreItemsLoadableLoadUntilScrollable() { - ifMoreItemsLoadableLoadUntilScrollable(0); - } - - /** - * If more items are loadable and the itemList is not scrollable -> load more data. - * - * @param recursiveCallCount Amount of recursive calls that occurred - * @see #ifMoreItemsLoadableLoadUntilScrollable() - */ - protected void ifMoreItemsLoadableLoadUntilScrollable(final int recursiveCallCount) { - // Try to prevent malfunction / stackoverflow - if (recursiveCallCount > 100) { - Log.w(TAG, "loadEnoughInitialData - Too many recursive calls - Aborting"); - return; - } - if (!hasMoreItems()) { - if (DEBUG) { - Log.d(TAG, "loadEnoughInitialData - OK: No more items to load"); - } - return; - } - if (itemsList.canScrollVertically(1) - || itemsList.canScrollVertically(-1)) { - if (DEBUG) { - Log.d(TAG, "loadEnoughInitialData - OK: itemList is scrollable"); - } - return; - } - if (DEBUG) { - Log.d(TAG, "loadEnoughInitialData - View is not scrollable " - + "but it could load more items -> Loading more"); - } - loadMoreItems(() -> - ifMoreItemsLoadableLoadUntilScrollable(recursiveCallCount + 1)); - } - - /** - * Loads more items. - * @param initialDataLoadCallback - * Callback used in {@link #ifMoreItemsLoadableLoadUntilScrollable()}. - *
- * Execute it once the data was loaded and added to the {@link #itemsList}. - *
- * Might be null. - */ - protected abstract void loadMoreItems(@Nullable Runnable initialDataLoadCallback); - - protected void loadMoreItems() { - loadMoreItems(null); - } + protected abstract void loadMoreItems(); protected abstract boolean hasMoreItems(); diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListInfoFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListInfoFragment.java index 87f031c12..ebd586e35 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListInfoFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListInfoFragment.java @@ -6,7 +6,6 @@ import android.util.Log; import android.view.View; import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import org.schabi.newpipe.error.ErrorInfo; import org.schabi.newpipe.error.UserAction; @@ -146,7 +145,6 @@ public abstract class BaseListInfoFragment currentInfo = result; currentNextPage = result.getNextPage(); handleResult(result); - ifMoreItemsLoadableLoadUntilScrollable(); }, throwable -> showError(new ErrorInfo(throwable, errorUserAction, "Start loading: " + url, serviceId))); @@ -162,7 +160,7 @@ public abstract class BaseListInfoFragment protected abstract Single loadMoreItemsLogic(); @Override - protected void loadMoreItems(@Nullable final Runnable initialDataLoadCallback) { + protected void loadMoreItems() { isLoading.set(true); if (currentWorker != null) { @@ -178,9 +176,6 @@ public abstract class BaseListInfoFragment .subscribe(infoItemsPage -> { isLoading.set(false); handleNextItems(infoItemsPage); - if (initialDataLoadCallback != null) { - initialDataLoadCallback.run(); - } }, (@NonNull Throwable throwable) -> dynamicallyShowErrorPanelOrSnackbar(new ErrorInfo(throwable, errorUserAction, "Loading more items: " + url, serviceId))); 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 35bb2c349..055c27733 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 @@ -868,15 +868,12 @@ public class SearchFragment extends BaseListFragment isLoading.set(false)) - .subscribe(result -> { - handleResult(result); - ifMoreItemsLoadableLoadUntilScrollable(); - }, this::onItemError); + .subscribe(this::handleResult, this::onItemError); } @Override - protected void loadMoreItems(@Nullable final Runnable initialDataLoadCallback) { + protected void loadMoreItems() { if (!Page.isValid(nextPage)) { return; } @@ -894,12 +891,7 @@ public class SearchFragment extends BaseListFragment isLoading.set(false)) - .subscribe(itemsPage -> { - handleNextItems(itemsPage); - if (initialDataLoadCallback != null) { - initialDataLoadCallback.run(); - } - }, this::onItemError); + .subscribe(this::handleNextItems, this::onItemError); } @Override From 85f701b94e8ce730e77bd91024d382d2e0753939 Mon Sep 17 00:00:00 2001 From: litetex <40789489+litetex@users.noreply.github.com> Date: Sun, 16 Jan 2022 19:42:30 +0100 Subject: [PATCH 10/19] Fixed listener not re-registering after e.g. a new search is started --- .../fragments/list/BaseListFragment.java | 45 ++++++++++++------- 1 file changed, 29 insertions(+), 16 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListFragment.java index 279d6d563..5b503cb8e 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListFragment.java @@ -304,28 +304,36 @@ public abstract class BaseListFragment extends BaseStateFragment } }); - infoListAdapter.setOnCommentsSelectedListener(new OnClickGesture() { + infoListAdapter.setOnCommentsSelectedListener(new OnClickGesture<>() { @Override public void selected(final CommentsInfoItem selectedItem) { onItemSelected(selectedItem); } }); + } + /** + * Remove all listeners and add the initial scroll listener to the {@link #itemsList}. + *
+ * Which tries to load more items when not enough are in the view (not scrollable) + * and more are available. + *
+ * Note: This method only works because "This callback will also be called if visible + * item range changes after a layout calculation. In that case, dx and dy will be 0." + * - which might be unexpected because no actual scrolling occurs... + *
+ * This listener will be replaced by DefaultItemListOnScrolledDownListener when + *
    + *
  • the view was actually scrolled
  • + *
  • the view is scrollable
  • + *
  • no more items can be loaded
  • + *
+ */ + protected void setItemsListInitialScrollListener() { + if (DEBUG) { + Log.d(TAG, "setItemsListInitialScrollListener called"); + } itemsList.clearOnScrollListeners(); - - /* - * Add initial scroll listener - which tries to load more items when not enough - * are in the view (not scrollable) and more are available. - * - * Note: This method only works because "This callback will also be called if visible - * item range changes after a layout calculation. In that case, dx and dy will be 0." - * - which might be unexpected because no actual scrolling occurs... - * - * This listener will be replaced by DefaultItemListOnScrolledDownListener when - * * the view was actually scrolled - * * the view is scrollable - * * No more items can be loaded - */ itemsList.addOnScrollListener(new DefaultItemListOnScrolledDownListener() { @Override public void onScrolled(final RecyclerView recyclerView, final int dx, final int dy) { @@ -360,7 +368,6 @@ public abstract class BaseListFragment extends BaseStateFragment } private void useNormalScrollListener() { - log("Unregistering and using normal listener"); itemsList.removeOnScrollListener(this); itemsList.addOnScrollListener(new DefaultItemListOnScrolledDownListener()); } @@ -467,6 +474,12 @@ public abstract class BaseListFragment extends BaseStateFragment // Load and handle //////////////////////////////////////////////////////////////////////////*/ + @Override + protected void startLoading(final boolean forceLoad) { + setItemsListInitialScrollListener(); + super.startLoading(forceLoad); + } + protected abstract void loadMoreItems(); protected abstract boolean hasMoreItems(); From 01683aa816b7792bab769b18b0509275b7eed6cc Mon Sep 17 00:00:00 2001 From: litetex <40789489+litetex@users.noreply.github.com> Date: Mon, 24 Jan 2022 20:57:23 +0100 Subject: [PATCH 11/19] Code improvements --- .../newpipe/info_list/InfoListAdapter.java | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/info_list/InfoListAdapter.java b/app/src/main/java/org/schabi/newpipe/info_list/InfoListAdapter.java index 839125fd1..718f7004c 100644 --- a/app/src/main/java/org/schabi/newpipe/info_list/InfoListAdapter.java +++ b/app/src/main/java/org/schabi/newpipe/info_list/InfoListAdapter.java @@ -79,7 +79,7 @@ public class InfoListAdapter extends RecyclerView.Adapter infoItemList; + private final List infoItemList; private final HistoryRecordManager recordManager; private boolean useMiniVariant = false; @@ -134,7 +134,7 @@ public class InfoListAdapter extends RecyclerView.Adapter offsetStart = " + offsetStart + ", " + "infoItemList.size() = " + infoItemList.size() + ", " - + "header = " + hasHeader() + ", " + + "hasHeader = " + hasHeader() + ", " + "showFooter = " + showFooter); } notifyItemRangeInserted(offsetStart, data.size()); @@ -211,7 +211,7 @@ public class InfoListAdapter extends RecyclerView.Adapter payloads) { + // an empty payload requires a full update (see RecyclerView javadoc) if (payloads.isEmpty() || !(holder instanceof InfoItemHolder)) { onBindViewHolder(holder, position); return; From 9c2cdd251390fab9e4949befe306fd4c7b589a2b Mon Sep 17 00:00:00 2001 From: litetex <40789489+litetex@users.noreply.github.com> Date: Thu, 27 Jan 2022 20:41:58 +0100 Subject: [PATCH 12/19] Removed useless code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit → https://github.com/TeamNewPipe/NewPipe/pull/7659#discussion_r793752985 --- .../newpipe/info_list/InfoListAdapter.java | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/info_list/InfoListAdapter.java b/app/src/main/java/org/schabi/newpipe/info_list/InfoListAdapter.java index 718f7004c..fb27593e7 100644 --- a/app/src/main/java/org/schabi/newpipe/info_list/InfoListAdapter.java +++ b/app/src/main/java/org/schabi/newpipe/info_list/InfoListAdapter.java @@ -11,7 +11,6 @@ import androidx.annotation.Nullable; import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.RecyclerView; -import org.schabi.newpipe.database.stream.model.StreamStateEntity; import org.schabi.newpipe.databinding.PignateFooterBinding; import org.schabi.newpipe.extractor.InfoItem; import org.schabi.newpipe.extractor.channel.ChannelInfoItem; @@ -311,24 +310,6 @@ public class InfoListAdapter extends RecyclerView.Adapter payloads) { - // an empty payload requires a full update (see RecyclerView javadoc) - if (payloads.isEmpty() || !(holder instanceof InfoItemHolder)) { - onBindViewHolder(holder, position); - return; - } - - for (final Object payload : payloads) { - if (payload instanceof StreamStateEntity || payload instanceof Boolean) { - ((InfoItemHolder) holder).updateState( - infoItemList.get(hasHeader() ? position - 1 : position), recordManager); - } - } - } - public GridLayoutManager.SpanSizeLookup getSpanSizeLookup(final int spanCount) { return new GridLayoutManager.SpanSizeLookup() { @Override From 2acaefdb2adce73da19875ec30bb468731ba8904 Mon Sep 17 00:00:00 2001 From: litetex <40789489+litetex@users.noreply.github.com> Date: Thu, 17 Feb 2022 20:58:53 +0100 Subject: [PATCH 13/19] Fixed scrolling not working when rotating device --- .../fragments/list/BaseListFragment.java | 35 ++++++++++++------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListFragment.java index 5b503cb8e..6ea0a8a0d 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListFragment.java @@ -310,10 +310,24 @@ public abstract class BaseListFragment extends BaseStateFragment onItemSelected(selectedItem); } }); + + // Ensure that there is always a scroll listener (e.g. when rotating the device) + useNormalItemListScrollListener(); } /** - * Remove all listeners and add the initial scroll listener to the {@link #itemsList}. + * Removes all listeners and adds the normal scroll listener to the {@link #itemsList}. + */ + protected void useNormalItemListScrollListener() { + if (DEBUG) { + Log.d(TAG, "useNormalItemListScrollListener called"); + } + itemsList.clearOnScrollListeners(); + itemsList.addOnScrollListener(new DefaultItemListOnScrolledDownListener()); + } + + /** + * Removes all listeners and adds the initial scroll listener to the {@link #itemsList}. *
* Which tries to load more items when not enough are in the view (not scrollable) * and more are available. @@ -329,9 +343,9 @@ public abstract class BaseListFragment extends BaseStateFragment *
  • no more items can be loaded
  • * */ - protected void setItemsListInitialScrollListener() { + protected void useInitialItemListLoadScrollListener() { if (DEBUG) { - Log.d(TAG, "setItemsListInitialScrollListener called"); + Log.d(TAG, "useInitialItemListLoadScrollListener called"); } itemsList.clearOnScrollListeners(); itemsList.addOnScrollListener(new DefaultItemListOnScrolledDownListener() { @@ -342,7 +356,7 @@ public abstract class BaseListFragment extends BaseStateFragment if (dy != 0) { log("Vertical scroll occurred"); - useNormalScrollListener(); + useNormalItemListScrollListener(); return; } if (isLoading.get()) { @@ -352,14 +366,14 @@ public abstract class BaseListFragment extends BaseStateFragment if (!hasMoreItems()) { log("No more items to load"); - useNormalScrollListener(); + useNormalItemListScrollListener(); return; } if (itemsList.canScrollVertically(1) || itemsList.canScrollVertically(-1)) { log("View is scrollable"); - useNormalScrollListener(); + useNormalItemListScrollListener(); return; } @@ -367,14 +381,9 @@ public abstract class BaseListFragment extends BaseStateFragment loadMoreItems(); } - private void useNormalScrollListener() { - itemsList.removeOnScrollListener(this); - itemsList.addOnScrollListener(new DefaultItemListOnScrolledDownListener()); - } - private void log(final String msg) { if (DEBUG) { - Log.d(TAG, "itemListInitScrollListener - " + msg); + Log.d(TAG, "initItemListLoadScrollListener - " + msg); } } }); @@ -476,7 +485,7 @@ public abstract class BaseListFragment extends BaseStateFragment @Override protected void startLoading(final boolean forceLoad) { - setItemsListInitialScrollListener(); + useInitialItemListLoadScrollListener(); super.startLoading(forceLoad); } From da12b92d752e87c19cda8838a64de0a801bce264 Mon Sep 17 00:00:00 2001 From: Stypox Date: Sat, 19 Feb 2022 11:00:05 +0100 Subject: [PATCH 14/19] Fix fast seek arc not going under system ui --- .../java/org/schabi/newpipe/player/Player.java | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 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 e0debc4e7..d3fd7b0ad 100644 --- a/app/src/main/java/org/schabi/newpipe/player/Player.java +++ b/app/src/main/java/org/schabi/newpipe/player/Player.java @@ -580,11 +580,17 @@ public final class Player implements v.getPaddingTop(), v.getPaddingRight(), v.getPaddingBottom()); - binding.fastSeekOverlay.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 + // the opposite side, so that the view covers all of the player (overflowing on + // some sides) and its center coincides with the center of other controls. + final RelativeLayout.LayoutParams fastSeekParams = (RelativeLayout.LayoutParams) + binding.fastSeekOverlay.getLayoutParams(); + fastSeekParams.leftMargin = -v.getPaddingRight(); + fastSeekParams.topMargin = -v.getPaddingBottom(); + fastSeekParams.rightMargin = -v.getPaddingLeft(); + fastSeekParams.bottomMargin = -v.getPaddingTop(); }); } From 579b8611be4bcb30cccdc90ba62ec3d9ef9788a3 Mon Sep 17 00:00:00 2001 From: Stypox Date: Sat, 19 Feb 2022 12:00:04 +0100 Subject: [PATCH 15/19] Change compileSdk from 30 to 31 This will allow newer libraries to be used, see #7782 and #2335. This should have no changes on the app since the targetSdk stayed the same. --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 0c37a960f..a441a27eb 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -8,7 +8,7 @@ plugins { } android { - compileSdk 30 + compileSdk 31 buildToolsVersion '30.0.3' defaultConfig { From 3c23fb0b131e9665703022e1bcc885bd5c035b09 Mon Sep 17 00:00:00 2001 From: Stypox Date: Sat, 19 Feb 2022 13:30:55 +0100 Subject: [PATCH 16/19] Small refactor in player class --- app/src/main/java/org/schabi/newpipe/player/Player.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/player/Player.java b/app/src/main/java/org/schabi/newpipe/player/Player.java index e0debc4e7..f035f3233 100644 --- a/app/src/main/java/org/schabi/newpipe/player/Player.java +++ b/app/src/main/java/org/schabi/newpipe/player/Player.java @@ -593,8 +593,7 @@ public final class Player implements */ private void setupPlayerSeekOverlay() { binding.fastSeekOverlay - .seekSecondsSupplier( - () -> (int) (retrieveSeekDurationFromPreferences(this) / 1000.0f)) + .seekSecondsSupplier(() -> retrieveSeekDurationFromPreferences(this) / 1000) .performListener(new PlayerFastSeekOverlay.PerformListener() { @Override @@ -607,6 +606,7 @@ public final class Player implements animate(binding.fastSeekOverlay, false, SEEK_OVERLAY_DURATION); } + @NonNull @Override public FastSeekDirection getFastSeekDirection( @NonNull final DisplayPortion portion From 96b930cd070ef067607788dcd0aade5a488725fc Mon Sep 17 00:00:00 2001 From: litetex <40789489+litetex@users.noreply.github.com> Date: Mon, 21 Feb 2022 20:30:56 +0100 Subject: [PATCH 17/19] Revert "Respect cutouts when playing in MultiWindow" This reverts commit c92a90749ef1188f50afe528245a54afd180613c. --- .../fragments/detail/VideoDetailFragment.java | 15 +++------------ 1 file changed, 3 insertions(+), 12 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 2d9abc6dc..78f0bfffb 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 @@ -1994,9 +1994,7 @@ public final class VideoDetailFragment // Prevent jumping of the player on devices with cutout if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { activity.getWindow().getAttributes().layoutInDisplayCutoutMode = - isMultiWindowOrFullscreen() - ? WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER - : WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT; + WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT; } activity.getWindow().getDecorView().setSystemUiVisibility(0); activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); @@ -2018,9 +2016,7 @@ public final class VideoDetailFragment // Prevent jumping of the player on devices with cutout if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { activity.getWindow().getAttributes().layoutInDisplayCutoutMode = - isMultiWindowOrFullscreen() - ? WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER - : WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES; + WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES; } int visibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN @@ -2037,7 +2033,7 @@ public final class VideoDetailFragment activity.getWindow().getDecorView().setSystemUiVisibility(visibility); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP - && isMultiWindowOrFullscreen()) { + && (isInMultiWindow || (isPlayerAvailable() && player.isFullscreen()))) { activity.getWindow().setStatusBarColor(Color.TRANSPARENT); activity.getWindow().setNavigationBarColor(Color.TRANSPARENT); } @@ -2053,11 +2049,6 @@ public final class VideoDetailFragment } } - private boolean isMultiWindowOrFullscreen() { - return DeviceUtils.isInMultiWindow(activity) - || (isPlayerAvailable() && player.isFullscreen()); - } - private boolean playerIsNotStopped() { return isPlayerAvailable() && !player.isStopped(); } From 443ebc46d6b35552e1b8a1c8accee30ecb0bd6b2 Mon Sep 17 00:00:00 2001 From: Stypox Date: Wed, 23 Feb 2022 15:16:37 +0100 Subject: [PATCH 18/19] Release 0.22.1 (984) --- app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index a441a27eb..633da37bd 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -16,8 +16,8 @@ android { resValue "string", "app_name", "NewPipe" minSdk 19 targetSdk 29 - versionCode 983 - versionName "0.22.0" + versionCode 984 + versionName "0.22.1" multiDexEnabled true From ee3c06394d74200254ded920a2cac705ca6806eb Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Sat, 26 Feb 2022 18:46:02 +0100 Subject: [PATCH 19/19] Translated using Weblate (Swedish) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 49.2% (32 of 65 strings) Translated using Weblate (Swedish) Currently translated at 100.0% (613 of 613 strings) Translated using Weblate (Greek) Currently translated at 100.0% (613 of 613 strings) Translated using Weblate (Chinese (Traditional)) Currently translated at 58.4% (38 of 65 strings) Translated using Weblate (Dutch (Belgium)) Currently translated at 23.0% (15 of 65 strings) Translated using Weblate (French) Currently translated at 66.1% (43 of 65 strings) Translated using Weblate (Azerbaijani) Currently translated at 7.6% (5 of 65 strings) Translated using Weblate (Italian) Currently translated at 38.4% (25 of 65 strings) Translated using Weblate (Polish) Currently translated at 55.3% (36 of 65 strings) Translated using Weblate (Hebrew) Currently translated at 53.8% (35 of 65 strings) Translated using Weblate (Ukrainian) Currently translated at 100.0% (65 of 65 strings) Translated using Weblate (Chinese (Traditional, Hong Kong)) Currently translated at 7.6% (5 of 65 strings) Translated using Weblate (German) Currently translated at 66.1% (43 of 65 strings) Translated using Weblate (Polish) Currently translated at 100.0% (613 of 613 strings) Translated using Weblate (Turkish) Currently translated at 100.0% (613 of 613 strings) Translated using Weblate (English) Currently translated at 100.0% (613 of 613 strings) Translated using Weblate (English) Currently translated at 100.0% (613 of 613 strings) Translated using Weblate (English) Currently translated at 100.0% (613 of 613 strings) Translated using Weblate (French) Currently translated at 65.6% (42 of 64 strings) Translated using Weblate (Dutch) Currently translated at 71.8% (46 of 64 strings) Translated using Weblate (Catalan) Currently translated at 100.0% (613 of 613 strings) Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (613 of 613 strings) Translated using Weblate (Indonesian) Currently translated at 100.0% (613 of 613 strings) Translated using Weblate (Arabic) Currently translated at 100.0% (613 of 613 strings) Translated using Weblate (Chinese (Traditional, Hong Kong)) Currently translated at 80.4% (493 of 613 strings) Translated using Weblate (French) Currently translated at 100.0% (613 of 613 strings) Translated using Weblate (Indonesian) Currently translated at 100.0% (613 of 613 strings) Co-authored-by: Agnieszka C Co-authored-by: Alex25820 Co-authored-by: Benedikt Freisen Co-authored-by: Corc Co-authored-by: Guillem Co-authored-by: Hosted Weblate Co-authored-by: Ihor Hordiichuk Co-authored-by: Issa1553 Co-authored-by: Linerly Co-authored-by: Mohammed Anas Co-authored-by: Oğuz Ersen Co-authored-by: Ray Co-authored-by: Retrial Co-authored-by: Stypox Co-authored-by: TiA4f8R Co-authored-by: Vitor Henrique Co-authored-by: Yaron Shahrabani Co-authored-by: mm4c Co-authored-by: ssantos Co-authored-by: zmni Co-authored-by: Éfrit Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/az/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/de/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/fr/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/he/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/it/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/nl/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/nl_BE/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/pl/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/sv/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/uk/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/zh_Hant/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/zh_Hant_HK/ Translation: NewPipe/Metadata --- app/src/main/res/values-ar/strings.xml | 6 +- app/src/main/res/values-ca/strings.xml | 4 +- app/src/main/res/values-el/strings.xml | 2 +- app/src/main/res/values-fr/strings.xml | 10 +- app/src/main/res/values-in/strings.xml | 2 +- app/src/main/res/values-pl/strings.xml | 16 +-- app/src/main/res/values-pt-rBR/strings.xml | 2 +- app/src/main/res/values-sv/strings.xml | 4 +- app/src/main/res/values-tr/strings.xml | 2 +- app/src/main/res/values-zh-rHK/strings.xml | 123 +++++++++++++++++- app/src/main/res/values/strings.xml | 27 +++- .../metadata/android/az/changelogs/63.txt | 8 ++ .../metadata/android/az/changelogs/64.txt | 7 + .../metadata/android/az/changelogs/65.txt | 1 + .../metadata/android/az/changelogs/66.txt | 1 + .../metadata/android/de/changelogs/730.txt | 2 + .../metadata/android/de/changelogs/900.txt | 14 ++ .../metadata/android/de/changelogs/963.txt | 1 + .../metadata/android/de/changelogs/965.txt | 6 + .../metadata/android/de/changelogs/973.txt | 4 + .../metadata/android/de/changelogs/974.txt | 5 + .../metadata/android/de/changelogs/979.txt | 2 + .../metadata/android/de/changelogs/980.txt | 13 ++ .../metadata/android/de/changelogs/981.txt | 2 + .../metadata/android/de/changelogs/982.txt | 1 + .../metadata/android/de/changelogs/983.txt | 9 ++ .../metadata/android/de/changelogs/984.txt | 7 + .../metadata/android/fr/changelogs/983.txt | 9 ++ .../metadata/android/fr/changelogs/984.txt | 6 + .../metadata/android/he/changelogs/984.txt | 7 + .../metadata/android/it/changelogs/984.txt | 7 + .../metadata/android/nl-BE/changelogs/63.txt | 8 ++ .../metadata/android/nl/changelogs/954.txt | 9 ++ .../metadata/android/nl/changelogs/969.txt | 8 ++ .../metadata/android/nl/changelogs/970.txt | 11 ++ .../metadata/android/nl/changelogs/971.txt | 3 + .../metadata/android/nl/changelogs/972.txt | 14 ++ .../metadata/android/pl/changelogs/984.txt | 7 + .../metadata/android/sv/changelogs/982.txt | 1 + .../metadata/android/sv/changelogs/984.txt | 7 + .../metadata/android/uk/changelogs/984.txt | 7 + .../android/zh-Hant/changelogs/984.txt | 7 + .../android/zh_Hant_HK/changelogs/984.txt | 7 + 43 files changed, 361 insertions(+), 38 deletions(-) create mode 100644 fastlane/metadata/android/az/changelogs/63.txt create mode 100644 fastlane/metadata/android/az/changelogs/64.txt create mode 100644 fastlane/metadata/android/az/changelogs/65.txt create mode 100644 fastlane/metadata/android/az/changelogs/66.txt create mode 100644 fastlane/metadata/android/de/changelogs/730.txt create mode 100644 fastlane/metadata/android/de/changelogs/900.txt create mode 100644 fastlane/metadata/android/de/changelogs/963.txt create mode 100644 fastlane/metadata/android/de/changelogs/965.txt create mode 100644 fastlane/metadata/android/de/changelogs/973.txt create mode 100644 fastlane/metadata/android/de/changelogs/974.txt create mode 100644 fastlane/metadata/android/de/changelogs/979.txt create mode 100644 fastlane/metadata/android/de/changelogs/980.txt create mode 100644 fastlane/metadata/android/de/changelogs/981.txt create mode 100644 fastlane/metadata/android/de/changelogs/982.txt create mode 100644 fastlane/metadata/android/de/changelogs/983.txt create mode 100644 fastlane/metadata/android/de/changelogs/984.txt create mode 100644 fastlane/metadata/android/fr/changelogs/983.txt create mode 100644 fastlane/metadata/android/fr/changelogs/984.txt create mode 100644 fastlane/metadata/android/he/changelogs/984.txt create mode 100644 fastlane/metadata/android/it/changelogs/984.txt create mode 100644 fastlane/metadata/android/nl-BE/changelogs/63.txt create mode 100644 fastlane/metadata/android/nl/changelogs/954.txt create mode 100644 fastlane/metadata/android/nl/changelogs/969.txt create mode 100644 fastlane/metadata/android/nl/changelogs/970.txt create mode 100644 fastlane/metadata/android/nl/changelogs/971.txt create mode 100644 fastlane/metadata/android/nl/changelogs/972.txt create mode 100644 fastlane/metadata/android/pl/changelogs/984.txt create mode 100644 fastlane/metadata/android/sv/changelogs/982.txt create mode 100644 fastlane/metadata/android/sv/changelogs/984.txt create mode 100644 fastlane/metadata/android/uk/changelogs/984.txt create mode 100644 fastlane/metadata/android/zh-Hant/changelogs/984.txt create mode 100644 fastlane/metadata/android/zh_Hant_HK/changelogs/984.txt diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index d1f19dbc2..a13589c19 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -329,7 +329,7 @@ \nتوضح سياسة خصوصية NewPipe بالتفصيل البيانات التي يتم إرسالها وتخزينها عند إرسال تقرير الأعطال. الإطلاع على سياسة الخصوصية من أجل الامتثال للائحة الأوروبية العامة لحماية البيانات (GDPR)، فإننا نلفت انتباهك إلى سياسة خصوصية NewPipe. يرجى قراءتها بعناية. -\nو يجب عليك قبولها لإرسال تقرير الأخطاء إلينا. +\nويجب عليك قبولها لإرسال تقرير الأخطاء إلينا. قبول رفض لا حدود @@ -637,7 +637,7 @@ هذا المحتوى غير متوفر في بلدك. اغلق التطبيق قسريا هذا الفيديو مقيد بالفئة العمرية. -\nنظرا لسياسات YouTube الجديدة المتعلقة بمقاطع الفيديو المقيدة بالفئة العمرية، لا يمكن لـNewPipe الوصول إلى أي من مقاطع الفيديو الخاصة بها وبالتالي لا يمكن تشغيلها. +\nنظرًا لسياسات YouTube الجديدة المتعلقة بمقاطع الفيديو المقيدة بالفئة العمرية، لا يمكن لـNewPipe الوصول إلى أي من مقاطع الفيديو الخاصة بها وبالتالي لا يمكن تشغيلها. إذاعة المميزة حل @@ -688,7 +688,7 @@ جودة عالية (أكبر) معاينة مصغرة على شريط التمرير علّمه كفيديو تمت مشاهدته - أعجب بها منشئ المحتوى + أُعجب بها منشئ المحتوى جاري تحميل تفاصيل القناة… خطأ في عرض تفاصيل القناة أظهر أشرطة ملونة لبيكاسو أعلى الصور تشير إلى مصدرها: الأحمر للشبكة والأزرق للقرص والأخضر للذاكرة diff --git a/app/src/main/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml index 034cbc875..13b8c5ac3 100644 --- a/app/src/main/res/values-ca/strings.xml +++ b/app/src/main/res/values-ca/strings.xml @@ -215,7 +215,7 @@ Controls de la velocitat de reproducció Tempo To - Toca la lupa per començar. + Toca \"Cerca\" per començar. Elimina l\'àudio en algunes resolucions Reproductor d\'àudio extern Desactiveu-ho per no guardar miniatures i estalviar dades i memòria. Canviant aquesta opció, s\'eliminarà la memòria cau d\'imatges tant de la memòria com de l\'emmagatzematge @@ -685,7 +685,7 @@ Elements de feed nous El mode d\'alimentació ràpida no proporciona més informació sobre això. Comentari fixat - Mostrar \"tancar de forma violenta el reproductor\" + Mostra \"Força el tancament del reproductor\" Mostra una opció de fallada quan s\'utilitza el reproductor Mostra les cintes de color Picasso a la part superior de les imatges que indiquen la seva font: vermell per a la xarxa, blau per al disc i verd per a la memòria El LeakCanary no està disponible diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index 29745830a..a57011bc3 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -71,7 +71,7 @@ Ιστορικό Ιστορικό Εμφάνιση πληροφοριών - Πατήστε το μεγενθυτικό φακό για να ξεκινήσετε. + Πατήστε το μεγεθυντικό φακό για να ξεκινήσετε. Δε βρέθηκε πρόγραμμα αναπαραγωγής ροής δεδομένων (μπορείτε να εγκαταστήσετε το VLC για να κάνετε αναπαραγωγή). Λήψη του αρχείου ροής Αφαιρείται ο ήχος από κάποιες αναλύσεις diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 8acc53603..2e4257695 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -52,7 +52,7 @@ En direct Impossible de charger toutes les miniatures Impossible de déchiffrer la signature URL de la vidéo - Désolé, cela n\'aurait pas dû se produire. + Désolé, cela n’aurait pas dû se produire. Signaler cette erreur par courriel Information : Ce qui s’est passé : @@ -73,7 +73,7 @@ Somme de contrôle OK Nom du fichier - Nombre de connexions simultanées + Connexions simultanées Erreur NewPipe télécharge Appuyer pour plus de détails @@ -668,8 +668,8 @@ Balayez un élément pour le supprimer Ne pas lancer les vidéos dans le mini lecteur mais directement en plein écran si la rotation automatique est verrouillée. Vous pouvez toujours accéder au mini-lecteur en quittant le mode plein écran Lancer le lecteur principal en plein écran - Mettre en file d’attente la suivante - Placé comme suivant dans liste de lecture + Ajouter à la liste de lecture + Suivant dans la liste de lecture Traitement en cours… Veuillez patienter Vérifier manuellement de nouvelles versions Vérification des mises à jour… @@ -685,7 +685,7 @@ Créer une notification d\'erreur Aucun gestionnaire de fichiers approprié n\'a été trouvé pour cette action. \nVeuillez installer un gestionnaire de fichiers compatible avec l\'Infrastructure d\'accès au stockage. - Afficher une barre d\'erreur + Afficher une barre d’erreur Aucun gestionnaire de fichier approprié n\'a été trouvé pour cette action. \nVeuillez installer un gestionnaire de fichiers ou essayez de désactiver \'%s\' dans les paramètres de téléchargement. Commentaire épinglé diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index 3a714b5ab..fb02fd4ff 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -661,7 +661,7 @@ Periksa manual untuk versi baru Memeriksa pembaruan… Item feed baru - Tampilkan \"hentikan pemain video\" + Tampilkan \"Mogokkan pemutar\" Menampilkan opsi penghentian ketika menggunakan pemain video Hentikan pemain video Notifikasi untuk melaporkan kegalatan diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 55300925b..93a497d7b 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -316,7 +316,7 @@ Usunięto historię wyszukiwania Usunięto jedną pozycję. Brak zainstalowanej aplikacji do odtworzenia tego pliku - NewPipe jest wolnym i bezpłatnym oprogramowaniem: Możesz używać, udostępniać i ulepszać je do woli. W szczególności możesz je redystrybuować i/lub modyfikować zgodnie z warunkami GNU General Public License opublikowanej przez Free Software Fundation w wersji 3 albo (według Twojego wyboru) jakąkolwiek późniejszą wersją. + NewPipe jest wolnym i bezpłatnym oprogramowaniem: Możesz używać, udostępniać i ulepszać je do woli. W szczególności możesz je redystrybuować i/lub modyfikować zgodnie z warunkami GNU General Public License, opublikowanej przez Free Software Fundation, w wersji 3 albo (według Twojego wyboru) jakiejkolwiek późniejszej wersji. Czy chcesz zaimportować również ustawienia? Polityka prywatności NewPipe Projekt NewPipe bardzo poważnie traktuje Twoją prywatność, dlatego aplikacja nie gromadzi żadnych danych bez Twojej zgody. @@ -377,11 +377,11 @@ Pobrany plik o tej nazwie już istnieje Trwa już pobieranie pliku o tej samej nazwie Pokaż błąd - Nie można utworzyć pliku - Nie można utworzyć folderu docelowego + Nie udało się utworzyć pliku + Nie udało się utworzyć folderu docelowego Nie udało się nawiązać bezpiecznego połączenia Nie udało się znaleźć serwera - Nie można połączyć się z serwerem + Nie udało się połączyć z serwerem Serwer nie wysyła danych Serwer nie akceptuje pobierania wielowątkowego, spróbuj ponownie za pomocą @string/msg_threads = 1 Nie znaleziono @@ -408,7 +408,7 @@ Usunięto pozycje odtwarzania Plik usunięty albo przeniesiony Plik z tą nazwą już istnieje - nie można nadpisać pliku + Nie udało się nadpisać pliku Plik o tej samej nazwie oczekuje na pobranie NewPipe został zamknięty podczas pracy nad plikiem Brak miejsca na urządzeniu @@ -457,7 +457,7 @@ Najbardziej lubiane Wygenerowana automatycznie (nie znaleziono przesyłającego) odzyskiwanie - Nie można odzyskać tego pobrania + Nie udało się odzyskać tego pobrania Wybierz serwer Wyczyść historię pobierania Usuń pobrane pliki @@ -481,7 +481,7 @@ \n• Pobieranie całego kanału subskrypcji, co jest powolne, ale kompletne. \n• Korzystanie z dedykowanego punktu końcowego usługi, co jest szybkie, ale zwykle nie jest kompletne. \n -\nRóżnica między nimi polega na tym, że w szybkim zwykle brakuje pewnych informacji, takich jak czas trwania lub typ pozycji (nie można odróżnić wideo na żywo od zwykłych) i może zwrócić mniej pozycji. +\nRóżnica między nimi polega na tym, że w szybkim zwykle brakuje pewnych informacji, takich jak czas trwania lub typ pozycji (nie można odróżnić wideo na żywo od zwykłych), i może zwrócić mniej pozycji. \n \nYouTube jest przykładem usługi, która oferuje tę szybką metodę z kanałem RSS. \n @@ -639,7 +639,7 @@ Tagi Kategoria Otwórz stronę - Teraz możesz zaznaczyć tekst wewnątrz opisu. Pamiętaj, że strona może migotać, a łącza mogą nie być klikalne w trybie zaznaczania. + Teraz możesz zaznaczyć tekst wewnątrz opisu. Pamiętaj, że w trybie zaznaczania strona może migotać i linki nie będą klikalne. %s podaje ten powód: Konto zamknięte Tryb szybki dla ładowania kanału nie dostarcza więcej informacji na ten temat. diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 841839909..9c1b47d32 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -410,7 +410,7 @@ Tempo limite de conexão Excluir todo o histórico de downloads ou excluir todos os arquivos baixados\? Limitar fila de downloads - Um download será feito por vez + Faz downloads um de cada vez Iniciar downloads Pausar downloads Perguntar onde salvar o arquivo diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index d7c571a4a..c632b264c 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -323,7 +323,7 @@ Snabbspola vid frånvaro av ljud Steg Återställ - För att uppfylla den Europeiska dataskyddsförordningen (GDPR) uppmärksammar vi er härmed på NewPipes sekretesspolicy. Var god läs den noggrant. + För att uppfylla den Europeiska dataskyddsförordningen (GDPR), uppmärksammar vi härmed NewPipes sekretesspolicy. Var god och läs den noggrant. \nDu måste acceptera den för att kunna skicka felrapporten. Acceptera Avböj @@ -673,7 +673,7 @@ Kolla manuellt efter nya versioner Söker efter uppdateringar… Nya flödes objekt - Visa \"krascha spelaren\" + Visa \"Krascha spelaren\" Krascha spelaren Visar ett kraschalternativ vid användning av spelaren Felrapport-avisering diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index 22f0cb9d9..fa87a4a18 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -312,7 +312,7 @@ NewPipe projesi, gizliliğinizi çok ciddiye alıyor. Bu nedenle, uygulama sizin izniniz olmadan herhangi bir veri toplamaz. \nNewPipe\'ın gizlilik ilkesi, çökme raporu gönderdiğinizde hangi verilerin gönderildiğini ve saklandığını ayrıntılı olarak açıklar. Gizlilik ilkesini oku - Avrupa Genel Veri Koruma Yönetmeliğine (GDPR) uymak için, dikkatinizi NewPipe\'ın gizlilik ilkesine çekiyoruz. Lütfen dikkatlice okuyun. + Avrupa Genel Veri Koruma Yönetmeliğine (GDPR) uymak için, dikkatinizi NewPipe\'ın gizlilik ilkesine çekiyoruz. Lütfen dikkatlice okuyun. \nBize hata bildirimini göndermek için kabul etmelisiniz. Kabul et Reddet diff --git a/app/src/main/res/values-zh-rHK/strings.xml b/app/src/main/res/values-zh-rHK/strings.xml index d584ae3fe..83085d9e4 100644 --- a/app/src/main/res/values-zh-rHK/strings.xml +++ b/app/src/main/res/values-zh-rHK/strings.xml @@ -29,7 +29,7 @@ 內容預設語言 影音 外觀 - 背景播放 + 幕後播緊 網絡問題 播放影片,片長: 上載者嘅頭像縮圖 @@ -95,8 +95,8 @@ 畫中畫模式需要此權限 需完成 reCAPTCHA 挑戰 某啲解像度可能會冇聲 - 背景播放 - 畫中畫播放 + 幕後播 + 浮面播 記住畫中畫大小及位置 記住最近設定的畫中畫大小及位置 搜尋建議 @@ -126,7 +126,7 @@ 轉唔到訂閱 更新唔到訂閱 顯示資訊 - 訂閱項目 + 訂閱 已收藏播放清單 用粗略快轉 加入去 @@ -259,7 +259,7 @@ \n您係咪要繼續? 幾時都唔使 自動 - 低畫質 (較細) + 低畫質 (細格啲) 唔顯示 撳一下去下載 無觀看次數 @@ -309,7 +309,7 @@ 無影片 影片播放器 僅限用 Wi-Fi 嘅時候 - 高畫質 (較大) + 高畫質 (大格啲) 無訂閱者 %s 位訂閱者 @@ -334,7 +334,7 @@ 最常播放 頭版內容 頭版要擺放邊啲分頁 - 滑走啲項目去剷走佢 + 打橫掃走啲項目去剷走佢 空白頁 重新開過個 app 之後就會轉新語言 時興 @@ -422,4 +422,113 @@ 發生問題,詳見通知 拖拉執排位 轉換服務,而家揀選咗嘅係: + 清單檢視模式 + 做噉一半冇咗,因為個檔案刪除咗 + 連線等太耐 + 開始晒所有下載 + 下載排隊逐個嚟,唔要一次過 + 近期 + 帳戶已被終止 + 語言 + 支援 + 覆寫唔到個檔案 + 暫停晒所有下載 + + 平板電腦模式 + 個檔案建立唔到 + 您係咪想喺搜尋紀錄度刪除呢個項目? + 睇下咩問題 + 有個整緊嘅下載撞名 + 有個等緊嘅下載撞名 + 試盡幾多次就取消個下載算數 + 喺鎖定畫面背景同埋通知都擺放縮圖 + 開始咗下載 + 年齡限制 + 您部機冇 app 開到佢 + 呢部影片係 YouTube Music Premium 會員限定,因此 NewPipe 未能串流或下載。 + 揀選啱您心水嘅夜色主題 — %s + 呢部內容係付費使用者限定,因此 NewPipe 未能串流或下載。 + 您可以喺下面揀選啱您心水嘅夜色主題 + 停用揀選描述入面嘅文字 + 一格格 + 一行行 + 加入去播放清單 + 新嘅播放清單 + 顯示頻道詳情 + 唔見影 + 揀選一個播放清單 + 伺服器唔接受多執行緒下載,請改用 @string/msg_threads = 1 再試下啦 + 連接唔到伺服器 + 播放清單頁面 + 載入緊頻道詳情… + 撳住就輪候 + 目的地資料夾建立唔到 + 建立唔到安全連線 + 喺幕後開始播放 + 部機冇晒位 + 頂櫳重試幾多次 + 若然有機會用到流動數據嘅時候,或者用得著,雖則有啲下載或者冇得暫停 + 輪住下載 + 內部 + 私人 + 停止 + 按用量收費嘅網絡就閘住 + 抹走下載紀錄 + 您想抹走您嘅下載紀錄,定係想剷走晒所有下載咗嘅檔案? + 剷走下載咗嘅檔案 + + 刪除咗 %1$s 個下載 + + 問我要下載去邊 + 排隊尾 + 搵唔到伺服器 + 伺服器冇傳回資料 + 後期處理失敗 + NewPipe 未搞掂個檔案就關閉咗 + 呢個下載恢復唔到 + 同個下載咗嘅檔案撞名 + 同個現有嘅檔案撞名 + + 揀選咗 %d 個 + + 揀選訂閱 + 未有揀選訂閱 + 顯示縮圖 + 頻道嘅頭像縮圖 + 由 %s 建立 + 出自 %s + 章節 + 呢部內容 NewPipe 仲未支援。 +\n +\n希望未來會喺日後嘅版本支援啦。 + 顯示睇過嘅項目 + %s 話理由如下: + 搵唔到合適嘅檔案總管進行呢個動作。 +\n請安裝一個檔案管理程式,又或者試下喺下載設定度停用「%s」。 + 搵唔到合適嘅檔案總管進行呢個動作。 +\n請安裝一個與儲存空間存取框架兼容嘅檔案管理程式。 + 呢部內容限區,喺您所在國家未有提供。 + 呢首 (至少喺您所在國家而言) 係 SoundCloud Go+ 單曲,因此 NewPipe 未能串流或下載。 + 呢部內容屬於私人,因此 NewPipe 未能串流或下載。 + 自動 (跟返部機嘅主題色系) + 精選 + 廣播 + 您而家可以揀選喺描述入面嘅文字喇。不過要單聲,喺揀選模式嘅時候,個頁面可能眨眨下,同埋啲連結會撳唔到。 + 啟用揀選描述入面嘅文字 + 版權協議 + 分類 + 標籤 + 公開設定 + 縮圖 URL + 公開 + 憑網址瀏覽 + 置頂留言 + 創作者畀咗心心 + 開啟網站 + + 顯示頻道詳情嘅時候有問題 + 主機 + 喺影片「詳情:」度撳一下「幕後播」或者「浮面播」個掣嘅時候顯示提示 + 紀錄 + 紀錄 \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 54551be14..c495066f2 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -150,7 +150,8 @@ Turn on YouTube\'s \"Restricted Mode\" YouTube provides a \"Restricted Mode\" which hides potentially mature content This video is age restricted.\n\nTurn on \"%1$s\" in the settings if you want to see it. - This video is age-restricted.\nDue to new YouTube policies with age-restricted videos, NewPipe cannot access any of its video streams and thus is unable to play it. + This video is age-restricted. +\nDue to new YouTube policies with age-restricted videos, NewPipe cannot access any of its video streams and thus is unable to play it. Live Downloads Downloads @@ -488,7 +489,8 @@ Step Reset - In order to comply with the European General Data Protection Regulation (GDPR), we herby draw your attention to NewPipe\'s privacy policy. Please read it carefully.\nYou must accept it to send us the bug report. + In order to comply with the European General Data Protection Regulation (GDPR), we hereby draw your attention to NewPipe\'s privacy policy. Please read it carefully. +\nYou must accept it to send us the bug report. Accept Decline @@ -557,11 +559,11 @@ There is a pending download with this name Show error - The file can not be created - The destination folder can not be created + The file cannot be created + The destination folder cannot be created Could not establish a secure connection Could not find the server - Can not connect to the server + Cannot connect to the server The server does not send data The server does not accept multi-threaded downloads, retry with @string/msg_threads = 1 Not found @@ -600,7 +602,8 @@ System default Remove watched Remove watched videos? - Videos that have been watched before and after being added to the playlist will be removed.\nAre you sure? This cannot be undone! + Videos that have been watched before and after being added to the playlist will be removed. +\nAre you sure\? This cannot be undone! Yes, and partially watched videos Due to ExoPlayer constraints the seek duration was set to %d seconds @@ -650,7 +653,17 @@ Available in some services, it is usually much faster but may return a limited amount of items and often incomplete information (e.g. no duration, item type, no live status) Enable fast mode Disable fast mode - Do you think feed loading is too slow? If so, try enabling fast loading (you can change it in settings or by pressing the button below).\n\nNewPipe offers two feed loading strategies:\n• Fetching the whole subscription channel, which is slow but complete.\n• Using a dedicated service endpoint, which is fast but usually not complete.\n\nThe difference between the two is that the fast one usually lacks some information, like the item\'s duration or type (can\'t distinguish between live videos and normal ones) and it may return less items.\n\nYouTube is an example of a service that offers this fast method with its RSS feed.\n\nSo the choice boils down to what you prefer: speed or precise information. + Do you think feed loading is too slow\? If so, try enabling fast loading (you can change it in settings or by pressing the button below). +\n +\nNewPipe offers two feed loading strategies: +\n• Fetching the whole subscription channel, which is slow but complete. +\n• Using a dedicated service endpoint, which is fast but usually not complete. +\n +\nThe difference between the two is that the fast one usually lacks some information, like the item\'s duration or type (can\'t distinguish between live videos and normal ones) and it may return less items. +\n +\nYouTube is an example of a service that offers this fast method with its RSS feed. +\n +\nSo the choice boils down to what you prefer: speed or precise information. Show watched items This content is not yet supported by NewPipe.\n\nIt will hopefully be supported in a future version. Channel\'s avatar thumbnail diff --git a/fastlane/metadata/android/az/changelogs/63.txt b/fastlane/metadata/android/az/changelogs/63.txt new file mode 100644 index 000000000..84cf8a75d --- /dev/null +++ b/fastlane/metadata/android/az/changelogs/63.txt @@ -0,0 +1,8 @@ +### Təkmilləşdirmələr +-İdxal/ixrac parametrləri #1333 +-Həddindən artıq çəkilişi azaldın (performansın yaxşılaşdırılması) #1371 +- Kiçik kod təkmilləşdirmələri #1375 +- GDPR #1420 haqqında hər şeyi əlavə edin + +### Sabit +- Yükləyici: .giga fayllarından bitməmiş endirmələrin yüklənməsi zamanı yaranan nasazlığı aradan qaldırın #1407 diff --git a/fastlane/metadata/android/az/changelogs/64.txt b/fastlane/metadata/android/az/changelogs/64.txt new file mode 100644 index 000000000..74e59b622 --- /dev/null +++ b/fastlane/metadata/android/az/changelogs/64.txt @@ -0,0 +1,7 @@ +### Təkmilləşdirmələr +- Mobil datadan istifadə edərkən video keyfiyyətini məhdudlaşdırmaq imkanı əlavə edildi. #1339 + - Sessiya üçün parlaqlığı yadda saxla #1442 + - Daha zəif CPU-lar üçün yükləmə performansını yaxşılaşdırın #1431 + - media sessiyası üçün (işləyən) dəstək əlavə edin #1433 +### Düzəliş +- Yükləmələrin açılması zamanı qəzanı düzəldin (indi buraxılış quruluşları üçün əlçatandır) #1441 diff --git a/fastlane/metadata/android/az/changelogs/65.txt b/fastlane/metadata/android/az/changelogs/65.txt new file mode 100644 index 000000000..e42c926fa --- /dev/null +++ b/fastlane/metadata/android/az/changelogs/65.txt @@ -0,0 +1 @@ +### Təkmilləşdirmələr - Burgermenyu ikona animasiyasını deaktiv edin #1486 - Yükləmələrin silinməsini geri qaytarın #1472 - Paylaşım menyusunda yükləmə seçimi #1498 - Uzun toxunma menyusuna paylaşma seçimi əlavə edildi #1454 - Çıxışda əsas oyunçunu minimuma endirin #1354 - Kitabxana versiyasının yenilənməsi və verilənlər bazası backup fix #1510 - ExoPlayer 2.8.2 Yeniləmə #1392 - Daha sürətli sürət dəyişikliyi üçün müxtəlif addım ölçülərini dəstəkləmək üçün oxutma sürətinə nəzarət. diff --git a/fastlane/metadata/android/az/changelogs/66.txt b/fastlane/metadata/android/az/changelogs/66.txt new file mode 100644 index 000000000..441691ae5 --- /dev/null +++ b/fastlane/metadata/android/az/changelogs/66.txt @@ -0,0 +1 @@ +# V0.13.7 Dəyişikliklər Qrupu ### Düzəltildi - v0.13.6-nın çeşidləmə filtri problemlərini düzəldin # v0.13.6-nın Dəyişikliklər Qrupu ###Təkmilləşdirmələr - Burgermenu ikona animasiyasını söndürün #1486.- ExoPlayer 2.8.2 Yeniləmə #1392 - Sürətin daha sürətli dəyişməsi üçün müxtəlif addım ölçülərini dəstəkləmək üçün oxutma sürətinə nəzarət dialoqu yenidən işlənmişdir. - Oynatma sətrinə nəzarətdə səssizliklər zamanı sürətli irəliləməyə keçid əlavə edildi. diff --git a/fastlane/metadata/android/de/changelogs/730.txt b/fastlane/metadata/android/de/changelogs/730.txt new file mode 100644 index 000000000..422bd31b3 --- /dev/null +++ b/fastlane/metadata/android/de/changelogs/730.txt @@ -0,0 +1,2 @@ +# Behoden +- erneuter Hotfix des Entschlüsselungsfunktionsfehlers. diff --git a/fastlane/metadata/android/de/changelogs/900.txt b/fastlane/metadata/android/de/changelogs/900.txt new file mode 100644 index 000000000..a4a8a1253 --- /dev/null +++ b/fastlane/metadata/android/de/changelogs/900.txt @@ -0,0 +1,14 @@ +Neu +- Abonnementgruppen und sortierte Feeds +- Stummschalttaste in Playern + +Verbessert +- Das Öffnen von music.youtube.com und media.ccc.de Links in NewPipe erlaubt +- Zwei Einstellungen wurden von "Erscheinungsbild" zu "Inhalt" verschoben +- Ausblenden der Suchoptionen 5, 15 und 25 Sekunden, wenn die ungenaue Suche aktiviert ist + +Behoben +- einige WebM-Videos sind nicht suchbar +- Datenbank-Backup auf Android P +- Absturz beim Teilen einer heruntergeladenen Datei +- YouTube-Extraktionsprobleme, ... diff --git a/fastlane/metadata/android/de/changelogs/963.txt b/fastlane/metadata/android/de/changelogs/963.txt new file mode 100644 index 000000000..6155e4a5e --- /dev/null +++ b/fastlane/metadata/android/de/changelogs/963.txt @@ -0,0 +1 @@ +• [YouTube] Fortsetzung des Kanals korrigiert diff --git a/fastlane/metadata/android/de/changelogs/965.txt b/fastlane/metadata/android/de/changelogs/965.txt new file mode 100644 index 000000000..935a3d867 --- /dev/null +++ b/fastlane/metadata/android/de/changelogs/965.txt @@ -0,0 +1,6 @@ +Absturz behoben, der beim Neuordnen von Kanalgruppen auftrat. +Das Abrufen weiterer YouTube-Videos aus Kanälen und Wiedergabelisten wurde behoben. +Das Abrufen von YouTube-Kommentaren wurde behoben. +Unterstützung für /watch/, /v/ und /w/ Unterpfade in YouTube URLs hinzugefügt. +Die Extraktion der SoundCloud-Client-ID und geografisch eingeschränkter Inhalte wurde korrigiert. +Nordkurdische Lokalisierung wurde hinzugefügt. diff --git a/fastlane/metadata/android/de/changelogs/973.txt b/fastlane/metadata/android/de/changelogs/973.txt new file mode 100644 index 000000000..953abb166 --- /dev/null +++ b/fastlane/metadata/android/de/changelogs/973.txt @@ -0,0 +1,4 @@ +Hotfix +- Thumbnails und Titel werden im Grid-Layout nicht mehr abgeschnitten, da falsch berechnet wurde, wie viele Videos in eine Reihe passen +- Der Download-Dialog verschwindet nicht mehr, wenn er über das Freigabemenü geöffnet wird +- Aktualisierung einer Bibliothek im Zusammenhang mit dem Öffnen von externen Aktivitäten wie dem Storage Access Framework File Picker diff --git a/fastlane/metadata/android/de/changelogs/974.txt b/fastlane/metadata/android/de/changelogs/974.txt new file mode 100644 index 000000000..607394d8f --- /dev/null +++ b/fastlane/metadata/android/de/changelogs/974.txt @@ -0,0 +1,5 @@ +Hotfix +- Behebung von Pufferproblemen, die durch YouTube-Drosselung verursacht werden +- Behebt die Extraktion von YouTube-Kommentaren und Abstürze bei deaktivierten Kommentaren +- Behebung der YouTube-Musiksuche +- Behebung von PeerTube-Livestreams diff --git a/fastlane/metadata/android/de/changelogs/979.txt b/fastlane/metadata/android/de/changelogs/979.txt new file mode 100644 index 000000000..03165629c --- /dev/null +++ b/fastlane/metadata/android/de/changelogs/979.txt @@ -0,0 +1,2 @@ +- Wiederaufnahme der Wiedergabe behoben +- Verbesserungen, um sicherzustellen, dass der Dienst, der bestimmt, ob NewPipe nach einer neuen Version suchen soll, nicht im Hintergrund gestartet wird diff --git a/fastlane/metadata/android/de/changelogs/980.txt b/fastlane/metadata/android/de/changelogs/980.txt new file mode 100644 index 000000000..3e32d136b --- /dev/null +++ b/fastlane/metadata/android/de/changelogs/980.txt @@ -0,0 +1,13 @@ +Neu +- Option "Zur Wiedergabeliste hinzufügen" zum Freigabemenü hinzugefügt +- Unterstützung für y2u.be und PeerTube Kurzlinks hinzugefügt + +Verbessert +- Playback-Speed-Controls kompakter gemacht +- Feed hebt jetzt neue Elemente hervor +- "Beobachtete Artikel anzeigen" Option im Feed wird nun gespeichert + +Behoben +- Extraktion von YouTube Likes und Dislikes behoben +- Automatische Wiederholung nach Rückkehr aus dem Hintergrund behoben +Und vieles mehr diff --git a/fastlane/metadata/android/de/changelogs/981.txt b/fastlane/metadata/android/de/changelogs/981.txt new file mode 100644 index 000000000..d4a2175db --- /dev/null +++ b/fastlane/metadata/android/de/changelogs/981.txt @@ -0,0 +1,2 @@ +Die MediaParser-Unterstützung wurde entfernt, um Probleme bei der Wiederaufnahme der Wiedergabe nach der Pufferung unter Android 11+ zu beheben. +Media Tunneling auf Philips QM16XE deaktiviert, um Wiedergabeprobleme zu beheben. diff --git a/fastlane/metadata/android/de/changelogs/982.txt b/fastlane/metadata/android/de/changelogs/982.txt new file mode 100644 index 000000000..e2a10be2e --- /dev/null +++ b/fastlane/metadata/android/de/changelogs/982.txt @@ -0,0 +1 @@ +Behoben, dass YouTube keinen Stream abspielte. diff --git a/fastlane/metadata/android/de/changelogs/983.txt b/fastlane/metadata/android/de/changelogs/983.txt new file mode 100644 index 000000000..eeef14bac --- /dev/null +++ b/fastlane/metadata/android/de/changelogs/983.txt @@ -0,0 +1,9 @@ +Neue UI und Verhalten beim doppelten Antippen zum Suchen hinzufügen +Einstellungen durchsuchbar machen +Angepinnte Kommentare als solche markieren +Open-With-App Unterstützung für FSFEs PeerTube-Instanz hinzufügen +Hinzufügen von Fehlerbenachrichtigungen +Replay des ersten Warteschlangenelements bei Spielerwechsel korrigieren +Längeres Warten beim Puffern während Livestreams, bevor ein Fehler auftritt +Reihenfolge der lokalen Suchergebnisse korrigieren +Leere Felder in der Warteschlange beheben diff --git a/fastlane/metadata/android/de/changelogs/984.txt b/fastlane/metadata/android/de/changelogs/984.txt new file mode 100644 index 000000000..fc90a91a9 --- /dev/null +++ b/fastlane/metadata/android/de/changelogs/984.txt @@ -0,0 +1,7 @@ +Scrollen in Listen auf Tablets und TVs behoben +Zufällige Abstürze beim Scrollen durch Listen behoben +Das Overlay zum schnellen Vor- und Zurückspringen liegt jetzt unter der System-UI +Änderungen für bessere Unterstützung von Cutouts wurden rückgängig gemacht, da diese auf einigen Geräten die Oberfläche des Players verschiebt +compileSDK wurde von 30auf 31 erhöht +Die Bibliothek zum Melden von Fehlern wurde aktualisiert +Kleine Teile des Player Codes wurden umstrukturiert diff --git a/fastlane/metadata/android/fr/changelogs/983.txt b/fastlane/metadata/android/fr/changelogs/983.txt new file mode 100644 index 000000000..b9760a8a1 --- /dev/null +++ b/fastlane/metadata/android/fr/changelogs/983.txt @@ -0,0 +1,9 @@ +Ajoute de nouveaux interface et comportement pour la recherche par double-touche +Rend les paramètres recherchables +Surligne les commentaires épinglés comme tels +Ajoute l’ouverture avec app pour l’instance PeerTube de la FSFE +Ajoute les notifications d’erreur +Corrige la relecture du premier item de la file lorsque le lecteur change +Attend plus longtemps lors des directs avant d’échouer +Corrige l’ordre des résultats d’une recherche locale +Corrige les champs d’item vides dans la liste de lecture diff --git a/fastlane/metadata/android/fr/changelogs/984.txt b/fastlane/metadata/android/fr/changelogs/984.txt new file mode 100644 index 000000000..a3d3eef75 --- /dev/null +++ b/fastlane/metadata/android/fr/changelogs/984.txt @@ -0,0 +1,6 @@ +Charge assez d’items dans les listes pour remplir l’écran et corriger le défilement sur les tablettes et les télés +Corrige les plantages lors du défilement des listes +L’arc de superposition de l’avance rapide est désormais sous l’interface du système +Revient sur les modifications des découpes lors de la lecture en multi-fenêtres, qui causent la régression du lecteur mal positionné sur certains appareils +Met à jour compileSdk à la version 31 +Met à jour la bibliothèque de rapports d’erreur diff --git a/fastlane/metadata/android/he/changelogs/984.txt b/fastlane/metadata/android/he/changelogs/984.txt new file mode 100644 index 000000000..3ae5c85a7 --- /dev/null +++ b/fastlane/metadata/android/he/changelogs/984.txt @@ -0,0 +1,7 @@ +מספיק פריטים נטענים באופן ראשוני ברשימות כדי למלא את כל המסך ולתקן גלילה במחשבי לוח ובטלוויזיות +תוקנו קריסות אקראיות בעת גלילה ברשימות +קשת הקפיצה קדימה שמופיעה על הסרטון יורדת אל מתחת לשכבת מנשק המשתמש במערכת +שוחזרו השינויים לחיתוכים בעת נגינה במספר חלונות, מה שגרם לנסיגה בנגן שהוזז בחלק מהטלפונים +compileSdk שודרג מ־30 ל־31 +ספריית דיווח השגיאות עודכנה +חלק מהקוד בנגן שופץ diff --git a/fastlane/metadata/android/it/changelogs/984.txt b/fastlane/metadata/android/it/changelogs/984.txt new file mode 100644 index 000000000..ae717f021 --- /dev/null +++ b/fastlane/metadata/android/it/changelogs/984.txt @@ -0,0 +1,7 @@ +Ora nelle liste vengono caricati abbastanza elementi per riempire l'intero schermo, evitando caricamenti infiniti su tablet e TV +Sistemati crash a caso nello scorrere le liste +L'arco dell'avanzamento rapido ora va anche sotto l'interfaccia di sistema +Annullati i cambiamenti alla gestione dei bordi dello schermo in modalità multi-finestra: il player era talvolta fuori posto +Incrementato compileSdk da 30 a 31 +Aggiornata la libreria di segnalazione degli errori +Ristrutturato del codice nel player diff --git a/fastlane/metadata/android/nl-BE/changelogs/63.txt b/fastlane/metadata/android/nl-BE/changelogs/63.txt new file mode 100644 index 000000000..3a8c7df1f --- /dev/null +++ b/fastlane/metadata/android/nl-BE/changelogs/63.txt @@ -0,0 +1,8 @@ +### Verbeteringen +- Instellingen importeren/exporteren #1333 +- Overdraw verminderen (prestatieverbetering) #1371 +- Kleine code verbeteringen #1375 +- Alles toevoegen over GDPR #1420 + +### Opgelost +- Downloader: Crash bij laden van onafgemaakte downloads van .giga bestanden verhelpen #1407 diff --git a/fastlane/metadata/android/nl/changelogs/954.txt b/fastlane/metadata/android/nl/changelogs/954.txt new file mode 100644 index 000000000..c225e5f11 --- /dev/null +++ b/fastlane/metadata/android/nl/changelogs/954.txt @@ -0,0 +1,9 @@ +- nieuwe applicatie-workflow: video's afspelen op detailpagina, omlaag vegen om speler te minimaliseren +- MediaStyle meldingen: aanpasbare acties in meldingen, prestaties verbeterd +- basisgrootte aanpassen bij NewPipe als desktop-app + +- dialoog met open opties tonen bij een niet-ondersteunde URL-toast +- Verbeterde zoeksuggestie-ervaring als externe niet kunnen worden opgehaald +- Verhoogde standaard videokwaliteit naar 720p60 (in-app speler) en 480p (pop-up speler) + +- veel bug fixes en meer diff --git a/fastlane/metadata/android/nl/changelogs/969.txt b/fastlane/metadata/android/nl/changelogs/969.txt new file mode 100644 index 000000000..961475654 --- /dev/null +++ b/fastlane/metadata/android/nl/changelogs/969.txt @@ -0,0 +1,8 @@ +• Installatie op externe opslag toestaan +• [Bandcamp] Ondersteuning voor het tonen van de eerste drie commentaren op een stream +• Toon alleen 'download is gestart' toast wanneer download is gestart +• Stel reCaptcha-cookie niet in wanneer er geen cookie is opgeslagen +• [Speler] Verbeter cache prestatie +• [Speler] Fix: speler die niet automatisch speelt +• Vorige Snackbalken verwijderen bij het verwijderen van downloads +• Hersteld dat objecten die niet in de lijst staan, verwijderd moeten worden diff --git a/fastlane/metadata/android/nl/changelogs/970.txt b/fastlane/metadata/android/nl/changelogs/970.txt new file mode 100644 index 000000000..95aa33d1a --- /dev/null +++ b/fastlane/metadata/android/nl/changelogs/970.txt @@ -0,0 +1,11 @@ +Nieuw +• Toon inhoud metadata (tags, categorieën, licentie, ...) onder de beschrijving +• "Toon kanaal details" optie in afspeellijsten op afstand (niet-lokaal) +• "Open in browser" optie toegevoegd aan lange-druk menu + +Fix +• Rotatie crash op video detail pagina opgelost +• "Play with Kodi" knop in speler vraagt altijd om Kore te installeren +• Im- en export paden hersteld en verbeterd +• [YouTube] Aantal reacties als opgelost +En nog veel meer diff --git a/fastlane/metadata/android/nl/changelogs/971.txt b/fastlane/metadata/android/nl/changelogs/971.txt new file mode 100644 index 000000000..936f637c5 --- /dev/null +++ b/fastlane/metadata/android/nl/changelogs/971.txt @@ -0,0 +1,3 @@ +Hotfix +- Vergroot buffer voor afspelen na rebuffer +- Crash op tablets en TV's verholpen bij het klikken op het play-queue icoon in de speler diff --git a/fastlane/metadata/android/nl/changelogs/972.txt b/fastlane/metadata/android/nl/changelogs/972.txt new file mode 100644 index 000000000..9f27419bc --- /dev/null +++ b/fastlane/metadata/android/nl/changelogs/972.txt @@ -0,0 +1,14 @@ +Nieuw +Herken tijdstempels en hashtags in beschrijving +Handmatige tablet-modus instelling +Mogelijkheid afgespeelde items in een feed te verbergen + +Verbeterd +Ondersteuning van Storage Access Framework +Foutafhandeling van niet-beschikbare en beëindigde kanalen +De Android share sheet voor Android 10+ gebruikers toont nu de titel van de inhoud +Invidious instanties. Ondersteuning voor Piped links + +Bugfix +[YouTube] Leeftijdsbeperkte inhoud +Voorkom uitgelekt venster Uitzondering bij openen keuzedialoog diff --git a/fastlane/metadata/android/pl/changelogs/984.txt b/fastlane/metadata/android/pl/changelogs/984.txt new file mode 100644 index 000000000..5197da252 --- /dev/null +++ b/fastlane/metadata/android/pl/changelogs/984.txt @@ -0,0 +1,7 @@ +Ładowanie wystarczającej liczby początkowych pozycji na listach, aby wypełnić cały ekran, oraz naprawiono przewijanie na tabletach i telewizorach +Naprawiono losowe awarie podczas przewijania list +Przesunięto nakładkę szybkiego przewijania odtwarzacza pod interfejs systemu +Cofnięto zmiany przy odtwarzaniu w trybie wielu okien powodujące błędy na niektórych telefonach +Podwyższono compileSdk z 30 do 31 +Zaktualizowano bibliotekę raportowania błędów +Refaktoryzacja kodu odtwarzacza diff --git a/fastlane/metadata/android/sv/changelogs/982.txt b/fastlane/metadata/android/sv/changelogs/982.txt new file mode 100644 index 000000000..4c434af54 --- /dev/null +++ b/fastlane/metadata/android/sv/changelogs/982.txt @@ -0,0 +1 @@ +Fixade att YouTube inte spelade någon stream. diff --git a/fastlane/metadata/android/sv/changelogs/984.txt b/fastlane/metadata/android/sv/changelogs/984.txt new file mode 100644 index 000000000..7f1e40a63 --- /dev/null +++ b/fastlane/metadata/android/sv/changelogs/984.txt @@ -0,0 +1,7 @@ +Ladda in tillräckligt många inledande objekt i listor för att fylla hela skärmen och för att åtgärda rullning på surfplattor och TV-apparater +Fixa slumpmässiga krascher vid rullning i listor +Lät spelarens snabbsöks funktion gå under systemets användargränssnitt +Tog bort ändringar av utskärningar när man spelar i flera fönster, vilket orsakade en felplacerad spelare på vissa telefoner +Öka compileSdk från 30 till 31 +Uppdatera biblioteket för felrapportering +Refaktorisering av viss kod i spelaren diff --git a/fastlane/metadata/android/uk/changelogs/984.txt b/fastlane/metadata/android/uk/changelogs/984.txt new file mode 100644 index 000000000..c9b4e7514 --- /dev/null +++ b/fastlane/metadata/android/uk/changelogs/984.txt @@ -0,0 +1,7 @@ +Завантаження достатньої кількості початкових елементів у списках, щоб заповнити весь екран і виправлено гортання на планшетах і телевізорах +Усунуто збої під час гортання списків +Виправлено проблему перемотування у програвачі +Скасовано зміни для пристроїв з вирізами під час програвання в багатовіконному режимі +compileSdk оновлено з 30 до 31 версії +Оновлено бібліотеку звітів про помилки +Рефакторинг коду програвача diff --git a/fastlane/metadata/android/zh-Hant/changelogs/984.txt b/fastlane/metadata/android/zh-Hant/changelogs/984.txt new file mode 100644 index 000000000..4de1b675f --- /dev/null +++ b/fastlane/metadata/android/zh-Hant/changelogs/984.txt @@ -0,0 +1,7 @@ +在清單中載入足夠初始項目以填滿整個螢幕並藉以修正平板電腦和電視上的捲動 +修正捲動清單時無常當機 +播放器快速搜索的覆蓋弧形置於系統介面之下 +還原多重視窗播放時的瀏海變更,免致部分手機出現播放器錯置迴歸 +compileSdk 由 30 增至 31 +更新錯誤報告程式庫 +重構播放器中的部分程式碼 diff --git a/fastlane/metadata/android/zh_Hant_HK/changelogs/984.txt b/fastlane/metadata/android/zh_Hant_HK/changelogs/984.txt new file mode 100644 index 000000000..34be1e7ef --- /dev/null +++ b/fastlane/metadata/android/zh_Hant_HK/changelogs/984.txt @@ -0,0 +1,7 @@ +喺清單度載入足夠多初始項目去填滿成個螢幕並修正喺平板電腦同電視上面嘅捲動問題 +修正捲動清單時偶發閃退 +播放器快轉嘅覆蓋弧形擺喺系統介面後面 +撤回多視窗播放時嘅 M 字額變動,以免部份手機出現播放器錯位嘅倒退 +將 compileSdk 由 30 升至 31 +更新問題報告程式庫 +執整播放器部份程式碼