-Added play buttons to channel fragment similar to playlist fragment.

-Fixed abstract info play queue reloading the same initial page.
-Fixed OOB on get item for abstract play queue.
This commit is contained in:
John Zhen Mo 2017-11-04 11:30:01 -07:00
parent b883f313ba
commit 7700cff5e5
6 changed files with 191 additions and 77 deletions

View File

@ -3,6 +3,7 @@ package org.schabi.newpipe.fragments.list.channel;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
@ -10,6 +11,7 @@ import android.support.v4.content.ContextCompat;
import android.support.v7.app.ActionBar;
import android.text.TextUtils;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
@ -19,6 +21,7 @@ import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.jakewharton.rxbinding2.view.RxView;
@ -30,10 +33,14 @@ import org.schabi.newpipe.extractor.channel.ChannelInfo;
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
import org.schabi.newpipe.fragments.list.BaseListInfoFragment;
import org.schabi.newpipe.fragments.subscription.SubscriptionService;
import org.schabi.newpipe.playlist.ChannelPlayQueue;
import org.schabi.newpipe.playlist.PlayQueue;
import org.schabi.newpipe.report.UserAction;
import org.schabi.newpipe.util.AnimationUtils;
import org.schabi.newpipe.util.ExtractorHelper;
import org.schabi.newpipe.util.Localization;
import org.schabi.newpipe.util.NavigationHelper;
import org.schabi.newpipe.util.PermissionHelper;
import java.util.List;
import java.util.concurrent.TimeUnit;
@ -69,6 +76,10 @@ public class ChannelFragment extends BaseListInfoFragment<ChannelInfo> {
private TextView headerSubscribersTextView;
private Button headerSubscribeButton;
private Button headerPlayAllButton;
private Button headerPopupButton;
private Button headerBackgroundButton;
private MenuItem menuRssButton;
public static ChannelFragment getInstance(int serviceId, String url, String name) {
@ -125,6 +136,10 @@ public class ChannelFragment extends BaseListInfoFragment<ChannelInfo> {
headerSubscribersTextView = headerRootLayout.findViewById(R.id.channel_subscriber_view);
headerSubscribeButton = headerRootLayout.findViewById(R.id.channel_subscribe_button);
headerPlayAllButton = headerRootLayout.findViewById(R.id.playlist_play_all_button);
headerPopupButton = headerRootLayout.findViewById(R.id.playlist_play_popup_button);
headerBackgroundButton = headerRootLayout.findViewById(R.id.playlist_play_bg_button);
return headerRootLayout;
}
@ -391,6 +406,42 @@ public class ChannelFragment extends BaseListInfoFragment<ChannelInfo> {
if (subscribeButtonMonitor != null) subscribeButtonMonitor.dispose();
updateSubscription(result);
monitorSubscription(result);
headerPlayAllButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
NavigationHelper.playOnMainPlayer(activity, getPlayQueue());
}
});
headerPopupButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !PermissionHelper.checkSystemAlertWindowPermission(activity)) {
Toast toast = Toast.makeText(activity, R.string.msg_popup_permission, Toast.LENGTH_LONG);
TextView messageView = toast.getView().findViewById(android.R.id.message);
if (messageView != null) messageView.setGravity(Gravity.CENTER);
toast.show();
return;
}
NavigationHelper.playOnPopupPlayer(activity, getPlayQueue());
}
});
headerBackgroundButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
NavigationHelper.playOnBackgroundPlayer(activity, getPlayQueue());
}
});
}
private PlayQueue getPlayQueue() {
return new ChannelPlayQueue(
currentInfo.service_id,
currentInfo.url,
currentInfo.next_streams_url,
infoListAdapter.getItemsList(),
0
);
}
@Override

View File

@ -26,7 +26,7 @@ abstract class AbstractInfoPlayQueue<T extends ListInfo, U extends InfoItem> ext
transient Disposable fetchReactor;
AbstractInfoPlayQueue(final U item) {
this(item.service_id, item.url, item.url, Collections.<InfoItem>emptyList(), 0);
this(item.service_id, item.url, null, Collections.<InfoItem>emptyList(), 0);
}
AbstractInfoPlayQueue(final int serviceId,
@ -55,7 +55,7 @@ abstract class AbstractInfoPlayQueue<T extends ListInfo, U extends InfoItem> ext
return new SingleObserver<T>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
if (isComplete || (fetchReactor != null && !fetchReactor.isDisposed())) {
if (isComplete || !isInitial || (fetchReactor != null && !fetchReactor.isDisposed())) {
d.dispose();
} else {
fetchReactor = d;
@ -64,6 +64,7 @@ abstract class AbstractInfoPlayQueue<T extends ListInfo, U extends InfoItem> ext
@Override
public void onSuccess(@NonNull T result) {
isInitial = false;
if (!result.has_more_streams) isComplete = true;
nextUrl = result.next_streams_url;
@ -86,7 +87,7 @@ abstract class AbstractInfoPlayQueue<T extends ListInfo, U extends InfoItem> ext
return new SingleObserver<ListExtractor.NextItemsResult>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
if (isComplete || (fetchReactor != null && !fetchReactor.isDisposed())) {
if (isComplete || isInitial || (fetchReactor != null && !fetchReactor.isDisposed())) {
d.dispose();
} else {
fetchReactor = d;

View File

@ -16,10 +16,10 @@ public final class ChannelPlayQueue extends AbstractInfoPlayQueue<ChannelInfo, C
}
public ChannelPlayQueue(final int serviceId,
final String url,
final String nextPageUrl,
final List<InfoItem> streams,
final int index) {
final String url,
final String nextPageUrl,
final List<InfoItem> streams,
final int index) {
super(serviceId, url, nextPageUrl, streams, index);
}

View File

@ -123,7 +123,7 @@ public abstract class PlayQueue implements Serializable {
* May throw {@link IndexOutOfBoundsException}.
* */
public PlayQueueItem getItem(int index) {
if (index >= streams.size() || streams.get(index) == null) return null;
if (index < 0 || index >= streams.size() || streams.get(index) == null) return null;
return streams.get(index);
}

View File

@ -16,10 +16,10 @@ public final class PlaylistPlayQueue extends AbstractInfoPlayQueue<PlaylistInfo,
}
public PlaylistPlayQueue(final int serviceId,
final String url,
final String nextPageUrl,
final List<InfoItem> streams,
final int index) {
final String url,
final String nextPageUrl,
final List<InfoItem> streams,
final int index) {
super(serviceId, url, nextPageUrl, streams, index);
}

View File

@ -5,76 +5,138 @@
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/channel_header_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="12dp">
android:layout_height="wrap_content">
<ImageView
android:id="@+id/channel_banner_image"
<RelativeLayout
android:id="@+id/channel_metadata"
android:layout_width="match_parent"
android:layout_height="70dp"
android:background="@android:color/black"
android:fitsSystemWindows="true"
android:scaleType="centerCrop"
android:src="@drawable/channel_banner"
tools:ignore="ContentDescription"/>
android:layout_height="wrap_content">
<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/channel_avatar_view"
android:layout_width="@dimen/channel_avatar_size"
android:layout_height="@dimen/channel_avatar_size"
android:layout_alignTop="@id/channel_banner_image"
android:layout_marginLeft="8dp"
android:layout_marginTop="50dp"
android:src="@drawable/buddy"
app:civ_border_color="#ffffff"
app:civ_border_width="2dp"
tools:ignore="RtlHardcoded"/>
<ImageView
android:id="@+id/channel_banner_image"
android:layout_width="match_parent"
android:layout_height="70dp"
android:background="@android:color/black"
android:fitsSystemWindows="true"
android:scaleType="centerCrop"
android:src="@drawable/channel_banner"
tools:ignore="ContentDescription"/>
<TextView
android:id="@+id/channel_title_view"
<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/channel_avatar_view"
android:layout_width="@dimen/channel_avatar_size"
android:layout_height="@dimen/channel_avatar_size"
android:layout_alignTop="@id/channel_banner_image"
android:layout_marginLeft="8dp"
android:layout_marginTop="50dp"
android:src="@drawable/buddy"
app:civ_border_color="#ffffff"
app:civ_border_width="2dp"
tools:ignore="RtlHardcoded"/>
<TextView
android:id="@+id/channel_title_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/channel_banner_image"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginTop="6dp"
android:layout_toLeftOf="@+id/channel_subscribe_button"
android:layout_toRightOf="@+id/channel_avatar_view"
android:ellipsize="end"
android:lines="1"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textSize="@dimen/video_item_detail_title_text_size"
tools:ignore="RtlHardcoded"
tools:text="Lorem ipsum dolor"/>
<TextView
android:id="@+id/channel_subscriber_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/channel_title_view"
android:layout_alignRight="@+id/channel_title_view"
android:layout_below="@+id/channel_title_view"
android:ellipsize="end"
android:gravity="left|center"
android:lines="1"
android:textSize="@dimen/channel_subscribers_text_size"
android:visibility="gone"
tools:ignore="RtlHardcoded"
tools:text="123,141,411 subscribers"
tools:visibility="visible"/>
<android.support.v7.widget.AppCompatButton
android:id="@+id/channel_subscribe_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_below="@+id/channel_banner_image"
android:layout_gravity="center_vertical|right"
android:layout_marginRight="2dp"
android:text="@string/subscribe_button_title"
android:textSize="@dimen/channel_rss_title_size"
android:theme="@style/RedButton"
android:visibility="gone"
tools:ignore="RtlHardcoded"
tools:visibility="visible"/>
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/channel_banner_image"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginTop="6dp"
android:layout_toLeftOf="@+id/channel_subscribe_button"
android:layout_toRightOf="@+id/channel_avatar_view"
android:ellipsize="end"
android:lines="1"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textSize="@dimen/video_item_detail_title_text_size"
tools:ignore="RtlHardcoded"
tools:text="Lorem ipsum dolor"/>
<TextView
android:id="@+id/channel_subscriber_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/channel_title_view"
android:layout_alignRight="@+id/channel_title_view"
android:layout_below="@+id/channel_title_view"
android:ellipsize="end"
android:gravity="left|center"
android:lines="1"
android:textSize="@dimen/channel_subscribers_text_size"
android:visibility="gone"
tools:ignore="RtlHardcoded"
tools:text="123,141,411 subscribers"
tools:visibility="visible"/>
<android.support.v7.widget.AppCompatButton
android:id="@+id/channel_subscribe_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_below="@+id/channel_banner_image"
android:layout_gravity="center_vertical|right"
android:id="@+id/play_control"
android:layout_marginRight="2dp"
android:text="@string/subscribe_button_title"
android:textSize="@dimen/channel_rss_title_size"
android:theme="@style/RedButton"
android:visibility="gone"
tools:ignore="RtlHardcoded"
tools:visibility="visible"/>
android:layout_marginEnd="2dp"
android:layout_below="@+id/channel_metadata">
<Button
android:id="@+id/playlist_play_bg_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|right"
android:layout_marginRight="2dp"
android:layout_toLeftOf="@+id/playlist_play_all_button"
android:layout_toStartOf="@+id/playlist_play_all_button"
android:text="@string/controls_background_title"
android:textSize="@dimen/channel_rss_title_size"
android:textColor="?attr/colorAccent"
android:theme="@style/RedButton"
android:drawableLeft="?attr/audio"
android:drawablePadding="4dp"
tools:ignore="RtlHardcoded"
tools:visibility="visible" />
<Button
android:id="@+id/playlist_play_all_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|right"
android:layout_marginRight="2dp"
android:layout_toLeftOf="@+id/playlist_play_popup_button"
android:layout_toStartOf="@+id/playlist_play_popup_button"
android:text="@string/play_all"
android:textSize="@dimen/channel_rss_title_size"
android:textColor="?attr/colorAccent"
android:theme="@style/RedButton"
tools:ignore="RtlHardcoded"
tools:visibility="visible"/>
<Button
android:id="@+id/playlist_play_popup_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|right"
android:layout_alignParentRight="true"
android:text="@string/controls_popup_title"
android:textSize="@dimen/channel_rss_title_size"
android:textColor="?attr/colorAccent"
android:theme="@style/RedButton"
android:drawableLeft="?attr/popup"
android:drawablePadding="4dp"
tools:ignore="RtlHardcoded"
tools:visibility="visible" />
</RelativeLayout>
</RelativeLayout>