mirror of
https://github.com/TeamNewPipe/NewPipe
synced 2024-11-05 01:26:23 +00:00
Merge pull request #7934 from TeamNewPipe/release/0.22.1
Release 0.22.1
This commit is contained in:
commit
47f9ed08e9
29
.github/workflows/image-minimizer.js
vendored
29
.github/workflows/image-minimizer.js
vendored
@ -4,7 +4,12 @@
|
||||
module.exports = async ({github, context}) => {
|
||||
const IGNORE_KEY = '<!-- IGNORE IMAGE MINIFY -->';
|
||||
const IGNORE_ALT_NAME_END = 'ignoreImageMinify';
|
||||
// Targeted maximum height
|
||||
const IMG_MAX_HEIGHT_PX = 600;
|
||||
// maximum width of GitHub issues/comments
|
||||
const IMG_MAX_WIDTH_PX = 800;
|
||||
// all images that have a lower aspect ratio (-> have a smaller width) than this will be minimized
|
||||
const MIN_ASPECT_RATIO = IMG_MAX_WIDTH_PX / IMG_MAX_HEIGHT_PX
|
||||
|
||||
// Get the body of the image
|
||||
let initialBody = null;
|
||||
@ -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_RATIO;
|
||||
} catch(e) {
|
||||
console.log('Probing failed:', e);
|
||||
// Immediately abort
|
||||
return match;
|
||||
}
|
||||
|
||||
if (shouldModifiy) {
|
||||
if (shouldModify) {
|
||||
wasMatchModified = true;
|
||||
console.log(`Modifying match '${match}'`);
|
||||
return `<img alt="${g1}" src="${g2}" height=${IMG_MAX_HEIGHT_PX} />`;
|
||||
}
|
||||
@ -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') {
|
||||
|
@ -8,7 +8,7 @@ plugins {
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdk 30
|
||||
compileSdk 31
|
||||
buildToolsVersion '30.0.3'
|
||||
|
||||
defaultConfig {
|
||||
@ -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
|
||||
|
||||
@ -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'
|
||||
|
@ -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() {
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
@ -79,11 +78,6 @@ public abstract class BaseListFragment<I, N> extends BaseStateFragment<I>
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDetach() {
|
||||
super.onDetach();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(final Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
@ -220,14 +214,10 @@ public abstract class BaseListFragment<I, N> extends BaseStateFragment<I>
|
||||
//////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
@Nullable
|
||||
protected ViewBinding getListHeader() {
|
||||
protected Supplier<View> getListHeaderSupplier() {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected ViewBinding getListFooter() {
|
||||
return PignateFooterBinding.inflate(activity.getLayoutInflater(), itemsList, false);
|
||||
}
|
||||
|
||||
protected RecyclerView.LayoutManager getListLayoutManager() {
|
||||
return new SuperScrollLayoutManager(activity);
|
||||
}
|
||||
@ -252,11 +242,10 @@ public abstract class BaseListFragment<I, N> extends BaseStateFragment<I>
|
||||
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<View> listHeaderSupplier = getListHeaderSupplier();
|
||||
if (listHeaderSupplier != null) {
|
||||
infoListAdapter.setHeaderSupplier(listHeaderSupplier);
|
||||
}
|
||||
|
||||
itemsList.setAdapter(infoListAdapter);
|
||||
@ -271,7 +260,7 @@ public abstract class BaseListFragment<I, N> extends BaseStateFragment<I>
|
||||
@Override
|
||||
protected void initListeners() {
|
||||
super.initListeners();
|
||||
infoListAdapter.setOnStreamSelectedListener(new OnClickGesture<StreamInfoItem>() {
|
||||
infoListAdapter.setOnStreamSelectedListener(new OnClickGesture<>() {
|
||||
@Override
|
||||
public void selected(final StreamInfoItem selectedItem) {
|
||||
onStreamSelected(selectedItem);
|
||||
@ -315,22 +304,98 @@ public abstract class BaseListFragment<I, N> extends BaseStateFragment<I>
|
||||
}
|
||||
});
|
||||
|
||||
infoListAdapter.setOnCommentsSelectedListener(new OnClickGesture<CommentsInfoItem>() {
|
||||
infoListAdapter.setOnCommentsSelectedListener(new OnClickGesture<>() {
|
||||
@Override
|
||||
public void selected(final CommentsInfoItem selectedItem) {
|
||||
onItemSelected(selectedItem);
|
||||
}
|
||||
});
|
||||
|
||||
// Ensure that there is always a scroll listener (e.g. when rotating the device)
|
||||
useNormalItemListScrollListener();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 OnScrollBelowItemsListener() {
|
||||
itemsList.addOnScrollListener(new DefaultItemListOnScrolledDownListener());
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all listeners and adds the initial scroll listener to the {@link #itemsList}.
|
||||
* <br/>
|
||||
* Which tries to load more items when not enough are in the view (not scrollable)
|
||||
* and more are available.
|
||||
* <br/>
|
||||
* 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...
|
||||
* <br/>
|
||||
* This listener will be replaced by DefaultItemListOnScrolledDownListener when
|
||||
* <ul>
|
||||
* <li>the view was actually scrolled</li>
|
||||
* <li>the view is scrollable</li>
|
||||
* <li>no more items can be loaded</li>
|
||||
* </ul>
|
||||
*/
|
||||
protected void useInitialItemListLoadScrollListener() {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "useInitialItemListLoadScrollListener called");
|
||||
}
|
||||
itemsList.clearOnScrollListeners();
|
||||
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");
|
||||
|
||||
useNormalItemListScrollListener();
|
||||
return;
|
||||
}
|
||||
if (isLoading.get()) {
|
||||
log("Still loading data -> Skipping");
|
||||
return;
|
||||
}
|
||||
if (!hasMoreItems()) {
|
||||
log("No more items to load");
|
||||
|
||||
useNormalItemListScrollListener();
|
||||
return;
|
||||
}
|
||||
if (itemsList.canScrollVertically(1)
|
||||
|| itemsList.canScrollVertically(-1)) {
|
||||
log("View is scrollable");
|
||||
|
||||
useNormalItemListScrollListener();
|
||||
return;
|
||||
}
|
||||
|
||||
log("Loading more data");
|
||||
loadMoreItems();
|
||||
}
|
||||
|
||||
private void log(final String msg) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "initItemListLoadScrollListener - " + 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(),
|
||||
@ -418,6 +483,12 @@ public abstract class BaseListFragment<I, N> extends BaseStateFragment<I>
|
||||
// Load and handle
|
||||
//////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
@Override
|
||||
protected void startLoading(final boolean forceLoad) {
|
||||
useInitialItemListLoadScrollListener();
|
||||
super.startLoading(forceLoad);
|
||||
}
|
||||
|
||||
protected abstract void loadMoreItems();
|
||||
|
||||
protected abstract boolean hasMoreItems();
|
||||
|
@ -65,7 +65,7 @@ public abstract class BaseListInfoFragment<I extends ListInfo>
|
||||
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 +105,7 @@ public abstract class BaseListInfoFragment<I extends ListInfo>
|
||||
// Load and handle
|
||||
//////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
@Override
|
||||
protected void doInitialLoadLogic() {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "doInitialLoadLogic() called");
|
||||
@ -158,6 +159,7 @@ public abstract class BaseListInfoFragment<I extends ListInfo>
|
||||
*/
|
||||
protected abstract Single<ListExtractor.InfoItemsPage> loadMoreItemsLogic();
|
||||
|
||||
@Override
|
||||
protected void loadMoreItems() {
|
||||
isLoading.set(true);
|
||||
|
||||
@ -171,9 +173,9 @@ public abstract class BaseListInfoFragment<I extends ListInfo>
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.doFinally(this::allowDownwardFocusScroll)
|
||||
.subscribe((@NonNull ListExtractor.InfoItemsPage InfoItemsPage) -> {
|
||||
.subscribe(infoItemsPage -> {
|
||||
isLoading.set(false);
|
||||
handleNextItems(InfoItemsPage);
|
||||
handleNextItems(infoItemsPage);
|
||||
}, (@NonNull Throwable throwable) ->
|
||||
dynamicallyShowErrorPanelOrSnackbar(new ErrorInfo(throwable,
|
||||
errorUserAction, "Loading more items: " + url, serviceId)));
|
||||
@ -223,7 +225,7 @@ public abstract class BaseListInfoFragment<I extends ListInfo>
|
||||
setTitle(name);
|
||||
|
||||
if (infoListAdapter.getItemsList().isEmpty()) {
|
||||
if (result.getRelatedItems().size() > 0) {
|
||||
if (!result.getRelatedItems().isEmpty()) {
|
||||
infoListAdapter.addInfoItemList(result.getRelatedItems());
|
||||
showListFooter(hasMoreItems());
|
||||
} else {
|
||||
@ -240,7 +242,7 @@ public abstract class BaseListInfoFragment<I extends ListInfo>
|
||||
final List<Throwable> 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(),
|
||||
|
@ -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<ChannelInfo>
|
||||
implements View.OnClickListener {
|
||||
|
||||
@ -145,12 +144,12 @@ public class ChannelFragment extends BaseListInfoFragment<ChannelInfo>
|
||||
//////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
@Override
|
||||
protected ViewBinding getListHeader() {
|
||||
protected Supplier<View> getListHeaderSupplier() {
|
||||
headerBinding = ChannelHeaderBinding
|
||||
.inflate(activity.getLayoutInflater(), itemsList, false);
|
||||
playlistControlBinding = headerBinding.playlistControl;
|
||||
|
||||
return headerBinding;
|
||||
return headerBinding::getRoot;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -183,13 +182,6 @@ public class ChannelFragment extends BaseListInfoFragment<ChannelInfo>
|
||||
}
|
||||
}
|
||||
|
||||
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 +189,10 @@ public class ChannelFragment extends BaseListInfoFragment<ChannelInfo>
|
||||
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 +511,11 @@ public class ChannelFragment extends BaseListInfoFragment<ChannelInfo>
|
||||
}
|
||||
|
||||
private PlayQueue getPlayQueue(final int index) {
|
||||
final List<StreamInfoItem> streamItems = new ArrayList<>();
|
||||
for (final InfoItem i : infoListAdapter.getItemsList()) {
|
||||
if (i instanceof StreamInfoItem) {
|
||||
streamItems.add((StreamInfoItem) i);
|
||||
}
|
||||
}
|
||||
final List<StreamInfoItem> 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);
|
||||
}
|
||||
|
@ -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<PlaylistInfo> {
|
||||
|
||||
private static final String PICASSO_PLAYLIST_TAG = "PICASSO_PLAYLIST_TAG";
|
||||
@ -120,12 +120,12 @@ public class PlaylistFragment extends BaseListInfoFragment<PlaylistInfo> {
|
||||
//////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
@Override
|
||||
protected ViewBinding getListHeader() {
|
||||
protected Supplier<View> getListHeaderSupplier() {
|
||||
headerBinding = PlaylistHeaderBinding
|
||||
.inflate(activity.getLayoutInflater(), itemsList, false);
|
||||
playlistControlBinding = headerBinding.playlistControl;
|
||||
|
||||
return headerBinding;
|
||||
return headerBinding::getRoot;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -413,7 +413,7 @@ public class PlaylistFragment extends BaseListInfoFragment<PlaylistInfo> {
|
||||
}
|
||||
|
||||
private Subscriber<List<PlaylistRemoteEntity>> getPlaylistBookmarkSubscriber() {
|
||||
return new Subscriber<List<PlaylistRemoteEntity>>() {
|
||||
return new Subscriber<>() {
|
||||
@Override
|
||||
public void onSubscribe(final Subscription s) {
|
||||
if (bookmarkReactor != null) {
|
||||
|
@ -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,14 +22,14 @@ 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;
|
||||
import io.reactivex.rxjava3.disposables.CompositeDisposable;
|
||||
|
||||
public class RelatedItemsFragment extends BaseListInfoFragment<RelatedItemInfo>
|
||||
implements SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
private static final String INFO_KEY = "related_info_key";
|
||||
private final CompositeDisposable disposables = new CompositeDisposable();
|
||||
|
||||
private RelatedItemInfo relatedItemInfo;
|
||||
|
||||
/*//////////////////////////////////////////////////////////////////////////
|
||||
@ -54,11 +52,6 @@ public class RelatedItemsFragment extends BaseListInfoFragment<RelatedItemInfo>
|
||||
// LifeCycle
|
||||
//////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
@Override
|
||||
public void onAttach(@NonNull final Context context) {
|
||||
super.onAttach(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(@NonNull final LayoutInflater inflater,
|
||||
@Nullable final ViewGroup container,
|
||||
@ -66,12 +59,6 @@ public class RelatedItemsFragment extends BaseListInfoFragment<RelatedItemInfo>
|
||||
return inflater.inflate(R.layout.fragment_related_items, container, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
disposables.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
headerBinding = null;
|
||||
@ -79,22 +66,23 @@ public class RelatedItemsFragment extends BaseListInfoFragment<RelatedItemInfo>
|
||||
}
|
||||
|
||||
@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<View> 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
|
||||
@ -128,7 +116,6 @@ public class RelatedItemsFragment extends BaseListInfoFragment<RelatedItemInfo>
|
||||
}
|
||||
ViewUtils.slideUp(requireView(), 120, 96, 0.06f);
|
||||
|
||||
disposables.clear();
|
||||
}
|
||||
|
||||
/*//////////////////////////////////////////////////////////////////////////
|
||||
@ -137,11 +124,13 @@ public class RelatedItemsFragment extends BaseListInfoFragment<RelatedItemInfo>
|
||||
|
||||
@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) {
|
||||
@ -169,11 +158,10 @@ public class RelatedItemsFragment extends BaseListInfoFragment<RelatedItemInfo>
|
||||
@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));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
@ -10,7 +11,7 @@ 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;
|
||||
import org.schabi.newpipe.extractor.comments.CommentsInfoItem;
|
||||
@ -34,6 +35,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,18 +76,20 @@ public class InfoListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
|
||||
private static final int MINI_COMMENT_HOLDER_TYPE = 0x400;
|
||||
private static final int COMMENT_HOLDER_TYPE = 0x401;
|
||||
|
||||
private final LayoutInflater layoutInflater;
|
||||
private final InfoItemBuilder infoItemBuilder;
|
||||
private final ArrayList<InfoItem> infoItemList;
|
||||
private final List<InfoItem> infoItemList;
|
||||
private final HistoryRecordManager recordManager;
|
||||
|
||||
private boolean useMiniVariant = false;
|
||||
private boolean useGridVariant = false;
|
||||
private boolean showFooter = false;
|
||||
private View header = null;
|
||||
private View footer = null;
|
||||
|
||||
private Supplier<View> 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 +133,12 @@ public class InfoListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "addInfoItemList() after > offsetStart = " + offsetStart + ", "
|
||||
+ "infoItemList.size() = " + infoItemList.size() + ", "
|
||||
+ "header = " + header + ", footer = " + footer + ", "
|
||||
+ "hasHeader = " + hasHeader() + ", "
|
||||
+ "showFooter = " + showFooter);
|
||||
}
|
||||
notifyItemRangeInserted(offsetStart, data.size());
|
||||
|
||||
if (footer != null && showFooter) {
|
||||
if (showFooter) {
|
||||
final int footerNow = sizeConsideringHeaderOffset();
|
||||
notifyItemMoved(offsetStart, footerNow);
|
||||
|
||||
@ -145,43 +149,6 @@ public class InfoListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
|
||||
}
|
||||
}
|
||||
|
||||
public void setInfoItemList(final List<? extends InfoItem> 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;
|
||||
@ -190,16 +157,16 @@ public class InfoListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void setHeader(final View header) {
|
||||
final boolean changed = header != this.header;
|
||||
this.header = header;
|
||||
public void setHeaderSupplier(@Nullable final Supplier<View> 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) {
|
||||
@ -219,48 +186,49 @@ public class InfoListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
|
||||
}
|
||||
|
||||
private int sizeConsideringHeaderOffset() {
|
||||
final int i = infoItemList.size() + (header != null ? 1 : 0);
|
||||
final int i = infoItemList.size() + (hasHeader() ? 1 : 0);
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "sizeConsideringHeaderOffset() called → " + i);
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
public ArrayList<InfoItem> getItemsList() {
|
||||
public List<InfoItem> getItemsList() {
|
||||
return infoItemList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
int count = infoItemList.size();
|
||||
if (header != null) {
|
||||
if (hasHeader()) {
|
||||
count++;
|
||||
}
|
||||
if (footer != null && showFooter) {
|
||||
if (showFooter) {
|
||||
count++;
|
||||
}
|
||||
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "getItemCount() called with: "
|
||||
+ "count = " + count + ", infoItemList.size() = " + infoItemList.size() + ", "
|
||||
+ "header = " + header + ", footer = " + footer + ", "
|
||||
+ "hasHeader = " + hasHeader() + ", "
|
||||
+ "showFooter = " + showFooter);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
@SuppressWarnings("FinalParameters")
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "getItemViewType() called with: position = [" + position + "]");
|
||||
}
|
||||
|
||||
if (header != null && position == 0) {
|
||||
if (hasHeader() && position == 0) {
|
||||
return HEADER_TYPE;
|
||||
} else if (header != null) {
|
||||
} else if (hasHeader()) {
|
||||
position--;
|
||||
}
|
||||
if (footer != null && position == infoItemList.size() && showFooter) {
|
||||
if (position == infoItemList.size() && showFooter) {
|
||||
return FOOTER_TYPE;
|
||||
}
|
||||
final InfoItem item = infoItemList.get(position);
|
||||
@ -290,10 +258,16 @@ public class InfoListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
|
||||
+ "parent = [" + parent + "], type = [" + type + "]");
|
||||
}
|
||||
switch (type) {
|
||||
// #4475 and #3368
|
||||
// Always create a new instance otherwise the same instance
|
||||
// is sometimes reused which causes a crash
|
||||
case HEADER_TYPE:
|
||||
return new HFHolder(header);
|
||||
return new HFHolder(headerSupplier.get());
|
||||
case FOOTER_TYPE:
|
||||
return new HFHolder(footer);
|
||||
return new HFHolder(PignateFooterBinding
|
||||
.inflate(layoutInflater, parent, false)
|
||||
.getRoot()
|
||||
);
|
||||
case MINI_STREAM_HOLDER_TYPE:
|
||||
return new StreamMiniInfoItemHolder(infoItemBuilder, parent);
|
||||
case STREAM_HOLDER_TYPE:
|
||||
@ -322,42 +296,17 @@ public class InfoListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder holder, int position) {
|
||||
public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder holder,
|
||||
final int position) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "onBindViewHolder() called with: "
|
||||
+ "holder = [" + holder.getClass().getSimpleName() + "], "
|
||||
+ "position = [" + position + "]");
|
||||
}
|
||||
if (holder instanceof InfoItemHolder) {
|
||||
// If header isn't null, offset the items by -1
|
||||
if (header != null) {
|
||||
position--;
|
||||
}
|
||||
|
||||
((InfoItemHolder) holder).updateFromItem(infoItemList.get(position), recordManager);
|
||||
} else if (holder instanceof HFHolder && position == 0 && header != null) {
|
||||
((HFHolder) holder).view = header;
|
||||
} else if (holder instanceof HFHolder && position == sizeConsideringHeaderOffset()
|
||||
&& footer != null && showFooter) {
|
||||
((HFHolder) holder).view = footer;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder holder, final int position,
|
||||
@NonNull final List<Object> 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 {
|
||||
onBindViewHolder(holder, position);
|
||||
((InfoItemHolder) holder).updateFromItem(
|
||||
// If header is present, offset the items by -1
|
||||
infoItemList.get(hasHeader() ? position - 1 : position), recordManager);
|
||||
}
|
||||
}
|
||||
|
||||
@ -371,12 +320,9 @@ public class InfoListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
|
||||
};
|
||||
}
|
||||
|
||||
public static class HFHolder extends RecyclerView.ViewHolder {
|
||||
public View view;
|
||||
|
||||
static class HFHolder extends RecyclerView.ViewHolder {
|
||||
HFHolder(final View v) {
|
||||
super(v);
|
||||
view = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
});
|
||||
}
|
||||
|
||||
@ -593,8 +599,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 +612,7 @@ public final class Player implements
|
||||
animate(binding.fastSeekOverlay, false, SEEK_OVERLAY_DURATION);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public FastSeekDirection getFastSeekDirection(
|
||||
@NonNull final DisplayPortion portion
|
||||
|
@ -329,7 +329,7 @@
|
||||
\nتوضح سياسة خصوصية NewPipe بالتفصيل البيانات التي يتم إرسالها وتخزينها عند إرسال تقرير الأعطال.</string>
|
||||
<string name="read_privacy_policy">الإطلاع على سياسة الخصوصية</string>
|
||||
<string name="start_accept_privacy_policy">من أجل الامتثال للائحة الأوروبية العامة لحماية البيانات (GDPR)، فإننا نلفت انتباهك إلى سياسة خصوصية NewPipe. يرجى قراءتها بعناية.
|
||||
\nو يجب عليك قبولها لإرسال تقرير الأخطاء إلينا.</string>
|
||||
\nويجب عليك قبولها لإرسال تقرير الأخطاء إلينا.</string>
|
||||
<string name="accept">قبول</string>
|
||||
<string name="decline">رفض</string>
|
||||
<string name="limit_data_usage_none_description">لا حدود</string>
|
||||
@ -637,7 +637,7 @@
|
||||
<string name="georestricted_content">هذا المحتوى غير متوفر في بلدك.</string>
|
||||
<string name="crash_the_app">اغلق التطبيق قسريا</string>
|
||||
<string name="restricted_video_no_stream">هذا الفيديو مقيد بالفئة العمرية.
|
||||
\nنظرا لسياسات YouTube الجديدة المتعلقة بمقاطع الفيديو المقيدة بالفئة العمرية، لا يمكن لـNewPipe الوصول إلى أي من مقاطع الفيديو الخاصة بها وبالتالي لا يمكن تشغيلها.</string>
|
||||
\nنظرًا لسياسات YouTube الجديدة المتعلقة بمقاطع الفيديو المقيدة بالفئة العمرية، لا يمكن لـNewPipe الوصول إلى أي من مقاطع الفيديو الخاصة بها وبالتالي لا يمكن تشغيلها.</string>
|
||||
<string name="radio">إذاعة</string>
|
||||
<string name="featured">المميزة</string>
|
||||
<string name="recaptcha_solve">حل</string>
|
||||
@ -688,7 +688,7 @@
|
||||
<string name="high_quality_larger">جودة عالية (أكبر)</string>
|
||||
<string name="seekbar_preview_thumbnail_title">معاينة مصغرة على شريط التمرير</string>
|
||||
<string name="mark_as_watched">علّمه كفيديو تمت مشاهدته</string>
|
||||
<string name="detail_heart_img_view_description">أعجب بها منشئ المحتوى</string>
|
||||
<string name="detail_heart_img_view_description">أُعجب بها منشئ المحتوى</string>
|
||||
<string name="loading_channel_details">جاري تحميل تفاصيل القناة…</string>
|
||||
<string name="error_show_channel_details">خطأ في عرض تفاصيل القناة</string>
|
||||
<string name="show_image_indicators_summary">أظهر أشرطة ملونة لبيكاسو أعلى الصور تشير إلى مصدرها: الأحمر للشبكة والأزرق للقرص والأخضر للذاكرة</string>
|
||||
|
@ -215,7 +215,7 @@
|
||||
<string name="playback_speed_control">Controls de la velocitat de reproducció</string>
|
||||
<string name="playback_tempo">Tempo</string>
|
||||
<string name="playback_pitch">To</string>
|
||||
<string name="main_bg_subtitle">Toca la lupa per començar.</string>
|
||||
<string name="main_bg_subtitle">Toca \"Cerca\" per començar.</string>
|
||||
<string name="use_external_video_player_summary">Elimina l\'àudio en algunes resolucions</string>
|
||||
<string name="use_external_audio_player_title">Reproductor d\'àudio extern</string>
|
||||
<string name="download_thumbnail_summary">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</string>
|
||||
@ -685,7 +685,7 @@
|
||||
<string name="feed_new_items">Elements de feed nous</string>
|
||||
<string name="feed_load_error_fast_unknown">El mode d\'alimentació ràpida no proporciona més informació sobre això.</string>
|
||||
<string name="detail_pinned_comment_view_description">Comentari fixat</string>
|
||||
<string name="show_crash_the_player_title">Mostrar \"tancar de forma violenta el reproductor\"</string>
|
||||
<string name="show_crash_the_player_title">Mostra \"Força el tancament del reproductor\"</string>
|
||||
<string name="show_crash_the_player_summary">Mostra una opció de fallada quan s\'utilitza el reproductor</string>
|
||||
<string name="show_image_indicators_summary">Mostra les cintes de color Picasso a la part superior de les imatges que indiquen la seva font: vermell per a la xarxa, blau per al disc i verd per a la memòria</string>
|
||||
<string name="leak_canary_not_available">El LeakCanary no està disponible</string>
|
||||
|
@ -71,7 +71,7 @@
|
||||
<string name="title_activity_history">Ιστορικό</string>
|
||||
<string name="action_history">Ιστορικό</string>
|
||||
<string name="show_info">Εμφάνιση πληροφοριών</string>
|
||||
<string name="main_bg_subtitle">Πατήστε το μεγενθυτικό φακό για να ξεκινήσετε.</string>
|
||||
<string name="main_bg_subtitle">Πατήστε το μεγεθυντικό φακό για να ξεκινήσετε.</string>
|
||||
<string name="no_player_found_toast">Δε βρέθηκε πρόγραμμα αναπαραγωγής ροής δεδομένων (μπορείτε να εγκαταστήσετε το VLC για να κάνετε αναπαραγωγή).</string>
|
||||
<string name="controls_download_desc">Λήψη του αρχείου ροής</string>
|
||||
<string name="use_external_video_player_summary">Αφαιρείται ο ήχος από κάποιες αναλύσεις</string>
|
||||
|
@ -52,7 +52,7 @@
|
||||
<string name="duration_live">En direct</string>
|
||||
<string name="could_not_load_thumbnails">Impossible de charger toutes les miniatures</string>
|
||||
<string name="youtube_signature_deobfuscation_error">Impossible de déchiffrer la signature URL de la vidéo</string>
|
||||
<string name="sorry_string">Désolé, cela n\'aurait pas dû se produire.</string>
|
||||
<string name="sorry_string">Désolé, cela n’aurait pas dû se produire.</string>
|
||||
<string name="error_report_button_text">Signaler cette erreur par courriel</string>
|
||||
<string name="what_device_headline">Information :</string>
|
||||
<string name="what_happened_headline">Ce qui s’est passé :</string>
|
||||
@ -73,7 +73,7 @@
|
||||
<string name="checksum">Somme de contrôle</string>
|
||||
<string name="ok">OK</string>
|
||||
<string name="msg_name">Nom du fichier</string>
|
||||
<string name="msg_threads">Nombre de connexions simultanées</string>
|
||||
<string name="msg_threads">Connexions simultanées</string>
|
||||
<string name="msg_error">Erreur</string>
|
||||
<string name="msg_running">NewPipe télécharge</string>
|
||||
<string name="msg_running_detail">Appuyer pour plus de détails</string>
|
||||
@ -668,8 +668,8 @@
|
||||
<string name="main_page_content_swipe_remove">Balayez un élément pour le supprimer</string>
|
||||
<string name="start_main_player_fullscreen_summary">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</string>
|
||||
<string name="start_main_player_fullscreen_title">Lancer le lecteur principal en plein écran</string>
|
||||
<string name="enqueue_next_stream">Mettre en file d’attente la suivante</string>
|
||||
<string name="enqueued_next">Placé comme suivant dans liste de lecture</string>
|
||||
<string name="enqueue_next_stream">Ajouter à la liste de lecture</string>
|
||||
<string name="enqueued_next">Suivant dans la liste de lecture</string>
|
||||
<string name="processing_may_take_a_moment">Traitement en cours… Veuillez patienter</string>
|
||||
<string name="manual_update_description">Vérifier manuellement de nouvelles versions</string>
|
||||
<string name="checking_updates_toast">Vérification des mises à jour…</string>
|
||||
@ -685,7 +685,7 @@
|
||||
<string name="create_error_notification">Créer une notification d\'erreur</string>
|
||||
<string name="no_appropriate_file_manager_message_android_10">Aucun gestionnaire de fichiers approprié n\'a été trouvé pour cette action.
|
||||
\nVeuillez installer un gestionnaire de fichiers compatible avec l\'Infrastructure d\'accès au stockage.</string>
|
||||
<string name="show_error_snackbar">Afficher une barre d\'erreur</string>
|
||||
<string name="show_error_snackbar">Afficher une barre d’erreur</string>
|
||||
<string name="no_appropriate_file_manager_message">Aucun gestionnaire de fichier approprié n\'a été trouvé pour cette action.
|
||||
\nVeuillez installer un gestionnaire de fichiers ou essayez de désactiver \'%s\' dans les paramètres de téléchargement.</string>
|
||||
<string name="detail_pinned_comment_view_description">Commentaire épinglé</string>
|
||||
|
@ -661,7 +661,7 @@
|
||||
<string name="manual_update_description">Periksa manual untuk versi baru</string>
|
||||
<string name="checking_updates_toast">Memeriksa pembaruan…</string>
|
||||
<string name="feed_new_items">Item feed baru</string>
|
||||
<string name="show_crash_the_player_title">Tampilkan \"hentikan pemain video\"</string>
|
||||
<string name="show_crash_the_player_title">Tampilkan \"Mogokkan pemutar\"</string>
|
||||
<string name="show_crash_the_player_summary">Menampilkan opsi penghentian ketika menggunakan pemain video</string>
|
||||
<string name="crash_the_player">Hentikan pemain video</string>
|
||||
<string name="error_report_channel_description">Notifikasi untuk melaporkan kegalatan</string>
|
||||
|
@ -316,7 +316,7 @@
|
||||
<string name="search_history_deleted">Usunięto historię wyszukiwania</string>
|
||||
<string name="one_item_deleted">Usunięto jedną pozycję.</string>
|
||||
<string name="toast_no_player">Brak zainstalowanej aplikacji do odtworzenia tego pliku</string>
|
||||
<string name="app_license">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ą.</string>
|
||||
<string name="app_license">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.</string>
|
||||
<string name="import_settings">Czy chcesz zaimportować również ustawienia?</string>
|
||||
<string name="privacy_policy_title">Polityka prywatności NewPipe</string>
|
||||
<string name="privacy_policy_encouragement">Projekt NewPipe bardzo poważnie traktuje Twoją prywatność, dlatego aplikacja nie gromadzi żadnych danych bez Twojej zgody.
|
||||
@ -377,11 +377,11 @@
|
||||
<string name="overwrite_finished_warning">Pobrany plik o tej nazwie już istnieje</string>
|
||||
<string name="download_already_running">Trwa już pobieranie pliku o tej samej nazwie</string>
|
||||
<string name="show_error">Pokaż błąd</string>
|
||||
<string name="error_file_creation">Nie można utworzyć pliku</string>
|
||||
<string name="error_path_creation">Nie można utworzyć folderu docelowego</string>
|
||||
<string name="error_file_creation">Nie udało się utworzyć pliku</string>
|
||||
<string name="error_path_creation">Nie udało się utworzyć folderu docelowego</string>
|
||||
<string name="error_ssl_exception">Nie udało się nawiązać bezpiecznego połączenia</string>
|
||||
<string name="error_unknown_host">Nie udało się znaleźć serwera</string>
|
||||
<string name="error_connect_host">Nie można połączyć się z serwerem</string>
|
||||
<string name="error_connect_host">Nie udało się połączyć z serwerem</string>
|
||||
<string name="error_http_no_content">Serwer nie wysyła danych</string>
|
||||
<string name="error_http_unsupported_range">Serwer nie akceptuje pobierania wielowątkowego, spróbuj ponownie za pomocą @string/msg_threads = 1</string>
|
||||
<string name="error_http_not_found">Nie znaleziono</string>
|
||||
@ -408,7 +408,7 @@
|
||||
<string name="watch_history_states_deleted">Usunięto pozycje odtwarzania</string>
|
||||
<string name="missing_file">Plik usunięty albo przeniesiony</string>
|
||||
<string name="overwrite_unrelated_warning">Plik z tą nazwą już istnieje</string>
|
||||
<string name="overwrite_failed">nie można nadpisać pliku</string>
|
||||
<string name="overwrite_failed">Nie udało się nadpisać pliku</string>
|
||||
<string name="download_already_pending">Plik o tej samej nazwie oczekuje na pobranie</string>
|
||||
<string name="error_postprocessing_stopped">NewPipe został zamknięty podczas pracy nad plikiem</string>
|
||||
<string name="error_insufficient_storage">Brak miejsca na urządzeniu</string>
|
||||
@ -457,7 +457,7 @@
|
||||
<string name="most_liked">Najbardziej lubiane</string>
|
||||
<string name="playlist_no_uploader">Wygenerowana automatycznie (nie znaleziono przesyłającego)</string>
|
||||
<string name="recovering">odzyskiwanie</string>
|
||||
<string name="error_download_resource_gone">Nie można odzyskać tego pobrania</string>
|
||||
<string name="error_download_resource_gone">Nie udało się odzyskać tego pobrania</string>
|
||||
<string name="choose_instance_prompt">Wybierz serwer</string>
|
||||
<string name="clear_download_history">Wyczyść historię pobierania</string>
|
||||
<string name="delete_downloaded_files">Usuń pobrane pliki</string>
|
||||
@ -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 @@
|
||||
<string name="metadata_tags">Tagi</string>
|
||||
<string name="metadata_category">Kategoria</string>
|
||||
<string name="open_website_license">Otwórz stronę</string>
|
||||
<string name="description_select_note">Teraz możesz zaznaczyć tekst wewnątrz opisu. Pamiętaj, że strona może migotać, a łącza mogą nie być klikalne w trybie zaznaczania.</string>
|
||||
<string name="description_select_note">Teraz możesz zaznaczyć tekst wewnątrz opisu. Pamiętaj, że w trybie zaznaczania strona może migotać i linki nie będą klikalne.</string>
|
||||
<string name="service_provides_reason">%s podaje ten powód:</string>
|
||||
<string name="account_terminated">Konto zamknięte</string>
|
||||
<string name="feed_load_error_fast_unknown">Tryb szybki dla ładowania kanału nie dostarcza więcej informacji na ten temat.</string>
|
||||
|
@ -410,7 +410,7 @@
|
||||
<string name="error_timeout">Tempo limite de conexão</string>
|
||||
<string name="confirm_prompt">Excluir todo o histórico de downloads ou excluir todos os arquivos baixados\?</string>
|
||||
<string name="enable_queue_limit">Limitar fila de downloads</string>
|
||||
<string name="enable_queue_limit_desc">Um download será feito por vez</string>
|
||||
<string name="enable_queue_limit_desc">Faz downloads um de cada vez</string>
|
||||
<string name="start_downloads">Iniciar downloads</string>
|
||||
<string name="pause_downloads">Pausar downloads</string>
|
||||
<string name="downloads_storage_ask_title">Perguntar onde salvar o arquivo</string>
|
||||
|
@ -323,7 +323,7 @@
|
||||
<string name="skip_silence_checkbox">Snabbspola vid frånvaro av ljud</string>
|
||||
<string name="playback_step">Steg</string>
|
||||
<string name="playback_reset">Återställ</string>
|
||||
<string name="start_accept_privacy_policy">För att uppfylla den Europeiska dataskyddsförordningen (GDPR) uppmärksammar vi er härmed på NewPipes sekretesspolicy. Var god läs den noggrant.
|
||||
<string name="start_accept_privacy_policy">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.</string>
|
||||
<string name="accept">Acceptera</string>
|
||||
<string name="decline">Avböj</string>
|
||||
@ -673,7 +673,7 @@
|
||||
<string name="manual_update_description">Kolla manuellt efter nya versioner</string>
|
||||
<string name="checking_updates_toast">Söker efter uppdateringar…</string>
|
||||
<string name="feed_new_items">Nya flödes objekt</string>
|
||||
<string name="show_crash_the_player_title">Visa \"krascha spelaren\"</string>
|
||||
<string name="show_crash_the_player_title">Visa \"Krascha spelaren\"</string>
|
||||
<string name="crash_the_player">Krascha spelaren</string>
|
||||
<string name="show_crash_the_player_summary">Visar ett kraschalternativ vid användning av spelaren</string>
|
||||
<string name="error_report_channel_name">Felrapport-avisering</string>
|
||||
|
@ -312,7 +312,7 @@
|
||||
<string name="privacy_policy_encouragement">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.</string>
|
||||
<string name="read_privacy_policy">Gizlilik ilkesini oku</string>
|
||||
<string name="start_accept_privacy_policy">Avrupa Genel Veri Koruma Yönetmeliğine (GDPR) uymak için, dikkatinizi NewPipe\'ın gizlilik ilkesine çekiyoruz. Lütfen dikkatlice okuyun.
|
||||
<string name="start_accept_privacy_policy">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.</string>
|
||||
<string name="accept">Kabul et</string>
|
||||
<string name="decline">Reddet</string>
|
||||
|
@ -29,7 +29,7 @@
|
||||
<string name="content_language_title">內容預設語言</string>
|
||||
<string name="settings_category_video_audio_title">影音</string>
|
||||
<string name="settings_category_appearance_title">外觀</string>
|
||||
<string name="background_player_playing_toast">背景播放</string>
|
||||
<string name="background_player_playing_toast">幕後播緊</string>
|
||||
<string name="network_error">網絡問題</string>
|
||||
<string name="detail_thumbnail_view_description">播放影片,片長:</string>
|
||||
<string name="detail_uploader_thumbnail_view_description">上載者嘅頭像縮圖</string>
|
||||
@ -95,8 +95,8 @@
|
||||
<string name="msg_popup_permission">畫中畫模式需要此權限</string>
|
||||
<string name="recaptcha_request_toast">需完成 reCAPTCHA 挑戰</string>
|
||||
<string name="use_external_video_player_summary">某啲解像度可能會冇聲</string>
|
||||
<string name="controls_background_title">背景播放</string>
|
||||
<string name="controls_popup_title">畫中畫播放</string>
|
||||
<string name="controls_background_title">幕後播</string>
|
||||
<string name="controls_popup_title">浮面播</string>
|
||||
<string name="popup_remember_size_pos_title">記住畫中畫大小及位置</string>
|
||||
<string name="popup_remember_size_pos_summary">記住最近設定的畫中畫大小及位置</string>
|
||||
<string name="show_search_suggestions_title">搜尋建議</string>
|
||||
@ -126,7 +126,7 @@
|
||||
<string name="subscription_change_failed">轉唔到訂閱</string>
|
||||
<string name="subscription_update_failed">更新唔到訂閱</string>
|
||||
<string name="show_info">顯示資訊</string>
|
||||
<string name="tab_subscriptions">訂閱項目</string>
|
||||
<string name="tab_subscriptions">訂閱</string>
|
||||
<string name="tab_bookmarks">已收藏播放清單</string>
|
||||
<string name="use_inexact_seek_title">用粗略快轉</string>
|
||||
<string name="controls_add_to_playlist_title">加入去</string>
|
||||
@ -259,7 +259,7 @@
|
||||
\n您係咪要繼續?</string>
|
||||
<string name="never">幾時都唔使</string>
|
||||
<string name="auto">自動</string>
|
||||
<string name="low_quality_smaller">低畫質 (較細)</string>
|
||||
<string name="low_quality_smaller">低畫質 (細格啲)</string>
|
||||
<string name="dont_show">唔顯示</string>
|
||||
<string name="app_update_notification_content_text">撳一下去下載</string>
|
||||
<string name="no_views">無觀看次數</string>
|
||||
@ -309,7 +309,7 @@
|
||||
<string name="no_videos">無影片</string>
|
||||
<string name="video_player">影片播放器</string>
|
||||
<string name="wifi_only">僅限用 Wi-Fi 嘅時候</string>
|
||||
<string name="high_quality_larger">高畫質 (較大)</string>
|
||||
<string name="high_quality_larger">高畫質 (大格啲)</string>
|
||||
<string name="no_subscribers">無訂閱者</string>
|
||||
<plurals name="subscribers">
|
||||
<item quantity="other">%s 位訂閱者</item>
|
||||
@ -334,7 +334,7 @@
|
||||
<string name="title_most_played">最常播放</string>
|
||||
<string name="main_page_content">頭版內容</string>
|
||||
<string name="main_page_content_summary">頭版要擺放邊啲分頁</string>
|
||||
<string name="main_page_content_swipe_remove">滑走啲項目去剷走佢</string>
|
||||
<string name="main_page_content_swipe_remove">打橫掃走啲項目去剷走佢</string>
|
||||
<string name="blank_page_summary">空白頁</string>
|
||||
<string name="localization_changes_requires_app_restart">重新開過個 app 之後就會轉新語言</string>
|
||||
<string name="trending">時興</string>
|
||||
@ -422,4 +422,113 @@
|
||||
<string name="error_report_notification_toast">發生問題,詳見通知</string>
|
||||
<string name="detail_drag_description">拖拉執排位</string>
|
||||
<string name="drawer_header_description">轉換服務,而家揀選咗嘅係:</string>
|
||||
<string name="list_view_mode">清單檢視模式</string>
|
||||
<string name="error_progress_lost">做噉一半冇咗,因為個檔案刪除咗</string>
|
||||
<string name="error_timeout">連線等太耐</string>
|
||||
<string name="start_downloads">開始晒所有下載</string>
|
||||
<string name="enable_queue_limit_desc">下載排隊逐個嚟,唔要一次過</string>
|
||||
<string name="recent">近期</string>
|
||||
<string name="account_terminated">帳戶已被終止</string>
|
||||
<string name="metadata_language">語言</string>
|
||||
<string name="metadata_support">支援</string>
|
||||
<string name="overwrite_failed">覆寫唔到個檔案</string>
|
||||
<string name="pause_downloads">暫停晒所有下載</string>
|
||||
<string name="on">開</string>
|
||||
<string name="tablet_mode_title">平板電腦模式</string>
|
||||
<string name="error_file_creation">個檔案建立唔到</string>
|
||||
<string name="delete_item_search_history">您係咪想喺搜尋紀錄度刪除呢個項目?</string>
|
||||
<string name="show_error">睇下咩問題</string>
|
||||
<string name="download_already_running">有個整緊嘅下載撞名</string>
|
||||
<string name="download_already_pending">有個等緊嘅下載撞名</string>
|
||||
<string name="max_retry_desc">試盡幾多次就取消個下載算數</string>
|
||||
<string name="show_thumbnail_summary">喺鎖定畫面背景同埋通知都擺放縮圖</string>
|
||||
<string name="download_has_started">開始咗下載</string>
|
||||
<string name="metadata_age_limit">年齡限制</string>
|
||||
<string name="no_app_to_open_intent">您部機冇 app 開到佢</string>
|
||||
<string name="youtube_music_premium_content">呢部影片係 YouTube Music Premium 會員限定,因此 NewPipe 未能串流或下載。</string>
|
||||
<string name="night_theme_summary">揀選啱您心水嘅夜色主題 — %s</string>
|
||||
<string name="paid_content">呢部內容係付費使用者限定,因此 NewPipe 未能串流或下載。</string>
|
||||
<string name="select_night_theme_toast">您可以喺下面揀選啱您心水嘅夜色主題</string>
|
||||
<string name="description_select_disable">停用揀選描述入面嘅文字</string>
|
||||
<string name="grid">一格格</string>
|
||||
<string name="list">一行行</string>
|
||||
<string name="add_to_playlist">加入去播放清單</string>
|
||||
<string name="create_playlist">新嘅播放清單</string>
|
||||
<string name="show_channel_details">顯示頻道詳情</string>
|
||||
<string name="error_http_not_found">唔見影</string>
|
||||
<string name="select_a_playlist">揀選一個播放清單</string>
|
||||
<string name="error_http_unsupported_range">伺服器唔接受多執行緒下載,請改用 @string/msg_threads = 1 再試下啦</string>
|
||||
<string name="error_connect_host">連接唔到伺服器</string>
|
||||
<string name="playlist_page_summary">播放清單頁面</string>
|
||||
<string name="loading_channel_details">載入緊頻道詳情…</string>
|
||||
<string name="hold_to_append">撳住就輪候</string>
|
||||
<string name="error_path_creation">目的地資料夾建立唔到</string>
|
||||
<string name="error_ssl_exception">建立唔到安全連線</string>
|
||||
<string name="start_here_on_background">喺幕後開始播放</string>
|
||||
<string name="error_insufficient_storage">部機冇晒位</string>
|
||||
<string name="max_retry_msg">頂櫳重試幾多次</string>
|
||||
<string name="pause_downloads_on_mobile_desc">若然有機會用到流動數據嘅時候,或者用得著,雖則有啲下載或者冇得暫停</string>
|
||||
<string name="enable_queue_limit">輪住下載</string>
|
||||
<string name="metadata_privacy_internal">內部</string>
|
||||
<string name="metadata_privacy_private">私人</string>
|
||||
<string name="stop">停止</string>
|
||||
<string name="pause_downloads_on_mobile">按用量收費嘅網絡就閘住</string>
|
||||
<string name="clear_download_history">抹走下載紀錄</string>
|
||||
<string name="confirm_prompt">您想抹走您嘅下載紀錄,定係想剷走晒所有下載咗嘅檔案?</string>
|
||||
<string name="delete_downloaded_files">剷走下載咗嘅檔案</string>
|
||||
<plurals name="deleted_downloads_toast">
|
||||
<item quantity="other">刪除咗 %1$s 個下載</item>
|
||||
</plurals>
|
||||
<string name="downloads_storage_ask_title">問我要下載去邊</string>
|
||||
<string name="enqueue">排隊尾</string>
|
||||
<string name="error_unknown_host">搵唔到伺服器</string>
|
||||
<string name="error_http_no_content">伺服器冇傳回資料</string>
|
||||
<string name="error_postprocessing_failed">後期處理失敗</string>
|
||||
<string name="error_postprocessing_stopped">NewPipe 未搞掂個檔案就關閉咗</string>
|
||||
<string name="error_download_resource_gone">呢個下載恢復唔到</string>
|
||||
<string name="overwrite_finished_warning">同個下載咗嘅檔案撞名</string>
|
||||
<string name="overwrite_unrelated_warning">同個現有嘅檔案撞名</string>
|
||||
<plurals name="feed_group_dialog_selection_count">
|
||||
<item quantity="other">揀選咗 %d 個</item>
|
||||
</plurals>
|
||||
<string name="feed_group_dialog_select_subscriptions">揀選訂閱</string>
|
||||
<string name="feed_group_dialog_empty_selection">未有揀選訂閱</string>
|
||||
<string name="show_thumbnail_title">顯示縮圖</string>
|
||||
<string name="detail_sub_channel_thumbnail_view_description">頻道嘅頭像縮圖</string>
|
||||
<string name="channel_created_by">由 %s 建立</string>
|
||||
<string name="video_detail_by">出自 %s</string>
|
||||
<string name="chapters">章節</string>
|
||||
<string name="content_not_supported">呢部內容 NewPipe 仲未支援。
|
||||
\n
|
||||
\n希望未來會喺日後嘅版本支援啦。</string>
|
||||
<string name="feed_toggle_show_played_items">顯示睇過嘅項目</string>
|
||||
<string name="service_provides_reason">%s 話理由如下:</string>
|
||||
<string name="no_appropriate_file_manager_message">搵唔到合適嘅檔案總管進行呢個動作。
|
||||
\n請安裝一個檔案管理程式,又或者試下喺下載設定度停用「%s」。</string>
|
||||
<string name="no_appropriate_file_manager_message_android_10">搵唔到合適嘅檔案總管進行呢個動作。
|
||||
\n請安裝一個與儲存空間存取框架兼容嘅檔案管理程式。</string>
|
||||
<string name="georestricted_content">呢部內容限區,喺您所在國家未有提供。</string>
|
||||
<string name="soundcloud_go_plus_content">呢首 (至少喺您所在國家而言) 係 SoundCloud Go+ 單曲,因此 NewPipe 未能串流或下載。</string>
|
||||
<string name="private_content">呢部內容屬於私人,因此 NewPipe 未能串流或下載。</string>
|
||||
<string name="auto_device_theme_title">自動 (跟返部機嘅主題色系)</string>
|
||||
<string name="featured">精選</string>
|
||||
<string name="radio">廣播</string>
|
||||
<string name="description_select_note">您而家可以揀選喺描述入面嘅文字喇。不過要單聲,喺揀選模式嘅時候,個頁面可能眨眨下,同埋啲連結會撳唔到。</string>
|
||||
<string name="description_select_enable">啟用揀選描述入面嘅文字</string>
|
||||
<string name="metadata_licence">版權協議</string>
|
||||
<string name="metadata_category">分類</string>
|
||||
<string name="metadata_tags">標籤</string>
|
||||
<string name="metadata_privacy">公開設定</string>
|
||||
<string name="metadata_thumbnail_url">縮圖 URL</string>
|
||||
<string name="metadata_privacy_public">公開</string>
|
||||
<string name="metadata_privacy_unlisted">憑網址瀏覽</string>
|
||||
<string name="detail_pinned_comment_view_description">置頂留言</string>
|
||||
<string name="detail_heart_img_view_description">創作者畀咗心心</string>
|
||||
<string name="open_website_license">開啟網站</string>
|
||||
<string name="off">關</string>
|
||||
<string name="error_show_channel_details">顯示頻道詳情嘅時候有問題</string>
|
||||
<string name="metadata_host">主機</string>
|
||||
<string name="show_hold_to_append_summary">喺影片「詳情:」度撳一下「幕後播」或者「浮面播」個掣嘅時候顯示提示</string>
|
||||
<string name="title_activity_history">紀錄</string>
|
||||
<string name="action_history">紀錄</string>
|
||||
</resources>
|
@ -150,7 +150,8 @@
|
||||
<string name="youtube_restricted_mode_enabled_title">Turn on YouTube\'s \"Restricted Mode\"</string>
|
||||
<string name="youtube_restricted_mode_enabled_summary">YouTube provides a \"Restricted Mode\" which hides potentially mature content</string>
|
||||
<string name="restricted_video">This video is age restricted.\n\nTurn on \"%1$s\" in the settings if you want to see it.</string>
|
||||
<string name="restricted_video_no_stream">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.</string>
|
||||
<string name="restricted_video_no_stream">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.</string>
|
||||
<string name="duration_live">Live</string>
|
||||
<string name="downloads">Downloads</string>
|
||||
<string name="downloads_title">Downloads</string>
|
||||
@ -488,7 +489,8 @@
|
||||
<string name="playback_step">Step</string>
|
||||
<string name="playback_reset">Reset</string>
|
||||
<!-- GDPR dialog -->
|
||||
<string name="start_accept_privacy_policy">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.</string>
|
||||
<string name="start_accept_privacy_policy">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.</string>
|
||||
<string name="accept">Accept</string>
|
||||
<string name="decline">Decline</string>
|
||||
<!-- Limit mobile data usage -->
|
||||
@ -557,11 +559,11 @@
|
||||
<string name="download_already_pending">There is a pending download with this name</string>
|
||||
<!-- message dialog about download error -->
|
||||
<string name="show_error">Show error</string>
|
||||
<string name="error_file_creation">The file can not be created</string>
|
||||
<string name="error_path_creation">The destination folder can not be created</string>
|
||||
<string name="error_file_creation">The file cannot be created</string>
|
||||
<string name="error_path_creation">The destination folder cannot be created</string>
|
||||
<string name="error_ssl_exception">Could not establish a secure connection</string>
|
||||
<string name="error_unknown_host">Could not find the server</string>
|
||||
<string name="error_connect_host">Can not connect to the server</string>
|
||||
<string name="error_connect_host">Cannot connect to the server</string>
|
||||
<string name="error_http_no_content">The server does not send data</string>
|
||||
<string name="error_http_unsupported_range">The server does not accept multi-threaded downloads, retry with @string/msg_threads = 1</string>
|
||||
<string name="error_http_not_found">Not found</string>
|
||||
@ -600,7 +602,8 @@
|
||||
<string name="systems_language">System default</string>
|
||||
<string name="remove_watched">Remove watched</string>
|
||||
<string name="remove_watched_popup_title">Remove watched videos?</string>
|
||||
<string name="remove_watched_popup_warning">Videos that have been watched before and after being added to the playlist will be removed.\nAre you sure? This cannot be undone!</string>
|
||||
<string name="remove_watched_popup_warning">Videos that have been watched before and after being added to the playlist will be removed.
|
||||
\nAre you sure\? This cannot be undone!</string>
|
||||
<string name="remove_watched_popup_yes_and_partially_watched_videos">Yes, and partially watched videos</string>
|
||||
<string name="new_seek_duration_toast">Due to ExoPlayer constraints the seek duration was set to %d seconds</string>
|
||||
<!-- Time duration plurals -->
|
||||
@ -650,7 +653,17 @@
|
||||
<string name="feed_use_dedicated_fetch_method_summary">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)</string>
|
||||
<string name="feed_use_dedicated_fetch_method_enable_button">Enable fast mode</string>
|
||||
<string name="feed_use_dedicated_fetch_method_disable_button">Disable fast mode</string>
|
||||
<string name="feed_use_dedicated_fetch_method_help_text">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.</string>
|
||||
<string name="feed_use_dedicated_fetch_method_help_text">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.</string>
|
||||
<string name="feed_toggle_show_played_items">Show watched items</string>
|
||||
<string name="content_not_supported">This content is not yet supported by NewPipe.\n\nIt will hopefully be supported in a future version.</string>
|
||||
<string name="detail_sub_channel_thumbnail_view_description">Channel\'s avatar thumbnail</string>
|
||||
|
@ -7,10 +7,6 @@
|
||||
files="LocalItemListAdapter.java"
|
||||
lines="232,304"/>
|
||||
|
||||
<suppress checks="FinalParameters"
|
||||
files="InfoListAdapter.java"
|
||||
lines="253,325"/>
|
||||
|
||||
<suppress checks="FinalParameters"
|
||||
files="ListHelper.java"
|
||||
lines="280,312"/>
|
||||
|
8
fastlane/metadata/android/az/changelogs/63.txt
Normal file
8
fastlane/metadata/android/az/changelogs/63.txt
Normal file
@ -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
|
7
fastlane/metadata/android/az/changelogs/64.txt
Normal file
7
fastlane/metadata/android/az/changelogs/64.txt
Normal file
@ -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
|
1
fastlane/metadata/android/az/changelogs/65.txt
Normal file
1
fastlane/metadata/android/az/changelogs/65.txt
Normal file
@ -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.
|
1
fastlane/metadata/android/az/changelogs/66.txt
Normal file
1
fastlane/metadata/android/az/changelogs/66.txt
Normal file
@ -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.
|
2
fastlane/metadata/android/de/changelogs/730.txt
Normal file
2
fastlane/metadata/android/de/changelogs/730.txt
Normal file
@ -0,0 +1,2 @@
|
||||
# Behoden
|
||||
- erneuter Hotfix des Entschlüsselungsfunktionsfehlers.
|
14
fastlane/metadata/android/de/changelogs/900.txt
Normal file
14
fastlane/metadata/android/de/changelogs/900.txt
Normal file
@ -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, ...
|
1
fastlane/metadata/android/de/changelogs/963.txt
Normal file
1
fastlane/metadata/android/de/changelogs/963.txt
Normal file
@ -0,0 +1 @@
|
||||
• [YouTube] Fortsetzung des Kanals korrigiert
|
6
fastlane/metadata/android/de/changelogs/965.txt
Normal file
6
fastlane/metadata/android/de/changelogs/965.txt
Normal file
@ -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.
|
4
fastlane/metadata/android/de/changelogs/973.txt
Normal file
4
fastlane/metadata/android/de/changelogs/973.txt
Normal file
@ -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
|
5
fastlane/metadata/android/de/changelogs/974.txt
Normal file
5
fastlane/metadata/android/de/changelogs/974.txt
Normal file
@ -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
|
2
fastlane/metadata/android/de/changelogs/979.txt
Normal file
2
fastlane/metadata/android/de/changelogs/979.txt
Normal file
@ -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
|
13
fastlane/metadata/android/de/changelogs/980.txt
Normal file
13
fastlane/metadata/android/de/changelogs/980.txt
Normal file
@ -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
|
2
fastlane/metadata/android/de/changelogs/981.txt
Normal file
2
fastlane/metadata/android/de/changelogs/981.txt
Normal file
@ -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.
|
1
fastlane/metadata/android/de/changelogs/982.txt
Normal file
1
fastlane/metadata/android/de/changelogs/982.txt
Normal file
@ -0,0 +1 @@
|
||||
Behoben, dass YouTube keinen Stream abspielte.
|
9
fastlane/metadata/android/de/changelogs/983.txt
Normal file
9
fastlane/metadata/android/de/changelogs/983.txt
Normal file
@ -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
|
7
fastlane/metadata/android/de/changelogs/984.txt
Normal file
7
fastlane/metadata/android/de/changelogs/984.txt
Normal file
@ -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
|
9
fastlane/metadata/android/fr/changelogs/983.txt
Normal file
9
fastlane/metadata/android/fr/changelogs/983.txt
Normal file
@ -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
|
6
fastlane/metadata/android/fr/changelogs/984.txt
Normal file
6
fastlane/metadata/android/fr/changelogs/984.txt
Normal file
@ -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
|
7
fastlane/metadata/android/he/changelogs/984.txt
Normal file
7
fastlane/metadata/android/he/changelogs/984.txt
Normal file
@ -0,0 +1,7 @@
|
||||
מספיק פריטים נטענים באופן ראשוני ברשימות כדי למלא את כל המסך ולתקן גלילה במחשבי לוח ובטלוויזיות
|
||||
תוקנו קריסות אקראיות בעת גלילה ברשימות
|
||||
קשת הקפיצה קדימה שמופיעה על הסרטון יורדת אל מתחת לשכבת מנשק המשתמש במערכת
|
||||
שוחזרו השינויים לחיתוכים בעת נגינה במספר חלונות, מה שגרם לנסיגה בנגן שהוזז בחלק מהטלפונים
|
||||
compileSdk שודרג מ־30 ל־31
|
||||
ספריית דיווח השגיאות עודכנה
|
||||
חלק מהקוד בנגן שופץ
|
7
fastlane/metadata/android/it/changelogs/984.txt
Normal file
7
fastlane/metadata/android/it/changelogs/984.txt
Normal file
@ -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
|
8
fastlane/metadata/android/nl-BE/changelogs/63.txt
Normal file
8
fastlane/metadata/android/nl-BE/changelogs/63.txt
Normal file
@ -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
|
9
fastlane/metadata/android/nl/changelogs/954.txt
Normal file
9
fastlane/metadata/android/nl/changelogs/954.txt
Normal file
@ -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
|
8
fastlane/metadata/android/nl/changelogs/969.txt
Normal file
8
fastlane/metadata/android/nl/changelogs/969.txt
Normal file
@ -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
|
11
fastlane/metadata/android/nl/changelogs/970.txt
Normal file
11
fastlane/metadata/android/nl/changelogs/970.txt
Normal file
@ -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
|
3
fastlane/metadata/android/nl/changelogs/971.txt
Normal file
3
fastlane/metadata/android/nl/changelogs/971.txt
Normal file
@ -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
|
14
fastlane/metadata/android/nl/changelogs/972.txt
Normal file
14
fastlane/metadata/android/nl/changelogs/972.txt
Normal file
@ -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
|
7
fastlane/metadata/android/pl/changelogs/984.txt
Normal file
7
fastlane/metadata/android/pl/changelogs/984.txt
Normal file
@ -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
|
1
fastlane/metadata/android/sv/changelogs/982.txt
Normal file
1
fastlane/metadata/android/sv/changelogs/982.txt
Normal file
@ -0,0 +1 @@
|
||||
Fixade att YouTube inte spelade någon stream.
|
7
fastlane/metadata/android/sv/changelogs/984.txt
Normal file
7
fastlane/metadata/android/sv/changelogs/984.txt
Normal file
@ -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
|
7
fastlane/metadata/android/uk/changelogs/984.txt
Normal file
7
fastlane/metadata/android/uk/changelogs/984.txt
Normal file
@ -0,0 +1,7 @@
|
||||
Завантаження достатньої кількості початкових елементів у списках, щоб заповнити весь екран і виправлено гортання на планшетах і телевізорах
|
||||
Усунуто збої під час гортання списків
|
||||
Виправлено проблему перемотування у програвачі
|
||||
Скасовано зміни для пристроїв з вирізами під час програвання в багатовіконному режимі
|
||||
compileSdk оновлено з 30 до 31 версії
|
||||
Оновлено бібліотеку звітів про помилки
|
||||
Рефакторинг коду програвача
|
7
fastlane/metadata/android/zh-Hant/changelogs/984.txt
Normal file
7
fastlane/metadata/android/zh-Hant/changelogs/984.txt
Normal file
@ -0,0 +1,7 @@
|
||||
在清單中載入足夠初始項目以填滿整個螢幕並藉以修正平板電腦和電視上的捲動
|
||||
修正捲動清單時無常當機
|
||||
播放器快速搜索的覆蓋弧形置於系統介面之下
|
||||
還原多重視窗播放時的瀏海變更,免致部分手機出現播放器錯置迴歸
|
||||
compileSdk 由 30 增至 31
|
||||
更新錯誤報告程式庫
|
||||
重構播放器中的部分程式碼
|
7
fastlane/metadata/android/zh_Hant_HK/changelogs/984.txt
Normal file
7
fastlane/metadata/android/zh_Hant_HK/changelogs/984.txt
Normal file
@ -0,0 +1,7 @@
|
||||
喺清單度載入足夠多初始項目去填滿成個螢幕並修正喺平板電腦同電視上面嘅捲動問題
|
||||
修正捲動清單時偶發閃退
|
||||
播放器快轉嘅覆蓋弧形擺喺系統介面後面
|
||||
撤回多視窗播放時嘅 M 字額變動,以免部份手機出現播放器錯位嘅倒退
|
||||
將 compileSdk 由 30 升至 31
|
||||
更新問題報告程式庫
|
||||
執整播放器部份程式碼
|
Loading…
Reference in New Issue
Block a user