+ * StreamInfoItemHolder.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 .
+ */
+
+public class PlayQueueItemHolder extends RecyclerView.ViewHolder {
+
+ public final TextView itemVideoTitleView, itemDurationView, itemAdditionalDetailsView;
+ public final ImageView itemSelected, itemThumbnailView, itemHandle;
+
+ public final View itemRoot;
+
+ public PlayQueueItemHolder(View v) {
+ super(v);
+ itemRoot = v.findViewById(R.id.itemRoot);
+ itemVideoTitleView = v.findViewById(R.id.itemVideoTitleView);
+ itemDurationView = v.findViewById(R.id.itemDurationView);
+ itemAdditionalDetailsView = v.findViewById(R.id.itemAdditionalDetails);
+ itemSelected = v.findViewById(R.id.itemSelected);
+ itemThumbnailView = v.findViewById(R.id.itemThumbnailView);
+ itemHandle = v.findViewById(R.id.itemHandle);
+ }
+}
diff --git a/app/src/main/java/org/schabi/newpipe/playlist/SinglePlayQueue.java b/app/src/main/java/org/schabi/newpipe/playlist/SinglePlayQueue.java
new file mode 100644
index 000000000..fc68e931a
--- /dev/null
+++ b/app/src/main/java/org/schabi/newpipe/playlist/SinglePlayQueue.java
@@ -0,0 +1,19 @@
+package org.schabi.newpipe.playlist;
+
+import org.schabi.newpipe.extractor.stream.StreamInfo;
+
+import java.util.Collections;
+
+public final class SinglePlayQueue extends PlayQueue {
+ public SinglePlayQueue(final StreamInfo info) {
+ super(0, Collections.singletonList(new PlayQueueItem(info)));
+ }
+
+ @Override
+ public boolean isComplete() {
+ return true;
+ }
+
+ @Override
+ public void fetch() {}
+}
diff --git a/app/src/main/java/org/schabi/newpipe/playlist/events/AppendEvent.java b/app/src/main/java/org/schabi/newpipe/playlist/events/AppendEvent.java
new file mode 100644
index 000000000..b3ba8835a
--- /dev/null
+++ b/app/src/main/java/org/schabi/newpipe/playlist/events/AppendEvent.java
@@ -0,0 +1,19 @@
+package org.schabi.newpipe.playlist.events;
+
+
+public class AppendEvent implements PlayQueueEvent {
+ final private int amount;
+
+ @Override
+ public PlayQueueEventType type() {
+ return PlayQueueEventType.APPEND;
+ }
+
+ public AppendEvent(final int amount) {
+ this.amount = amount;
+ }
+
+ public int getAmount() {
+ return amount;
+ }
+}
diff --git a/app/src/main/java/org/schabi/newpipe/playlist/events/ErrorEvent.java b/app/src/main/java/org/schabi/newpipe/playlist/events/ErrorEvent.java
new file mode 100644
index 000000000..45629feb6
--- /dev/null
+++ b/app/src/main/java/org/schabi/newpipe/playlist/events/ErrorEvent.java
@@ -0,0 +1,31 @@
+package org.schabi.newpipe.playlist.events;
+
+
+public class ErrorEvent implements PlayQueueEvent {
+ final private int errorIndex;
+ final private int queueIndex;
+ final private boolean skippable;
+
+ @Override
+ public PlayQueueEventType type() {
+ return PlayQueueEventType.ERROR;
+ }
+
+ public ErrorEvent(final int errorIndex, final int queueIndex, final boolean skippable) {
+ this.errorIndex = errorIndex;
+ this.queueIndex = queueIndex;
+ this.skippable = skippable;
+ }
+
+ public int getErrorIndex() {
+ return errorIndex;
+ }
+
+ public int getQueueIndex() {
+ return queueIndex;
+ }
+
+ public boolean isSkippable() {
+ return skippable;
+ }
+}
diff --git a/app/src/main/java/org/schabi/newpipe/playlist/events/InitEvent.java b/app/src/main/java/org/schabi/newpipe/playlist/events/InitEvent.java
new file mode 100644
index 000000000..1c1d01508
--- /dev/null
+++ b/app/src/main/java/org/schabi/newpipe/playlist/events/InitEvent.java
@@ -0,0 +1,8 @@
+package org.schabi.newpipe.playlist.events;
+
+public class InitEvent implements PlayQueueEvent {
+ @Override
+ public PlayQueueEventType type() {
+ return PlayQueueEventType.INIT;
+ }
+}
diff --git a/app/src/main/java/org/schabi/newpipe/playlist/events/MoveEvent.java b/app/src/main/java/org/schabi/newpipe/playlist/events/MoveEvent.java
new file mode 100644
index 000000000..4370fe328
--- /dev/null
+++ b/app/src/main/java/org/schabi/newpipe/playlist/events/MoveEvent.java
@@ -0,0 +1,24 @@
+package org.schabi.newpipe.playlist.events;
+
+public class MoveEvent implements PlayQueueEvent {
+ final private int fromIndex;
+ final private int toIndex;
+
+ @Override
+ public PlayQueueEventType type() {
+ return PlayQueueEventType.MOVE;
+ }
+
+ public MoveEvent(final int oldIndex, final int newIndex) {
+ this.fromIndex = oldIndex;
+ this.toIndex = newIndex;
+ }
+
+ public int getFromIndex() {
+ return fromIndex;
+ }
+
+ public int getToIndex() {
+ return toIndex;
+ }
+}
diff --git a/app/src/main/java/org/schabi/newpipe/playlist/events/PlayQueueEvent.java b/app/src/main/java/org/schabi/newpipe/playlist/events/PlayQueueEvent.java
new file mode 100644
index 000000000..c56c3fbc0
--- /dev/null
+++ b/app/src/main/java/org/schabi/newpipe/playlist/events/PlayQueueEvent.java
@@ -0,0 +1,7 @@
+package org.schabi.newpipe.playlist.events;
+
+import java.io.Serializable;
+
+public interface PlayQueueEvent extends Serializable {
+ PlayQueueEventType type();
+}
diff --git a/app/src/main/java/org/schabi/newpipe/playlist/events/PlayQueueEventType.java b/app/src/main/java/org/schabi/newpipe/playlist/events/PlayQueueEventType.java
new file mode 100644
index 000000000..0fc40c098
--- /dev/null
+++ b/app/src/main/java/org/schabi/newpipe/playlist/events/PlayQueueEventType.java
@@ -0,0 +1,27 @@
+package org.schabi.newpipe.playlist.events;
+
+public enum PlayQueueEventType {
+ INIT,
+
+ // sent when the index is changed
+ SELECT,
+
+ // sent when more streams are added to the play queue
+ APPEND,
+
+ // sent when a pending stream is removed from the play queue
+ REMOVE,
+
+ // sent when two streams swap place in the play queue
+ MOVE,
+
+ // sent when queue is shuffled
+ REORDER,
+
+ // sent when recovery record is set on a stream
+ RECOVERY,
+
+ // sent when the item at index has caused an exception
+ ERROR
+}
+
diff --git a/app/src/main/java/org/schabi/newpipe/playlist/events/RecoveryEvent.java b/app/src/main/java/org/schabi/newpipe/playlist/events/RecoveryEvent.java
new file mode 100644
index 000000000..715cf88c4
--- /dev/null
+++ b/app/src/main/java/org/schabi/newpipe/playlist/events/RecoveryEvent.java
@@ -0,0 +1,25 @@
+package org.schabi.newpipe.playlist.events;
+
+
+public class RecoveryEvent implements PlayQueueEvent {
+ final private int index;
+ final private long position;
+
+ @Override
+ public PlayQueueEventType type() {
+ return PlayQueueEventType.RECOVERY;
+ }
+
+ public RecoveryEvent(final int index, final long position) {
+ this.index = index;
+ this.position = position;
+ }
+
+ public int getIndex() {
+ return index;
+ }
+
+ public long getPosition() {
+ return position;
+ }
+}
diff --git a/app/src/main/java/org/schabi/newpipe/playlist/events/RemoveEvent.java b/app/src/main/java/org/schabi/newpipe/playlist/events/RemoveEvent.java
new file mode 100644
index 000000000..464dbfa49
--- /dev/null
+++ b/app/src/main/java/org/schabi/newpipe/playlist/events/RemoveEvent.java
@@ -0,0 +1,25 @@
+package org.schabi.newpipe.playlist.events;
+
+
+public class RemoveEvent implements PlayQueueEvent {
+ final private int removeIndex;
+ final private int queueIndex;
+
+ @Override
+ public PlayQueueEventType type() {
+ return PlayQueueEventType.REMOVE;
+ }
+
+ public RemoveEvent(final int removeIndex, final int queueIndex) {
+ this.removeIndex = removeIndex;
+ this.queueIndex = queueIndex;
+ }
+
+ public int getQueueIndex() {
+ return queueIndex;
+ }
+
+ public int getRemoveIndex() {
+ return removeIndex;
+ }
+}
diff --git a/app/src/main/java/org/schabi/newpipe/playlist/events/ReorderEvent.java b/app/src/main/java/org/schabi/newpipe/playlist/events/ReorderEvent.java
new file mode 100644
index 000000000..f1d09d457
--- /dev/null
+++ b/app/src/main/java/org/schabi/newpipe/playlist/events/ReorderEvent.java
@@ -0,0 +1,12 @@
+package org.schabi.newpipe.playlist.events;
+
+public class ReorderEvent implements PlayQueueEvent {
+ @Override
+ public PlayQueueEventType type() {
+ return PlayQueueEventType.REORDER;
+ }
+
+ public ReorderEvent() {
+
+ }
+}
diff --git a/app/src/main/java/org/schabi/newpipe/playlist/events/SelectEvent.java b/app/src/main/java/org/schabi/newpipe/playlist/events/SelectEvent.java
new file mode 100644
index 000000000..d1d0b1137
--- /dev/null
+++ b/app/src/main/java/org/schabi/newpipe/playlist/events/SelectEvent.java
@@ -0,0 +1,25 @@
+package org.schabi.newpipe.playlist.events;
+
+
+public class SelectEvent implements PlayQueueEvent {
+ final private int oldIndex;
+ final private int newIndex;
+
+ @Override
+ public PlayQueueEventType type() {
+ return PlayQueueEventType.SELECT;
+ }
+
+ public SelectEvent(final int oldIndex, final int newIndex) {
+ this.oldIndex = oldIndex;
+ this.newIndex = newIndex;
+ }
+
+ public int getOldIndex() {
+ return oldIndex;
+ }
+
+ public int getNewIndex() {
+ return newIndex;
+ }
+}
diff --git a/app/src/main/java/org/schabi/newpipe/settings/BasePreferenceFragment.java b/app/src/main/java/org/schabi/newpipe/settings/BasePreferenceFragment.java
index a16f7dd79..e3c52cdad 100644
--- a/app/src/main/java/org/schabi/newpipe/settings/BasePreferenceFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/settings/BasePreferenceFragment.java
@@ -19,8 +19,8 @@ public abstract class BasePreferenceFragment extends PreferenceFragmentCompat {
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
defaultPreferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
+ super.onCreate(savedInstanceState);
}
@Override
diff --git a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java
index 6021b40fd..2cda95987 100644
--- a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java
@@ -1,12 +1,175 @@
package org.schabi.newpipe.settings;
+import android.app.Activity;
import android.os.Bundle;
+import android.support.v7.preference.ListPreference;
+import android.support.v7.preference.Preference;
import org.schabi.newpipe.R;
+import org.schabi.newpipe.extractor.NewPipe;
+import org.schabi.newpipe.extractor.StreamingService;
+import org.schabi.newpipe.extractor.exceptions.ExtractionException;
+import org.schabi.newpipe.report.ErrorActivity;
+import org.schabi.newpipe.report.UserAction;
+import org.schabi.newpipe.util.Constants;
+import org.schabi.newpipe.util.KioskTranslator;
public class ContentSettingsFragment extends BasePreferenceFragment {
+
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
+
addPreferencesFromResource(R.xml.content_settings);
+
+ final ListPreference mainPageContentPref = (ListPreference) findPreference(getString(R.string.main_page_content_key));
+ mainPageContentPref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValueO) {
+ final String newValue = newValueO.toString();
+
+ final String mainPrefOldValue =
+ defaultPreferences.getString(getString(R.string.main_page_content_key), "blank_page");
+ final String mainPrefOldSummary = getMainPagePrefSummery(mainPrefOldValue, mainPageContentPref);
+
+ if(newValue.equals(getString(R.string.kiosk_page_key))) {
+ SelectKioskFragment selectKioskFragment = new SelectKioskFragment();
+ selectKioskFragment.setOnSelectedLisener(new SelectKioskFragment.OnSelectedLisener() {
+ @Override
+ public void onKioskSelected(String kioskId, int service_id) {
+ defaultPreferences.edit()
+ .putInt(getString(R.string.main_page_selected_service), service_id).apply();
+ defaultPreferences.edit()
+ .putString(getString(R.string.main_page_selectd_kiosk_id), kioskId).apply();
+ String serviceName = "";
+ try {
+ serviceName = NewPipe.getService(service_id).getServiceInfo().name;
+ } catch (ExtractionException e) {
+ onError(e);
+ }
+ String kioskName = KioskTranslator.getTranslatedKioskName(kioskId,
+ getContext());
+
+ String summary =
+ String.format(getString(R.string.service_kiosk_string),
+ serviceName,
+ kioskName);
+
+ mainPageContentPref.setSummary(summary);
+ }
+ });
+ selectKioskFragment.setOnCancelListener(new SelectKioskFragment.OnCancelListener() {
+ @Override
+ public void onCancel() {
+ mainPageContentPref.setSummary(mainPrefOldSummary);
+ mainPageContentPref.setValue(mainPrefOldValue);
+ }
+ });
+ selectKioskFragment.show(getFragmentManager(), "select_kiosk");
+ } else if(newValue.equals(getString(R.string.channel_page_key))) {
+ SelectChannelFragment selectChannelFragment = new SelectChannelFragment();
+ selectChannelFragment.setOnSelectedLisener(new SelectChannelFragment.OnSelectedLisener() {
+ @Override
+ public void onChannelSelected(String url, String name, int service) {
+ defaultPreferences.edit()
+ .putInt(getString(R.string.main_page_selected_service), service).apply();
+ defaultPreferences.edit()
+ .putString(getString(R.string.main_page_selected_channel_url), url).apply();
+ defaultPreferences.edit()
+ .putString(getString(R.string.main_page_selected_channel_name), name).apply();
+
+ mainPageContentPref.setSummary(name);
+ }
+ });
+ selectChannelFragment.setOnCancelListener(new SelectChannelFragment.OnCancelListener() {
+ @Override
+ public void onCancel() {
+ mainPageContentPref.setSummary(mainPrefOldSummary);
+ mainPageContentPref.setValue(mainPrefOldValue);
+ }
+ });
+ selectChannelFragment.show(getFragmentManager(), "select_channel");
+ } else {
+ mainPageContentPref.setSummary(getMainPageSummeryByKey(newValue));
+ }
+
+ defaultPreferences.edit().putBoolean(Constants.KEY_MAIN_PAGE_CHANGE, true).apply();
+
+ return true;
+ }
+ });
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+
+ final String mainPageContentKey = getString(R.string.main_page_content_key);
+ final Preference mainPagePref = findPreference(getString(R.string.main_page_content_key));
+ final String bpk = getString(R.string.blank_page_key);
+ if(defaultPreferences.getString(mainPageContentKey, bpk)
+ .equals(getString(R.string.channel_page_key))) {
+ mainPagePref.setSummary(defaultPreferences.getString(getString(R.string.main_page_selected_channel_name), "error"));
+ } else if(defaultPreferences.getString(mainPageContentKey, bpk)
+ .equals(getString(R.string.kiosk_page_key))) {
+ try {
+ StreamingService service = NewPipe.getService(
+ defaultPreferences.getInt(
+ getString(R.string.main_page_selected_service), 0));
+
+ String kioskName = KioskTranslator.getTranslatedKioskName(
+ defaultPreferences.getString(
+ getString(R.string.main_page_selectd_kiosk_id), "Trending"),
+ getContext());
+
+ String summary =
+ String.format(getString(R.string.service_kiosk_string),
+ service.getServiceInfo().name,
+ kioskName);
+
+ mainPagePref.setSummary(summary);
+ } catch (Exception e) {
+ onError(e);
+ }
+ }
+ }
+
+ /*//////////////////////////////////////////////////////////////////////////
+ // Utils
+ //////////////////////////////////////////////////////////////////////////*/
+ private String getMainPagePrefSummery(final String mainPrefOldValue, final ListPreference mainPageContentPref) {
+ if(mainPrefOldValue.equals(getString(R.string.channel_page_key))) {
+ return defaultPreferences.getString(getString(R.string.main_page_selected_channel_name), "error");
+ } else {
+ return mainPageContentPref.getSummary().toString();
+ }
+ }
+
+ private int getMainPageSummeryByKey(final String key) {
+ if(key.equals(getString(R.string.blank_page_key))) {
+ return R.string.blank_page_summary;
+ } else if(key.equals(getString(R.string.kiosk_page_key))) {
+ return R.string.kiosk_page_summary;
+ } else if(key.equals(getString(R.string.feed_page_key))) {
+ return R.string.feed_page_summary;
+ } else if(key.equals(getString(R.string.subscription_page_key))) {
+ return R.string.subscription_page_summary;
+ } else if(key.equals(getString(R.string.channel_page_key))) {
+ return R.string.channel_page_summary;
+ }
+ return R.string.blank_page_summary;
+ }
+
+ /*//////////////////////////////////////////////////////////////////////////
+ // Error
+ //////////////////////////////////////////////////////////////////////////*/
+
+ protected boolean onError(Throwable e) {
+ final Activity activity = getActivity();
+ ErrorActivity.reportError(activity, e,
+ activity.getClass(),
+ null,
+ ErrorActivity.ErrorInfo.make(UserAction.UI_ERROR,
+ "none", "", R.string.app_ui_crash));
+ return true;
}
}
diff --git a/app/src/main/java/org/schabi/newpipe/settings/SelectChannelFragment.java b/app/src/main/java/org/schabi/newpipe/settings/SelectChannelFragment.java
new file mode 100644
index 000000000..97af11f1b
--- /dev/null
+++ b/app/src/main/java/org/schabi/newpipe/settings/SelectChannelFragment.java
@@ -0,0 +1,238 @@
+package org.schabi.newpipe.settings;
+
+import android.app.Activity;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.support.v4.app.DialogFragment;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ProgressBar;
+import android.widget.TextView;
+
+import com.nostra13.universalimageloader.core.DisplayImageOptions;
+import com.nostra13.universalimageloader.core.ImageLoader;
+
+import org.schabi.newpipe.R;
+import org.schabi.newpipe.database.subscription.SubscriptionEntity;
+import org.schabi.newpipe.fragments.subscription.SubscriptionService;
+import org.schabi.newpipe.report.ErrorActivity;
+import org.schabi.newpipe.report.UserAction;
+
+import java.util.List;
+import java.util.Vector;
+
+import de.hdodenhof.circleimageview.CircleImageView;
+import io.reactivex.Observer;
+import io.reactivex.android.schedulers.AndroidSchedulers;
+import io.reactivex.disposables.Disposable;
+import io.reactivex.schedulers.Schedulers;
+
+
+/**
+ * Created by Christian Schabesberger on 26.09.17.
+ * SelectChannelFragment.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 .
+ */
+
+public class SelectChannelFragment extends DialogFragment {
+ private SelectChannelAdapter channelAdapter;
+ private SubscriptionService subscriptionService;
+ private ImageLoader imageLoader = ImageLoader.getInstance();
+
+ private ProgressBar progressBar;
+ private TextView emptyView;
+ private RecyclerView recyclerView;
+
+ private List subscriptions = new Vector<>();
+
+ /*//////////////////////////////////////////////////////////////////////////
+ // Interfaces
+ //////////////////////////////////////////////////////////////////////////*/
+
+ public interface OnSelectedLisener {
+ void onChannelSelected(String url, String name, int service);
+ }
+ OnSelectedLisener onSelectedLisener = null;
+ public void setOnSelectedLisener(OnSelectedLisener listener) {
+ onSelectedLisener = listener;
+ }
+
+ public interface OnCancelListener {
+ void onCancel();
+ }
+ OnCancelListener onCancelListener = null;
+ public void setOnCancelListener(OnCancelListener listener) {
+ onCancelListener = listener;
+ }
+
+ /*//////////////////////////////////////////////////////////////////////////
+ // Init
+ //////////////////////////////////////////////////////////////////////////*/
+
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ View v = inflater.inflate(R.layout.select_channel_fragment, container, false);
+ recyclerView = (RecyclerView) v.findViewById(R.id.items_list);
+ recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
+ channelAdapter = new SelectChannelAdapter();
+ recyclerView.setAdapter(channelAdapter);
+
+ progressBar = v.findViewById(R.id.progressBar);
+ emptyView = v.findViewById(R.id.empty_state_view);
+ progressBar.setVisibility(View.VISIBLE);
+ recyclerView.setVisibility(View.GONE);
+ emptyView.setVisibility(View.GONE);
+
+
+ subscriptionService = SubscriptionService.getInstance();
+ subscriptionService.getSubscription().toObservable()
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(getSubscriptionObserver());
+
+ return v;
+ }
+
+
+ /*//////////////////////////////////////////////////////////////////////////
+ // Handle actions
+ //////////////////////////////////////////////////////////////////////////*/
+
+ @Override
+ public void onCancel(final DialogInterface dialogInterface) {
+ super.onCancel(dialogInterface);
+ if(onCancelListener != null) {
+ onCancelListener.onCancel();
+ }
+ }
+
+ private void clickedItem(int position) {
+ if(onSelectedLisener != null) {
+ SubscriptionEntity entry = subscriptions.get(position);
+ onSelectedLisener.onChannelSelected(entry.getUrl(), entry.getName(), entry.getServiceId());
+ }
+ dismiss();
+ }
+
+ /*//////////////////////////////////////////////////////////////////////////
+ // Item handling
+ //////////////////////////////////////////////////////////////////////////*/
+
+ private void displayChannels(List subscriptions) {
+ this.subscriptions = subscriptions;
+ progressBar.setVisibility(View.GONE);
+ if(subscriptions.isEmpty()) {
+ emptyView.setVisibility(View.VISIBLE);
+ return;
+ }
+ recyclerView.setVisibility(View.VISIBLE);
+
+ }
+
+ private Observer> getSubscriptionObserver() {
+ return new Observer>() {
+ @Override
+ public void onSubscribe(Disposable d) {
+ }
+
+ @Override
+ public void onNext(List subscriptions) {
+ displayChannels(subscriptions);
+ }
+
+ @Override
+ public void onError(Throwable exception) {
+ onError(exception);
+ }
+
+ @Override
+ public void onComplete() {
+ }
+ };
+ }
+
+ private class SelectChannelAdapter extends
+ RecyclerView.Adapter {
+
+ @Override
+ public SelectChannelItemHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ View item = LayoutInflater.from(parent.getContext())
+ .inflate(R.layout.select_channel_item, parent, false);
+ return new SelectChannelItemHolder(item);
+ }
+
+ @Override
+ public void onBindViewHolder(SelectChannelItemHolder holder, final int position) {
+ SubscriptionEntity entry = subscriptions.get(position);
+ holder.titleView.setText(entry.getName());
+ holder.view.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ clickedItem(position);
+ }
+ });
+ imageLoader.displayImage(entry.getAvatarUrl(), holder.thumbnailView, DISPLAY_IMAGE_OPTIONS);
+ }
+
+ @Override
+ public int getItemCount() {
+ return subscriptions.size();
+ }
+
+ public class SelectChannelItemHolder extends RecyclerView.ViewHolder {
+ public SelectChannelItemHolder(View v) {
+ super(v);
+ this.view = v;
+ thumbnailView = v.findViewById(R.id.itemThumbnailView);
+ titleView = v.findViewById(R.id.itemTitleView);
+ }
+ public View view;
+ public CircleImageView thumbnailView;
+ public TextView titleView;
+ }
+ }
+
+ /*//////////////////////////////////////////////////////////////////////////
+ // Error
+ //////////////////////////////////////////////////////////////////////////*/
+
+ protected boolean onError(Throwable e) {
+ final Activity activity = getActivity();
+ ErrorActivity.reportError(activity, e,
+ activity.getClass(),
+ null,
+ ErrorActivity.ErrorInfo.make(UserAction.UI_ERROR,
+ "none", "", R.string.app_ui_crash));
+ return true;
+ }
+
+
+ /*//////////////////////////////////////////////////////////////////////////
+ // ImageLoaderOptions
+ //////////////////////////////////////////////////////////////////////////*/
+
+ /**
+ * Base display options
+ */
+ public static final DisplayImageOptions DISPLAY_IMAGE_OPTIONS =
+ new DisplayImageOptions.Builder()
+ .cacheInMemory(true)
+ .build();
+}
diff --git a/app/src/main/java/org/schabi/newpipe/settings/SelectKioskFragment.java b/app/src/main/java/org/schabi/newpipe/settings/SelectKioskFragment.java
new file mode 100644
index 000000000..9e5420b6e
--- /dev/null
+++ b/app/src/main/java/org/schabi/newpipe/settings/SelectKioskFragment.java
@@ -0,0 +1,192 @@
+package org.schabi.newpipe.settings;
+
+import android.app.Activity;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.support.v4.app.DialogFragment;
+import android.support.v4.content.ContextCompat;
+import android.support.v7.widget.LinearLayoutManager;
+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 org.schabi.newpipe.database.subscription.SubscriptionEntity;
+import org.schabi.newpipe.extractor.NewPipe;
+import org.schabi.newpipe.extractor.StreamingService;
+import org.schabi.newpipe.fragments.subscription.SubscriptionService;
+import org.schabi.newpipe.report.ErrorActivity;
+import org.schabi.newpipe.report.UserAction;
+import org.schabi.newpipe.util.KioskTranslator;
+import org.schabi.newpipe.util.ServiceIconMapper;
+
+import java.util.List;
+import java.util.Vector;
+
+import io.reactivex.android.schedulers.AndroidSchedulers;
+import io.reactivex.schedulers.Schedulers;
+
+/**
+ * Created by Christian Schabesberger on 09.10.17.
+ * SelectKioskFragment.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 .
+ */
+
+public class SelectKioskFragment extends DialogFragment {
+
+ RecyclerView recyclerView = null;
+ SelectKioskAdapter selectKioskAdapter = null;
+
+ /*//////////////////////////////////////////////////////////////////////////
+ // Interfaces
+ //////////////////////////////////////////////////////////////////////////*/
+
+ public interface OnSelectedLisener {
+ void onKioskSelected(String kioskId, int service_id);
+ }
+
+ OnSelectedLisener onSelectedLisener = null;
+ public void setOnSelectedLisener(OnSelectedLisener listener) {
+ onSelectedLisener = listener;
+ }
+
+ public interface OnCancelListener {
+ void onCancel();
+ }
+ OnCancelListener onCancelListener = null;
+ public void setOnCancelListener(OnCancelListener listener) {
+ onCancelListener = listener;
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ View v = inflater.inflate(R.layout.select_kiosk_fragment, container, false);
+ recyclerView = (RecyclerView) v.findViewById(R.id.items_list);
+ recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
+ try {
+ selectKioskAdapter = new SelectKioskAdapter();
+ } catch (Exception e) {
+ onError(e);
+ }
+ recyclerView.setAdapter(selectKioskAdapter);
+
+ return v;
+ }
+
+ /*//////////////////////////////////////////////////////////////////////////
+ // Handle actions
+ //////////////////////////////////////////////////////////////////////////*/
+
+ @Override
+ public void onCancel(final DialogInterface dialogInterface) {
+ super.onCancel(dialogInterface);
+ if(onCancelListener != null) {
+ onCancelListener.onCancel();
+ }
+ }
+
+ private void clickedItem(SelectKioskAdapter.Entry entry) {
+ if(onSelectedLisener != null) {
+ onSelectedLisener.onKioskSelected(entry.kioskId, entry.serviceId);
+ }
+ dismiss();
+ }
+
+ private class SelectKioskAdapter
+ extends RecyclerView.Adapter {
+ public class Entry {
+ public Entry (int i, int si, String ki, String kn){
+ icon = i; serviceId=si; kioskId=ki; kioskName = kn;
+ }
+ int icon;
+ int serviceId;
+ String kioskId;
+ String kioskName;
+ }
+
+ private List kioskList = new Vector<>();
+
+ public SelectKioskAdapter()
+ throws Exception {
+
+ for(StreamingService service : NewPipe.getServices()) {
+ for(String kioskId : service.getKioskList().getAvailableKiosks()) {
+ String name = String.format(getString(R.string.service_kiosk_string),
+ service.getServiceInfo().name,
+ KioskTranslator.getTranslatedKioskName(kioskId, getContext()));
+ kioskList.add(new Entry(
+ //ServiceIconMapper.getIconResource(service.getServiceId()),
+ ServiceIconMapper.getIconResource(-1),
+ service.getServiceId(),
+ kioskId,
+ name));
+ }
+ }
+ }
+
+ public int getItemCount() {
+ //todo: uncommend this line on multyservice support
+ //return kioskList.size();
+ return 1;
+ }
+
+ public SelectKioskItemHolder onCreateViewHolder(ViewGroup parent, int type) {
+ View item = LayoutInflater.from(parent.getContext())
+ .inflate(R.layout.select_kiosk_item, parent, false);
+ return new SelectKioskItemHolder(item);
+ }
+
+ public class SelectKioskItemHolder extends RecyclerView.ViewHolder {
+ public SelectKioskItemHolder(View v) {
+ super(v);
+ this.view = v;
+ thumbnailView = v.findViewById(R.id.itemThumbnailView);
+ titleView = v.findViewById(R.id.itemTitleView);
+ }
+ public View view;
+ public ImageView thumbnailView;
+ public TextView titleView;
+ }
+
+ public void onBindViewHolder(SelectKioskItemHolder holder, final int position) {
+ final Entry entry = kioskList.get(position);
+ holder.titleView.setText(entry.kioskName);
+ holder.thumbnailView.setImageDrawable(ContextCompat.getDrawable(getContext(), entry.icon));
+ holder.view.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ clickedItem(entry);
+ }
+ });
+ }
+ }
+
+ /*//////////////////////////////////////////////////////////////////////////
+ // Error
+ //////////////////////////////////////////////////////////////////////////*/
+
+ protected boolean onError(Throwable e) {
+ final Activity activity = getActivity();
+ ErrorActivity.reportError(activity, e,
+ activity.getClass(),
+ null,
+ ErrorActivity.ErrorInfo.make(UserAction.UI_ERROR,
+ "none", "", R.string.app_ui_crash));
+ return true;
+ }
+}
diff --git a/app/src/main/java/org/schabi/newpipe/util/Constants.java b/app/src/main/java/org/schabi/newpipe/util/Constants.java
index b31a95cca..a6aec96e2 100644
--- a/app/src/main/java/org/schabi/newpipe/util/Constants.java
+++ b/app/src/main/java/org/schabi/newpipe/util/Constants.java
@@ -9,6 +9,7 @@ public class Constants {
public static final String KEY_QUERY = "key_query";
public static final String KEY_THEME_CHANGE = "key_theme_change";
+ public static final String KEY_MAIN_PAGE_CHANGE = "key_main_page_change";
public static final int NO_SERVICE_ID = -1;
}
diff --git a/app/src/main/java/org/schabi/newpipe/util/ExtractorHelper.java b/app/src/main/java/org/schabi/newpipe/util/ExtractorHelper.java
index 0dd2c00ab..4763b6a02 100644
--- a/app/src/main/java/org/schabi/newpipe/util/ExtractorHelper.java
+++ b/app/src/main/java/org/schabi/newpipe/util/ExtractorHelper.java
@@ -26,6 +26,7 @@ import org.schabi.newpipe.extractor.Info;
import org.schabi.newpipe.extractor.ListExtractor.NextItemsResult;
import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.channel.ChannelInfo;
+import org.schabi.newpipe.extractor.kiosk.KioskInfo;
import org.schabi.newpipe.extractor.playlist.PlaylistInfo;
import org.schabi.newpipe.extractor.search.SearchEngine;
import org.schabi.newpipe.extractor.search.SearchResult;
@@ -138,6 +139,24 @@ public final class ExtractorHelper {
});
}
+ public static Single getKioskInfo(final int serviceId, final String url, final String contentCountry, boolean forceLoad) {
+ return checkCache(forceLoad, serviceId, url, Single.fromCallable(new Callable() {
+ @Override
+ public KioskInfo call() throws Exception {
+ return KioskInfo.getInfo(NewPipe.getService(serviceId), url, contentCountry);
+ }
+ }));
+ }
+
+ public static Single getMoreKioskItems(final int serviceId, final String url, final String nextStreamsUrl) {
+ return Single.fromCallable(new Callable() {
+ @Override
+ public NextItemsResult call() throws Exception {
+ return KioskInfo.getMoreItems(NewPipe.getService(serviceId), url, nextStreamsUrl);
+ }
+ });
+ }
+
/*//////////////////////////////////////////////////////////////////////////
// Utils
//////////////////////////////////////////////////////////////////////////*/
diff --git a/app/src/main/java/org/schabi/newpipe/util/KioskTranslator.java b/app/src/main/java/org/schabi/newpipe/util/KioskTranslator.java
new file mode 100644
index 000000000..4740b82e0
--- /dev/null
+++ b/app/src/main/java/org/schabi/newpipe/util/KioskTranslator.java
@@ -0,0 +1,38 @@
+package org.schabi.newpipe.util;
+
+import android.content.Context;
+
+import org.schabi.newpipe.R;
+
+/**
+ * Created by Chrsitian Schabesberger on 28.09.17.
+ * KioskTranslator.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 .
+ */
+
+public class KioskTranslator {
+ public static String getTranslatedKioskName(String kioskId, Context c) {
+ switch(kioskId) {
+ case "Trending":
+ return c.getString(R.string.trending);
+ case "Top 50":
+ return c.getString(R.string.top_50);
+ case "New & hot":
+ return c.getString(R.string.new_and_hot);
+ default:
+ return kioskId;
+ }
+ }
+}
diff --git a/app/src/main/java/org/schabi/newpipe/util/ListHelper.java b/app/src/main/java/org/schabi/newpipe/util/ListHelper.java
index 3fda47438..697a0c7c1 100644
--- a/app/src/main/java/org/schabi/newpipe/util/ListHelper.java
+++ b/app/src/main/java/org/schabi/newpipe/util/ListHelper.java
@@ -56,6 +56,13 @@ public final class ListHelper {
if (defaultPreferences == null) return 0;
String defaultResolution = defaultPreferences.getString(context.getString(R.string.default_resolution_key), context.getString(R.string.default_resolution_value));
+ return getDefaultResolutionIndex(context, videoStreams, defaultResolution);
+ }
+
+ /**
+ * @see #getDefaultResolutionIndex(String, String, MediaFormat, List)
+ */
+ public static int getDefaultResolutionIndex(Context context, List videoStreams, String defaultResolution) {
return getDefaultResolutionWithDefaultFormat(context, defaultResolution, videoStreams);
}
@@ -67,6 +74,13 @@ public final class ListHelper {
if (defaultPreferences == null) return 0;
String defaultResolution = defaultPreferences.getString(context.getString(R.string.default_popup_resolution_key), context.getString(R.string.default_popup_resolution_value));
+ return getPopupDefaultResolutionIndex(context, videoStreams, defaultResolution);
+ }
+
+ /**
+ * @see #getDefaultResolutionIndex(String, String, MediaFormat, List)
+ */
+ public static int getPopupDefaultResolutionIndex(Context context, List videoStreams, String defaultResolution) {
return getDefaultResolutionWithDefaultFormat(context, defaultResolution, videoStreams);
}
diff --git a/app/src/main/java/org/schabi/newpipe/util/Localization.java b/app/src/main/java/org/schabi/newpipe/util/Localization.java
index b6ec3cd3a..43ebc1677 100644
--- a/app/src/main/java/org/schabi/newpipe/util/Localization.java
+++ b/app/src/main/java/org/schabi/newpipe/util/Localization.java
@@ -6,6 +6,7 @@ import android.content.res.Resources;
import android.preference.PreferenceManager;
import android.support.annotation.PluralsRes;
import android.support.annotation.StringRes;
+import android.text.TextUtils;
import org.schabi.newpipe.R;
diff --git a/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java b/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java
index 538675685..a68494706 100644
--- a/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java
+++ b/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java
@@ -1,11 +1,14 @@
package org.schabi.newpipe.util;
import android.app.Activity;
+import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
+import android.net.Uri;
import android.preference.PreferenceManager;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
+import android.support.v7.app.AppCompatActivity;
import com.nostra13.universalimageloader.core.ImageLoader;
@@ -17,22 +20,19 @@ import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.ServiceList;
import org.schabi.newpipe.extractor.StreamingService;
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
-import org.schabi.newpipe.extractor.stream.AudioStream;
-import org.schabi.newpipe.extractor.stream.StreamInfo;
import org.schabi.newpipe.fragments.MainFragment;
import org.schabi.newpipe.fragments.detail.VideoDetailFragment;
import org.schabi.newpipe.fragments.list.channel.ChannelFragment;
import org.schabi.newpipe.fragments.list.feed.FeedFragment;
+import org.schabi.newpipe.fragments.list.kiosk.KioskFragment;
import org.schabi.newpipe.fragments.list.playlist.PlaylistFragment;
import org.schabi.newpipe.fragments.list.search.SearchFragment;
import org.schabi.newpipe.history.HistoryActivity;
-import org.schabi.newpipe.player.BackgroundPlayer;
import org.schabi.newpipe.player.BasePlayer;
import org.schabi.newpipe.player.VideoPlayer;
+import org.schabi.newpipe.playlist.PlayQueue;
import org.schabi.newpipe.settings.SettingsActivity;
-import java.util.ArrayList;
-
@SuppressWarnings({"unused", "WeakerAccess"})
public class NavigationHelper {
public static final String MAIN_FRAGMENT_TAG = "main_fragment_tag";
@@ -40,46 +40,41 @@ public class NavigationHelper {
/*//////////////////////////////////////////////////////////////////////////
// Players
//////////////////////////////////////////////////////////////////////////*/
+ public static Intent getPlayerIntent(final Context context,
+ final Class targetClazz,
+ final PlayQueue playQueue,
+ final String quality) {
+ Intent intent = new Intent(context, targetClazz)
+ .putExtra(VideoPlayer.PLAY_QUEUE, playQueue);
+ if (quality != null) intent.putExtra(VideoPlayer.PLAYBACK_QUALITY, quality);
- public static Intent getOpenVideoPlayerIntent(Context context, Class targetClazz, StreamInfo info, int selectedStreamIndex) {
- Intent mIntent = new Intent(context, targetClazz)
- .putExtra(BasePlayer.VIDEO_TITLE, info.name)
- .putExtra(BasePlayer.VIDEO_URL, info.url)
- .putExtra(BasePlayer.VIDEO_THUMBNAIL_URL, info.thumbnail_url)
- .putExtra(BasePlayer.CHANNEL_NAME, info.uploader_name)
- .putExtra(VideoPlayer.INDEX_SEL_VIDEO_STREAM, selectedStreamIndex)
- .putExtra(VideoPlayer.VIDEO_STREAMS_LIST, new ArrayList<>(ListHelper.getSortedStreamVideosList(context, info.video_streams, info.video_only_streams, false)))
- .putExtra(VideoPlayer.VIDEO_ONLY_AUDIO_STREAM, ListHelper.getHighestQualityAudio(info.audio_streams));
- if (info.start_position > 0) mIntent.putExtra(BasePlayer.START_POSITION, info.start_position * 1000L);
- return mIntent;
+ return intent;
}
- public static Intent getOpenVideoPlayerIntent(Context context, Class targetClazz, VideoPlayer instance) {
- return new Intent(context, targetClazz)
- .putExtra(BasePlayer.VIDEO_TITLE, instance.getVideoTitle())
- .putExtra(BasePlayer.VIDEO_URL, instance.getVideoUrl())
- .putExtra(BasePlayer.VIDEO_THUMBNAIL_URL, instance.getVideoThumbnailUrl())
- .putExtra(BasePlayer.CHANNEL_NAME, instance.getUploaderName())
- .putExtra(VideoPlayer.INDEX_SEL_VIDEO_STREAM, instance.getSelectedStreamIndex())
- .putExtra(VideoPlayer.VIDEO_STREAMS_LIST, instance.getVideoStreamsList())
- .putExtra(VideoPlayer.VIDEO_ONLY_AUDIO_STREAM, instance.getAudioStream())
- .putExtra(BasePlayer.START_POSITION, instance.getPlayer().getCurrentPosition())
- .putExtra(BasePlayer.PLAYBACK_SPEED, instance.getPlaybackSpeed());
+ public static Intent getPlayerIntent(final Context context,
+ final Class targetClazz,
+ final PlayQueue playQueue) {
+ return getPlayerIntent(context, targetClazz, playQueue, null);
}
- public static Intent getOpenBackgroundPlayerIntent(Context context, StreamInfo info) {
- return getOpenBackgroundPlayerIntent(context, info, info.audio_streams.get(ListHelper.getDefaultAudioFormat(context, info.audio_streams)));
+ public static Intent getPlayerEnqueueIntent(final Context context,
+ final Class targetClazz,
+ final PlayQueue playQueue) {
+ return getPlayerIntent(context, targetClazz, playQueue)
+ .putExtra(BasePlayer.APPEND_ONLY, true);
}
- public static Intent getOpenBackgroundPlayerIntent(Context context, StreamInfo info, AudioStream audioStream) {
- Intent mIntent = new Intent(context, BackgroundPlayer.class)
- .putExtra(BasePlayer.VIDEO_TITLE, info.name)
- .putExtra(BasePlayer.VIDEO_URL, info.url)
- .putExtra(BasePlayer.VIDEO_THUMBNAIL_URL, info.thumbnail_url)
- .putExtra(BasePlayer.CHANNEL_NAME, info.uploader_name)
- .putExtra(BackgroundPlayer.AUDIO_STREAM, audioStream);
- if (info.start_position > 0) mIntent.putExtra(BasePlayer.START_POSITION, info.start_position * 1000L);
- return mIntent;
+ public static Intent getPlayerIntent(final Context context,
+ final Class targetClazz,
+ final PlayQueue playQueue,
+ final int repeatMode,
+ final float playbackSpeed,
+ final float playbackPitch,
+ final String playbackQuality) {
+ return getPlayerIntent(context, targetClazz, playQueue, playbackQuality)
+ .putExtra(BasePlayer.REPEAT_MODE, repeatMode)
+ .putExtra(BasePlayer.PLAYBACK_SPEED, playbackSpeed)
+ .putExtra(BasePlayer.PLAYBACK_PITCH, playbackPitch);
}
/*//////////////////////////////////////////////////////////////////////////
@@ -93,7 +88,7 @@ public class NavigationHelper {
if (!popped) openMainFragment(fragmentManager);
}
- private static void openMainFragment(FragmentManager fragmentManager) {
+ public static void openMainFragment(FragmentManager fragmentManager) {
InfoCache.getInstance().trimCache();
fragmentManager.popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
@@ -163,6 +158,15 @@ public class NavigationHelper {
.commit();
}
+ public static void openKioskFragment(FragmentManager fragmentManager, int serviceId, String kioskId)
+ throws ExtractionException {
+ fragmentManager.beginTransaction()
+ .setCustomAnimations(R.animator.custom_fade_in, R.animator.custom_fade_out, R.animator.custom_fade_in, R.animator.custom_fade_out)
+ .replace(R.id.fragment_holder, KioskFragment.getInstance(serviceId, kioskId))
+ .addToBackStack(null)
+ .commit();
+ }
+
/*//////////////////////////////////////////////////////////////////////////
// Through Intents
//////////////////////////////////////////////////////////////////////////*/
@@ -293,4 +297,55 @@ public class NavigationHelper {
}
return null;
}
+
+
+ private static Uri openMarketUrl(String packageName) {
+ return Uri.parse("market://details")
+ .buildUpon()
+ .appendQueryParameter("id", packageName)
+ .build();
+ }
+
+ private static Uri getGooglePlayUrl(String packageName) {
+ return Uri.parse("https://play.google.com/store/apps/details")
+ .buildUpon()
+ .appendQueryParameter("id", packageName)
+ .build();
+ }
+
+ private static void installApp(Context context, String packageName) {
+ try {
+ // Try market:// scheme
+ context.startActivity(new Intent(Intent.ACTION_VIEW, openMarketUrl(packageName)));
+ } catch (ActivityNotFoundException e) {
+ // Fall back to google play URL (don't worry F-Droid can handle it :)
+ context.startActivity(new Intent(Intent.ACTION_VIEW, getGooglePlayUrl(packageName)));
+ }
+ }
+
+ /**
+ * Start an activity to install Kore
+ * @param context the context
+ */
+ public static void installKore(Context context) {
+ installApp(context, context.getString(R.string.kore_package));
+ }
+
+ /**
+ * Start Kore app to show a video on Kodi
+ *
+ * For a list of supported urls see the
+ *
+ * Kore source code
+ * .
+ *
+ * @param context the context to use
+ * @param videoURL the url to the video
+ */
+ public static void playWithKore(Context context, Uri videoURL) {
+ Intent intent = new Intent(Intent.ACTION_VIEW);
+ intent.setPackage(context.getString(R.string.kore_package));
+ intent.setData(videoURL);
+ context.startActivity(intent);
+ }
}
diff --git a/app/src/main/java/org/schabi/newpipe/util/ServiceIconMapper.java b/app/src/main/java/org/schabi/newpipe/util/ServiceIconMapper.java
new file mode 100644
index 000000000..060013dd2
--- /dev/null
+++ b/app/src/main/java/org/schabi/newpipe/util/ServiceIconMapper.java
@@ -0,0 +1,35 @@
+package org.schabi.newpipe.util;
+
+import org.schabi.newpipe.R;
+import org.schabi.newpipe.extractor.NewPipe;
+
+/**
+ * Created by Chrsitian Schabesberger on 09.10.17.
+ * ServiceIconMapper.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 .
+ */
+
+public class ServiceIconMapper {
+ public static int getIconResource(int service_id) {
+ switch(service_id) {
+ case 0:
+ return R.drawable.youtube;
+ case 1:
+ return R.drawable.soud_cloud;
+ default:
+ return R.drawable.service;
+ }
+ }
+}
diff --git a/app/src/main/res/drawable-hdpi/ic_channel_black_24dp.png b/app/src/main/res/drawable-hdpi/ic_channel_black_24dp.png
new file mode 100644
index 000000000..ac66a3b86
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_channel_black_24dp.png differ
diff --git a/app/src/main/res/drawable-hdpi/ic_channel_white_24dp.png b/app/src/main/res/drawable-hdpi/ic_channel_white_24dp.png
new file mode 100644
index 000000000..e0ef2a1a8
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_channel_white_24dp.png differ
diff --git a/app/src/main/res/drawable-hdpi/ic_drag_handle_black_24dp.png b/app/src/main/res/drawable-hdpi/ic_drag_handle_black_24dp.png
new file mode 100644
index 000000000..7ebc39358
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_drag_handle_black_24dp.png differ
diff --git a/app/src/main/res/drawable-hdpi/ic_drag_handle_white_24dp.png b/app/src/main/res/drawable-hdpi/ic_drag_handle_white_24dp.png
new file mode 100644
index 000000000..8747b9ecb
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_drag_handle_white_24dp.png differ
diff --git a/app/src/main/res/drawable-hdpi/ic_fiber_manual_record_black_24dp.png b/app/src/main/res/drawable-hdpi/ic_fiber_manual_record_black_24dp.png
new file mode 100644
index 000000000..459eec3fe
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_fiber_manual_record_black_24dp.png differ
diff --git a/app/src/main/res/drawable-hdpi/ic_fiber_manual_record_white_24dp.png b/app/src/main/res/drawable-hdpi/ic_fiber_manual_record_white_24dp.png
new file mode 100644
index 000000000..2c476010b
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_fiber_manual_record_white_24dp.png differ
diff --git a/app/src/main/res/drawable-hdpi/ic_shuffle_white_24dp.png b/app/src/main/res/drawable-hdpi/ic_shuffle_white_24dp.png
new file mode 100644
index 000000000..ab55a83f4
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_shuffle_white_24dp.png differ
diff --git a/app/src/main/res/drawable-hdpi/ic_whatshot_black_24dp.png b/app/src/main/res/drawable-hdpi/ic_whatshot_black_24dp.png
new file mode 100644
index 000000000..b2db5994c
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_whatshot_black_24dp.png differ
diff --git a/app/src/main/res/drawable-hdpi/ic_whatshot_white_24dp.png b/app/src/main/res/drawable-hdpi/ic_whatshot_white_24dp.png
new file mode 100644
index 000000000..46ed1f8b6
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_whatshot_white_24dp.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_channel_black_24dp.png b/app/src/main/res/drawable-mdpi/ic_channel_black_24dp.png
new file mode 100644
index 000000000..984ff498e
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_channel_black_24dp.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_channel_white_24dp.png b/app/src/main/res/drawable-mdpi/ic_channel_white_24dp.png
new file mode 100644
index 000000000..68f6ffd7f
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_channel_white_24dp.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_drag_handle_black_24dp.png b/app/src/main/res/drawable-mdpi/ic_drag_handle_black_24dp.png
new file mode 100644
index 000000000..e09d492fc
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_drag_handle_black_24dp.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_drag_handle_white_24dp.png b/app/src/main/res/drawable-mdpi/ic_drag_handle_white_24dp.png
new file mode 100644
index 000000000..e509264d3
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_drag_handle_white_24dp.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_fiber_manual_record_black_24dp.png b/app/src/main/res/drawable-mdpi/ic_fiber_manual_record_black_24dp.png
new file mode 100644
index 000000000..cfc8b4e60
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_fiber_manual_record_black_24dp.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_fiber_manual_record_white_24dp.png b/app/src/main/res/drawable-mdpi/ic_fiber_manual_record_white_24dp.png
new file mode 100644
index 000000000..f6f53a154
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_fiber_manual_record_white_24dp.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_shuffle_white_24dp.png b/app/src/main/res/drawable-mdpi/ic_shuffle_white_24dp.png
new file mode 100644
index 000000000..d13a258a3
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_shuffle_white_24dp.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_whatshot_black_24dp.png b/app/src/main/res/drawable-mdpi/ic_whatshot_black_24dp.png
new file mode 100644
index 000000000..31b1981f0
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_whatshot_black_24dp.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_whatshot_white_24dp.png b/app/src/main/res/drawable-mdpi/ic_whatshot_white_24dp.png
new file mode 100644
index 000000000..4cf6f85f8
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_whatshot_white_24dp.png differ
diff --git a/app/src/main/res/drawable-nodpi/service.png b/app/src/main/res/drawable-nodpi/service.png
new file mode 100644
index 000000000..cfaff19e2
Binary files /dev/null and b/app/src/main/res/drawable-nodpi/service.png differ
diff --git a/app/src/main/res/drawable-nodpi/soud_cloud.png b/app/src/main/res/drawable-nodpi/soud_cloud.png
new file mode 100644
index 000000000..0fa6045d5
Binary files /dev/null and b/app/src/main/res/drawable-nodpi/soud_cloud.png differ
diff --git a/app/src/main/res/drawable-nodpi/youtube.png b/app/src/main/res/drawable-nodpi/youtube.png
new file mode 100644
index 000000000..82aa58ff1
Binary files /dev/null and b/app/src/main/res/drawable-nodpi/youtube.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_channel_black_24dp.png b/app/src/main/res/drawable-xhdpi/ic_channel_black_24dp.png
new file mode 100644
index 000000000..0851f1738
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_channel_black_24dp.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_channel_white_24dp.png b/app/src/main/res/drawable-xhdpi/ic_channel_white_24dp.png
new file mode 100644
index 000000000..2f0f6c5fd
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_channel_white_24dp.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_drag_handle_black_24dp.png b/app/src/main/res/drawable-xhdpi/ic_drag_handle_black_24dp.png
new file mode 100644
index 000000000..906f5eee0
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_drag_handle_black_24dp.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_drag_handle_white_24dp.png b/app/src/main/res/drawable-xhdpi/ic_drag_handle_white_24dp.png
new file mode 100644
index 000000000..aa1547b04
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_drag_handle_white_24dp.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_fiber_manual_record_black_24dp.png b/app/src/main/res/drawable-xhdpi/ic_fiber_manual_record_black_24dp.png
new file mode 100644
index 000000000..3eb79e4c1
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_fiber_manual_record_black_24dp.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_fiber_manual_record_white_24dp.png b/app/src/main/res/drawable-xhdpi/ic_fiber_manual_record_white_24dp.png
new file mode 100644
index 000000000..0fa16b016
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_fiber_manual_record_white_24dp.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_shuffle_white_24dp.png b/app/src/main/res/drawable-xhdpi/ic_shuffle_white_24dp.png
new file mode 100644
index 000000000..66c15ce62
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_shuffle_white_24dp.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_whatshot_black_24dp.png b/app/src/main/res/drawable-xhdpi/ic_whatshot_black_24dp.png
new file mode 100644
index 000000000..e9ae82670
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_whatshot_black_24dp.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_whatshot_white_24dp.png b/app/src/main/res/drawable-xhdpi/ic_whatshot_white_24dp.png
new file mode 100644
index 000000000..3651d061a
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_whatshot_white_24dp.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_channel_black_24dp.png b/app/src/main/res/drawable-xxhdpi/ic_channel_black_24dp.png
new file mode 100644
index 000000000..4861728c4
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_channel_black_24dp.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_channel_white_24dp.png b/app/src/main/res/drawable-xxhdpi/ic_channel_white_24dp.png
new file mode 100644
index 000000000..2fd740ee8
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_channel_white_24dp.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_drag_handle_black_24dp.png b/app/src/main/res/drawable-xxhdpi/ic_drag_handle_black_24dp.png
new file mode 100644
index 000000000..71da19a59
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_drag_handle_black_24dp.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_drag_handle_white_24dp.png b/app/src/main/res/drawable-xxhdpi/ic_drag_handle_white_24dp.png
new file mode 100644
index 000000000..e91ef07e9
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_drag_handle_white_24dp.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_fiber_manual_record_black_24dp.png b/app/src/main/res/drawable-xxhdpi/ic_fiber_manual_record_black_24dp.png
new file mode 100644
index 000000000..b53beb106
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_fiber_manual_record_black_24dp.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_fiber_manual_record_white_24dp.png b/app/src/main/res/drawable-xxhdpi/ic_fiber_manual_record_white_24dp.png
new file mode 100644
index 000000000..422487473
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_fiber_manual_record_white_24dp.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_shuffle_white_24dp.png b/app/src/main/res/drawable-xxhdpi/ic_shuffle_white_24dp.png
new file mode 100644
index 000000000..dc8e5341b
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_shuffle_white_24dp.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_whatshot_black_24dp.png b/app/src/main/res/drawable-xxhdpi/ic_whatshot_black_24dp.png
new file mode 100644
index 000000000..a14dcd695
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_whatshot_black_24dp.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_whatshot_white_24dp.png b/app/src/main/res/drawable-xxhdpi/ic_whatshot_white_24dp.png
new file mode 100644
index 000000000..8eaf3755d
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_whatshot_white_24dp.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_channel_black_24dp.png b/app/src/main/res/drawable-xxxhdpi/ic_channel_black_24dp.png
new file mode 100644
index 000000000..2ff64b449
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_channel_black_24dp.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_channel_white_24dp.png b/app/src/main/res/drawable-xxxhdpi/ic_channel_white_24dp.png
new file mode 100644
index 000000000..9384592d6
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_channel_white_24dp.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_drag_handle_black_24dp.png b/app/src/main/res/drawable-xxxhdpi/ic_drag_handle_black_24dp.png
new file mode 100644
index 000000000..d102adeb2
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_drag_handle_black_24dp.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_drag_handle_white_24dp.png b/app/src/main/res/drawable-xxxhdpi/ic_drag_handle_white_24dp.png
new file mode 100644
index 000000000..122690738
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_drag_handle_white_24dp.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_fiber_manual_record_black_24dp.png b/app/src/main/res/drawable-xxxhdpi/ic_fiber_manual_record_black_24dp.png
new file mode 100644
index 000000000..eff1e3594
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_fiber_manual_record_black_24dp.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_fiber_manual_record_white_24dp.png b/app/src/main/res/drawable-xxxhdpi/ic_fiber_manual_record_white_24dp.png
new file mode 100644
index 000000000..591b54a57
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_fiber_manual_record_white_24dp.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_shuffle_white_24dp.png b/app/src/main/res/drawable-xxxhdpi/ic_shuffle_white_24dp.png
new file mode 100644
index 000000000..e24dfa3b0
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_shuffle_white_24dp.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_whatshot_black_24dp.png b/app/src/main/res/drawable-xxxhdpi/ic_whatshot_black_24dp.png
new file mode 100644
index 000000000..8f03a95c7
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_whatshot_black_24dp.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_whatshot_white_24dp.png b/app/src/main/res/drawable-xxxhdpi/ic_whatshot_white_24dp.png
new file mode 100644
index 000000000..5c5d86873
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_whatshot_white_24dp.png differ
diff --git a/app/src/main/res/drawable/dark_selector.xml b/app/src/main/res/drawable/dark_selector.xml
new file mode 100644
index 000000000..eb658e16d
--- /dev/null
+++ b/app/src/main/res/drawable/dark_selector.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/app/src/main/res/drawable/light_selector.xml b/app/src/main/res/drawable/light_selector.xml
new file mode 100644
index 000000000..63f2ccaf3
--- /dev/null
+++ b/app/src/main/res/drawable/light_selector.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout-land/activity_player_queue_control.xml b/app/src/main/res/layout-land/activity_player_queue_control.xml
new file mode 100644
index 000000000..a577b7fe0
--- /dev/null
+++ b/app/src/main/res/layout-land/activity_player_queue_control.xml
@@ -0,0 +1,300 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_history.xml b/app/src/main/res/layout/activity_history.xml
index 7076eb34f..e53b9bff9 100644
--- a/app/src/main/res/layout/activity_history.xml
+++ b/app/src/main/res/layout/activity_history.xml
@@ -13,7 +13,6 @@
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:paddingTop="@dimen/appbar_padding_top"
android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.ActionBar">
diff --git a/app/src/main/res/layout/activity_main_player.xml b/app/src/main/res/layout/activity_main_player.xml
index e3ef022f9..5c6349c35 100644
--- a/app/src/main/res/layout/activity_main_player.xml
+++ b/app/src/main/res/layout/activity_main_player.xml
@@ -1,9 +1,10 @@
-
@@ -11,6 +12,7 @@
android:id="@+id/aspectRatioLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:layout_centerInParent="true"
android:layout_gravity="center">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -94,10 +178,15 @@
android:id="@+id/channelTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:ellipsize="end"
- android:maxLines="1"
+ android:ellipsize="marquee"
+ android:fadingEdge="horizontal"
+ android:marqueeRepeatLimit="marquee_forever"
+ android:scrollHorizontally="true"
+ android:singleLine="true"
android:textColor="@android:color/white"
android:textSize="12sp"
+ android:clickable="true"
+ android:focusable="true"
tools:text="The Video Artist LONG very LONG very Long"/>
@@ -135,26 +224,28 @@
android:layout_height="35dp"
android:layout_marginLeft="2dp"
android:layout_marginRight="2dp"
- android:layout_toLeftOf="@+id/repeatButton"
+ android:layout_toLeftOf="@+id/queueButton"
android:background="#00ffffff"
android:clickable="true"
+ android:focusable="true"
android:padding="8dp"
android:scaleType="fitXY"
android:src="@drawable/ic_screen_rotation_white"
tools:ignore="ContentDescription,RtlHardcoded"/>
@@ -223,11 +315,45 @@
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_centerInParent="true"
- android:background="#00000000"
+ android:clickable="true"
+ android:focusable="true"
+ android:background="?attr/selectableItemBackgroundBorderless"
android:scaleType="fitXY"
android:src="@drawable/ic_pause_white"
tools:ignore="ContentDescription"/>
+
+
+
+
@@ -328,4 +454,4 @@
tools:visibility="visible"/>
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_player_queue_control.xml b/app/src/main/res/layout/activity_player_queue_control.xml
new file mode 100644
index 000000000..a59e5ba2e
--- /dev/null
+++ b/app/src/main/res/layout/activity_player_queue_control.xml
@@ -0,0 +1,289 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_blank.xml b/app/src/main/res/layout/fragment_blank.xml
index ad91b1d1d..d1167d722 100644
--- a/app/src/main/res/layout/fragment_blank.xml
+++ b/app/src/main/res/layout/fragment_blank.xml
@@ -16,4 +16,10 @@
android:layout_marginTop="50dp"
android:visibility="gone" />
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_channel.xml b/app/src/main/res/layout/fragment_channel.xml
index 460f95a7a..67691fc81 100644
--- a/app/src/main/res/layout/fragment_channel.xml
+++ b/app/src/main/res/layout/fragment_channel.xml
@@ -62,4 +62,10 @@
android:visibility="gone"
tools:visibility="visible"/>
+
+
diff --git a/app/src/main/res/layout/fragment_feed.xml b/app/src/main/res/layout/fragment_feed.xml
index 0f2d0b675..0868d8233 100644
--- a/app/src/main/res/layout/fragment_feed.xml
+++ b/app/src/main/res/layout/fragment_feed.xml
@@ -34,4 +34,10 @@
android:visibility="gone"
tools:visibility="visible"/>
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_kiosk.xml b/app/src/main/res/layout/fragment_kiosk.xml
new file mode 100644
index 000000000..4730e66c8
--- /dev/null
+++ b/app/src/main/res/layout/fragment_kiosk.xml
@@ -0,0 +1,71 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_main.xml b/app/src/main/res/layout/fragment_main.xml
index dac5478ff..b1dd3e20b 100644
--- a/app/src/main/res/layout/fragment_main.xml
+++ b/app/src/main/res/layout/fragment_main.xml
@@ -10,13 +10,14 @@
android:id="@+id/main_tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_alignParentBottom="true"
+ android:layout_alignParentTop="true"
+ android:background="@color/dark_youtube_primary_color"
app:tabGravity="fill"/>
+ android:layout_below="@id/main_tab_layout"/>
diff --git a/app/src/main/res/layout/fragment_playlist.xml b/app/src/main/res/layout/fragment_playlist.xml
index d5ef26a63..37c609fa4 100644
--- a/app/src/main/res/layout/fragment_playlist.xml
+++ b/app/src/main/res/layout/fragment_playlist.xml
@@ -62,4 +62,10 @@
android:visibility="gone"
tools:visibility="visible"/>
+
+
diff --git a/app/src/main/res/layout/fragment_search.xml b/app/src/main/res/layout/fragment_search.xml
index 04b10347c..d49d23175 100644
--- a/app/src/main/res/layout/fragment_search.xml
+++ b/app/src/main/res/layout/fragment_search.xml
@@ -81,4 +81,10 @@
android:visibility="gone"
tools:visibility="visible"/>
+
+
diff --git a/app/src/main/res/layout/fragment_subscription.xml b/app/src/main/res/layout/fragment_subscription.xml
index 35cfbfeb7..e0d0348dc 100644
--- a/app/src/main/res/layout/fragment_subscription.xml
+++ b/app/src/main/res/layout/fragment_subscription.xml
@@ -35,4 +35,10 @@
android:visibility="gone"
tools:visibility="visible"/>
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_video_detail.xml b/app/src/main/res/layout/fragment_video_detail.xml
index 0d87809fc..86e8d6ad9 100644
--- a/app/src/main/res/layout/fragment_video_detail.xml
+++ b/app/src/main/res/layout/fragment_video_detail.xml
@@ -28,6 +28,7 @@
android:layout_height="wrap_content"
android:background="@android:color/black"
android:clickable="true"
+ android:focusable="true"
android:foreground="?attr/selectableItemBackground">
+
@@ -68,6 +86,7 @@
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:clickable="true"
+ android:focusable="true"
android:paddingLeft="12dp"
android:paddingRight="12dp">
@@ -223,10 +242,12 @@
android:layout_width="80dp"
android:layout_height="55dp"
android:layout_alignParentRight="true"
+ android:layout_alignParentEnd="true"
android:layout_alignParentTop="true"
android:layout_gravity="center_vertical"
android:background="?attr/selectableItemBackgroundBorderless"
android:clickable="true"
+ android:focusable="true"
android:contentDescription="@string/open_in_popup_mode"
android:drawableTop="?attr/popup"
android:gravity="center"
@@ -242,8 +263,10 @@
android:layout_alignParentTop="true"
android:layout_gravity="center_vertical"
android:layout_toLeftOf="@id/detail_controls_popup"
+ android:layout_toStartOf="@id/detail_controls_popup"
android:background="?attr/selectableItemBackgroundBorderless"
android:clickable="true"
+ android:focusable="true"
android:contentDescription="@string/play_audio"
android:drawableTop="?attr/audio"
android:gravity="center"
diff --git a/app/src/main/res/layout/play_queue_item.xml b/app/src/main/res/layout/play_queue_item.xml
new file mode 100644
index 000000000..4d5a6fbd4
--- /dev/null
+++ b/app/src/main/res/layout/play_queue_item.xml
@@ -0,0 +1,102 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/player_notification.xml b/app/src/main/res/layout/player_notification.xml
index 958b9bf3d..157615bb7 100644
--- a/app/src/main/res/layout/player_notification.xml
+++ b/app/src/main/res/layout/player_notification.xml
@@ -12,6 +12,7 @@
android:layout_height="64dp"
android:background="@color/background_notification_color"
android:clickable="true"
+ android:focusable="true"
android:gravity="center_vertical"
android:orientation="horizontal">
@@ -58,6 +59,7 @@
android:layout_height="match_parent"
android:background="#00000000"
android:clickable="true"
+ android:focusable="true"
android:padding="5dp"
android:scaleType="fitCenter"
android:src="@drawable/ic_repeat_white"
@@ -69,9 +71,10 @@
android:layout_height="match_parent"
android:background="#00000000"
android:clickable="true"
+ android:focusable="true"
android:padding="5dp"
android:scaleType="fitCenter"
- android:src="@drawable/ic_action_av_fast_rewind"
+ android:src="@drawable/exo_controls_previous"
tools:ignore="ContentDescription"/>
@@ -89,9 +93,10 @@
android:layout_height="match_parent"
android:background="#00000000"
android:clickable="true"
+ android:focusable="true"
android:padding="5dp"
android:scaleType="fitCenter"
- android:src="@drawable/ic_action_av_fast_forward"
+ android:src="@drawable/exo_controls_next"
tools:ignore="ContentDescription"/>
@@ -26,6 +27,7 @@
android:layout_alignParentRight="true"
android:background="#00000000"
android:clickable="true"
+ android:focusable="true"
android:padding="8dp"
android:scaleType="fitCenter"
android:src="@drawable/ic_close_white_24dp"
@@ -82,9 +84,11 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
+ android:layout_marginStart="8dp"
android:layout_marginTop="2dp"
android:layout_alignTop="@+id/notificationProgressBar"
android:layout_toRightOf="@+id/notificationCover"
+ android:layout_toEndOf="@+id/notificationCover"
android:ellipsize="end"
android:maxLines="1"
android:textSize="12sp"
@@ -109,6 +113,7 @@
android:layout_centerVertical="true"
android:background="#00000000"
android:clickable="true"
+ android:focusable="true"
android:scaleType="fitXY"
android:src="@drawable/ic_repeat_white"
tools:ignore="ContentDescription"/>
@@ -122,9 +127,10 @@
android:layout_toLeftOf="@+id/notificationPlayPause"
android:background="#00000000"
android:clickable="true"
+ android:focusable="true"
android:padding="2dp"
android:scaleType="fitCenter"
- android:src="@drawable/ic_action_av_fast_rewind"
+ android:src="@drawable/exo_controls_previous"
tools:ignore="ContentDescription"/>
@@ -150,107 +157,10 @@
android:layout_marginRight="8dp"
android:background="#00000000"
android:clickable="true"
+ android:focusable="true"
android:padding="2dp"
android:scaleType="fitCenter"
- android:src="@drawable/ic_action_av_fast_forward"
+ android:src="@drawable/exo_controls_next"
tools:ignore="ContentDescription"/>
-
-
-
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/player_popup_notification.xml b/app/src/main/res/layout/player_popup_notification.xml
index 4010064d9..ab436a1fa 100644
--- a/app/src/main/res/layout/player_popup_notification.xml
+++ b/app/src/main/res/layout/player_popup_notification.xml
@@ -7,6 +7,7 @@
android:layout_height="64dp"
android:background="@color/background_notification_color"
android:clickable="true"
+ android:focusable="true"
android:gravity="center_vertical"
android:orientation="horizontal">
@@ -54,6 +55,7 @@
android:layout_height="match_parent"
android:background="#00000000"
android:clickable="true"
+ android:focusable="true"
android:padding="5dp"
android:scaleType="fitCenter"
android:src="@drawable/ic_repeat_white"
@@ -65,6 +67,7 @@
android:layout_height="match_parent"
android:background="#00000000"
android:clickable="true"
+ android:focusable="true"
android:src="@drawable/ic_pause_white"
tools:ignore="ContentDescription"/>
@@ -75,6 +78,7 @@
android:layout_marginLeft="5dp"
android:background="#00000000"
android:clickable="true"
+ android:focusable="true"
android:padding="5dp"
android:scaleType="fitCenter"
android:src="@drawable/ic_close_white_24dp"
diff --git a/app/src/main/res/layout/playlist_header.xml b/app/src/main/res/layout/playlist_header.xml
index 192363359..0f129672d 100644
--- a/app/src/main/res/layout/playlist_header.xml
+++ b/app/src/main/res/layout/playlist_header.xml
@@ -20,62 +20,125 @@
android:maxLines="2"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textSize="@dimen/playlist_detail_title_text_size"
- tools:text="Mix musics #23 title Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc tristique vitae sem vitae blanditLorem ipsumLorem ipsumLorem ipsumLorem ipsumLorem ipsumLorem ipsumLorem ipsum"/>
+ tools:text="Mix musics #23 title Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc tristique vitae sem vitae blanditLorem ipsumLorem ipsumLorem ipsumLorem ipsumLorem ipsumLorem ipsumLorem ipsum" />
+ android:id="@+id/playlist_meta">
+
-
+
+
+
+
+ tools:text="234 videos"/>
+
-
+ android:id="@+id/play_control"
+ android:paddingLeft="5dp"
+ android:paddingRight="5dp"
+ android:layout_below="@+id/playlist_meta">
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/select_channel_fragment.xml b/app/src/main/res/layout/select_channel_fragment.xml
new file mode 100644
index 000000000..11c723b4b
--- /dev/null
+++ b/app/src/main/res/layout/select_channel_fragment.xml
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/select_channel_item.xml b/app/src/main/res/layout/select_channel_item.xml
new file mode 100644
index 000000000..09602a371
--- /dev/null
+++ b/app/src/main/res/layout/select_channel_item.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/select_kiosk_fragment.xml b/app/src/main/res/layout/select_kiosk_fragment.xml
new file mode 100644
index 000000000..8e376742b
--- /dev/null
+++ b/app/src/main/res/layout/select_kiosk_fragment.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/select_kiosk_item.xml b/app/src/main/res/layout/select_kiosk_item.xml
new file mode 100644
index 000000000..2efadca79
--- /dev/null
+++ b/app/src/main/res/layout/select_kiosk_item.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/toolbar_layout.xml b/app/src/main/res/layout/toolbar_layout.xml
index 36ab6454e..096974c03 100644
--- a/app/src/main/res/layout/toolbar_layout.xml
+++ b/app/src/main/res/layout/toolbar_layout.xml
@@ -36,9 +36,4 @@
-
-
\ No newline at end of file
diff --git a/app/src/main/res/menu/main_menu.xml b/app/src/main/res/menu/main_menu.xml
index be3548532..02402e2e8 100644
--- a/app/src/main/res/menu/main_menu.xml
+++ b/app/src/main/res/menu/main_menu.xml
@@ -20,6 +20,6 @@
+ android:title="@string/action_about"/>
\ No newline at end of file
diff --git a/app/src/main/res/menu/menu_play_queue.xml b/app/src/main/res/menu/menu_play_queue.xml
new file mode 100644
index 000000000..8fd0c9b6b
--- /dev/null
+++ b/app/src/main/res/menu/menu_play_queue.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml
index fc3706bba..44599b136 100644
--- a/app/src/main/res/values-ar/strings.xml
+++ b/app/src/main/res/values-ar/strings.xml
@@ -1,63 +1,87 @@
-
-
- جاري التشغيل في الخلفية
- إلغاء
- إختر متصفح
- مظلم
- صيغة الصوت الإفتراضية
- الدقة الإفتراضية
- عدم الإعجاب
- الإعجابات
- صور معاينة الفيديو
- "Uploader's userpic thumbnail"
- هل تقصد:
- تنزيل
- تنزيل
- أدخل مسار التنزيل للملفات الصوتية.
- مسار حفظ التنزيلات الصوتية في.
- مسار الصوتيات المحفوظة
- أدخل مسار التنزيل لملفات الفيديو
- مسار حفظ تنزيلات الفيديو في.
- مسار الفيديوهات المحفوظة
- "لا يمكن إنشاء مجلد للتنزيلات في '%1$s'"
- "تم إنشاء مجلد تنزيلات في '%1$s'"
- تثبيت
- تطبيق Kore غير موجود. هل تريد تثبيته؟
- مضيء
- صور معاينة الفيديو
- m4a — جودة أفضل
- خطأ في الشبكة
- الفيديو التالي
- لا يوجد مشغل فيديو. هل تريد تثبيت VLC ؟
- فتح في المتصفح
- صوت
- تشغيل
- تشغيل بواسطة Kodi
- تدوير
- بحث
- لغة المحتوى المفضل
- الإعدادات
- المظهر
- تعريب JetSub مدونة درويديات
- الفيديو والصوتيات
- مشاركة
- مشاركة بواسطة
- عرض التالي والفيديوهات المشابهة
- عرض خيار لتشغيل الفيديو بواسطة Kodi Media Center.
- عرض خيار التشغيل بواسطة Kodi.
- الثيم
- تم الرفع في %1$s
- الرابط غير مدعوم
- استخدام مشغل صوتيات خارجي
- استخدام مشغل فيديو خارجي
- إجراء التنزيلات من خلال استخدام بروكسي Tor لزيادة الخصوصية ( تشغيل الفيديو المباشر غير مدعوم حتى الأن )
- استخدام Tor
- %1$s المشاهدات
- WebM
- Blocked by GEMA.
- المحتوى غير متاح.
- لم يتمكن من تحميل كل صور المعاينة
- خطأ
- لا يمكن تحليل الموقع.
- لا يمكن فك تشفير توقيع رابط الفيديو.
-
+
+
+ جاري التشغيل في الخلفية
+ إلغاء
+ إختر متصفح
+ مظلم
+ صيغة الصوت الإفتراضية
+ الدقة الإفتراضية
+ عدم الإعجاب
+ الإعجابات
+ صور معاينة الفيديو
+ "Uploader's userpic thumbnail"
+ هل تقصد : %1$s ؟
+ تنزيل
+ تنزيل
+ أدخل مسار التنزيل للملفات الصوتية.
+ مسار حفظ التنزيلات الصوتية في.
+ مسار الصوتيات المحفوظة
+ أدخل مسار التنزيل لملفات الفيديو
+ مسار حفظ تنزيلات الفيديو في
+ مسار الفيديوهات المحفوظة
+ "لا يمكن إنشاء مجلد للتنزيلات في '%1$s'"
+ "تم إنشاء مجلد تنزيلات في '%1$s'"
+ تثبيت
+ تطبيق Kore غير موجود. هل تريد تثبيته؟
+ مضيء
+ صور معاينة الفيديو
+ m4a — جودة أفضل
+ خطأ في الشبكة
+ الفيديو التالي
+ لا يوجد مشغل فيديو. هل تريد تثبيت VLC ؟
+ فتح في المتصفح
+ صوت
+ تشغيل
+ تشغيل بواسطة Kodi
+ تدوير
+ بحث
+ لغة المحتوى المفضل
+ الإعدادات
+ المظهر
+ تعريب JetSub مدونة درويديات
+ الفيديو والصوتيات
+ مشاركة
+ مشاركة بواسطة
+ عرض التالي والفيديوهات المشابهة
+ عرض خيار لتشغيل الفيديو بواسطة Kodi Media Center.
+ عرض خيار التشغيل بواسطة Kodi.
+ السمة
+ تم نشرها في %1$s
+ الرابط غير مدعوم
+ استخدام مشغل صوتيات خارجي
+ استخدام مشغل فيديو خارجي
+ إجراء التنزيلات من خلال استخدام بروكسي Tor لزيادة الخصوصية ( تشغيل الفيديو المباشر غير مدعوم حتى الأن )
+ استخدام Tor
+ %1$s المشاهدات
+ WebM
+ Blocked by GEMA.
+ المحتوى غير متاح.
+ لم يتمكن من تحميل كل صور المعاينة
+ خطأ
+ لا يمكن تحليل الموقع.
+ لا يمكن فك تشفير توقيع رابط الفيديو.
+إضغط على البحث للمواصلة
+ إشترك
+ مشترك
+ الرئيسية
+ الإشتراكات
+
+ ما الجديد
+
+ الخلفية
+ التشغيل التلقائي
+ أسود
+ التأريخ
+ التأريخ
+ المحتوى
+ التنزيلات
+ التنزيلات
+ الكل
+ قناة
+ فيديو
+ التنزيل
+ عن التطبيق
+ عن التطبيق
+ التأريخ
+ التأريخ
+
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
index 0e183f2f8..e6d39d3c9 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -203,7 +203,7 @@
Abo beenden
Abos
- Änderungen
+ Neuigkeiten
Suchverlauf
Speichere den Suchverlauf lokal
@@ -259,4 +259,29 @@
Nichts hier außer Grillen
Möchten Sie dieses Element aus dem Suchverlauf löschen?
-
+Leere Seite
+ Wähle einen Kanal aus
+ Noch kein Kanal abonniert
+ Trends
+ Angereiht an Popup Player
+ Alles abspielen
+
+ Entfernen
+ Audio Einstellungen
+ Abspielen des Streams fehlgeschlagen
+ Inhalt der Hauptseite
+ Abonnement-Seite
+ Feed-Seite
+ Kanal-Seite
+ Hintergrund-Player
+ Popup-Player
+ Details
+ Top 50
+ Es ist ein unumgänglicher Fehler im Video-Spieler aufgetreten
+ Player-Fehler gelöst
+
+ Kiosk-Seite
+ Kiosk auswählen
+
+ Kiosk
+
diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml
index 7d09d85b9..d39156260 100644
--- a/app/src/main/res/values-es/strings.xml
+++ b/app/src/main/res/values-es/strings.xml
@@ -260,4 +260,17 @@ abrir en modo popup
Elemento eliminado
¿Desea eliminar este elemento del historial de búsqueda?
+Contenido de la página principal
+ Página en blanco
+ Página del kiosco
+ Página de suscripción
+ Página de feed
+ Página del canal
+ Seleccione un canal
+ No hay canal suscrito todavía
+ Seleccione un kiosco
+
+ Kiosco
+ Tendencias
+ Top 50
diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml
index 33b4a6cd5..963739903 100644
--- a/app/src/main/res/values-fi/strings.xml
+++ b/app/src/main/res/values-fi/strings.xml
@@ -2,7 +2,7 @@
Napauta hakua aloittaaksesi
%1$s näyttökertaa
Julkaistu %1$s
- Ei löytynyt suoratoisto soitinta. Haluatko asentaa VLC:n?
+ Ei löytynyt suoratoistosoitinta. Haluatko asentaa VLC:n?
Asenna
Peruuta
Avaa selaimessa
@@ -15,9 +15,9 @@
Jaa
Valitse selain
kierto
- Käytä ulkoista videotoistinta
+ Käytä ulkoista videosoitinta
Joillain resoluutioilla EI ole ääntä, kun tämä on valittuna
- Käytä ulkoista äänitoistinta
+ Käytä ulkoista äänisoitinta
NewPipe ponnahdusikkuna
Tilaa
Tilattu
@@ -28,16 +28,16 @@
Päävalikko
Tilaukset
- Uusimmat
+ Uudet
Taustatoisto
- Ponnahdusikkuna
+ Ikkuna
Videon latauksen sijainti
Sijainti ladatuille videoille
Aseta sijainti minne videot tallennetaan
- Audio latauksen sijainti
+ Audion latauksen sijainti
Sijainti ladatuille audiotiedostoille
Aseta sijainti minne audiotiedostot tallennetaan
@@ -73,10 +73,10 @@
Jatka toistoa keskeytysten jälkeen (esim. puhelut)
Lataa
Seuraava video
- Näytä seuraava ja samankaltaisia videoita
+ Näytä seuraava video ja samankaltaisia videoita
URL ei tueta
- Oletus-sisällon kieli
- Toistin
+ Oletus sisällon kieli
+ Soitin
Käyttäytyminen
Video & Audio
Historia
@@ -89,7 +89,7 @@
Sisältö
Näytä ikärajoitettua sisältöä
Ikärajoitettu video. Ikärajoituksen voi sallia asetuksista.
- live
+ suora
Lataukset
Lataukset
Virheraportti
@@ -124,10 +124,10 @@
Sovellus/UI kaatui
Pahoittelut, noin ei olisi pitänyt käydä.
Raportoi virhe sähköpostin kautta
- Pahoittelit, joitain virheitä tapahtui.
+ Pahoittelut, joitain virheitä tapahtui.
RAPORTTI
Mitä tapahtui:
- Sinun viesti (Englanniksi):
+ Sinun viesti (englanniksi):
Yksityiskohdat:
@@ -150,29 +150,29 @@
Audio
Toista uudelleen
Oikeus tallennustilan hallintaan evätty
- Käytä vanhaa toistinta
- Käytä vanhaa sisäänrakennettua Mediaframework toistinta
+ Käytä vanhaa soitinta
+ Käytä vanhaa sisäänrakennettua Mediaframework soitinta
t.
- Milj.
- Bilj.
+ milj.
+ bilj.
Ei tilaajia
- %s tilaaja
- - %s tilaajia
+ - %s tilaajaa
Ei katselukertoja
- %s katselukerta
- - %s katselukertoja
+ - %s katselukertaa
Ei videoita
- %s video
- - %s videoita
+ - %s videota
Aloita
@@ -185,7 +185,7 @@
OK
Tiedostonimi
- Säikeet
+ Viestiketjut
Virhe
Serveriä ei tueta
Tiedosto on jo olemassa
@@ -202,9 +202,9 @@
reCAPTCHA Haaste pyydetty
Lataus
- Sallittuja merkkejä tiedostonimissä
+ Sallitut merkit tiedostonimissä
Epäkelvot merkit korvataan tällä arvolla
- Korvaus merkki
+ Korvaava merkki
Kirjaimia ja numeroita
Suurin osa erikoismerkeistä
@@ -221,7 +221,7 @@
Vapaa kevyt YouTube frontend Android:lle.
Näytä GitHub:ssa
NewPipe:n Lisenssi
- Olkoon sinulla ideoita; käännöksistä, design muutoksista, koodin siivoamisesta tai raskaista koodimuutoksista—apu on aina tervetullutta. Mitä enemmän saadaan tehtyä sen paremmaksi se tulee!
+ Olkoon sinulla ideoita; käännöksistä, design muutoksista, koodin siivoamisesta tai raskaista koodimuutoksista—apu on aina tervetullutta. Mitä enemmän saadaan tehtyä, sen paremmaksi sovellus tulee!
Lue lisenssi
Lahjoitus
@@ -234,4 +234,37 @@
Historia pyyhitty
Poistettu
Haluatko poistaa tämän hakuhistoriasta?
+Jatka toistoa
+ Info:
+ Mikä:\\nPyyntö:\\nSisällön kieli:\\nPalvelu:\\nGMT Aika:\\nPaketti:\\nVersio:\\nOS versio:\\nGlob. IP väli:
+ © %1$s %2$s %3$s alla
+ Pääsivun sisältö
+ Tyhjä sivu
+ Kioski sivu
+ Tilaukset sivu
+ Syötteet sivu
+ Kanavat sivu
+ Valitse kanava
+ Ei yhtään tilattua kanavaa vielä
+ Valitse kioski
+
+ Kioski
+ Nousussa
+ Top 50
+ Uudet & kuumat
+Näytä vihje kun taustasoitto tai popup painiketta on painettu
+ Lisätty taustasoittojonoon
+ Lisätty popup-jonoon
+ Toista kaikki
+
+ Suoratoisto epäonnistui
+ Palautuskelvoton soittimen virhe
+ Palaudutaan soittimen virheestä
+
+ Taustasoittosoitin
+ Popup-soitin
+ Poista
+ Yksityiskohdat
+ Audioasetukset
+ Pidä pohjassa lisätäksesi jonoon
diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml
index f8de02050..5b5620f72 100644
--- a/app/src/main/res/values-fr/strings.xml
+++ b/app/src/main/res/values-fr/strings.xml
@@ -257,4 +257,25 @@
Objet effacé
Voulez-vous supprimer cet élément de l\'historique de recherche ?
-
+Contentu
+ Page vide
+ Page de souscription
+ Page de Flux
+ Page de la chaîne
+ Sélectionnez une chaîne
+ Populaires
+ Top 50
+ Nouveau & populaire
+Mettre en file d\'attente du lecteur en arrière plan
+ Mettre en fil d\'attente du lecteur flottant
+ Lire tout
+
+ Échec de la lecture de cette vidéo
+ Une erreur irrécupérable du lecteur s\'est produite
+ Encore aucune chaîne souscrite
+ Lecteur en arrière plan
+ Lecteur flottant
+ Retirer
+ Détails
+ Réglages audio
+
diff --git a/app/src/main/res/values-hr/strings.xml b/app/src/main/res/values-hr/strings.xml
index 30d72a9ef..9c671e439 100644
--- a/app/src/main/res/values-hr/strings.xml
+++ b/app/src/main/res/values-hr/strings.xml
@@ -156,7 +156,7 @@
Počni
Pauziraj
- Pregled
+ Reproduciraj
Izbriši
Kontrolna suma
@@ -248,4 +248,11 @@
Stavka je izbrisana
-
+U redu čekanja za reprod. u pozadini
+ Reproduciraj sve
+
+ Nije moguće reproducirati ovaj stream
+ Dogodila se neoporavljiva pogreška reproduktora
+ Oporavljanje od pogreške reproduktora
+
+
diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml
index 0081c9844..68c1da06b 100644
--- a/app/src/main/res/values-it/strings.xml
+++ b/app/src/main/res/values-it/strings.xml
@@ -149,7 +149,7 @@
Apri in modalità popup
- NewPipe in modalità popup
+ NewPipe modalità a comparsa
Riproduzione in modalità popup
Disattivato
@@ -240,7 +240,7 @@
Annulla
Notifiche NewPipe
- Notifiche per NewPipe in background e Popup Player
+ Notifiche per NewPipe in background e per il lettore a comparsa
Nessun risultato
Nessun iscritto
@@ -257,12 +257,42 @@
Nessun video
- - %s video
- - %s video
+ - %s filmato
+ - %s filmati
Elemento eliminato
Nulla da mostrare
Vuoi eliminare questo elemento dalla cronologia?
+Contenuto della pagina principale
+ Pagina vuota
+ Edicola
+ Pagina iscrizione
+ Pagina del feed
+ Pagina del canale
+ Seleziona un canale
+ Non ancora iscritto a nessun canale
+ Seleziona un\'edicola
+
+ Edicola
+ In tendenza
+ Primi 50
+ Nuovi e caldi
+Mostra il suggerimento di tenere premuto per appendere
+ Mostra un suggerimento quando il pulsante in sottofondo o a comparsa viene premuto nella pagina dei dettagli di un video
+ In coda al riproduttore in sottofondo
+ In coda al riproduttore a comparsa
+ Riproduci tutto
+
+ Impossibile riprodurre questo flusso
+ Si è verificato un errore irrecuperabile al riproduttore
+ Recupero dall\'errore del riproduttore
+
+ Riproduttore di sottofondo
+ Riproduttore a comparsa
+ Rimuovi
+ Dettagli
+ Impostazioni audio
+ Tieni premuto per accodare
diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml
index a6b3daec9..5c155a644 100644
--- a/app/src/main/res/values-lt/strings.xml
+++ b/app/src/main/res/values-lt/strings.xml
@@ -1,2 +1,167 @@
-
-
\ No newline at end of file
+
+Palieskite paiešką, kad pradėtumėte
+ %1$s peržiūrų
+ Publikuota %1$s
+ Nerastas srauto grotuvas. Ar norite įdiegti VLC?
+ Įdiegti
+ Atšaukti
+ Atverti naršyklėje
+ Atverti išokančiojo lango rėžime
+ Dalintis
+ Atsisiųsti
+ Paieška
+ Nustatymai
+ Ar turėjote omenyje %1$s ?
+ Dalintis su
+ Pasirinkti naršyklę
+ sukimas
+ Naudoti išorinį vaizdo grotuvą
+ Kai kurios raiškos nepalaiko audio, kai ši parinktis įgalinta
+ Naudoti išorinį audio grotuvą
+ NewPipe iššokančiojo lango rėžimas
+ Fonas
+ Išokantis langelis
+
+ Vaizdo įrašų parsiuntimo kelias
+ Vieta parsisiųstų vaizdo įrašų laikymui
+ Įvesti parsiuntimo kelią vaizdo įrašams
+
+ Garso įrašų parsiuntimo kelias
+ Vieta laikyti parsisiųstus garso įrašus
+ Įveskite atsisiuntimų kelią garso įrašams
+
+ Automatinis paleidimas
+ Automatiškai groti vaizdo įrašą, kai NewPipe iškvečiama per kitą programėlę
+ Numatytoji raiška
+ Numatytoji išokančiojo lango raiška
+ Rodyti aukštesnes raiškas
+ Tik kai kurie įrenginiai palaiko 2K/4K vaizdo įrašų peržiūrą
+ Groti su Kodi
+ Kore programėlė nerasta. Įdiegti Kore?
+ Rodyti \"Peržiūra su Kodi\" pasirinkimą
+ Rodyti pasirinkimą peržiūrėti vaizdo įrašus per Kodi mediacentrą
+ Garso įrašas
+ Numatytasos garso formatas
+ Numatytasos vaizdo formatas
+ WebM — laisvas formatas
+ M4A - geresnė kokybė
+ Tema
+ Šviesumas
+ Tamsi
+ Juoda
+ Prisiminti sumažinto lango dydį ir vietą
+ Prisiminti paskutinį dydį ir vietą nustatytą langelio rėžimui
+ Grotuvo valdymas gestais
+ Naudokite gestus valdyti grotuvo ryškumą ir garsumą
+ Paieškos nuspėjimai
+ Rodyti nuspėjimus, kai ieškoma
+ Atsisiųsti
+ Kitas vaizdo įrašas
+ Rodyti kitus panašius vaizdo įrašus
+ URL nepalaikoma
+ Numatytoji turinio kalba
+ Vaizdas ir garsas
+ Iššokantis langas
+ Išvaizda
+ Kita
+ Groja fone
+ Grojama iššokančiojo lango rėžime
+ Groti
+ Turinys
+ Rodyti amžiaus cenzo apribotą turinį
+ Gyvai
+ Atsisiuntimai
+ Atsisiuntimai
+ Klaidų ataskaita
+ Visi
+ Kanalas
+ Taip
+ Vėliau
+ Išjungta
+ Filtras
+ Atnaujinti
+ Išvalyti
+ Dydžio keitimas
+ Geriausia raiška
+ Klaida
+ Tinklo klaida
+ Negalima įkelti visų miniatiūrų
+ Negalima iššifruoti vaizdo įrašo skaitmeninio parašo
+ Negalima apdoroti tinklapio
+ Negalima visiškai apdoroti tinklapio
+ Turinys neprieinamas
+ Užblokavo GEMA
+ Negalima sutvarkyti atsisiuntimų meniu
+ Tai gyvas srautas. Tokie kol kas nepalaikomi.
+ Negalima gauti jokio srauto
+ Negalima įkelti jokio paveikslėlio
+ Programėlė/ vartotojo sąsaja nulūžo
+ Atsiprašome, taip neturėjo įvykti
+ Raportuoti apie klaidą e- paštu
+ Atsiprašome, ištiko keletas klaidų.
+ ATASKAITA
+ Informacija
+ Kas nutiko:
+ Kas:\\nUžklausa:\\nTurinys Kalba:\\nPaslauga:\\nGMT Time:\\nPaketas:\\nVersija:\\nOperacinė Sistema versija:\\nGlob. IP diapazonas:
+ Jūsų komentaras (abglų kalba):
+ Detalės:
+
+
+ Vaizdo įrašo peržiūros miniatiūra
+ Vaizdo įrašo peržiūros miniatiūra
+ Įkėlėjo naudotojo paveikslėlio miniatiūra
+ Pamėgimai
+ Nemėgimai
+ Naudoti Tor
+ (Eksperimentinis) priverstinaisiųsti per Tor dėl privatumo (vaizdo įrašų užkrovimas dar nepalaikomas).
+ Pranešti apie klaidą
+ Naudoti raportavimą
+ Negalima sukurti atsisiuntimų aplanko \'%1$s\'
+ Sukurtas atsisiuntimų apkankas \'%1$s\'
+
+ Vaizdas
+ Muzika
+ Bandyti iš naujo
+ Naudoti seną grotuvą
+ Senas įtaisytas media grotuvas
+
+
+ - %s prenumeratorius
+ - %s prenumeratoriai
+
+
+
+
+
+ - Vaizdo įrašai
+
+
+
+
+
+ Pradėti
+ Pauzė
+ Ištrinti
+ Kontrolinė suma
+
+ Nauja užduotis
+ Gerai
+
+ Bylos pavadinimas
+ Gijos
+ Klaida
+ Tarnybinė stotis nepalaikoma
+ Byla jau egzistuoja
+ Neteisingas adresas arba negalimas internetas
+ NewPipe Atsiunčiama
+ Palieskite, kad peržiūrėtumėte detales
+ Prašome palaukti...
+ Nukopijuota į iškarpinę
+ Prašome pasirinkti galimą atsisiuntimų aplankalą
+ Šis leidimas nereikalingas, kad atidarytiviššokančio lango rėžime
+
+ reCAPTCHA
+ reCAPTCHA iššūkis
+ reCAPTCHA prašomas iššūkis
+
+
diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml
index 75cebf954..574b3189e 100644
--- a/app/src/main/res/values-nl/strings.xml
+++ b/app/src/main/res/values-nl/strings.xml
@@ -261,4 +261,5 @@ te openen in pop-upmodus
Item verwijderd
Wil je dit item uit je geschiedenis verwijderen?
-
+Laat vasthouden om te toevoegen zien
+
diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml
index 9123f868c..590008846 100644
--- a/app/src/main/res/values-pt-rBR/strings.xml
+++ b/app/src/main/res/values-pt-rBR/strings.xml
@@ -242,4 +242,34 @@ abrir em modo popup
Não há nada aqui
Deseja apagar este item do seu histórico de busca?
+Conteúdo
+ Página em Branco
+ Página de Quiosque
+ Página de Inscrição
+ Página de Atualizações
+ Página de Canais
+ Selecione um canal
+ Nenhuma inscrição ainda
+ Selecione um quiosque
+
+ Quiosque
+ Em Alta
+ Top 50
+ Novos e tendências
+Mostrar dica para Mantenha pressionado para colocar na fila
+ Mostrar dica quando o botão de plano de fundo ou de popup for pressionado na página de detalhes do vídeo
+ Adicionado a fila do reprodutor em plano de fundo
+ Adicionado a fila no reprodutor popup
+ Reproduzir tudo
+
+ Falha ao reproduzir esta stream
+ Ocorreu um erro no reprodutor
+ Recuperando erro do reprodutor
+
+ Reprodutor de plano de fundo
+ Reprodutor Popup
+ Remover
+ Detalhes
+ Configurações de Áudio
+ Mantenha pressionado para colocar na fila
diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml
index 46b0b0584..e3a29073a 100644
--- a/app/src/main/res/values-ro/strings.xml
+++ b/app/src/main/res/values-ro/strings.xml
@@ -1,8 +1,8 @@
- %1$s (de) vizionări
+ %1$s vizionări
Încărcat pe %1$s
- Nici un player pentru stream-uri găsit. Instalați VLC?
+ Niciun player pentru stream-uri găsit. Instalați VLC?
Instalare
Anulare
Deschidere în browser
@@ -17,17 +17,17 @@
Folosește un player video extern
Folosește un player audio extern
- Locul în care se vor descărca videoclipurile
- Locul în care se vor stoca videoclipurile descărcate
- Introduceți locul în care se vor descărca videoclipurile
+ Locația videoclipurilor descărcate
+ Locul în care se vor descărca videoclipurile
+ Introduceți locația în care se vor descărca videoclipurile
- Calea de descărcare a sunetelor
- Locul în care se vor stoca fișierele audio descărcate
- Introduceți calea de descărcare pentru fișierele audio
+ Locația audio-ului descărcat
+ Locul în care se va descărca audio-ul
+ Introduceți locația în care se va descărca audio-ul
Rezoluție implicită
Redați folosind Kodi
- Aplicația Kore nu a fost găsită. Instalați Kore?
+ Aplicația Kore nu a fost găsită. Doriți să o instalați?
Arată opțiunea \"Redați folosind Kodi\"
Arătați o opțiune de redare a videoclipurilor via centrului media Kodi
Audio
@@ -60,13 +60,13 @@
Nu s-a putut analiza website-ul
Conținut indisponibil
Blocat de către GEMA
- Nu s-a putut seta meniul de descărcare.
- Acesta este un LIVE STREAM. Acestea nu sunt încă suportate.
+ Imposibil de inițializat meniul pentru descărcări
+ Acesta este un LIVE STREAM, care încă nu este suportat.
Thumbnail de previzualizare al videoclipului
Thumbnail de previzualizare al videoclipului
- Thumbnail-ul pentru userpicul persoanei care a încărcat videoclipul
+ Thumbnail-ul autorului
Au apreciat
Nu au apreciat
Folosiți Tor
@@ -75,7 +75,7 @@
Nu s-a putut crea directorul de descărcare \'%1$s\'
Apăsați căutare pentru a începe
Redă automat
- Redă automat un video când NewPipe este chemat de altă aplicație
+ Redă automat un videoclip atunci când NewPipe este deschis din altă aplicație
în direct
Descărcări
Descărcări
@@ -85,7 +85,7 @@
Nu s-a putut prelua niciun stream
Scuze, asta n-ar fi trebui să se întâmple.
Raportează eroarea prin e-mail
- Scuze, câteva erori au apărut.
+ Ne scuzați, au apărut câteva erori.
RAPORTAȚI
Informații:
Ce s-a întâmplat:
@@ -103,15 +103,15 @@
Start
Pauză
- Vezi
+ Redă
Șterge
Suma de control
Misiune nouă
- Ok
+ OK
- Nume fișier
+ Numele fișierului
Thread-uri
Eroare
Server nesuportat
@@ -120,10 +120,10 @@
NewPipe Descarcă
Apasă pentru detalii
Vă rugăm așteptați…
- Copiat în clipboard.
- Vă rugăm selectați un director de descărcare disponibil.
+ Copiat în clipboard
+ Vă rugăm alegeți un folder pentru descărcări
- Deschide in mod pop-up
+ Deschide in modul popup
Aceasta permisiune este necesara
pentru a deschide în mod pop-up
@@ -131,11 +131,11 @@ pentru a deschide în mod pop-up
reCAPTCHA noua
reCAPTCHA noua ceruta
- NewPipe mod Pop-up
+ NewPipe mod pop-up
Rezoluție inițială pop-up
- Arată rezoluție mai mare
- Doar anumite dispozitive suportă afișare video în mod 2K/4K
+ Afișează rezoluții mai mari
+ Doar anumite dispozitive suportă redarea videoclipurilor 2K/4K
Format video preferat
Negru
@@ -150,12 +150,12 @@ pentru a deschide în mod pop-up
App/UI eroare
What:\\nRequest:\\nContent Lang:\\nService:\\nGMT Time:\\nPackage:\\nVersion:\\nOS version:\\nGlob. IP clasa:
Folosește player vechi
- Versiune veche în Mediaframework player.
+ Player Mediaframework implicit
K
- M
- B
+ mil.
+ mld.
Anumite rezoluții NU vor avea sunet atunci când această opțiune este activată
Fundal
@@ -173,18 +173,18 @@ pentru a deschide în mod pop-up
Reîmprospătare
Șterge
Redimensionare
- Cea mai bună rezoluție
+ Rezoluția optimă
Abonează-te
Abonat
Canal dezabonat
- Nu s-a putut modifica abonarea
- Nu s-a putut actualiza abonarea
+ Nu s-a putut modifica abonamentul
+ Nu s-a putut actualiza abonamentul
Principal
- Abonări
+ Abonamente
- Ce e nou
+ Ce este nou
Istoric de căutare
Stochează local căutările
@@ -202,6 +202,75 @@ pentru a deschide în mod pop-up
Notificări pentru NewPipe Background și Popup Players
Fără rezultate
- Nimic Aici Doar Greieri
+ Nimic aici în afară de sunetul greierilor
-
+ Niciun abonat
+
+ - %s abonat
+ - %s abonați
+ - %s abonați
+
+
+ Nicio vizionare
+
+ - %s vizionare
+ - %s vizionări
+ - %s vizionări
+
+
+ Niciun videoclip
+
+ - %s videoclip
+ - %s videoclipuri
+ - %s videoclipuri
+
+
+ Descarcă
+ Caractere permise în numele fișierelor
+ Caracterele invalide sunt înlocuite cu această valoare
+ Caracter înlocuitor
+
+ Litere și cifre
+ Caracterele cele mai speciale
+
+ Despre NewPipe
+ Setări
+ Despre
+ Licențe terță-parte
+ © %1$s de %2$s sub %3$s
+ Nu s-a putut încărca licența
+ Accesează site-ul
+ Despre
+ Contributori
+ Licențe
+ Un player Youtube lightweight gratuit, pentru Android.
+ Vedeți pe GitHub
+ Licența NewPipe
+ Dacă aveți idei, doriți să traduceți, să schimbați design-ul, să curățați codul sau să schimbați codul, ajutorul este mereu bine primit. Cu cât mai mult, cu atât mai bine!
+ Citiți licența
+ Contribuție
+
+ Istoric
+ Căutat
+ Vizionat
+ Istoricul este dezactivat
+ Istoric
+ Istoricul este gol
+ Istoric curățat
+ Element șters
+ Doriți să ștergeți acest element din istoricul de căutare?
+Conținutul paginii principale
+ Pagină Goală
+ Pagină Chioșc
+ Pagină Abonări
+ Pagină Feed
+ Pagină Canale
+ Alegeți un canal
+ Nu v-ați abonat la niciun canal deocamdată
+ Alegeți un chioșc
+
+ Chioșc
+ Trenduri
+ Top 50
+ Tendințe
+
diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml
index e60ec9917..5f20f9721 100644
--- a/app/src/main/res/values-ru/strings.xml
+++ b/app/src/main/res/values-ru/strings.xml
@@ -185,7 +185,7 @@
Бесплатный лёгкий интерфейс YouTube для Android.
Открыть на GitHub
Приветствуется всё — идеи, перевод, изменения дизайна, чистка кода или огромные изменения в коде. Чем больше сделано, тем лучше!
- © %1$s за авторством %2$s под лицензией %3$s
+ © %1$s %2$s под лицензией %3$s
Помощь проекту
Подписаться
Не удалось изменить подписку
@@ -258,4 +258,24 @@
Элемент удалён
Удалить этот элемент из истории поиска?
-
+Контент главной страницы
+ Пустая страница
+ Страница киоска
+ Страница подписки
+ Страница ленты
+ Страница канала
+ Выберите канал
+ Выберите киоск
+
+ Киоск
+ В тренде
+ Топ 50
+ Новое и горячее
+ Добавлено в очередь в фоне
+ Добавлено в очередь в окне
+ Воспроизвести всё
+
+ Не удалось воспроизвести этот поток
+ Подробности
+ Настройки аудио
+
diff --git a/app/src/main/res/values-sr/strings.xml b/app/src/main/res/values-sr/strings.xml
index 9bb47a7c7..2c04fd81c 100644
--- a/app/src/main/res/values-sr/strings.xml
+++ b/app/src/main/res/values-sr/strings.xml
@@ -269,4 +269,34 @@
Лиценца Њупајпа
Помоћ је увек добро дошла, било да имате идеју за превод, дизајн, козметичке или озбиљне измене кôда. Што се више уради, боље је!
Ставка обрисана
-
+Приказ савета када је позадинско или искачуће дугме притиснуто на страници детаља видеа
+ У реду за позадински плејер
+ У реду за искачући плејер
+ Пусти све
+
+ Неуспех пуштања овог тока
+ Десила се непоправљива грешка плејера
+ Опорављам се од грешке плејера
+
+ Желите ли да обришете ову ставку из историјата претраге?
+
+ Садржај на главној страници
+ Празна страница
+ Киоск страница
+ Страница претплате
+ Страница довода
+ Страница канала
+ Изаберите канал
+ Још нема претплата на канал
+ Изаберите киоск
+
+ Киоск
+ У тренду
+ Топ 50
+ Ново и вруће
+ Позадински плејер
+ Искачући плејер
+ Уклони
+ Детаљи
+ Поставке звука
+
diff --git a/app/src/main/res/values/attrs.xml b/app/src/main/res/values/attrs.xml
index dd92f916a..abf7c7b09 100644
--- a/app/src/main/res/values/attrs.xml
+++ b/app/src/main/res/values/attrs.xml
@@ -18,10 +18,14 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index 9f8a41bc5..3750bdb78 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -10,6 +10,9 @@
#48868686
#1fa6a6a6
#5a000000
+ #ffffff
+ #212121
+ #c8ffffff
#222222
@@ -20,6 +23,9 @@
#48ffffff
#1f717171
#82000000
+ #424242
+ #ffffff
+ #af000000
#000
@@ -37,8 +43,11 @@
#e53935
#fff
- #d6d6d6 d
- #717171 d
+ #d6d6d6
+ #717171
+
+ #00000000
+ #96717171
#607D8B
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
index 32e300ca1..829c412e5 100644
--- a/app/src/main/res/values/dimens.xml
+++ b/app/src/main/res/values/dimens.xml
@@ -67,4 +67,10 @@
24dp
28dp
+
+ 62dp
+ 40dp
+
+
+ 30sp
diff --git a/app/src/main/res/values/settings_keys.xml b/app/src/main/res/values/settings_keys.xml
index 76cd10681..5eee12c6c 100644
--- a/app/src/main/res/values/settings_keys.xml
+++ b/app/src/main/res/values/settings_keys.xml
@@ -1,5 +1,8 @@
+
+ current_service
+
download_path
download_path_audio
@@ -89,15 +92,34 @@
- @string/black_theme_title
+
show_search_suggestions
show_play_with_kodi
show_next_video
+ show_hold_to_append
en
search_language
show_age_restricted_content
use_tor
enable_search_history
enable_watch_history
+ main_page_content
+ blank_page
+ feed_page
+ subscription_page_key
+ kiosk_page
+ channel_page
+
+ - @string/blank_page_key
+ - @string/kiosk_page_key
+ - @string/feed_page_key
+ - @string/subscription_page_key
+ - @string/channel_page_key
+
+ main_page_selected_service
+ main_page_selected_channel_name
+ main_page_selected_channel_url
+ main_page_selectd_kiosk_id
file_rename
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index e798e62e9..ad69915b9 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -53,7 +53,7 @@
Only some devices support playing 2K/4K videos
Play with Kodi
Kore app not found. Install it?
- https://f-droid.org/repository/browse/?fdfilter=Kore&fdid=org.xbmc.kore
+ org.xbmc.kore
Show \"Play with Kodi\" option
Display an option to play a video via Kodi media center
Audio
@@ -80,6 +80,8 @@
Download
Next video
Show next and similar videos
+ Show Hold to Append Tip
+ Show tip when background or popup button is pressed on video details page
URL not supported
Default content language
Player
@@ -91,6 +93,8 @@
Other
Playing in background
Playing in popup mode
+ Queued on background player
+ Queued on popup player
https://www.c3s.cc/
Play
Content
@@ -112,6 +116,7 @@
Resizing
Best resolution
Undo
+ Play All
newpipe
NewPipe Notification
@@ -131,6 +136,10 @@
Could not get any stream
Could not load image
App/UI crashed
+ Failed to play this stream
+ Unrecoverable player error occurred
+ Recovering from player error
+
Sorry, that should not have happened.
Guru Meditation.
@@ -266,4 +275,37 @@
History cleared
Item deleted
Do you want to delete this item from search history?
+
+
+ Content of main page
+ Blank Page
+ Kiosk Page
+ Subscription Page
+ Feed Page
+ Channel Page
+
+ - @string/blank_page_summary
+ - @string/kiosk_page_summary
+ - @string/feed_page_summary
+ - @string/subscription_page_summary
+ - @string/channel_page_summary
+
+ Select a channel
+ No channel subscribed yet
+ Select a kiosk
+
+
+ Kiosk
+ Trending
+ Top 50
+ New & hot
+ %1$s/%2$s
+
+
+ Background Player
+ Popup Player
+ Remove
+ Details
+ Audio Settings
+ Hold To Enqueue
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
index fa37f0e5d..8f0bb02cd 100644
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -25,10 +25,14 @@
- @drawable/ic_palette_black_24dp
- @drawable/ic_language_black_24dp
- @drawable/ic_history_black_24dp
+ - @drawable/ic_drag_handle_black_24dp
+ - @drawable/ic_fiber_manual_record_black_24dp
- @color/light_separator_color
- @color/light_contrast_background_color
+ - @color/light_queue_background_color
- @drawable/toolbar_shadow_light
+ - @drawable/light_selector
- @color/light_ripple_color
- @style/PreferenceThemeOverlay.v14.Material
@@ -59,10 +63,14 @@
- @drawable/ic_palette_white_24dp
- @drawable/ic_language_white_24dp
- @drawable/ic_history_white_24dp
+ - @drawable/ic_drag_handle_white_24dp
+ - @drawable/ic_fiber_manual_record_white_24dp
- @color/dark_separator_color
- @color/dark_contrast_background_color
+ - @color/dark_queue_background_color
- @drawable/toolbar_shadow_dark
+ - @drawable/dark_selector
- @color/dark_ripple_color
- @style/PreferenceThemeOverlay.v14.Material
diff --git a/app/src/main/res/xml/appearance_settings.xml b/app/src/main/res/xml/appearance_settings.xml
index 62199a781..58b08a284 100644
--- a/app/src/main/res/xml/appearance_settings.xml
+++ b/app/src/main/res/xml/appearance_settings.xml
@@ -16,4 +16,9 @@
android:key="@string/show_next_video_key"
android:title="@string/show_next_and_similar_title"/>
+
diff --git a/app/src/main/res/xml/content_settings.xml b/app/src/main/res/xml/content_settings.xml
index 63cd3cd01..11672671e 100644
--- a/app/src/main/res/xml/content_settings.xml
+++ b/app/src/main/res/xml/content_settings.xml
@@ -21,5 +21,12 @@
android:key="@string/show_search_suggestions_key"
android:summary="@string/show_search_suggestions_summary"
android:title="@string/show_search_suggestions_title"/>
+
diff --git a/app/src/main/res/xml/provider_paths.xml b/app/src/main/res/xml/provider_paths.xml
index ffa74ab56..7c55d5a29 100644
--- a/app/src/main/res/xml/provider_paths.xml
+++ b/app/src/main/res/xml/provider_paths.xml
@@ -1,4 +1,5 @@
+
\ No newline at end of file
diff --git a/assets/service.svg b/assets/service.svg
new file mode 100644
index 000000000..172cc106f
--- /dev/null
+++ b/assets/service.svg
@@ -0,0 +1,109 @@
+
+
+
+
+
+
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+