mirror of
https://github.com/TeamNewPipe/NewPipe.git
synced 2024-11-26 04:52:29 +01:00
Base implementation of showing playback positions in lists
This commit is contained in:
parent
4e1423d224
commit
73be8cf074
@ -65,6 +65,12 @@ public abstract class BaseListFragment<I, N> extends BaseStateFragment<I> implem
|
|||||||
infoListAdapter = new InfoListAdapter(activity);
|
infoListAdapter = new InfoListAdapter(activity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDetach() {
|
||||||
|
infoListAdapter.dispose();
|
||||||
|
super.onDetach();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
@ -2,12 +2,14 @@ package org.schabi.newpipe.info_list;
|
|||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
import com.nostra13.universalimageloader.core.ImageLoader;
|
import com.nostra13.universalimageloader.core.ImageLoader;
|
||||||
|
|
||||||
|
import org.schabi.newpipe.database.stream.model.StreamStateEntity;
|
||||||
import org.schabi.newpipe.extractor.InfoItem;
|
import org.schabi.newpipe.extractor.InfoItem;
|
||||||
import org.schabi.newpipe.extractor.channel.ChannelInfoItem;
|
import org.schabi.newpipe.extractor.channel.ChannelInfoItem;
|
||||||
import org.schabi.newpipe.extractor.comments.CommentsInfoItem;
|
import org.schabi.newpipe.extractor.comments.CommentsInfoItem;
|
||||||
@ -59,13 +61,14 @@ public class InfoItemBuilder {
|
|||||||
this.context = context;
|
this.context = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
public View buildView(@NonNull ViewGroup parent, @NonNull final InfoItem infoItem) {
|
public View buildView(@NonNull ViewGroup parent, @NonNull final InfoItem infoItem, @Nullable StreamStateEntity state) {
|
||||||
return buildView(parent, infoItem, false);
|
return buildView(parent, infoItem, state, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public View buildView(@NonNull ViewGroup parent, @NonNull final InfoItem infoItem, boolean useMiniVariant) {
|
public View buildView(@NonNull ViewGroup parent, @NonNull final InfoItem infoItem,
|
||||||
|
@Nullable StreamStateEntity state, boolean useMiniVariant) {
|
||||||
InfoItemHolder holder = holderFromInfoType(parent, infoItem.getInfoType(), useMiniVariant);
|
InfoItemHolder holder = holderFromInfoType(parent, infoItem.getInfoType(), useMiniVariant);
|
||||||
holder.updateFromItem(infoItem);
|
holder.updateFromItem(infoItem, state);
|
||||||
return holder.itemView;
|
return holder.itemView;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,16 +7,17 @@ import android.util.Log;
|
|||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
|
import org.schabi.newpipe.database.stream.model.StreamStateEntity;
|
||||||
import org.schabi.newpipe.extractor.InfoItem;
|
import org.schabi.newpipe.extractor.InfoItem;
|
||||||
import org.schabi.newpipe.extractor.channel.ChannelInfoItem;
|
import org.schabi.newpipe.extractor.channel.ChannelInfoItem;
|
||||||
import org.schabi.newpipe.extractor.comments.CommentsInfoItem;
|
import org.schabi.newpipe.extractor.comments.CommentsInfoItem;
|
||||||
import org.schabi.newpipe.extractor.playlist.PlaylistInfoItem;
|
import org.schabi.newpipe.extractor.playlist.PlaylistInfoItem;
|
||||||
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
|
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
|
||||||
|
import org.schabi.newpipe.info_list.holder.ChannelGridInfoItemHolder;
|
||||||
import org.schabi.newpipe.info_list.holder.ChannelInfoItemHolder;
|
import org.schabi.newpipe.info_list.holder.ChannelInfoItemHolder;
|
||||||
import org.schabi.newpipe.info_list.holder.ChannelMiniInfoItemHolder;
|
import org.schabi.newpipe.info_list.holder.ChannelMiniInfoItemHolder;
|
||||||
import org.schabi.newpipe.info_list.holder.CommentsInfoItemHolder;
|
import org.schabi.newpipe.info_list.holder.CommentsInfoItemHolder;
|
||||||
import org.schabi.newpipe.info_list.holder.CommentsMiniInfoItemHolder;
|
import org.schabi.newpipe.info_list.holder.CommentsMiniInfoItemHolder;
|
||||||
import org.schabi.newpipe.info_list.holder.ChannelGridInfoItemHolder;
|
|
||||||
import org.schabi.newpipe.info_list.holder.InfoItemHolder;
|
import org.schabi.newpipe.info_list.holder.InfoItemHolder;
|
||||||
import org.schabi.newpipe.info_list.holder.PlaylistGridInfoItemHolder;
|
import org.schabi.newpipe.info_list.holder.PlaylistGridInfoItemHolder;
|
||||||
import org.schabi.newpipe.info_list.holder.PlaylistInfoItemHolder;
|
import org.schabi.newpipe.info_list.holder.PlaylistInfoItemHolder;
|
||||||
@ -24,12 +25,16 @@ import org.schabi.newpipe.info_list.holder.PlaylistMiniInfoItemHolder;
|
|||||||
import org.schabi.newpipe.info_list.holder.StreamGridInfoItemHolder;
|
import org.schabi.newpipe.info_list.holder.StreamGridInfoItemHolder;
|
||||||
import org.schabi.newpipe.info_list.holder.StreamInfoItemHolder;
|
import org.schabi.newpipe.info_list.holder.StreamInfoItemHolder;
|
||||||
import org.schabi.newpipe.info_list.holder.StreamMiniInfoItemHolder;
|
import org.schabi.newpipe.info_list.holder.StreamMiniInfoItemHolder;
|
||||||
|
import org.schabi.newpipe.local.history.HistoryRecordManager;
|
||||||
import org.schabi.newpipe.util.FallbackViewHolder;
|
import org.schabi.newpipe.util.FallbackViewHolder;
|
||||||
import org.schabi.newpipe.util.OnClickGesture;
|
import org.schabi.newpipe.util.OnClickGesture;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||||
|
import io.reactivex.disposables.CompositeDisposable;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Created by Christian Schabesberger on 01.08.16.
|
* Created by Christian Schabesberger on 01.08.16.
|
||||||
*
|
*
|
||||||
@ -70,7 +75,10 @@ public class InfoListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
|
|||||||
private static final int COMMENT_HOLDER_TYPE = 0x401;
|
private static final int COMMENT_HOLDER_TYPE = 0x401;
|
||||||
|
|
||||||
private final InfoItemBuilder infoItemBuilder;
|
private final InfoItemBuilder infoItemBuilder;
|
||||||
|
private final HistoryRecordManager historyRecordManager;
|
||||||
private final ArrayList<InfoItem> infoItemList;
|
private final ArrayList<InfoItem> infoItemList;
|
||||||
|
private final ArrayList<StreamStateEntity> states;
|
||||||
|
private final CompositeDisposable stateLoaders;
|
||||||
private boolean useMiniVariant = false;
|
private boolean useMiniVariant = false;
|
||||||
private boolean useGridVariant = false;
|
private boolean useGridVariant = false;
|
||||||
private boolean showFooter = false;
|
private boolean showFooter = false;
|
||||||
@ -88,7 +96,10 @@ public class InfoListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
|
|||||||
|
|
||||||
public InfoListAdapter(Activity a) {
|
public InfoListAdapter(Activity a) {
|
||||||
infoItemBuilder = new InfoItemBuilder(a);
|
infoItemBuilder = new InfoItemBuilder(a);
|
||||||
|
historyRecordManager = new HistoryRecordManager(a);
|
||||||
infoItemList = new ArrayList<>();
|
infoItemList = new ArrayList<>();
|
||||||
|
states = new ArrayList<>();
|
||||||
|
stateLoaders = new CompositeDisposable();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setOnStreamSelectedListener(OnClickGesture<StreamInfoItem> listener) {
|
public void setOnStreamSelectedListener(OnClickGesture<StreamInfoItem> listener) {
|
||||||
@ -115,7 +126,17 @@ public class InfoListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
|
|||||||
this.useGridVariant = useGridVariant;
|
this.useGridVariant = useGridVariant;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addInfoItemList(List<InfoItem> data) {
|
public void addInfoItemList(final List<InfoItem> data) {
|
||||||
|
stateLoaders.add(
|
||||||
|
historyRecordManager.loadStreamStateBatch(data)
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribe(streamStateEntities -> {
|
||||||
|
addInfoItemList(data, streamStateEntities);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addInfoItemList(List<InfoItem> data, List<StreamStateEntity> statesEntities) {
|
||||||
if (data != null) {
|
if (data != null) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.d(TAG, "addInfoItemList() before > infoItemList.size() = " + infoItemList.size() + ", data.size() = " + data.size());
|
Log.d(TAG, "addInfoItemList() before > infoItemList.size() = " + infoItemList.size() + ", data.size() = " + data.size());
|
||||||
@ -123,6 +144,7 @@ public class InfoListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
|
|||||||
|
|
||||||
int offsetStart = sizeConsideringHeaderOffset();
|
int offsetStart = sizeConsideringHeaderOffset();
|
||||||
infoItemList.addAll(data);
|
infoItemList.addAll(data);
|
||||||
|
states.addAll(statesEntities);
|
||||||
|
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.d(TAG, "addInfoItemList() after > offsetStart = " + offsetStart + ", infoItemList.size() = " + infoItemList.size() + ", header = " + header + ", footer = " + footer + ", showFooter = " + showFooter);
|
Log.d(TAG, "addInfoItemList() after > offsetStart = " + offsetStart + ", infoItemList.size() = " + infoItemList.size() + ", header = " + header + ", footer = " + footer + ", showFooter = " + showFooter);
|
||||||
@ -140,6 +162,16 @@ public class InfoListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void addInfoItem(InfoItem data) {
|
public void addInfoItem(InfoItem data) {
|
||||||
|
stateLoaders.add(
|
||||||
|
historyRecordManager.loadStreamState(data)
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribe(streamStateEntity -> {
|
||||||
|
addInfoItem(data, streamStateEntity);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addInfoItem(InfoItem data, StreamStateEntity state) {
|
||||||
if (data != null) {
|
if (data != null) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.d(TAG, "addInfoItem() before > infoItemList.size() = " + infoItemList.size() + ", thread = " + Thread.currentThread());
|
Log.d(TAG, "addInfoItem() before > infoItemList.size() = " + infoItemList.size() + ", thread = " + Thread.currentThread());
|
||||||
@ -147,6 +179,7 @@ public class InfoListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
|
|||||||
|
|
||||||
int positionInserted = sizeConsideringHeaderOffset();
|
int positionInserted = sizeConsideringHeaderOffset();
|
||||||
infoItemList.add(data);
|
infoItemList.add(data);
|
||||||
|
states.add(state);
|
||||||
|
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.d(TAG, "addInfoItem() after > position = " + positionInserted + ", infoItemList.size() = " + infoItemList.size() + ", header = " + header + ", footer = " + footer + ", showFooter = " + showFooter);
|
Log.d(TAG, "addInfoItem() after > position = " + positionInserted + ", infoItemList.size() = " + infoItemList.size() + ", header = " + header + ", footer = " + footer + ", showFooter = " + showFooter);
|
||||||
@ -167,6 +200,7 @@ public class InfoListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
infoItemList.clear();
|
infoItemList.clear();
|
||||||
|
states.clear();
|
||||||
notifyDataSetChanged();
|
notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -284,7 +318,7 @@ public class InfoListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
|
|||||||
// If header isn't null, offset the items by -1
|
// If header isn't null, offset the items by -1
|
||||||
if (header != null) position--;
|
if (header != null) position--;
|
||||||
|
|
||||||
((InfoItemHolder) holder).updateFromItem(infoItemList.get(position));
|
((InfoItemHolder) holder).updateFromItem(infoItemList.get(position), states.get(position));
|
||||||
} else if (holder instanceof HFHolder && position == 0 && header != null) {
|
} else if (holder instanceof HFHolder && position == 0 && header != null) {
|
||||||
((HFHolder) holder).view = header;
|
((HFHolder) holder).view = header;
|
||||||
} else if (holder instanceof HFHolder && position == sizeConsideringHeaderOffset() && footer != null && showFooter) {
|
} else if (holder instanceof HFHolder && position == sizeConsideringHeaderOffset() && footer != null && showFooter) {
|
||||||
@ -301,4 +335,8 @@ public class InfoListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void dispose() {
|
||||||
|
stateLoaders.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
package org.schabi.newpipe.info_list.holder;
|
package org.schabi.newpipe.info_list.holder;
|
||||||
|
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import org.schabi.newpipe.R;
|
import org.schabi.newpipe.R;
|
||||||
|
import org.schabi.newpipe.database.stream.model.StreamStateEntity;
|
||||||
import org.schabi.newpipe.extractor.InfoItem;
|
import org.schabi.newpipe.extractor.InfoItem;
|
||||||
import org.schabi.newpipe.extractor.channel.ChannelInfoItem;
|
import org.schabi.newpipe.extractor.channel.ChannelInfoItem;
|
||||||
import org.schabi.newpipe.info_list.InfoItemBuilder;
|
import org.schabi.newpipe.info_list.InfoItemBuilder;
|
||||||
@ -38,8 +40,8 @@ public class ChannelInfoItemHolder extends ChannelMiniInfoItemHolder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateFromItem(final InfoItem infoItem) {
|
public void updateFromItem(final InfoItem infoItem, @Nullable final StreamStateEntity state) {
|
||||||
super.updateFromItem(infoItem);
|
super.updateFromItem(infoItem, state);
|
||||||
|
|
||||||
if (!(infoItem instanceof ChannelInfoItem)) return;
|
if (!(infoItem instanceof ChannelInfoItem)) return;
|
||||||
final ChannelInfoItem item = (ChannelInfoItem) infoItem;
|
final ChannelInfoItem item = (ChannelInfoItem) infoItem;
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
package org.schabi.newpipe.info_list.holder;
|
package org.schabi.newpipe.info_list.holder;
|
||||||
|
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import org.schabi.newpipe.R;
|
import org.schabi.newpipe.R;
|
||||||
|
import org.schabi.newpipe.database.stream.model.StreamStateEntity;
|
||||||
import org.schabi.newpipe.extractor.InfoItem;
|
import org.schabi.newpipe.extractor.InfoItem;
|
||||||
import org.schabi.newpipe.extractor.channel.ChannelInfoItem;
|
import org.schabi.newpipe.extractor.channel.ChannelInfoItem;
|
||||||
import org.schabi.newpipe.info_list.InfoItemBuilder;
|
import org.schabi.newpipe.info_list.InfoItemBuilder;
|
||||||
@ -30,7 +32,7 @@ public class ChannelMiniInfoItemHolder extends InfoItemHolder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateFromItem(final InfoItem infoItem) {
|
public void updateFromItem(final InfoItem infoItem, @Nullable final StreamStateEntity state) {
|
||||||
if (!(infoItem instanceof ChannelInfoItem)) return;
|
if (!(infoItem instanceof ChannelInfoItem)) return;
|
||||||
final ChannelInfoItem item = (ChannelInfoItem) infoItem;
|
final ChannelInfoItem item = (ChannelInfoItem) infoItem;
|
||||||
|
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
package org.schabi.newpipe.info_list.holder;
|
package org.schabi.newpipe.info_list.holder;
|
||||||
|
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import org.schabi.newpipe.R;
|
import org.schabi.newpipe.R;
|
||||||
|
import org.schabi.newpipe.database.stream.model.StreamStateEntity;
|
||||||
import org.schabi.newpipe.extractor.InfoItem;
|
import org.schabi.newpipe.extractor.InfoItem;
|
||||||
import org.schabi.newpipe.extractor.channel.ChannelInfoItem;
|
|
||||||
import org.schabi.newpipe.extractor.comments.CommentsInfoItem;
|
import org.schabi.newpipe.extractor.comments.CommentsInfoItem;
|
||||||
import org.schabi.newpipe.info_list.InfoItemBuilder;
|
import org.schabi.newpipe.info_list.InfoItemBuilder;
|
||||||
import org.schabi.newpipe.util.Localization;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Created by Christian Schabesberger on 12.02.17.
|
* Created by Christian Schabesberger on 12.02.17.
|
||||||
@ -41,8 +41,8 @@ public class CommentsInfoItemHolder extends CommentsMiniInfoItemHolder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateFromItem(final InfoItem infoItem) {
|
public void updateFromItem(final InfoItem infoItem, @Nullable final StreamStateEntity state) {
|
||||||
super.updateFromItem(infoItem);
|
super.updateFromItem(infoItem, state);
|
||||||
|
|
||||||
if (!(infoItem instanceof CommentsInfoItem)) return;
|
if (!(infoItem instanceof CommentsInfoItem)) return;
|
||||||
final CommentsInfoItem item = (CommentsInfoItem) infoItem;
|
final CommentsInfoItem item = (CommentsInfoItem) infoItem;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package org.schabi.newpipe.info_list.holder;
|
package org.schabi.newpipe.info_list.holder;
|
||||||
|
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
import android.support.v7.app.AppCompatActivity;
|
||||||
import android.text.util.Linkify;
|
import android.text.util.Linkify;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
@ -8,6 +9,7 @@ import android.widget.TextView;
|
|||||||
|
|
||||||
import org.jsoup.helper.StringUtil;
|
import org.jsoup.helper.StringUtil;
|
||||||
import org.schabi.newpipe.R;
|
import org.schabi.newpipe.R;
|
||||||
|
import org.schabi.newpipe.database.stream.model.StreamStateEntity;
|
||||||
import org.schabi.newpipe.extractor.InfoItem;
|
import org.schabi.newpipe.extractor.InfoItem;
|
||||||
import org.schabi.newpipe.extractor.comments.CommentsInfoItem;
|
import org.schabi.newpipe.extractor.comments.CommentsInfoItem;
|
||||||
import org.schabi.newpipe.info_list.InfoItemBuilder;
|
import org.schabi.newpipe.info_list.InfoItemBuilder;
|
||||||
@ -65,7 +67,7 @@ public class CommentsMiniInfoItemHolder extends InfoItemHolder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateFromItem(final InfoItem infoItem) {
|
public void updateFromItem(final InfoItem infoItem, @Nullable final StreamStateEntity state) {
|
||||||
if (!(infoItem instanceof CommentsInfoItem)) return;
|
if (!(infoItem instanceof CommentsInfoItem)) return;
|
||||||
final CommentsInfoItem item = (CommentsInfoItem) infoItem;
|
final CommentsInfoItem item = (CommentsInfoItem) infoItem;
|
||||||
|
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
package org.schabi.newpipe.info_list.holder;
|
package org.schabi.newpipe.info_list.holder;
|
||||||
|
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
|
import org.schabi.newpipe.database.stream.model.StreamStateEntity;
|
||||||
import org.schabi.newpipe.extractor.InfoItem;
|
import org.schabi.newpipe.extractor.InfoItem;
|
||||||
import org.schabi.newpipe.info_list.InfoItemBuilder;
|
import org.schabi.newpipe.info_list.InfoItemBuilder;
|
||||||
|
|
||||||
@ -35,5 +37,5 @@ public abstract class InfoItemHolder extends RecyclerView.ViewHolder {
|
|||||||
this.itemBuilder = infoItemBuilder;
|
this.itemBuilder = infoItemBuilder;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void updateFromItem(final InfoItem infoItem);
|
public abstract void updateFromItem(final InfoItem infoItem, @Nullable final StreamStateEntity state);
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
package org.schabi.newpipe.info_list.holder;
|
package org.schabi.newpipe.info_list.holder;
|
||||||
|
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import org.schabi.newpipe.R;
|
import org.schabi.newpipe.R;
|
||||||
|
import org.schabi.newpipe.database.stream.model.StreamStateEntity;
|
||||||
import org.schabi.newpipe.extractor.InfoItem;
|
import org.schabi.newpipe.extractor.InfoItem;
|
||||||
import org.schabi.newpipe.extractor.playlist.PlaylistInfoItem;
|
import org.schabi.newpipe.extractor.playlist.PlaylistInfoItem;
|
||||||
import org.schabi.newpipe.info_list.InfoItemBuilder;
|
import org.schabi.newpipe.info_list.InfoItemBuilder;
|
||||||
@ -30,7 +32,7 @@ public class PlaylistMiniInfoItemHolder extends InfoItemHolder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateFromItem(final InfoItem infoItem) {
|
public void updateFromItem(final InfoItem infoItem, @Nullable final StreamStateEntity state) {
|
||||||
if (!(infoItem instanceof PlaylistInfoItem)) return;
|
if (!(infoItem instanceof PlaylistInfoItem)) return;
|
||||||
final PlaylistInfoItem item = (PlaylistInfoItem) infoItem;
|
final PlaylistInfoItem item = (PlaylistInfoItem) infoItem;
|
||||||
|
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
package org.schabi.newpipe.info_list.holder;
|
package org.schabi.newpipe.info_list.holder;
|
||||||
|
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import org.schabi.newpipe.R;
|
import org.schabi.newpipe.R;
|
||||||
|
import org.schabi.newpipe.database.stream.model.StreamStateEntity;
|
||||||
import org.schabi.newpipe.extractor.InfoItem;
|
import org.schabi.newpipe.extractor.InfoItem;
|
||||||
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
|
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
|
||||||
import org.schabi.newpipe.info_list.InfoItemBuilder;
|
import org.schabi.newpipe.info_list.InfoItemBuilder;
|
||||||
@ -40,8 +42,8 @@ public class StreamInfoItemHolder extends StreamMiniInfoItemHolder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateFromItem(final InfoItem infoItem) {
|
public void updateFromItem(final InfoItem infoItem, @Nullable final StreamStateEntity state) {
|
||||||
super.updateFromItem(infoItem);
|
super.updateFromItem(infoItem, state);
|
||||||
|
|
||||||
if (!(infoItem instanceof StreamInfoItem)) return;
|
if (!(infoItem instanceof StreamInfoItem)) return;
|
||||||
final StreamInfoItem item = (StreamInfoItem) infoItem;
|
final StreamInfoItem item = (StreamInfoItem) infoItem;
|
||||||
|
@ -1,12 +1,15 @@
|
|||||||
package org.schabi.newpipe.info_list.holder;
|
package org.schabi.newpipe.info_list.holder;
|
||||||
|
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
import android.support.v4.content.ContextCompat;
|
import android.support.v4.content.ContextCompat;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
|
import android.widget.ProgressBar;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import org.schabi.newpipe.R;
|
import org.schabi.newpipe.R;
|
||||||
|
import org.schabi.newpipe.database.stream.model.StreamStateEntity;
|
||||||
import org.schabi.newpipe.extractor.InfoItem;
|
import org.schabi.newpipe.extractor.InfoItem;
|
||||||
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
|
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
|
||||||
import org.schabi.newpipe.extractor.stream.StreamType;
|
import org.schabi.newpipe.extractor.stream.StreamType;
|
||||||
@ -14,12 +17,15 @@ import org.schabi.newpipe.info_list.InfoItemBuilder;
|
|||||||
import org.schabi.newpipe.util.ImageDisplayConstants;
|
import org.schabi.newpipe.util.ImageDisplayConstants;
|
||||||
import org.schabi.newpipe.util.Localization;
|
import org.schabi.newpipe.util.Localization;
|
||||||
|
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
public class StreamMiniInfoItemHolder extends InfoItemHolder {
|
public class StreamMiniInfoItemHolder extends InfoItemHolder {
|
||||||
|
|
||||||
public final ImageView itemThumbnailView;
|
public final ImageView itemThumbnailView;
|
||||||
public final TextView itemVideoTitleView;
|
public final TextView itemVideoTitleView;
|
||||||
public final TextView itemUploaderView;
|
public final TextView itemUploaderView;
|
||||||
public final TextView itemDurationView;
|
public final TextView itemDurationView;
|
||||||
|
public final ProgressBar itemProgressView;
|
||||||
|
|
||||||
StreamMiniInfoItemHolder(InfoItemBuilder infoItemBuilder, int layoutId, ViewGroup parent) {
|
StreamMiniInfoItemHolder(InfoItemBuilder infoItemBuilder, int layoutId, ViewGroup parent) {
|
||||||
super(infoItemBuilder, layoutId, parent);
|
super(infoItemBuilder, layoutId, parent);
|
||||||
@ -28,6 +34,7 @@ public class StreamMiniInfoItemHolder extends InfoItemHolder {
|
|||||||
itemVideoTitleView = itemView.findViewById(R.id.itemVideoTitleView);
|
itemVideoTitleView = itemView.findViewById(R.id.itemVideoTitleView);
|
||||||
itemUploaderView = itemView.findViewById(R.id.itemUploaderView);
|
itemUploaderView = itemView.findViewById(R.id.itemUploaderView);
|
||||||
itemDurationView = itemView.findViewById(R.id.itemDurationView);
|
itemDurationView = itemView.findViewById(R.id.itemDurationView);
|
||||||
|
itemProgressView = itemView.findViewById(R.id.itemProgressView);
|
||||||
}
|
}
|
||||||
|
|
||||||
public StreamMiniInfoItemHolder(InfoItemBuilder infoItemBuilder, ViewGroup parent) {
|
public StreamMiniInfoItemHolder(InfoItemBuilder infoItemBuilder, ViewGroup parent) {
|
||||||
@ -35,7 +42,7 @@ public class StreamMiniInfoItemHolder extends InfoItemHolder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateFromItem(final InfoItem infoItem) {
|
public void updateFromItem(final InfoItem infoItem, @Nullable final StreamStateEntity state) {
|
||||||
if (!(infoItem instanceof StreamInfoItem)) return;
|
if (!(infoItem instanceof StreamInfoItem)) return;
|
||||||
final StreamInfoItem item = (StreamInfoItem) infoItem;
|
final StreamInfoItem item = (StreamInfoItem) infoItem;
|
||||||
|
|
||||||
@ -47,13 +54,22 @@ public class StreamMiniInfoItemHolder extends InfoItemHolder {
|
|||||||
itemDurationView.setBackgroundColor(ContextCompat.getColor(itemBuilder.getContext(),
|
itemDurationView.setBackgroundColor(ContextCompat.getColor(itemBuilder.getContext(),
|
||||||
R.color.duration_background_color));
|
R.color.duration_background_color));
|
||||||
itemDurationView.setVisibility(View.VISIBLE);
|
itemDurationView.setVisibility(View.VISIBLE);
|
||||||
|
if (state != null) {
|
||||||
|
itemProgressView.setVisibility(View.VISIBLE);
|
||||||
|
itemProgressView.setMax((int) item.getDuration());
|
||||||
|
itemProgressView.setProgress((int) TimeUnit.MILLISECONDS.toSeconds(state.getProgressTime()));
|
||||||
|
} else {
|
||||||
|
itemProgressView.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
} else if (item.getStreamType() == StreamType.LIVE_STREAM) {
|
} else if (item.getStreamType() == StreamType.LIVE_STREAM) {
|
||||||
itemDurationView.setText(R.string.duration_live);
|
itemDurationView.setText(R.string.duration_live);
|
||||||
itemDurationView.setBackgroundColor(ContextCompat.getColor(itemBuilder.getContext(),
|
itemDurationView.setBackgroundColor(ContextCompat.getColor(itemBuilder.getContext(),
|
||||||
R.color.live_duration_background_color));
|
R.color.live_duration_background_color));
|
||||||
itemDurationView.setVisibility(View.VISIBLE);
|
itemDurationView.setVisibility(View.VISIBLE);
|
||||||
|
itemProgressView.setVisibility(View.GONE);
|
||||||
} else {
|
} else {
|
||||||
itemDurationView.setVisibility(View.GONE);
|
itemDurationView.setVisibility(View.GONE);
|
||||||
|
itemProgressView.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default thumbnail is shown on error, while loading and if the url is empty
|
// Default thumbnail is shown on error, while loading and if the url is empty
|
||||||
|
@ -36,6 +36,7 @@ import org.schabi.newpipe.database.stream.dao.StreamDAO;
|
|||||||
import org.schabi.newpipe.database.stream.dao.StreamStateDAO;
|
import org.schabi.newpipe.database.stream.dao.StreamStateDAO;
|
||||||
import org.schabi.newpipe.database.stream.model.StreamEntity;
|
import org.schabi.newpipe.database.stream.model.StreamEntity;
|
||||||
import org.schabi.newpipe.database.stream.model.StreamStateEntity;
|
import org.schabi.newpipe.database.stream.model.StreamStateEntity;
|
||||||
|
import org.schabi.newpipe.extractor.InfoItem;
|
||||||
import org.schabi.newpipe.extractor.stream.StreamInfo;
|
import org.schabi.newpipe.extractor.stream.StreamInfo;
|
||||||
import org.schabi.newpipe.player.playqueue.PlayQueueItem;
|
import org.schabi.newpipe.player.playqueue.PlayQueueItem;
|
||||||
|
|
||||||
@ -220,6 +221,40 @@ public class HistoryRecordManager {
|
|||||||
})).subscribeOn(Schedulers.io());
|
})).subscribeOn(Schedulers.io());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Single<StreamStateEntity> loadStreamState(final InfoItem info) {
|
||||||
|
return Single.fromCallable(() -> {
|
||||||
|
final List<StreamEntity> entities = streamTable.getStream(info.getServiceId(), info.getUrl()).blockingFirst();
|
||||||
|
if (entities.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
final List<StreamStateEntity> states = streamStateTable.getState(entities.get(0).getUid()).blockingFirst();
|
||||||
|
if (states.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return states.get(0);
|
||||||
|
}).subscribeOn(Schedulers.io());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Single<List<StreamStateEntity>> loadStreamStateBatch(final List<InfoItem> infos) {
|
||||||
|
return Single.fromCallable(() -> {
|
||||||
|
final List<StreamStateEntity> result = new ArrayList<>(infos.size());
|
||||||
|
for (InfoItem info : infos) {
|
||||||
|
final List<StreamEntity> entities = streamTable.getStream(info.getServiceId(), info.getUrl()).blockingFirst();
|
||||||
|
if (entities.isEmpty()) {
|
||||||
|
result.add(null);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
final List<StreamStateEntity> states = streamStateTable.getState(entities.get(0).getUid()).blockingFirst();
|
||||||
|
if (states.isEmpty()) {
|
||||||
|
result.add(null);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
result.add(states.get(0));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}).subscribeOn(Schedulers.io());
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////
|
||||||
// Utility
|
// Utility
|
||||||
///////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////
|
||||||
|
@ -23,7 +23,6 @@ import android.support.annotation.Nullable;
|
|||||||
import android.support.v4.app.FragmentManager;
|
import android.support.v4.app.FragmentManager;
|
||||||
import android.support.v4.content.LocalBroadcastManager;
|
import android.support.v4.content.LocalBroadcastManager;
|
||||||
import android.support.v7.app.ActionBar;
|
import android.support.v7.app.ActionBar;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
|
||||||
import android.support.v7.widget.GridLayoutManager;
|
import android.support.v7.widget.GridLayoutManager;
|
||||||
import android.support.v7.widget.LinearLayoutManager;
|
import android.support.v7.widget.LinearLayoutManager;
|
||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
@ -48,10 +47,8 @@ import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
|||||||
import org.schabi.newpipe.extractor.subscription.SubscriptionExtractor;
|
import org.schabi.newpipe.extractor.subscription.SubscriptionExtractor;
|
||||||
import org.schabi.newpipe.fragments.BaseStateFragment;
|
import org.schabi.newpipe.fragments.BaseStateFragment;
|
||||||
import org.schabi.newpipe.info_list.InfoListAdapter;
|
import org.schabi.newpipe.info_list.InfoListAdapter;
|
||||||
import org.schabi.newpipe.report.UserAction;
|
|
||||||
import org.schabi.newpipe.local.subscription.services.SubscriptionsExportService;
|
import org.schabi.newpipe.local.subscription.services.SubscriptionsExportService;
|
||||||
import org.schabi.newpipe.local.subscription.services.SubscriptionsImportService;
|
import org.schabi.newpipe.local.subscription.services.SubscriptionsImportService;
|
||||||
import org.schabi.newpipe.report.ErrorActivity;
|
|
||||||
import org.schabi.newpipe.report.UserAction;
|
import org.schabi.newpipe.report.UserAction;
|
||||||
import org.schabi.newpipe.util.FilePickerActivityHelper;
|
import org.schabi.newpipe.util.FilePickerActivityHelper;
|
||||||
import org.schabi.newpipe.util.NavigationHelper;
|
import org.schabi.newpipe.util.NavigationHelper;
|
||||||
@ -131,6 +128,12 @@ public class SubscriptionFragment extends BaseStateFragment<List<SubscriptionEnt
|
|||||||
subscriptionService = SubscriptionService.getInstance(activity);
|
subscriptionService = SubscriptionService.getInstance(activity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDetach() {
|
||||||
|
infoListAdapter.dispose();
|
||||||
|
super.onDetach();
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
|
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
|
||||||
|
@ -66,4 +66,16 @@
|
|||||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||||
android:textSize="@dimen/video_item_search_uploader_text_size"
|
android:textSize="@dimen/video_item_search_uploader_text_size"
|
||||||
tools:text="Uploader"/>
|
tools:text="Uploader"/>
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:id="@+id/itemProgressView"
|
||||||
|
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
|
||||||
|
android:progressDrawable="?progress_horizontal_drawable"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="4dp"
|
||||||
|
android:layout_marginTop="-2dp"
|
||||||
|
android:layout_alignStart="@id/itemThumbnailView"
|
||||||
|
android:layout_alignEnd="@id/itemThumbnailView"
|
||||||
|
android:layout_below="@id/itemThumbnailView"/>
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
@ -79,4 +79,16 @@
|
|||||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||||
android:textSize="@dimen/video_item_search_upload_date_text_size"
|
android:textSize="@dimen/video_item_search_upload_date_text_size"
|
||||||
tools:text="2 years ago • 10M views"/>
|
tools:text="2 years ago • 10M views"/>
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:id="@+id/itemProgressView"
|
||||||
|
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
|
||||||
|
android:progressDrawable="?progress_horizontal_drawable"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="4dp"
|
||||||
|
android:layout_marginTop="-2dp"
|
||||||
|
android:layout_alignStart="@id/itemThumbnailView"
|
||||||
|
android:layout_alignEnd="@id/itemThumbnailView"
|
||||||
|
android:layout_below="@id/itemThumbnailView"/>
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
@ -69,4 +69,16 @@
|
|||||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||||
android:textSize="@dimen/video_item_search_uploader_text_size"
|
android:textSize="@dimen/video_item_search_uploader_text_size"
|
||||||
tools:text="Uploader" />
|
tools:text="Uploader" />
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:id="@+id/itemProgressView"
|
||||||
|
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
|
||||||
|
android:progressDrawable="?progress_horizontal_drawable"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="4dp"
|
||||||
|
android:layout_marginTop="-2dp"
|
||||||
|
android:layout_alignStart="@id/itemThumbnailView"
|
||||||
|
android:layout_alignEnd="@id/itemThumbnailView"
|
||||||
|
android:layout_below="@id/itemThumbnailView"/>
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
Loading…
Reference in New Issue
Block a user