diff --git a/.github/PULL_REQUEST_TEAMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
similarity index 100%
rename from .github/PULL_REQUEST_TEAMPLATE.md
rename to .github/PULL_REQUEST_TEMPLATE.md
diff --git a/app/build.gradle b/app/build.gradle
index bad561ae5..2f1dd4005 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -48,7 +48,7 @@ dependencies {
exclude module: 'support-annotations'
}
- compile 'com.github.TeamNewPipe:NewPipeExtractor:7ae274b'
+ compile 'com.github.TeamNewPipe:NewPipeExtractor:1df3f67'
testCompile 'junit:junit:4.12'
testCompile 'org.mockito:mockito-core:1.10.19'
diff --git a/app/src/main/java/org/schabi/newpipe/Downloader.java b/app/src/main/java/org/schabi/newpipe/Downloader.java
index dede9617e..77f12fa46 100644
--- a/app/src/main/java/org/schabi/newpipe/Downloader.java
+++ b/app/src/main/java/org/schabi/newpipe/Downloader.java
@@ -12,7 +12,6 @@ import java.io.InterruptedIOException;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
-import java.util.List;
import java.util.Map;
import javax.net.ssl.HttpsURLConnection;
@@ -135,11 +134,8 @@ public class Downloader implements org.schabi.newpipe.extractor.Downloader {
}
in = new BufferedReader(new InputStreamReader(con.getInputStream()));
- for (Map.Entry> entry : con.getHeaderFields().entrySet()) {
- System.err.println(entry.getKey() + ": " + entry.getValue());
- }
- String inputLine;
+ String inputLine;
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
diff --git a/app/src/main/java/org/schabi/newpipe/database/history/dao/SearchHistoryDAO.java b/app/src/main/java/org/schabi/newpipe/database/history/dao/SearchHistoryDAO.java
index 921ce63a1..70799d971 100644
--- a/app/src/main/java/org/schabi/newpipe/database/history/dao/SearchHistoryDAO.java
+++ b/app/src/main/java/org/schabi/newpipe/database/history/dao/SearchHistoryDAO.java
@@ -11,6 +11,7 @@ import io.reactivex.Flowable;
import static org.schabi.newpipe.database.history.model.SearchHistoryEntry.CREATION_DATE;
import static org.schabi.newpipe.database.history.model.SearchHistoryEntry.ID;
+import static org.schabi.newpipe.database.history.model.SearchHistoryEntry.SEARCH;
import static org.schabi.newpipe.database.history.model.SearchHistoryEntry.SERVICE_ID;
import static org.schabi.newpipe.database.history.model.SearchHistoryEntry.TABLE_NAME;
@@ -27,11 +28,20 @@ public interface SearchHistoryDAO extends HistoryDAO {
@Override
int deleteAll();
+ @Query("DELETE FROM " + TABLE_NAME + " WHERE " + SEARCH + " = :query")
+ int deleteAllWhereQuery(String query);
+
@Query("SELECT * FROM " + TABLE_NAME + ORDER_BY_CREATION_DATE)
@Override
Flowable> getAll();
+ @Query("SELECT * FROM " + TABLE_NAME + " GROUP BY " + SEARCH + ORDER_BY_CREATION_DATE + " LIMIT :limit")
+ Flowable> getUniqueEntries(int limit);
+
@Query("SELECT * FROM " + TABLE_NAME + " WHERE " + SERVICE_ID + " = :serviceId" + ORDER_BY_CREATION_DATE)
@Override
Flowable> listByService(int serviceId);
+
+ @Query("SELECT * FROM " + TABLE_NAME + " WHERE " + SEARCH + " LIKE :query || '%' GROUP BY " + SEARCH + " LIMIT :limit")
+ Flowable> getSimilarEntries(String query, int limit);
}
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java
index db036859e..90d4d9741 100644
--- a/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java
@@ -2,14 +2,16 @@ package org.schabi.newpipe.fragments.list.search;
import android.app.Activity;
import android.content.Context;
+import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
-import android.os.Build;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.app.ActionBar;
+import android.support.v7.app.AlertDialog;
+import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.TooltipCompat;
import android.text.Editable;
import android.text.TextUtils;
@@ -25,12 +27,14 @@ import android.view.ViewGroup;
import android.view.animation.DecelerateInterpolator;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
-import android.widget.AdapterView;
-import android.widget.AutoCompleteTextView;
+import android.widget.EditText;
import android.widget.TextView;
+import org.schabi.newpipe.NewPipeDatabase;
import org.schabi.newpipe.R;
import org.schabi.newpipe.ReCaptchaActivity;
+import org.schabi.newpipe.database.history.dao.SearchHistoryDAO;
+import org.schabi.newpipe.database.history.model.SearchHistoryEntry;
import org.schabi.newpipe.extractor.InfoItem;
import org.schabi.newpipe.extractor.ListExtractor;
import org.schabi.newpipe.extractor.NewPipe;
@@ -38,26 +42,35 @@ import org.schabi.newpipe.extractor.StreamingService;
import org.schabi.newpipe.extractor.exceptions.ParsingException;
import org.schabi.newpipe.extractor.search.SearchEngine;
import org.schabi.newpipe.extractor.search.SearchResult;
+import org.schabi.newpipe.fragments.BackPressable;
import org.schabi.newpipe.fragments.list.BaseListFragment;
import org.schabi.newpipe.history.HistoryListener;
import org.schabi.newpipe.report.UserAction;
import org.schabi.newpipe.util.Constants;
+import org.schabi.newpipe.util.AnimationUtils;
import org.schabi.newpipe.util.ExtractorHelper;
+import org.schabi.newpipe.util.LayoutManagerSmoothScroller;
import org.schabi.newpipe.util.NavigationHelper;
-import org.schabi.newpipe.util.StateSaver;
+import java.io.IOException;
+import java.io.InterruptedIOException;
+import java.net.SocketException;
import java.util.ArrayList;
+import java.util.Iterator;
import java.util.List;
import java.util.Queue;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
import icepick.State;
+import io.reactivex.Flowable;
import io.reactivex.Notification;
import io.reactivex.Observable;
+import io.reactivex.ObservableSource;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;
+import io.reactivex.functions.BiFunction;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.functions.Predicate;
@@ -66,21 +79,22 @@ import io.reactivex.subjects.PublishSubject;
import static org.schabi.newpipe.util.AnimationUtils.animateView;
-public class SearchFragment extends BaseListFragment {
+public class SearchFragment extends BaseListFragment implements BackPressable {
/*//////////////////////////////////////////////////////////////////////////
// Search
//////////////////////////////////////////////////////////////////////////*/
/**
- * The suggestions will appear only if the query meet this threshold (>=).
+ * The suggestions will only be fetched from network if the query meet this threshold (>=).
+ * (local ones will be fetched regardless of the length)
*/
- private static final int THRESHOLD_SUGGESTION = 3;
+ private static final int THRESHOLD_NETWORK_SUGGESTION = 1;
/**
* How much time have to pass without emitting a item (i.e. the user stop typing) to fetch/show the suggestions, in milliseconds.
*/
- private static final int SUGGESTIONS_DEBOUNCE = 150; //ms
+ private static final int SUGGESTIONS_DEBOUNCE = 120; //ms
@State
protected int filterItemCheckedId = -1;
@@ -89,47 +103,54 @@ public class SearchFragment extends BaseListFragment suggestionPublisher = PublishSubject.create();
private Disposable searchDisposable;
- private Disposable suggestionWorkerDisposable;
+ private Disposable suggestionDisposable;
private CompositeDisposable disposables = new CompositeDisposable();
private SuggestionListAdapter suggestionListAdapter;
+ private SearchHistoryDAO searchHistoryDAO;
/*//////////////////////////////////////////////////////////////////////////
// Views
//////////////////////////////////////////////////////////////////////////*/
private View searchToolbarContainer;
- private AutoCompleteTextView searchEditText;
+ private EditText searchEditText;
private View searchClear;
+ private View suggestionsPanel;
+ private RecyclerView suggestionsRecyclerView;
+
/*////////////////////////////////////////////////////////////////////////*/
public static SearchFragment getInstance(int serviceId, String query) {
SearchFragment searchFragment = new SearchFragment();
searchFragment.setQuery(serviceId, query);
- searchFragment.searchOnResume();
+
+ if (!TextUtils.isEmpty(query)) {
+ searchFragment.setSearchOnResume();
+ }
+
return searchFragment;
}
/**
* Set wasLoading to true so when the fragment onResume is called, the initial search is done.
- * (it will only start searching if the query is not null or empty)
*/
- private void searchOnResume() {
- if (!TextUtils.isEmpty(searchQuery)) {
- wasLoading.set(true);
- }
+ private void setSearchOnResume() {
+ wasLoading.set(true);
}
/*//////////////////////////////////////////////////////////////////////////
@@ -140,6 +161,16 @@ public class SearchFragment extends BaseListFragment currentPage) loadMoreItems();
@@ -181,7 +216,16 @@ public class SearchFragment extends BaseListFragment= Build.VERSION_CODES.JELLY_BEAN_MR1) {
- searchEditText.setText("", false);
- } else searchEditText.setText("");
- suggestionListAdapter.updateAdapter(new ArrayList());
- showSoftKeyboard(searchEditText);
+ searchEditText.setText("");
+ suggestionListAdapter.setItems(new ArrayList());
+ showKeyboardSearch();
}
});
@@ -373,7 +417,9 @@ public class SearchFragment extends BaseListFragment parent, View view, int position, long id) {
- if (DEBUG) {
- Log.d(TAG, "onItemClick() called with: parent = [" + parent + "], view = [" + view + "], position = [" + position + "], id = [" + id + "]");
- }
- String s = suggestionListAdapter.getSuggestion(position);
- if (DEBUG) Log.d(TAG, "onItemClick text = " + s);
- submitQuery(s);
+ public void onSuggestionItemSelected(SuggestionItem item) {
+ search(item.query);
+ searchEditText.setText(item.query);
+ }
+
+ @Override
+ public void onSuggestionItemLongClick(SuggestionItem item) {
+ if (item.fromHistory) showDeleteSuggestionDialog(item);
}
});
- searchEditText.setThreshold(THRESHOLD_SUGGESTION);
if (textWatcher != null) searchEditText.removeTextChangedListener(textWatcher);
textWatcher = new TextWatcher() {
@@ -411,32 +459,32 @@ public class SearchFragment extends BaseListFragment() {
+ @Override
+ public Integer call() throws Exception {
+ return searchHistoryDAO.deleteAllWhereQuery(item.query);
+ }
+ })
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(new Consumer() {
+ @Override
+ public void accept(Integer howManyDeleted) throws Exception {
+ suggestionPublisher.onNext(searchEditText.getText().toString());
+ }
+ }, new Consumer() {
+ @Override
+ public void accept(Throwable throwable) throws Exception {
+ showSnackBarError(throwable, UserAction.SOMETHING_ELSE, "none", "Deleting item failed", R.string.general_error);
+ }
+ }));
+ }
+ }).show();
+ }
+
+ @Override
+ public boolean onBackPressed() {
+ if (suggestionsPanel.getVisibility() == View.VISIBLE && infoListAdapter.getItemsList().size() > 0 && !isLoading.get()) {
+ hideSuggestionsPanel();
+ hideKeyboardSearch();
+ searchEditText.setText(lastSearchedQuery);
+ return true;
+ }
+ return false;
}
public void giveSearchEditTextFocus() {
- showSoftKeyboard(searchEditText);
+ showKeyboardSearch();
}
private void initSuggestionObserver() {
- if (suggestionWorkerDisposable != null) suggestionWorkerDisposable.dispose();
- final Predicate checkEnabledAndLength = new Predicate() {
- @Override
- public boolean test(@io.reactivex.annotations.NonNull String s) throws Exception {
- boolean lengthCheck = s.length() >= THRESHOLD_SUGGESTION;
- // Clear the suggestions adapter if the length check fails
- if (!lengthCheck && !suggestionListAdapter.isEmpty()) {
- suggestionListAdapter.updateAdapter(new ArrayList());
- }
- // Only pass through if suggestions is enabled and the query length is equal or greater than THRESHOLD_SUGGESTION
- return showSuggestions && lengthCheck;
- }
- };
+ if (DEBUG) Log.d(TAG, "initSuggestionObserver() called");
+ if (suggestionDisposable != null) suggestionDisposable.dispose();
- suggestionWorkerDisposable = suggestionPublisher
+ final Observable observable = suggestionPublisher
.debounce(SUGGESTIONS_DEBOUNCE, TimeUnit.MILLISECONDS)
- .startWith(!TextUtils.isEmpty(searchQuery) ? searchQuery : "")
- .filter(checkEnabledAndLength)
- .switchMap(new Function>>>() {
+ .startWith(searchQuery != null ? searchQuery : "")
+ .filter(new Predicate() {
@Override
- public Observable>> apply(@io.reactivex.annotations.NonNull String query) throws Exception {
- return ExtractorHelper.suggestionsFor(serviceId, query, searchLanguage).toObservable().materialize();
+ public boolean test(@io.reactivex.annotations.NonNull String query) throws Exception {
+ return isSuggestionsEnabled;
+ }
+ });
+
+ suggestionDisposable = observable
+ .switchMap(new Function>>>() {
+ @Override
+ public ObservableSource>> apply(@io.reactivex.annotations.NonNull final String query) throws Exception {
+ final Flowable> flowable = query.length() > 0
+ ? searchHistoryDAO.getSimilarEntries(query, 3)
+ : searchHistoryDAO.getUniqueEntries(25);
+ final Observable> local = flowable.toObservable()
+ .map(new Function, List>() {
+ @Override
+ public List apply(@io.reactivex.annotations.NonNull List searchHistoryEntries) throws Exception {
+ List result = new ArrayList<>();
+ for (SearchHistoryEntry entry : searchHistoryEntries)
+ result.add(new SuggestionItem(true, entry.getSearch()));
+ return result;
+ }
+ });
+
+ if (query.length() < THRESHOLD_NETWORK_SUGGESTION) {
+ // Only pass through if the query length is equal or greater than THRESHOLD_NETWORK_SUGGESTION
+ return local.materialize();
+ }
+
+ final Observable> network = ExtractorHelper.suggestionsFor(serviceId, query, searchLanguage).toObservable()
+ .map(new Function, List>() {
+ @Override
+ public List apply(@io.reactivex.annotations.NonNull List strings) throws Exception {
+ List result = new ArrayList<>();
+ for (String entry : strings) result.add(new SuggestionItem(false, entry));
+ return result;
+ }
+ });
+
+ return Observable.zip(local, network, new BiFunction, List, List>() {
+ @Override
+ public List apply(@io.reactivex.annotations.NonNull List localResult, @io.reactivex.annotations.NonNull List networkResult) throws Exception {
+ List result = new ArrayList<>();
+ if (localResult.size() > 0) result.addAll(localResult);
+
+ // Remove duplicates
+ final Iterator iterator = networkResult.iterator();
+ while (iterator.hasNext() && localResult.size() > 0) {
+ final SuggestionItem next = iterator.next();
+ for (SuggestionItem item : localResult) {
+ if (item.query.equals(next.query)) {
+ iterator.remove();
+ break;
+ }
+ }
+ }
+
+ if (networkResult.size() > 0) result.addAll(networkResult);
+ return result;
+ }
+ }).materialize();
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
- .subscribe(new Consumer>>() {
+ .subscribe(new Consumer>>() {
@Override
- public void accept(@io.reactivex.annotations.NonNull Notification> listNotification) throws Exception {
+ public void accept(@io.reactivex.annotations.NonNull Notification> listNotification) throws Exception {
if (listNotification.isOnNext()) {
handleSuggestions(listNotification.getValue());
- if (errorPanelRoot.getVisibility() == View.VISIBLE) {
- hideLoading();
- }
} else if (listNotification.isOnError()) {
Throwable error = listNotification.getError();
- if (!ExtractorHelper.isInterruptedCaused(error)) {
+ if (!ExtractorHelper.hasAssignableCauseThrowable(error,
+ IOException.class, SocketException.class, InterruptedException.class, InterruptedIOException.class)) {
onSuggestionError(error);
}
}
@@ -520,6 +666,7 @@ public class SearchFragment extends BaseListFragment suggestions) {
+ public void handleSuggestions(@NonNull final List suggestions) {
if (DEBUG) Log.d(TAG, "handleSuggestions() called with: suggestions = [" + suggestions + "]");
- suggestionListAdapter.updateAdapter(suggestions);
+ suggestionsRecyclerView.smoothScrollToPosition(0);
+ suggestionsRecyclerView.post(new Runnable() {
+ @Override
+ public void run() {
+ suggestionListAdapter.setItems(suggestions);
+ }
+ });
+
+ if (errorPanelRoot.getVisibility() == View.VISIBLE) {
+ hideLoading();
+ }
}
public void onSuggestionError(Throwable exception) {
@@ -682,6 +829,13 @@ public class SearchFragment extends BaseListFragment 0) {
infoListAdapter.addInfoItemList(result.resultList);
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/search/SuggestionItem.java b/app/src/main/java/org/schabi/newpipe/fragments/list/search/SuggestionItem.java
new file mode 100644
index 000000000..722638926
--- /dev/null
+++ b/app/src/main/java/org/schabi/newpipe/fragments/list/search/SuggestionItem.java
@@ -0,0 +1,16 @@
+package org.schabi.newpipe.fragments.list.search;
+
+public class SuggestionItem {
+ public final boolean fromHistory;
+ public final String query;
+
+ public SuggestionItem(boolean fromHistory, String query) {
+ this.fromHistory = fromHistory;
+ this.query = query;
+ }
+
+ @Override
+ public String toString() {
+ return "[" + fromHistory + "→" + query + "]";
+ }
+}
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/search/SuggestionListAdapter.java b/app/src/main/java/org/schabi/newpipe/fragments/list/search/SuggestionListAdapter.java
index 0a7e3d613..71d9bf780 100644
--- a/app/src/main/java/org/schabi/newpipe/fragments/list/search/SuggestionListAdapter.java
+++ b/app/src/main/java/org/schabi/newpipe/fragments/list/search/SuggestionListAdapter.java
@@ -1,89 +1,108 @@
package org.schabi.newpipe.fragments.list.search;
import android.content.Context;
-import android.database.Cursor;
-import android.database.MatrixCursor;
-import android.support.v4.widget.ResourceCursorAdapter;
+import android.content.res.TypedArray;
+import android.support.annotation.AttrRes;
+import android.support.v7.widget.RecyclerView;
+import android.view.LayoutInflater;
import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
import android.widget.TextView;
+import org.schabi.newpipe.R;
+
+import java.util.ArrayList;
import java.util.List;
-/*
- * Created by Christian Schabesberger on 02.08.16.
- *
- * Copyright (C) Christian Schabesberger 2016
- * SuggestionListAdapter.java is part of NewPipe.
- *
- * NewPipe is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * NewPipe is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with NewPipe. If not, see .
- */
-
-/**
- * {@link ResourceCursorAdapter} to display suggestions.
- */
-public class SuggestionListAdapter extends ResourceCursorAdapter {
-
- private static final String[] columns = new String[]{"_id", "title"};
- private static final int INDEX_ID = 0;
- private static final int INDEX_TITLE = 1;
+public class SuggestionListAdapter extends RecyclerView.Adapter {
+ private final ArrayList items = new ArrayList<>();
+ private final Context context;
+ private OnSuggestionItemSelected listener;
+ public interface OnSuggestionItemSelected {
+ void onSuggestionItemSelected(SuggestionItem item);
+ void onSuggestionItemLongClick(SuggestionItem item);
+ }
public SuggestionListAdapter(Context context) {
- super(context, android.R.layout.simple_list_item_1, null, 0);
+ this.context = context;
+ }
+
+ public void setItems(List items) {
+ this.items.clear();
+ this.items.addAll(items);
+ notifyDataSetChanged();
+ }
+
+ public void setListener(OnSuggestionItemSelected listener) {
+ this.listener = listener;
}
@Override
- public void bindView(View view, Context context, Cursor cursor) {
- ViewHolder viewHolder = new ViewHolder(view);
- viewHolder.suggestionTitle.setText(cursor.getString(INDEX_TITLE));
- }
-
- /**
- * Update the suggestion list
- * @param suggestions the list of suggestions
- */
- public void updateAdapter(List suggestions) {
- MatrixCursor cursor = new MatrixCursor(columns, suggestions.size());
- int i = 0;
- for (String suggestion : suggestions) {
- String[] columnValues = new String[columns.length];
- columnValues[INDEX_TITLE] = suggestion;
- columnValues[INDEX_ID] = Integer.toString(i);
- cursor.addRow(columnValues);
- i++;
- }
- changeCursor(cursor);
- }
-
- /**
- * Get the suggestion for a position
- * @param position the position of the suggestion
- * @return the suggestion
- */
- public String getSuggestion(int position) {
- return ((Cursor) getItem(position)).getString(INDEX_TITLE);
+ public SuggestionItemHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ return new SuggestionItemHolder(LayoutInflater.from(context).inflate(R.layout.item_search_suggestion, parent, false));
}
@Override
- public CharSequence convertToString(Cursor cursor) {
- return cursor.getString(INDEX_TITLE);
+ public void onBindViewHolder(SuggestionItemHolder holder, int position) {
+ final SuggestionItem currentItem = getItem(position);
+ holder.updateFrom(currentItem);
+ holder.itemView.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if (listener != null) listener.onSuggestionItemSelected(currentItem);
+ }
+ });
+ holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
+ @Override
+ public boolean onLongClick(View v) {
+ if (listener != null) listener.onSuggestionItemLongClick(currentItem);
+ return true;
+ }
+ });
}
- private class ViewHolder {
- private final TextView suggestionTitle;
- private ViewHolder(View view) {
- this.suggestionTitle = view.findViewById(android.R.id.text1);
+ private SuggestionItem getItem(int position) {
+ return items.get(position);
+ }
+
+ @Override
+ public int getItemCount() {
+ return items.size();
+ }
+
+ public boolean isEmpty() {
+ return getItemCount() == 0;
+ }
+
+ public static class SuggestionItemHolder extends RecyclerView.ViewHolder {
+ private final TextView itemSuggestionQuery;
+ private final ImageView suggestionIcon;
+
+ // Cache some ids, as they can potentially be constantly updated/recycled
+ private final int historyResId;
+ private final int searchResId;
+
+ private SuggestionItemHolder(View rootView) {
+ super(rootView);
+ suggestionIcon = rootView.findViewById(R.id.item_suggestion_icon);
+ itemSuggestionQuery = rootView.findViewById(R.id.item_suggestion_query);
+
+ historyResId = resolveResourceIdFromAttr(rootView.getContext(), R.attr.history);
+ searchResId = resolveResourceIdFromAttr(rootView.getContext(), R.attr.search);
+ }
+
+ private void updateFrom(SuggestionItem item) {
+ suggestionIcon.setImageResource(item.fromHistory ? historyResId : searchResId);
+ itemSuggestionQuery.setText(item.query);
+ }
+
+ private static int resolveResourceIdFromAttr(Context context, @AttrRes int attr) {
+ TypedArray a = context.getTheme().obtainStyledAttributes(new int[]{attr});
+ int attributeResourceId = a.getResourceId(0, 0);
+ a.recycle();
+ return attributeResourceId;
}
}
-}
\ No newline at end of file
+}
diff --git a/app/src/main/java/org/schabi/newpipe/util/AnimationUtils.java b/app/src/main/java/org/schabi/newpipe/util/AnimationUtils.java
index ac70bd05f..c954211fa 100644
--- a/app/src/main/java/org/schabi/newpipe/util/AnimationUtils.java
+++ b/app/src/main/java/org/schabi/newpipe/util/AnimationUtils.java
@@ -19,7 +19,7 @@ public class AnimationUtils {
private static final boolean DEBUG = MainActivity.DEBUG;
public enum Type {
- ALPHA, SCALE_AND_ALPHA, LIGHT_SCALE_AND_ALPHA
+ ALPHA, SCALE_AND_ALPHA, LIGHT_SCALE_AND_ALPHA, SLIDE_AND_ALPHA, LIGHT_SLIDE_AND_ALPHA
}
public static void animateView(View view, boolean enterOrExit, long duration) {
@@ -95,9 +95,16 @@ public class AnimationUtils {
case LIGHT_SCALE_AND_ALPHA:
animateLightScaleAndAlpha(view, enterOrExit, duration, delay, execOnEnd);
break;
+ case SLIDE_AND_ALPHA:
+ animateSlideAndAlpha(view, enterOrExit, duration, delay, execOnEnd);
+ break;
+ case LIGHT_SLIDE_AND_ALPHA:
+ animateLightSlideAndAlpha(view, enterOrExit, duration, delay, execOnEnd);
+ break;
}
}
+
/**
* Animate the background color of a view
*/
@@ -237,4 +244,50 @@ public class AnimationUtils {
}).start();
}
}
+
+ private static void animateSlideAndAlpha(final View view, boolean enterOrExit, long duration, long delay, final Runnable execOnEnd) {
+ if (enterOrExit) {
+ view.setTranslationY(-view.getHeight());
+ view.setAlpha(0f);
+ view.animate().setInterpolator(new FastOutSlowInInterpolator()).alpha(1f).translationY(0)
+ .setDuration(duration).setStartDelay(delay).setListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ if (execOnEnd != null) execOnEnd.run();
+ }
+ }).start();
+ } else {
+ view.animate().setInterpolator(new FastOutSlowInInterpolator()).alpha(0f).translationY(-view.getHeight())
+ .setDuration(duration).setStartDelay(delay).setListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ view.setVisibility(View.GONE);
+ if (execOnEnd != null) execOnEnd.run();
+ }
+ }).start();
+ }
+ }
+
+ private static void animateLightSlideAndAlpha(final View view, boolean enterOrExit, long duration, long delay, final Runnable execOnEnd) {
+ if (enterOrExit) {
+ view.setTranslationY(-view.getHeight() / 2);
+ view.setAlpha(0f);
+ view.animate().setInterpolator(new FastOutSlowInInterpolator()).alpha(1f).translationY(0)
+ .setDuration(duration).setStartDelay(delay).setListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ if (execOnEnd != null) execOnEnd.run();
+ }
+ }).start();
+ } else {
+ view.animate().setInterpolator(new FastOutSlowInInterpolator()).alpha(0f).translationY(-view.getHeight() / 2)
+ .setDuration(duration).setStartDelay(delay).setListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ view.setVisibility(View.GONE);
+ if (execOnEnd != null) execOnEnd.run();
+ }
+ }).start();
+ }
+ }
}
diff --git a/app/src/main/java/org/schabi/newpipe/util/LayoutManagerSmoothScroller.java b/app/src/main/java/org/schabi/newpipe/util/LayoutManagerSmoothScroller.java
new file mode 100644
index 000000000..9eca2d610
--- /dev/null
+++ b/app/src/main/java/org/schabi/newpipe/util/LayoutManagerSmoothScroller.java
@@ -0,0 +1,43 @@
+package org.schabi.newpipe.util;
+
+import android.content.Context;
+import android.graphics.PointF;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.LinearSmoothScroller;
+import android.support.v7.widget.RecyclerView;
+
+public class LayoutManagerSmoothScroller extends LinearLayoutManager {
+
+ public LayoutManagerSmoothScroller(Context context) {
+ super(context, VERTICAL, false);
+ }
+
+ public LayoutManagerSmoothScroller(Context context, int orientation, boolean reverseLayout) {
+ super(context, orientation, reverseLayout);
+ }
+
+ @Override
+ public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) {
+ RecyclerView.SmoothScroller smoothScroller = new TopSnappedSmoothScroller(recyclerView.getContext());
+ smoothScroller.setTargetPosition(position);
+ startSmoothScroll(smoothScroller);
+ }
+
+ private class TopSnappedSmoothScroller extends LinearSmoothScroller {
+ public TopSnappedSmoothScroller(Context context) {
+ super(context);
+
+ }
+
+ @Override
+ public PointF computeScrollVectorForPosition(int targetPosition) {
+ return LayoutManagerSmoothScroller.this
+ .computeScrollVectorForPosition(targetPosition);
+ }
+
+ @Override
+ protected int getVerticalSnapPreference() {
+ return SNAP_TO_START;
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/us/shandian/giga/get/DownloadManagerImpl.java b/app/src/main/java/us/shandian/giga/get/DownloadManagerImpl.java
index 479a5cee3..acbd41680 100755
--- a/app/src/main/java/us/shandian/giga/get/DownloadManagerImpl.java
+++ b/app/src/main/java/us/shandian/giga/get/DownloadManagerImpl.java
@@ -101,6 +101,18 @@ public class DownloadManagerImpl implements DownloadManager {
}
+ /**
+ * Sort a list of mission by its timestamp. Oldest first
+ * @param missions the missions to sort
+ */
+ static void sortByTimestamp(List missions) {
+ Collections.sort(missions, new Comparator() {
+ @Override
+ public int compare(DownloadMission o1, DownloadMission o2) {
+ return Long.valueOf(o1.timestamp).compareTo(o2.timestamp);
+ }
+ });
+ }
/**
* Loads finished missions from the data source
@@ -111,12 +123,8 @@ public class DownloadManagerImpl implements DownloadManager {
finishedMissions = new ArrayList<>();
}
// Ensure its sorted
- Collections.sort(finishedMissions, new Comparator() {
- @Override
- public int compare(DownloadMission o1, DownloadMission o2) {
- return (int) (o1.timestamp - o2.timestamp);
- }
- });
+ sortByTimestamp(finishedMissions);
+
mMissions.ensureCapacity(mMissions.size() + finishedMissions.size());
for (DownloadMission mission : finishedMissions) {
File downloadedFile = mission.getDownloadedFile();
diff --git a/app/src/main/res/layout/fragment_search.xml b/app/src/main/res/layout/fragment_search.xml
index 9ba44e76f..04b10347c 100644
--- a/app/src/main/res/layout/fragment_search.xml
+++ b/app/src/main/res/layout/fragment_search.xml
@@ -51,6 +51,25 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/toolbar_search_layout.xml b/app/src/main/res/layout/toolbar_search_layout.xml
index 7780a0226..797eea48e 100644
--- a/app/src/main/res/layout/toolbar_search_layout.xml
+++ b/app/src/main/res/layout/toolbar_search_layout.xml
@@ -4,16 +4,9 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
- android:background="?attr/colorPrimary"
- android:focusable="true"
- android:focusableInTouchMode="true">
+ android:background="?attr/colorPrimary">
-
-
- Použít externí audio přehrávač
Cesta, kam se uloží stažené audio
- Zadejte umístění pro stažené audio soubory.
+ Zadejte umístění pro stažené audio soubory
Umístění pro stažené audio
Výchozí rozlišení
Přehrát pomocí Kodi
- Aplikace Kore nenalezena. Nainstalovat Kore?
+ Aplikace Kore nenalezena. Chcete ji nainstalovat?
%1$s zhlédnutí
Umístění pro stažené video
- Cesta, kam se uloží stažené video.
+ Cesta, kam se uloží stažené video
Zadejte umístění pro stažená videa
Zobrazit možnost \"Přehrát pomocí Kodi\"
- Zobrazit možnost přehrání videa pomocí multimediálního centra Kodi.
+ Zobrazit možnost přehrání videa pomocí multimediálního centra Kodi
Audio
Výchozí audio formát
WebM — svobodný formát
- m4a — lepší kvalita
+ M4A — lepší kvalita
Téma
Tmavé
Světlé
@@ -51,10 +51,10 @@
Chyba
Chyba sítě
Nebylo možné nahrát všechny náhledy
- Nebylo možné dekódovat URL videa.
- Nebylo možné analyzovat webovou stránku.
- Obsah není k dispozici.
- Obsah blokuje GEMA.
+ Nebylo možné dekódovat URL videa
+ Nebylo možné analyzovat webovou stránku
+ Obsah není k dispozici
+ Obsah blokuje GEMA
Náhled videa
Náhled videa
@@ -66,16 +66,16 @@
Nebylo možné vytvořit složku pro stažené soubory \'%1$s\'
Vytvořena složka pro stažené soubory \'%1$s\'
- Automaticky přehrávat při otevření z jiné aplikace
- Automaticky přehrát video, když je NewPipe otevřen z jiné aplikace.
+ Automaticky přehrávat
+ Automaticky přehrát video, když je NewPipe otevřen z jiné aplikace
Obsah
Zobrazovat věkově omezený obsah
Toto video je věkově omezeno. Povolte věkově omezená videa v nastavení.
živě
- Nebylo možné kompletně analyzovat stránku.
+ Nebylo možné kompletně analyzovat stránku
Pro začátek stiskni hledat
- Zkopírováno do schránky.
+ Zkopírováno do schránky
Počkejte prosím…
NewPipe se stahuje
Stiskněte pro detaily
@@ -104,15 +104,15 @@
Nepodařilo se nahrát obrázek
Aplikace/UI spadlo
Tento stream je vysílán živě, funkce ještě není podporována.
- Nepodařilo se dostat žádný stream.
- Nepodařilo se nastavit menu stahování.
+ Nepodařilo se dostat žádný stream
+ Nepodařilo se nastavit menu stahování
Nahlásit chybu
Stažené soubory
Stažené soubory
Info:
Vaše poznámky (Anglicky):
- Oprávnění přístupu do Úložiště bylo zamítnuto
+ Oprávnění přístupu do úložiště bylo zamítnuto
Shlédnout
Nová mise
Hotovo
@@ -123,9 +123,9 @@
Černé
- Checksum
+ Kontrolní součet
- Prosím vyberte dostupnou složku pro stažení souborů.
+ Prosím vyberte dostupnou složku pro stažení souborů
Hlášení uživatele
@@ -150,4 +150,111 @@ otevření ve vyskakovacím okně
Preferovaný video formát
Zapamatovat si velikost a pozici vyskakovacího okna
Zapamatovat si poslední nastavení velikosti a pozice vyskakovacího okna
-
+ Režim NewPipe vyskakovacího okna
+ Odebírat
+ Odebírané
+ Odběr zrušen
+ Nelze změnit odběr
+ Nelze aktualizovat odběr
+
+ Hlavní
+ Odběry
+
+ Co je nové
+
+ V pozadí
+ V okně
+
+ Výchozí rozlišení v okně
+ Nastavení gest přehrávače
+ Používat gesta pro kontrolu jasu a hlasitosti přehrávače
+ Vyhledat návrhy
+ Ukazovat návrhy při vyhledávání
+ Historie prohlížení
+ Ukládat hledané výrazy lokálně
+ Historie
+ Evidovat sledovaná videa
+ Přehrávat po přechodu do popředí
+ Pokračovat v přehrávání po přerušení (např. hovor)
+ Přehrávač
+ Chování
+ Historie
+ V okně
+ Přehrávání v okně
+ Playlist
+ Vypnuto
+ Filtr
+ Obnovit
+ Vyčistit
+ Změna velikosti
+ Nejlepší rozlošení
+ Vrátit
+
+ NewPipe notifikace
+ Notifikace pro NewPipe v pozadí a v okně
+
+ Žádné výsledky
+ Je tu sranda jak v márnici
+
+ Starý zabudovaný Mediaframework přehrávač
+
+ B
+
+ Žádní odběratelé
+
+ - %s odběratel
+ - %s odběratelů
+ - %s odběratelé
+
+
+
+ Žádná shlédnutí
+
+ - %s shlédnutí
+ - %s shlédnutí
+ - %s shlédnutí
+
+
+
+ Žádná videa
+
+ - %s video
+ - %s videí
+ - %s videa
+
+
+
+ Stahování
+ Povolené znaky v názvech souborů
+ Neplatné znaky jdou nahrazeny těmito znaky
+ Náhradní znak
+
+ Písmena a číslice
+ Většina speciálních znaků
+
+ O NewPipe
+ Nastavení
+ O
+ Licence třetích stran
+ © %1$s od %2$s pod %3$s
+ Nemožné nahrát licenci
+ Otevřít webstránku
+ O
+ Přispěvatelé
+ Licence
+ Bezplatná a nenáročná YouTube aplikace pro Android.
+ Zobraz na GitHubu
+ Licence NewPipe
+ Pokud máte nápady na zlepšení jako; překlad, změny designu, vylepšování kódu nebo opravdu velké změny kódu - pomoc je vždy vítána. Čím více se udělá, tím lepší to bude!
+ Přečíst licenci
+ Příspěvek
+
+ Histrorie
+ Vyhledáváno
+ Sledováno
+ Historie je vypnutá
+ Historie
+ Historie je prázdná
+ Historie byla vymazána
+ Položka byla odstraněna
+
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
index e25dc099e..eb29f78b0 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -119,7 +119,7 @@
Starten
Pause
- Ansehen
+ Abspielen
Neue Mission
OK
Server nicht unterstützt
@@ -254,4 +254,9 @@
Die meisten Sonderzeichen
Element gelöscht
+Fortsetzen bei erneutem Fokussieren
+ Player
+ Nichts hier außer Grillen
+
+ Möchten Sie dieses Element aus dem Suchverlauf löschen?
diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml
index f257a61d3..7d09d85b9 100644
--- a/app/src/main/res/values-es/strings.xml
+++ b/app/src/main/res/values-es/strings.xml
@@ -1,7 +1,7 @@
%1$s visualizaciones
- Publicado en %1$s
+ Publicado el %1$s
No se encontró ningún reproductor de vídeo. ¿Desea instalar VLC?
Instalar
Cancelar
@@ -12,7 +12,7 @@
Ajustes
¿Quiso decir: %1$s?
Compartir con
- Seleccionar navegador
+ Elegir navegador
rotación
Ruta de descarga de vídeo
Ruta para almacenar los vídeos descargados
@@ -72,7 +72,7 @@
Mostrar contenido restringido por edad
Vídeo restringido por edad. Permitir este tipo de material es posible desde Ajustes.
- Toque buscar para empezar
+ Toque en buscar para empezar
Autoreproducir
Reproducir automáticamente un vídeo cuando NewPipe es llamado desde otra aplicación
en vivo
@@ -170,7 +170,7 @@ abrir en modo popup
Popup
Redimensionando
- Algunas resoluciones podrían no tener audio cuando esta opción está activada
+ Algunas resoluciones podrían NO tener audio cuando esta opción está activada
Controles de gestos del reproductor
Usar gestos para controlar el brillo y volumen del reproductor
Sugerencias de búsqueda
@@ -238,7 +238,7 @@ abrir en modo popup
Deshacer
No hay resultados
- Nada aquí, pero grillos
+ Nada más que grillos
Sin suscriptores
@@ -259,4 +259,5 @@ abrir en modo popup
Elemento eliminado
+¿Desea eliminar este elemento del historial de búsqueda?
diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml
index 173607732..f8de02050 100644
--- a/app/src/main/res/values-fr/strings.xml
+++ b/app/src/main/res/values-fr/strings.xml
@@ -18,7 +18,7 @@
Paramètres
Partager
Partager avec
- Afficher une option pour lire la vidéo via la médiathèque Kodi
+ Afficher une option pour lire la vidéo via Kodi
Afficher l’option « Lire avec Kodi »
Ajoutée le %1$s
%1$s vues
@@ -133,34 +133,33 @@
Test reCAPTCHA
Test reCAPTCHA demandé
- Ouvrir dans une fenêtre popup
- Mode popup de NewPipe
+ Ouvrir dans une fenêtre flottante
+ Mode flottant de NewPipe
- Lecture en mode popup
+ Lire dans le lecteur flottant
Oui
Plus tard
Désactivé
- Quoi :\\nRequête :\\nLang. du contenu:\\nService :\\nHeure GMT :\\nPaquage :\\nVersion :\\nVersion de l\'OS:\\nGamme globale d\'IPs :
+ Quoi :\\nRequête :\\nLangue du contenu :\\nService :\\nHeure GMT :\\nPaquet :\\nVersion :\\nVersion du système :\\nGlob. Plage IP :
Utiliser l\'ancien lecteur
Ancienne version du lecteur Mediaframework
K
M
- Cette permission est nécessaire
-pour ouvrir en mode popup
+ Cette permission est nécessaire pour ouvrir en mode flottant
Arrière-plan
- Lecture intégrée
+ Lecture flottante
- Résolution de la lecture intégrée
+ Résolution de la lecture flottante
Afficher des résolutions plus grandes
Seulement certains périphériques supportent la lecture 2K/4K
Format vidéo par défaut
- Mémoriser la taille et la position du lecteur intégré
- Mémoriser les derniers emplacements et la taille du lecteur intégré
+ Mémoriser la taille et la position du lecteur flottant
+ Mémoriser les derniers emplacements et la taille du lecteur flottant
- Lecteur intégré
+ Lecteur flottant
Filtre
Actualiser
Effacer
@@ -178,7 +177,7 @@ pour ouvrir en mode popup
S\'abonner
Abonné
- Désabonné de la chaîne
+ Désabonner de la chaîne
Principal
Abonnements
@@ -189,7 +188,7 @@ pour ouvrir en mode popup
À propos
Licences tierces
Impossible de charger la licence
- Ouvrir le site web
+ Ouvrir le site
À propos
Contributeurs
Licences
@@ -231,7 +230,7 @@ pour ouvrir en mode popup
Comportement
Historique
Liste de lecture
- Notifications pour les lecteurs Background et Popup de NewPipe
+ Notifications pour les lecteurs arrière-plan et flottant de NewPipe
Aucun résultat
Rien ici à part des grillons
@@ -257,4 +256,5 @@ pour ouvrir en mode popup
Caractères spéciaux
Objet effacé
+Voulez-vous supprimer cet élément de l\'historique de recherche ?
diff --git a/app/src/main/res/values-hr/strings.xml b/app/src/main/res/values-hr/strings.xml
index fcae17568..30d72a9ef 100644
--- a/app/src/main/res/values-hr/strings.xml
+++ b/app/src/main/res/values-hr/strings.xml
@@ -1,23 +1,23 @@
-Dodirni pretragu za početak
+Dodirnite pretragu za početak
%1$s pregleda
Objavljeno %1$s
- Svirač za stream nije pronađen. Želite li instalirati VLC?
+ Reproduktor za stream nije pronađen. Želite li instalirati VLC?
Instaliraj
Poništi
Otvori u pregledniku
Otvori skočni prozor
Podijeli
Preuzimanje
- Traži
+ Pretraživanje
Postavke
Jeste li mislili: %1$s ?
Podijeli putem
Izaberi pretraživač
rotacija
- Koristi vanjski svirač videa
- Nele rezolucije NEĆE imati zvuk kad je ova opcija uključena
- Koristi vanjski svirač glazbe
+ Koristi vanjski reproduktor videozapisa
+ Neke razlučivosti NEĆE imati zvuk kad je ova opcija omogućena
+ Koristi vanjski reproduktor za zvuk
NewPipe skočni prozor
Pretplati se
Pretplaćeno
@@ -25,7 +25,7 @@
Nije moguće promijeniti pretplatu
Nije moguće osvježiti pretplatu
- Glavno
+ Početna
Pretplate
Što je novo
@@ -33,63 +33,63 @@
Pozadina
Skočni prozor
- Putanja za preuzimanje videa
- Putanja za spremanje videa
- Unesi putanju za preuzimanje videa
+ Put za preuzimanje videozapisa
+ Put za spremanje videozapisa u
+ Unesi put za preuzimanje videozapisa
- Putanja za preuzimanje zvuka
- Putanja za spremanje zvuka
- Unesi download putanju za audio datoteke
+ Put za preuzimanje zvuka
+ Put za spremanje preuzetog zvuka u
+ Unesi put za preuzimanje zvučne datoteke
- Automatski reproduciraj kada je NewPipe otvoren iz druge aplikacije
- Automatski reproduciraj video kad je NewPipe otvoren iz druge aplikacije
- Zadana rezolucija
- Zadana rezolucija skočnog prozora
- Prikaži veće rezolucije
- Samo neki uređaji podržavaju reprodukciju 2K/4K videa
+ Automatski reprod. kada je NewPipe pozvan iz druge aplikacije
+ Automatski reproduciraj videozapis kad je NewPipe pozvan iz druge aplikacije
+ Zadana razlučivost
+ Zadana razlučivost skočnog prozora
+ Prikaži veće razlučivosti
+ Samo neki uređaji podržavaju reprodukciju 2K/4K videozapisa
Reproduciraj sa Kodijem
- Kore aplikacija nije pronađena. Instaliraj Kore?
+ Kore aplikacija nije pronađena. Želite li ju instalirati?
Prikaži \"Reproduciraj putem Kodija\" opciju
- Prikaži opciju za reproduciranje videa putem Kodija
- Audio
- Zadani audio format
- Preferirani video format
+ Prikaži opciju za reproduciranje videozapisa putem Kodija
+ Zvuk
+ Zadani format zvuka
+ Zadani format videozapisa
WebM - slobodni format
- m4a - bolja kvaliteta
+ M4A - bolja kvaliteta
Tema
Svijetla
Tamna
Crno
Zapamti veličinu i poziciju skočnog prozora
- Zapamti posljednju veličinu i poziciju postavljenu skočnom prozoru
- Playerovo kontroliranje gestama
- Koristi geste za kontrolu svjetline i glasnoće playera
+ Zapamti posljednju veličinu i poziciju skočnog prozora
+ Kontroliranje reproduktora gestama
+ Koristi geste za kontrolu svjetline i glasnoće reproduktora
Sugestije pri traženju
- Prikaži sugestije pri traženju
+ Prikaži prijedloge pri traženju
Povijest pretraživanja
- Spremi svaku pretragu lokalno
- Povijest gledanja
- Spremaj povijest gledanja
+ Svaku pretragu spremi lokalno
+ Povijest
+ Pratite pogledane videozapise
Nastavi nakon dobivanja fokusa
Nastavi reproducirati nakon prekidanja (npr. telefonski pozivi)
Preuzmi
- Sljedeći video
- Prikaži sljedeći i slične videe
+ Sljedeći videozapis
+ Prikaži sljedeće i slične videozapise
URL nije podržan
- Preferirani jezik sadržaja
- Video i audio
+ Zadani jezik sadržaja
+ Video i zvuk
Skočni prozor
Izgled
Drugo
- Sviraj u pozadini
+ Reprodukcija u pozadini
Reproduciram u skočnom prozoru
Reproduciraj
Sadržaj
Prikaži eksplicitni sadržaj
- Video je dobno ograničen. Prije uključi eksplicitni sadržaj u postavkama.
+ Videozapis je dobno ograničen. Dopuštanje takvog sadržaja moguće je u postavkama.
uživo
Preuzimanja
Preuzimanja
@@ -103,23 +103,23 @@
Osvježi
Očisti
Mijenjanje veličine
- Najbolja rezolucija
+ Najbolja razlučivost
Greška
Greška u mreži
Nije moguće učitati sve ikone
- Nije moguće dekriptirati URL potpis videa.
- Nije moguće dohvatiti stranicu.
- Nije moguće dohvatiti stranicu u potpunosti.
- Sadržaj nije dostupan.
- Blokirano od GEMA-e.
- Nije moguće postaviti download menu.
- Ovo je PRIJENOS UŽIVO. Oni nisu još podržani.
- Nije moguće dobaviti stream.
+ Nije moguće dešifrirati URL potpis videozapisa
+ Nije moguće dohvatiti stranicu
+ Nije moguće u potpunosti dohvatiti stranicu
+ Sadržaj nije dostupan
+ Blokirano od GEMA-e
+ Nije moguće postaviti izbornik za preuzimanje
+ Ovo je PRIJENOS UŽIVO, koji još nije podržan.
+ Nije moguće dobaviti stream
Nije moguće učitati sliku
Aplikacija/UI se srušio
Oprostitee, ovo se nije trebalo dogoditi.
- Prijavi grešku putem e-maila
+ Prijavi pogrešku putem e-maila
Oprostite, neke greške su se dogodile.
PRIJAVI
Informacije:
@@ -129,25 +129,25 @@
Detalji:
- Ikona za pregled videa
- Ikona za pregled videa
- Profilna slika uploadera
+ Sličica pregleda videozapisa
+ Sličica pregleda videozapisa
+ Profilna slika prenositelja
Goreglasovi
Doljeglasovi
Koristi Tor
- (Eksperimentalno) Forsiraj promet preuzimanja kroz Tor radi povećane privatnosti (streamanje videa nije još podržano).
+ (Eksperimentalno) Prisili promet preuzimanja kroz Tor radi povećane privatnosti (streamanje videozapisa još nije podržano).
Prijavi grešku
Korisničke prijave
Nije moguće napraviti direktorij za preuzimanje \'%1$s\'
Napravljen direktorij za preuzimanje \'%1$s\'
- Video
- Audio
+ Videozapis
+ Zvuk
Ponovno pokušaj
- Dozvola za pisanje po memoriji je odbijena
- Koristi stari player
- Stari ugrađeni Mediaframework player.
+ Dozvola za pisanje po pohrani je odbijena
+ Koristi stari reproduktor
+ Stari ugrađeni Mediaframework reproduktor
tis
@@ -157,13 +157,13 @@
Počni
Pauziraj
Pregled
- Obriši
+ Izbriši
Kontrolna suma
Novi zadatak
U redu
- Ime datoteke
+ Naziv datoteke
Niti
Greška
Server nije podržan
@@ -172,16 +172,17 @@
NewPipe preuzima
Dodirni za detalje
Molimo pričekajte…
- Kopirano u clipboard.
- Molimo odaberite dostupni direktorij za preuzimanje.
- Ova dozvola je potrebna za otvaranje skočnog prozora
+ Kopirano u međuspremnik
+ Molimo odaberite dostupnu mapu za preuzimanje
+ Ova dozvola je potrebna za
+\notvaranje skočnog prozora
reCAPTCHA
reCAPTCHA zadatak
Traži se reCAPTCHA zadatak
Preuzimanja
- Dozvoljeni znakovi u imenima datoteka
+ Dozvoljeni znakovi u nazivima datoteka
Nedozvoljeni znakovi su zamjenjeni ovima
Znak za zamjenu
@@ -190,7 +191,7 @@
O NewPipeu
Postavke
- O
+ O aplikaciji
Licence treće strane
© %1$s od %2$s pod %3$s
Nije moguće učitati licencu
@@ -198,7 +199,7 @@
O
Doprinositelji
Licence
- Besplatni, slobodni i lagani YouTube frontend za Android.
+ Besplatna i lagana YouTube aplikacija za Android.
Pogledaj na GitHubu
Licenca za NewPipe
Ako imate ideja za prijevod, promjene u dizajnu, čišćenje koda ili neke veće promjene u kodu, pomoć je uvijek dobro došla. Što više radimo, to bolji postajemo!
@@ -210,10 +211,41 @@
Gledano
Povijest ugašena
Povijest
- Povijest prazna.
+ Povijest je prazna
Povijest očišćena
NewPipe obavijest
- Obavijesti za NewPipe pozadinske i skočne playere
+ Obavijesti za NewPipe pozadinske i skočne reproduktore
-
+ Reproduktor
+ Ponašanje
+ Povijest
+ Popis naslova
+ Poništi
+
+ Nema rezultata
+ Ovdje nema ništa osim cvrčaka
+
+ Nema pretplatnika
+
+ - %s pretplatnik
+ - %s pretplatnika
+ - %s pretplatnika
+
+
+ Nema pregleda
+
+ - %s pregled
+ - %s pregleda
+ - %s pregledi
+
+
+ Nema videozapisa
+
+ - %s video
+ - %s videozapisa
+ - %s videozapisi
+
+
+ Stavka je izbrisana
+
diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml
index 30530c73d..0081c9844 100644
--- a/app/src/main/res/values-it/strings.xml
+++ b/app/src/main/res/values-it/strings.xml
@@ -12,16 +12,16 @@
Impostazioni
Intendevi: %1$s ?
Condividi con
- Scegli browser
+ Scegli il browser
rotazione
- Cartella dei video scaricati
- Cartella in cui memorizzare i video scaricati.
+ Percorso dei video scaricati
+ Percorso in cui memorizzare i video scaricati
Inserisci il percorso per i download
Risoluzione predefinita
Riproduci con Kodi
- L\'applicazione Kore non è stata trovata. Vorresti installarla?
+ L\'applicazione Kore non è stata trovata. Vuoi installarla?
Mostra l\'opzione \"Riproduci con Kodi\"
- Mostra l\'opzione per riprodurre i video tramite Kodi.
+ Mostra l\'opzione per riprodurre i video tramite Kodi
Audio
Formato audio predefinito
WebM — formato libero
@@ -30,7 +30,7 @@
Prossimo video
Mostra video a seguire e video simili
URL non supportato
- Lingua preferita per i contenuti
+ Lingua predefinita per i contenuti
Video e Audio
Anteprima video
@@ -40,12 +40,12 @@
Mi piace
Impossibile creare la cartella di download \'%1$s\'
Creata la cartella per i download \'%1$s\'
- Usa un lettore video esterno
- Usa un lettore audio esterno
+ Usa un riproduttore video esterno
+ Usa un riproduttore audio esterno
- Cartella degli audio scaricati
- Cartella dove salvare gli audio scaricati.
- Inserisci la cartella per i file audio
+ Percorso degli audio scaricati
+ Percorso dove salvare gli audio scaricati
+ Inserisci il percorso per i file audio
Tema
Scuro
@@ -63,26 +63,26 @@
Contenuto non disponibile
Bloccato dalla GEMA
Usa Tor
- (Sperimentale) Forza il traffico in download tramite Tor per una maggiore privacy (lo streaming dei video non è ancora supportato).
+ (Sperimentale) Forza il traffico in download tramite Tor per una maggiore riservatezza (lo streaming dei video non è ancora supportato).
Impossibile analizzare il sito web
Impossibile impostare il menù di download
- Questo è uno stream dal vivo. Gli stream dal vivo non sono ancora supportati.
+ Questo è uno stream in diretta, il quale non è ancora supportato.
Contenuti
Mostra contenuti vincolati all\'età
- Questo video è riservato ad un pubblico maturo. Per accedervi, abilita \"Mostra video vincolati all\'età\" nelle impostazioni.
+ Questo video è riservato ad un pubblico maggiorenne. Per accedervi, abilita \"Mostra video vincolati all\'età\" nelle impostazioni.
Tocca \"cerca\" per iniziare
- Inizia automaticamente la riproduzione se NewPipe viene aperto da un\'altra app
+ Riproduzione automatica
Riproduci i video automaticamente quando NewPipe viene aperto da un\'altra app
in diretta
- Impossibile eseguire il parsing completo del sito
- Non è stato ottenuto alcuno stream
+ Impossibile analizzare completamente il sito web
+ Non è stato ottenuto alcun flusso
Ci dispiace, non sarebbe dovuto succedere.
Segnala l\'errore via e-mail
Ci dispiace, c\'è stato qualche errore.
@@ -99,18 +99,18 @@
Video
Audio
Riprova
- È stato negato il permesso di accedere all\'archiviazione di massa
+ È stato negato il permesso di accesso all\'archiviazione di massa
Download
Download
Segnalazione errori
Inizia
Pausa
- Visualizza
+ Riproduci
Elimina
- Checksum
+ Codice di controllo
- Nuova missione
+ Nuovo obiettivo
OK
Nome del file
@@ -126,7 +126,7 @@
Seleziona una cartella disponibile in cui salvare i download
Impossibile caricare l\'immagine
- L\'app/UI è andata in crash
+ L\'app/UI si è interrotta
Cosa:\\nRichiesta:\\nLingua contenuto:\\nServizio:\\nOrario GMT:\\nPacchetto:\\nVersione:\\nVersione SO:\\nRange IP glob.:
reCAPTCHA
@@ -149,26 +149,26 @@
Apri in modalità popup
- NewPipe Modo popup
+ NewPipe in modalità popup
Riproduzione in modalità popup
Disattivato
Usa il vecchio riproduttore
-Alcune risoluzioni non avranno audio se questa opzione viene abilitata.
+Alcune risoluzioni NON avranno l\'audio se questa opzione viene abilitata
In sottofondo
Popup
- Risoluzione predefinita per il popup
+ Risoluzione predefinita per la modalità popup
Mostra risoluzioni più alte
- Solo alcuni dispositivi supportano la riproduzione di video in 2K e 4K.
- Formato video preferito
+ Solo alcuni dispositivi supportano la riproduzione di video in 2K e 4K
+ Formato video predefinito
Ricorda grandezza e posizione del popup
Ricorda l\'ultima grandezza e posizione del popup
Controlli gestuali
- Usa i gesti per controllare luminosità e volume.
+ Usa i gesti per controllare luminosità e volume
Suggerimenti di ricerca
- Mostra suggerimenti durante la ricerca.
+ Mostra i suggerimenti durante la ricerca
Popup
Filtra i risultati
@@ -177,10 +177,10 @@
Ridimensionamento
Risoluzione migliore
- Precedente riproduttore integrato facente uso di Mediaframework
+ Precedente riproduttore integrato Mediaframework
- Questo permesso è necessario
-\nper la modalità popup
+ Questo permesso è necessario
+\nper aprire la modalità popup
Impostazioni
Informazioni
@@ -206,7 +206,7 @@
Iscrizioni
- Nuovo
+ Novità
Cronologia ricerche
Salva le ricerche localmente
@@ -233,10 +233,10 @@
Cronologia cancellata
Principale
- Player
+ Riproduttore
Comportamento
Cronologia
- Playlist
+ Scaletta
Annulla
Notifiche NewPipe
@@ -262,4 +262,7 @@
Elemento eliminato
+Nulla da mostrare
+
+ Vuoi eliminare questo elemento dalla cronologia?
diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml
index 200c02810..2c638e48c 100644
--- a/app/src/main/res/values-nl/strings.xml
+++ b/app/src/main/res/values-nl/strings.xml
@@ -104,7 +104,7 @@
Toegang tot opslag geweigerd
Begin
Pauzeren
- Bekijken
+ Afspelen
Verwijderen
Controlesom
diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml
index afeb71021..0ea3a4090 100644
--- a/app/src/main/res/values-pl/strings.xml
+++ b/app/src/main/res/values-pl/strings.xml
@@ -26,7 +26,7 @@
Ścieżka zapisu pobranych audio
Podaj ścieżkę zapisu audio
- Autoodtwarzanie po wezwaniu z innej aplikacji
+ Autoodtwarzanie
Automatycznie odtwórz video kiedy NewPipe zostanie wywołany z innej aplikacji
Domyślna rozdzielczość
Odtwórz w Kodi
@@ -205,7 +205,7 @@
Zapisuj historie wyszukiwania lokalnie
Historia oglądania
Zapisuj historie oglądania
-
+
Kontynuuj odtwarzanie po przerwaniu (np. po rozmowie telefonicznej)
@@ -221,4 +221,12 @@
Historia jest pusta.
Historia została wyczyszczona
-
+Odtwarzacz
+ Zachowanie
+ Historia
+ Playlista
+ Cofnij
+
+ Brak wyników
+ Brak wyświetleń
+
diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml
index b1aa26283..9123f868c 100644
--- a/app/src/main/res/values-pt-rBR/strings.xml
+++ b/app/src/main/res/values-pt-rBR/strings.xml
@@ -7,7 +7,7 @@
Informações:
WebM — formato aberto
%1$s visualizações
- Ver
+ Reproduzir
Vídeo com restrição de idade. Permissão para vídeos com essa restrição podem ser feitas no menu configurações.
Vídeo
Reproduzir o vídeo automaticamente quando o NewPipe for aberto a partir de outro app
@@ -95,7 +95,7 @@
Não foi possível interpretar completamente o site
Miniatura do vídeo
Isto é uma transmissão ao vivo, a qual ainda não é suportada.
- Toque em busca para começar
+ Toque em pesquisar para começar
Arquivo já existe
Threads
URL inválida ou internet indisponível
@@ -233,12 +233,13 @@ abrir em modo popup
Nenhum video
- - %s video
- - %s videos
+ - %s vídeo
+ - %s vídeos
Item excluído
-Player
+Reprodutor
Não há nada aqui
-
+ Deseja apagar este item do seu histórico de busca?
+
diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml
index c9e138d1e..8fa2cf0a0 100644
--- a/app/src/main/res/values-pt/strings.xml
+++ b/app/src/main/res/values-pt/strings.xml
@@ -21,18 +21,18 @@
Introduza o caminho para os vídeos
Resolução padrão
Reproduzir no Kodi
- Aplicação não encontrada. Instalar o Kore?
+ Aplicação Kore não encontrada. Quer instalá-la?
Mostrar opção \"Reproduzir no Kodi\"
Mostra uma opção para reproduzir o vídeo no Kodi
Áudio
Formato áudio padrão
WebM — formato livre
- m4a — melhor qualidade
+ M4A — melhor qualidade
Transferir
Vídeo seguinte
Mostrar vídeos seguintes e semelhantes
URL não suportado
- Idioma preferido do conteúdo
+ Idioma predefinido do conteúdo
Vídeo e áudio
Miniatura de vídeos
@@ -60,19 +60,19 @@
Diretório \'%1$s\' criado com sucesso
Erro
Incapaz de carregar todas as miniaturas
- Incapaz de decodificar a assinatura do vídeo.
- Incapaz de processar o sítio web.
- Conteúdo não disponível.
- Bloqueado pela GEMA.
+ Incapaz de decodificar a assinatura do vídeo
+ Incapaz de processar o sítio da web
+ Conteúdo não disponível
+ Bloqueado pela GEMA
Conteúdo
Restringir conteúdo por idade
- O vídeo está restrito por idade. Ative a restrição de vídeos por idade nas definições.
+ Vídeo com restrição de idade. É possível permitir este material através das Definições.
- Não foi possível processar o sítio web.
- Não foi possível configurar o menu de transferências.
- Esta é uma EMISSÃO EM DIRETO. Estas emissões ainda não são suportadas.
- Não foi possível obter a emissão.
+ Não foi possível processar o sítio da web
+ Não foi possível configurar o menu de transferências
+ Esta é uma EMISSÃO EM DIRETO, as quais ainda não são suportadas.
+ Não foi possível obter a emissão
Desculpe, isto não deveria ter acontecido.
Reportar erro por e-mail
Ocorreram alguns erros.
@@ -86,9 +86,9 @@
Vídeo
Áudio
Tentar novamente
- Não foi concedida permissão para aceder ao armazenamento
+ Permissão para aceder ao armazenamento foi negada
Toque para iniciar a pesquisa
- Reproduzir se invocado por outra aplicação
+ Reprodução automática
Reproduzir vídeo automaticamente se o NewPipe for invocado por outra aplicação
direto
@@ -101,7 +101,7 @@
Iniciar
Pausa
- Ver
+ Reproduzir
Apagar
Checksum
@@ -115,8 +115,8 @@
URL inválido ou Internet não disponível
Toque para detalhes
Por favor aguarde…
- Copiado para a área de transferência.
- Por favor selecione um diretório disponível.
+ Copiado para a área de transferência
+ Por favor selecione um diretório disponível para download
OK
Processos
@@ -145,11 +145,11 @@ o modo “popup“
Desafio reCAPTCHA
Desafio reCAPTCHA solicitado
- Modo popup de NewPipe
+ Modo popup do NewPipe
Reproduzir em modo de popup
Usar reprodutor antigo
- Versão antiga no reprodutor Mediaframework.
+ Versão antiga do reprodutor Mediaframework
Formato de vídeo preferido
Desativado
@@ -186,10 +186,73 @@ o modo “popup“
Sobre
Colaboradores
Licenças
- Aplicação leve, simples e grátis de Youtube para Android.
- Ver no Github
+ Aplicação leve, simples e grátis de YouTube para Android.
+ Ver no GitHub
Licença do NewPipe
- Se tem ideias, tradução, alterações de design, limpeza de código ou alterações de código pesado, ajuda é sempre bem-vinda. Quanto mais se faz melhor fica!
+ Se tem ideias de tradução, alterações de design, limpeza de código ou alterações de código pesado—ajuda é sempre bem-vinda. Quanto mais se faz melhor fica!
Ler licença
Contribuição
+Subscrever
+ Subscrito
+ Canal não subscrito
+ Incapaz de alterar a subscrição
+ Incapaz de atualizar a subscrição
+
+ Principal
+ Subscrições
+
+ O que há de novo
+
+ Histórico de Pesquisa
+ Armazenar termos de pesquisa localmente
+ Histórico
+ Armazenar histórico de vídeos assistidos
+ Retomar reprodução ao ganhar foco
+ Continuar reprodução após interrupções (ex. chamadas)
+ Reprodutor de vídeo
+ Comportamento
+ Histórico
+ Lista de Reprodução
+ Desfazer
+
+ Notificação do NewPipe
+ Notificações do NewPipe em Segundo Plano e Reprodutores de Vídeo em Popup
+
+ Sem resultados
+ Aqui não há nada para ver
+
+ Sem subscritores
+
+ - %s subscrito
+ - %s subscritos
+
+
+ Sem visualizações
+
+ - %s visualização
+ - %s visualizações
+
+
+ Sem vídeos
+
+ - %s vídeo
+ - %s vídeos
+
+
+ Download
+ Caracteres permitidos em nomes de ficheiros
+ Caracteres inválidos são substituídos por este valor
+ Caracter de substituição
+
+ Letras e dígitos
+ Caracteres mais especiais
+
+ Histórico
+ Procurados
+ Visualizado
+ Histórico está desativado
+ Histórico
+ O histórico está vazio
+ Histórico eliminado
+ Objeto eliminado
diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml
index 372ee9435..4424781f8 100644
--- a/app/src/main/res/values-ru/strings.xml
+++ b/app/src/main/res/values-ru/strings.xml
@@ -79,7 +79,7 @@
Ошибка
Ваш комментарий (на английском):
Невозможно создать папку для загрузки \'%1$s\'
- Автоматически воспроизводить при открытии из другого приложения
+ Воспроизводить автоматически
Автоматически воспроизводить видео при вызове NewPipe из другого приложения
Контент
Видео с возрастными ограничениями. Разрешить подобный контент можно в настройках.
@@ -96,10 +96,10 @@
Это прямая трансляция, они пока не поддерживаются.
Не удалось загрузить изображение
"Падение приложения/пользовательского интерфейса "
- Простите, такое не должно было произойти.
+ Простите, это не должно было произойти.
Отправить отчёт об ошибке по электронной почте
Простите, произошли ошибки.
- ОТЧЕТ
+ ОТЧЁТ
Информация:
Что произошло:
Детали:
@@ -223,4 +223,38 @@
История пуста
История очищена
+Плеер
+ Поведение
+ История
+ Плейлист
+ Отменить
+
+ Нет результатов
+ Тут только сверчки
+
+ Нет подписчиков
+
+ - %s подписчик
+ - %s подписчика
+ - %s подписчиков
+
+
+
+ Нет просмотров
+
+ - %s просмотр
+ - %s просмотра
+ - %s просмотров
+
+
+
+ Нет видео
+
+ - %s видео
+ - %s видео
+ - %s видео
+
+
+
+ Элемент удалён
diff --git a/app/src/main/res/values-sl/strings.xml b/app/src/main/res/values-sl/strings.xml
index 3bd31c4c5..798063738 100644
--- a/app/src/main/res/values-sl/strings.xml
+++ b/app/src/main/res/values-sl/strings.xml
@@ -102,7 +102,7 @@
Začnite z iskanjem
Začni
Premor
- Poglej
+ Predvajaj
Izbriši
Nadzorna vsota
@@ -272,4 +272,5 @@ odpiranje v pojavnem načinu
Predmet je izbrisan
+Ali želite izbrisati predmet iz zgodovine iskanja?
diff --git a/app/src/main/res/values-sr/strings.xml b/app/src/main/res/values-sr/strings.xml
index 26fc272ff..9bb47a7c7 100644
--- a/app/src/main/res/values-sr/strings.xml
+++ b/app/src/main/res/values-sr/strings.xml
@@ -100,7 +100,7 @@
Аутоматско пуштање видеа по позиву друге апликације
Почни
Паузирај
- Приказ
+ Пусти
Обриши
Хеш
diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml
index c0bab0191..d56ff5e11 100644
--- a/app/src/main/res/values-tr/strings.xml
+++ b/app/src/main/res/values-tr/strings.xml
@@ -1,9 +1,9 @@
Başlamak için aramaya dokunun
- %1$s izlenme
+ %1$s görüntüleme
Yayımlanma: %1$s
- Yayın oynatıcı bulunamadı. VLC\'yi kurmak ister misiniz?
+ Akış oynatıcı bulunamadı. VLC\'yi kurmak ister misiniz?
Kur
İptal
Tarayıcıda aç
@@ -12,7 +12,7 @@
Ara
Ayarlar
Bunu mu demek istediniz: %1$s ?
- Bununla paylaş
+ Şununla paylaş
Tarayıcı seç
döndürme
Harici video oynatıcı kullan
@@ -26,17 +26,17 @@
İndirilmiş seslerin saklanacağı konum
Ses dosyaları için indirme konumu girin
- Başka uygulamadan çağrıldığında kendiliğinden oynat
+ Kendiliğinden oynat
NewPipe başka bir uygulamadan çağırıldığında videoyu kendiliğinden oynatır
Öntanımlı çözünürlük
- Kodi ile çal
- Kore uygulaması bulunamadı. Kurmak ister misiniz?
+ Kodi ile oynat
+ Kore uygulaması bulunamadı. Kur?
\"Kodi ile Oynat\" seçeneğini göster
- Kodi medya merkezi aracılığıyla video oynatmak için bir seçenek görüntüler
+ Kodi ortam merkezi aracılığıyla video oynatmak için bir seçenek görüntüler
Öntanımlı ses biçimi
- WebM - özgür biçim
- m4a — daha iyi kalite
- Tema
+ WebM — özgür biçim
+ M4A — daha iyi nitelik
+ Gövde
Koyu
Açık
@@ -44,16 +44,16 @@
Sonraki video
Sonraki ve benzer videoları göster
URL desteklenmiyor
- Yeğlenen içerik dili
+ Öntanımlı içerik dili
Ses
Video ve Ses
Görünüm
Diğer
- Arka planda çalıyor
+ Arka planda oynatıyor
Oynat
İçerik
Yaş sınırlı içeriği göster
- Bu video Yaş Sınırlıdır. İlk önce ayarlardaki yaş sınırlı videoları etkinleştirin.
+ Yaş Sınırlı Video. Bu gibi materyallere Ayarlar\'dan izin verilebilir.
canlı
İndirilenler
İndirilenler
@@ -62,24 +62,24 @@
Hata
Ağ hatası
Küçük resimlerin tümü yüklenemedi
- Video URL imzası çözülemedi.
- Web sitesi ayrıştırılamadı.
- Web sitesi tümüyle ayrıştırılamadı.
- İçerik yok.
- GEMA tarafından engellendi.
- Bu bir CANLI YAYIN. Bunlar henüz desteklenmiyor.
- Herhangi bir yayın alınamadı.
+ Video URL imzası çözülemedi
+ Web sitesi ayrıştırılamadı
+ Web sitesi tümüyle ayrıştırılamadı
+ İçerik kullanılabilir değil
+ GEMA tarafından engellendi
+ Bu bir CANLI AKIŞ, henüz desteklenmiyor.
+ Herhangi bir akış alınamadı
Resim yüklenemedi
Uygulama/Kullanıcı arayüzü çöktü
Üzgünüz, bu olmamalıydı.
- Hatayı postayla bildir
+ Hatayı e-postayla bildir
Üzgünüz, bazı hatalar oluştu.
BİLDİR
Bilgi:
Ne oldu:
Ne:\\nİstek:\\nİçerik Dili:\\nHizmet:\\nGMT Zamanı:\\nPaket:\\nSürüm:\\nİşletim sistemi sürümü:\\nGlob. IP aralığı:
Video ön izleme küçük resmi
- Yükleyenin kullanıcı küçük resmi
+ Yükleyenin küçük resmi
Beğeni
Beğenmeme
Tor kullan
@@ -93,11 +93,11 @@
Video
Ses
Yeniden dene
- Depolamaya erişme izni reddedildi
+ Depolama erişim izni reddedildi
Başlat
Duraklat
- Görünüm
+ Oynat
Sil
Sağlama
@@ -114,13 +114,13 @@
NewPipe İndiriyor
Ayrıntılar için dokun
Lütfen bekleyin…
- Panoya kopyalandı.
- Lütfen kullanılabilir bir indirme dizini seçin.
+ Panoya kopyalandı
+ Lütfen uygun bir indirme klasörü seçin
- İndirme menüsü kurulamadı.
+ İndirme menüsü ayarlanamadı
Açılır pencere kipinde aç
- NewPipe Açılır pencere kipi
+ NewPipe açılır pencere kipi
Öntanımlı açılır pencere çözünürlüğü
Daha yüksek çözünürlükleri göster
@@ -141,7 +141,7 @@
Video ön izleme küçük resmi
Eski oynatıcıyı kullan
- Eski içe gömülü Mediaframework oynatıcısı.
+ Eski içe gömülü Mediaframework oynatıcısı
K
@@ -162,15 +162,15 @@
Yenile
Temizle
- Açılır pencere boyutunu ve yerini hatırla
- Açılır pencerenin ayarlandığı en son boyutu ve yeri hatırla
+ Açılır pencere boyutunu ve yerini anımsa
+ Açılır pencerenin ayarlandığı son boyutu ve yeri anımsa
Açılır Pencere
Boyutlandırılıyor
Bu seçenek etkinken bazı çözünürlüklerin sesi olmayacak
Oynatıcının parlaklığını ve sesini yönetmek için el hareketlerini kullan
- Oynatıcı el hareketi kontrolleri
+ Oynatıcı el hareketi denetimleri
Arama önerileri
Ararken önerileri göster
@@ -186,10 +186,10 @@
Hakkında
Katkıda bulunanlar
Lisanslar
- Android için hafif ücretsiz bir Youtube arayüzü.
- Github\'da görüntüle
+ Android için özgür hafif bir YouTube arayüzü.
+ GitHub\'da gör
NewPipe\'ın Lisansı
- Fikirleriniz, çeviri, tasarım değişiklikleri olsun, kod temizliği, yada gerçek köklü kod değişikleri olsun, yardımınıza her zaman açığız. Daha çok yapıldıkça daha iyiye gider!
+ Fikirleriniz; çeviri, tasarım değişiklikleri, kod temizliği, ya da gerçek köklü kod değişikleri olsun—yardımınıza her zaman açığız. Daha çok yapıldıkça daha iyiye gider!
Lisansı oku
Katkı
İndirme
@@ -200,4 +200,60 @@
Harfler ve rakamlar
Özel karakterlerin çoğu
-
+ Abone ol
+ Abone olundu
+ Kanal aboneliğinden çıktınız
+ Abonelik değiştirilemiyor
+ Abonelik güncellenemiyor
+
+ Temel
+ Abonelikler
+
+ Yenilikler Ne
+
+ Arama geçmişi
+ Arama sorgularını yerel olarak biriktir
+ Geçmiş
+ İzlenen videoların kaydını tut
+ Odaklanıldığında sürdür
+ Kesilmelerden sonra (örn. telefon çağrıları) oynatmayı sürdür
+ Oynatıcı
+ Davranış
+ Geçmiş
+ Oynatma listesi
+ Geri al
+
+ NewPipe Bildirimi
+ New Pipe Arka Plan ve Açılır Pencere Oynatıcıları için bildirimler
+
+ Sonuç yok
+ Burada Cırcır Böceklerinden Başka Şey Yok
+
+ Abone yok
+
+ - %s abone
+ - %s abone
+
+
+ Görüntüleme yok
+
+ - %s görüntüleme
+ - %s görüntüleme
+
+
+ Video yok
+
+ - %s video
+ - %s video
+
+
+ Geçmiş
+ Arandı
+ İzlendi
+ Geçmiş devre dışı
+ Geçmiş
+ Geçmiş boş
+ Geçmiş temizlendi
+ Öge silindi
+Bu içeriği arama geçmişinden silmek istiyor musunuz?
+
diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml
index af4216e42..3d7166d84 100644
--- a/app/src/main/res/values-vi/strings.xml
+++ b/app/src/main/res/values-vi/strings.xml
@@ -5,7 +5,7 @@
Không tìm thấy trình phát. Bạn có muốn cài đặt VLC?
Cài đặt
Hủy
- Mở trong teinhf duyệt
+ Mở trong trình duyệt
Mở trong chế độ popup
Chia sẻ
Tải về
@@ -179,4 +179,8 @@
Ngôn ngữ nội dung ưu tiên
Video & Âm thanh
Bật lên
+ Lịch sử
+ Lịch sử
+ Danh sách
+ Không tìm thấy
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index a5b3993d8..e798e62e9 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -194,7 +194,7 @@
Start
Pause
- View
+ Play
Delete
Checksum
@@ -265,4 +265,5 @@
The history is empty
History cleared
Item deleted
+ Do you want to delete this item from search history?
diff --git a/app/src/test/java/us/shandian/giga/get/get/DownloadManagerImplTest.java b/app/src/test/java/us/shandian/giga/get/DownloadManagerImplTest.java
similarity index 84%
rename from app/src/test/java/us/shandian/giga/get/get/DownloadManagerImplTest.java
rename to app/src/test/java/us/shandian/giga/get/DownloadManagerImplTest.java
index a7242ba10..6ff702273 100644
--- a/app/src/test/java/us/shandian/giga/get/get/DownloadManagerImplTest.java
+++ b/app/src/test/java/us/shandian/giga/get/DownloadManagerImplTest.java
@@ -1,4 +1,4 @@
-package us.shandian.giga.get.get;
+package us.shandian.giga.get;
import org.junit.Ignore;
import org.junit.Test;
@@ -153,4 +153,34 @@ public class DownloadManagerImplTest {
assertSame(missions.get(1), downloadManager.getMission(1));
}
+ @Test
+ public void sortByTimestamp() throws Exception {
+ ArrayList downloadMissions = new ArrayList<>();
+ DownloadMission mission = new DownloadMission();
+ mission.timestamp = 0;
+
+ DownloadMission mission1 = new DownloadMission();
+ mission1.timestamp = Integer.MAX_VALUE + 1L;
+
+ DownloadMission mission2 = new DownloadMission();
+ mission2.timestamp = 2L * Integer.MAX_VALUE ;
+
+ DownloadMission mission3 = new DownloadMission();
+ mission3.timestamp = 2L * Integer.MAX_VALUE + 5L;
+
+
+ downloadMissions.add(mission3);
+ downloadMissions.add(mission1);
+ downloadMissions.add(mission2);
+ downloadMissions.add(mission);
+
+
+ DownloadManagerImpl.sortByTimestamp(downloadMissions);
+
+ assertEquals(mission, downloadMissions.get(0));
+ assertEquals(mission1, downloadMissions.get(1));
+ assertEquals(mission2, downloadMissions.get(2));
+ assertEquals(mission3, downloadMissions.get(3));
+ }
+
}
\ No newline at end of file